オンプレサーバーに加え、複数のクラウドサービスや VPS を使うようになってくると Linux サーバーのアカウント管理が非常に面倒になってきました。(全てがコンテナと SaaS になるのはまだ先)
そこで以前から気になっていた STNS を試してみることにしました。すべてを VPN で接続しているわけでもなく、IPアドレス制限で頑張るのもクラウドらしくなく LDAP 公開は出来ない。STNS はクライアント証明書も使えるし、ユーザーのパスワードを登録しなければ最悪取られてもアカウント名、uid, gid, 公開鍵程度なので公開しても大丈夫そう。
STNSサーバー が公開されていますが、サーバーグループごとにログインできる人をコントロールしったかったため独自のサーバーを書くことにしました。STNS は HTTP で https://stns.jp/en/interface に沿った JSON を返せば良いだけなのでサーバーを書くのも難しくありませんでした。
作ったプロトタイプサーバー
- 管理 UI としてDjango の Adminapp が便利そうだったので Django に挑戦しました
- ユーザーは複数の公開鍵を持つ
- ユーザーは複数の unix group に所属できる
- ユーザーには有効期限を設定可能
- ユーザーは有効・無効フラグをもつ
- サーバーの識別は Basic 認証のIDまたはクライアント証明書のCommonNameを使う
- サーバーとユーザーがそれぞれ1つ以上のロールを持ち、これでどのユーザーがどのサーバーにログインできるのかを制御する
サーバーの起動
CentOS 7 でとりあえず起動
sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm
sudo yum -y install git gcc python36u python36u-devel python36u-pip
git clone https://github.com/yteraoka/morion.git
cd morion
git checkout develop
python3.6 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
cd morion
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver 0.0.0.0:8000
http://server:8000/admin/ にアクセスして createsuperuser
で作成したアカウントでログインして各種リソースを作成する。クライアント証明書によるサーバー識別は未実装なので Basic 認証を使う、サーバーリソースにパスワードを設定する。
CentOS 7 でのクライアントセットアップ
package のインストール
curl -fsSL https://repo.stns.jp/scripts/yum-repo.sh | sh
sudo yum -y install stns libnss-stns libpam-stns nscd
libnss_stns.conf の編集
sudoedit /etc/stns/libnss_stns.conf
次の内容で package に含まれており、環境に合わせて編集する
api_end_point = ["http://localhost:1104/v3"]
# user = "basic_user"
# password = "basic_password"
# wrapper_path = "/usr/local/bin/stns-query-wrapper"
# chain_ssh_wrapper = "/usr/libexec/openssh/ssh-ldap-wrapper"
# ssl_verify = true
# request_timeout = 3
# http_proxy = "http://example.com:8080"
# [request_header]
# x-api-key = "token"
ログイン時に Home directory を作成するための設定
echo 'session required pam_mkhomedir.so skel=/etc/skel/ umask=0022' \
| sudo bash -c "cat >> /etc/pam.d/sshd"
OpenSSH Server が Public key を STNS サーバーから取得できるようにする
sudo sed -i -r \
-e 's@^#?(AuthorizedKeysCommand) .*@\1 /usr/lib/stns/stns-key-wrapper@' \
-e 's@^#?(AuthorizedKeysCommandUser) .*@\1 root@' \
/etc/ssh/sshd_config
sudo systemctl restart sshd
nsswitch.conf 設定 (passwd, shadow, group に stns を追加)
sudoedit /etc/nsswitch.conf
passwd: files sss stns
shadow: files sss stns
group: files sss stns
nscd.conf 設定 (毎回外部へ問い合わせていては遅いのでキャッシュさせる)
sudoedit /etc/nscd.conf
sudo systemctl enable nscd
sudo systemctl start nscd
(TTL の動作が期待と違ってよくわからん・・・)
SELinux 対応
SELinux が enforcing だとうまく動かないため、関係するドメインを permissive にする
sudo yum -y install policycoreutils-python
sudo semanage permissive -a sshd_t
sudo semanage permissive -a chkpwd_t
sudo semanage permissive -a nscd_t
試してみて
- 便利、使えそう
- 履歴などを残そうとすると Web UI を持たせるよりも TOML や YAML で Git 管理の方が良かった
- オリジナルの STNS サーバーはコレで TOML ファイル管理
- 更新頻度的にも Web UI は必要じゃなかった
- サーバー書き直して実用したい
Slide
https://www.slideshare.net/yteraoka1/stns
追記
ユーザー(グループ)単位でのアクセス制限については sshd_config の AllowGroups を使うことで解決できるため、これを理由に独自サーバーを実装する必要はなかったと判明しました。