Edited at

STNSの独自サーバーを書いてみた

オンプレサーバーに加え、複数のクラウドサービスや 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 のインストール

https://github.com/STNS/libnss_stns

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 を使うことで解決できるため、これを理由に独自サーバーを実装する必要はなかったと判明しました。