Linuxユーザ管理の決定版？ 〜STNSとサーバレスで夢が広がる〜【cloudpack大阪ブログ】

#こんなん作りました
STNS＋AWS API Gataway＋DynamoDBでサーバレスユーザ統合管理
https://github.com/shogomuranushi/stns-apibackend
#これなんなん？
STNSという簡易LDAP的なユーザ管理のOSSとAPI Gateway、DynamoDBを組み合わせたもの
#何が出来るん？
複数台のLinuxユーザ管理を手軽にサーバレスで出来る

#今までのユーザ管理は何があかんかったん？
|How|Use|
|:--|:--|
|PAM|ベター。複数台は管理出来ない。複数台管理するなら同じコマンドとかを実行して回る必要有り|
|LDAP|Lightweight？大規模なら良いけど管理面倒。学習コスト高い|
|STNS|これ。（以下参照）|

#STNS
[![STNS](https://qiita-image-store.s3.amazonaws.com/0/7454/b085f587-16fa-655d-1dd7-b8c4a6ffaaa9.jpeg "STNS")](https://speakerdeck.com/pyama86/shi-dai-gaqiu-metastnstopu)

#STNSで何が課題やったん？
お客さん「十数台規模でLDAPとか面倒だよね。管理とか冗長化とかも考えたくないし。」
俺「STNSでもサーバ側のインフラ管理面倒だな、、。やりたいのはユーザ管理でサーバ管理じゃないし」
俺「STNSのバックエンドははRESTで受けてJSONで返せば何でもいいのか。API GatewayとDynamoDB使えばバックエンドをサーバレスに出来るんじゃ？」

# 実現したこと
STNS＋AWS API Gataway＋DynamoDBでサーバレスユーザ統合管理

# 構成
|What|How|
|:--|:--|
|クライアント（Linuxサーバ）|STNS|
|バックエンドのSTNSサーバ|API Gateway＋DynamoDB|

# 特徴
## STNSでシンプルにユーザの統合管理を実現
- シンプルで軽量
- 既存のPAMも併用可能
- バックエンドはRESTであれば自由

## バックエンドのSTNSサーバはAPI GatewayとDynamoDBを利用することでサーバレスで高可用性
- 冗長化とか考える必要無し（もちろん止まることはある）
- DynamoDBは複数箇所にデータ分散してるためバックアップ不要
- PaaSなのでサーバの運用とか障害対応とか不要
- サーバ間はAPIキーにて認証

## OSユーザの管理もAWSコンソールからする時代に
- ユーザ管理はDynamoDB上なのでマネジメントコンソール
- もちろんAWS CLI、SDKで管理も可能

#導入方法（安心してください。自動化してます。）
##準備するもの
###AWSのアクセスキー、シークレットキーを手元に
##1.terraformのインストール
1. https://www.terraform.io/downloads.html からterraformをダウンロードし解凍する
1. パスの通ったディレクトリに置くか、任意のディレクトリに置いてパスを通してください
1. terraform --helpを実行しヘルプが表示されたらインストール完了

```bash
$ terraform --help
```
##2.stns-apibackend（apigateway+dynamodb）のインストール
```bash
$ git clone https://github.com/shogomuranushi/stns-apibackend.git
$ cd stns-apibackend
$ vi aws.tf

variable "role" {
    default = "user" #必要に応じて好きな役割名に変更
}

variable "region" {
    default = "ap-northeast-1" #API GatewayとDynamoDBをデプロイするリージョンを指定
}

provider "aws" {
    access_key = "" #アクセスキーを指定
    secret_key = "" #シークレットキーを指定
    region = "${var.region}"
}
```
##3.stns-apibackend（apigateway+dynamodb）の構築
terraform実行後に最終行に表示される「API Gateway URL」「API Key」をメモる。
※ applyは1回目でエラーが出た場合はもう一度実行してください。実行順序の整理が出来ていません。

```bash
$ terraform plan #動作確認
$ terraform apply #実行、反映
xxx
xxx
xxx

Outputs:

API Gateway URL = https://xxxxxxx
API Key = xxxxxx
```

##4.stnsのインストールと各種設定
最新手順や、やってる内容は http://stns.jp/ja/install 参照
簡易に試したい人はクライアントとなるサーバで、以下に↑の「API Gateway URL」と「API Key」を埋め込んでコピペしてください

```bash
API_Gateway_URL="https://xxx"
API_Key="xxx"

# STNSのインストール
curl -fsSL https://repo.stns.jp/scripts/yum-repo.sh | sh
yum -y install stns libnss-stns libpam-stns nscd

# ユーザーとグループ名の名前解決をキャッシュ関係
cat <<EOF > /etc/nscd.conf
#      	logfile			/var/log/nscd.log
#      	threads			4
#      	max-threads    		32
       	server-user    		nscd
#      	stat-user      		somebody
       	debug-level    		0
#      	reload-count   		5
       	paranoia       		no
#      	restart-interval       	3600
enable-cache            passwd          yes
positive-time-to-live   passwd          180
negative-time-to-live   passwd          300
check-files             passwd          yes
shared                  group           yes

enable-cache            group           yes
positive-time-to-live   group           180
negative-time-to-live   group           300
check-files             group           yes
shared                  group           yes

enable-cache            hosts           no
enable-cache            services        no
enable-cache            netgroup        no
EOF
service nscd reload

# STNSサーバの接続先定義
sed -i -e "s/^api_end_point/#api_end_point/g" /etc/stns/libnss_stns.conf
sed -i -e "s/# wrapper_path/wrapper_path/g" /etc/stns/libnss_stns.conf
echo "api_end_point = [\"${API_Gateway_URL}\"]" >> /etc/stns/libnss_stns.conf
echo "x-api-key = \"${API_Key}\"" >> /etc/stns/libnss_stns.conf


# STNS経由での名前解決を有効
sed -i -e "s/passwd:     files sss/passwd:     files stns sss/g" /etc/nsswitch.conf
sed -i -e "s/shadow:     files sss/shadow:     files stns sss/g" /etc/nsswitch.conf
sed -i -e "s/group:      files sss/group:      files stns sss/g" /etc/nsswitch.conf

# ログイン時のホームディレクトリ作成（この手順はSTNSインストール手順になかった）
echo "session optional pam_mkhomedir.so skel=/etc/skel umask=022" >> /etc/pam.d/system-auth-ac
echo "session optional pam_mkhomedir.so skel=/etc/skel umask=022" >> /etc/pam.d/password-auth

# SSHログインを可能にする
echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config
echo "AuthorizedKeysCommand /usr/lib/stns/stns-key-wrapper" >> /etc/ssh/sshd_config
echo "AuthorizedKeysCommandUser root" >> /etc/ssh/sshd_config
service sshd restart
```
##5.ユーザ追加（お好きにどうぞ）
DynamoDBの「user-stns-osuser」と「user-stns-osgroup」にユーザ情報を登録
※サンプル等を登録する詳細は以下参照

##6. 動作確認

```bash
$ id orenouser
uid=1002(orenouser) gid=1002(orenogroup) groups=1002(orenogroup)
```

#管理方法
##DynamoDBなのでマネージメントコンソールでもSDK経由でも更新可能
###一応、サンプル用意した。
アクセスキー、シークレットキーを入れて下さい

```bash
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_DEFAULT_REGION=ap-northeast-1
./dynamodb-sampleuser.sh
```
##補足：DynamoDB定義情報
### user情報（表）

|Key|Value|
|:--|:--|
| name |orenouser|
| id |1002|
| directory |/home/orenouser|
| gecos |null|
| group_id |1002|
| keys |"ssh-rsa xxxxx"|
| link_users |null|
| password |null|
| shell |/bin/bash|

### group情報（表）

|Key|Value|
|:--|:--|
| name |orenogroup|
| id |1002|
| link_groups |null|
| users |"orenouser"|

#最後に
API GatewayとDynamoDBはPaaSなので止まることは有る
止まった時用に別口で入れるユーザ（PAM）は用意しておいてください

#いろいろ夢広がりますな