ポートフォリオを作り始めた

# ポートフォリオを作り始めた（備忘録的な）

久しぶりの投稿です。ポートフォリオサイトを作り始めました。
こんな感じの。

[ポートフォリオ](http://hnkznosite.mydns.jp/)
([github](https://github.com/hnkz/rocket_server_for_portfolio))

まだやっと原型が完成したなーって感じです(2018/3/3時点)。
苦労した点とかまとめて行きます。

## 構成
サーバ側は全てRustで書いています。RocketというWebフレームワークを使いました。
フロントは普通にJS。

ターミナル形式のかっこいいサイト作りました。
コマンドは全て鯖側で処理します。

## 苦労した点その1 Rust
Rustがまだよくわからない、色々と作ったりしてるんですが、Rustの掟にしたがって書けているのか、いまいちわからない。文字列処理らへんが特にわかってない気がする。**真面目**に調査をする必要があるなぁ...

### 軽く解説　&str と String
(途中）

Rustには&strとStringの二つの文字列型がある。

参考[String vs &str in Rust functions](http://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html)

## 苦労した点その2 JSの非同期処理
Promise、最初はわからなかったんですが、素晴らしいですねこれ。
コードの形で処理順がわかるので、以前（コールバック地獄の時代）と比べるとかなり読みやすいし、作るのも楽ですね。

```javascript
// get response
        post_ajax_call("/api/ajax/post_do_command", command).then((result) => {
                console.log(result);
                type_elm.innerHTML += "<br>" + result;
                console.log(type_elm.innerHTML);

                // scroll bottom
                bottom.scrollIntoView(true);
                return post_ajax_call("/api/ajax/post_pre_prompt", "");
            })
            .then((result) => {
                pre_prompt_text = result;

                // create element
                var new_now_line = document.createElement("span");
                new_now_line.id = "now_line";
                new_now_line.innerHTML = pre_prompt_layout.replace(/\#\#\#/g, pre_prompt_text);

                // add element
                type_elm.parentNode.insertBefore(new_now_line, type_elm.nextSibling);

                // remove element
                type_elm.removeAttribute("id");

            })
            .catch((err) => {
                console.log("error: " + err);
            })
```

thenの中のアロー関数でPromiseを返してるのがポイント。
そこでまたthenを呼んで、同期処理を書いていきます。

## 苦労した点その3 サーバの権限設定
擬似SSHは完成したが、任意のコマンドが実行できる状態だった。それはかなりまずい...
だってこんなコマンドが実行できちゃう。
`sudo rm -rf /`
こんなのも
`:(){:|:&};:`

~~流石にまずいので、権限に制限を設けたユーザを作成した。でもどこかに漏れがありそう。何か発見した人はぜひ教えていただきたい...😢~~

rbashを用いて権限を絞ってたんですが、systemdを導入したらうまく動かなくなってしまいました...
ですから、代わりにchroot環境を導入しました。

### 軽く解説 超権限を絞ったユーザの作り方とプログラムの実行(chroot環境)
(途中）

### 軽く解説 超権限を絞ったユーザの作り方とプログラムの実行(rbash環境)

* 権限を絞ったguestユーザを作る
* コマンドの実行権限をguestユーザにする

上の二つが実現できれば、root権限には触れらない制限された環境が作れそう。

とういことで、ググってたら、以下を発見。

[rbashで一部のユーザが実行できるコマンドを制限する(特定コマンドしか実行できないようにする)](https://orebibou.com/2016/09/rbash%E3%81%A7%E4%B8%80%E9%83%A8%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%8C%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%88%B6%E9%99%90%E3%81%99/)


発見したリンクを参考に以下の作業を行なった。

1. `/opt/bin`にrbashのシンボリックリンクを作ってあげる
    * `ln -s /bin/bash /opt/bin/rbash`
2. rbashを起動シェルとしたユーザguestを作成
    * `useradd -m -s /opt/bin/rbash`
    * `passwd guest`でパスワードを付与
3. `/opt/bin/guest`にguestが使えるコマンドをシンボリックリンクで置いてあげる
    * `ln -s /bin/ls /opt/bin/guest`みたいな感じ
4. `.bashrc`に`export PATH="/opt/bin/guest"'に書き込む

上記作業後`login guest`でguestにログインしたら、ガッチガチに固められたguestユーザを作成できた。
guestでwebサーバを実行することで、コマンドにも制限をつけることができた。

今回ポートフォリオを作りはじめて、rbashについて初めて知った。以下、rbashの備忘録的なものを残しておきます。

#### rbash

rbashとはbashに制限をつけたシェルのこと。bashと比べて以下のような制限がある。

* cdできない
* 環境変数を変更できない
* /を含むコマンドを実行できない（引数には取れる）
* リダイレクトできない（そもそも今回の擬似SSHではリダイレクト機能がない）
* execできない
* カレントディレクトリで/を含むシェルスクリプトを実行できない
* 起動時にシェルで定義された関数を実行できない ...などなど

これらの制限は、起動ファイルが読まれた後に施行されるそう。
だから、`.bashrc`とかは処理してくれる。

ただ、シェルスクリプトを実行されると、rbashの制限が一気に解けちゃうらしい。
そこだけ気をつけていればOKかな...?

参考[いますぐ実践! Linux システム管理](http://www.usupi.org/sysad/042.html)