LoginSignup
6

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-12-11

オンプレサーバーに加え、複数のクラウドサービスや 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つ以上のロールを持ち、これでどのユーザーがどのサーバーにログインできるのかを制御する

stns-server-1.png

サーバーの起動

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

stns-server-slide1.png
https://www.slideshare.net/yteraoka1/stns

追記

ユーザー(グループ)単位でのアクセス制限については sshd_config の AllowGroups を使うことで解決できるため、これを理由に独自サーバーを実装する必要はなかったと判明しました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6