LoginSignup
10
6

More than 3 years have passed since last update.

stnsバックエンドでユーザを一元管理

Last updated at Posted at 2018-09-11

はじめに

stnsを使ってユーザ管理を一元化したので、その構築手順や実装例を紹介します。

STNSとは?

サーバにSSHログインする際に使用する公開鍵をtoml形式のファイル(もしくはstns I/Fを
持ったバックエンド)で提供することで、ユーザの設定状態を一元管理するためのツールです。
各サーバにOSユーザを作成する必要がなく、一元管理でき、利用者の増減(例えば、
入社、部署移動、退職など)を簡単に反映でき、運用の手間を減らせます。
こちらを読めば開発の動機、背景がわかります。

STNSバックエンドを自前で立てる理由

そもそもなぜ自前のバックエンドが必要かというと、stnsには標準でtoml形式でユーザ管理するバックエンドが
同梱されていますが、それを使う場合にtomlファイルをgit等で管理すること(情報の一元管理)はできますが、
結局各サーバにそのtomlを反映する必要があり、状態の一元管理は難しい。
(反映自動化してもいいのですが、サーバ数や環境増減の頻度によってはそれでもツライし。。)
そのため、利用者共通(全サービス/サーバ共通)で使うSTNSバックエンドが必要と考えました。

やりたいこと

今回実装したSTNSバックエンド要件です。

  • 複数サービス/環境を跨ってユーザ一元管理
  • 登録ユーザは全ての環境にログインできる
  • (QA/本番等の)環境ごとにsudo可能なユーザを設定できる

シンプルにしました。
複数の自社サービス(異なるNW環境で稼働)、全て内製、という弊社の環境としては、上記で十分という感じです。
要件変われば実装変えて対応できますし^^;

やれなくてよいこと

  • sudoパスワードは管理しない
  • 組織構造はフラット(link_groupsは使用しない)

構成

環境概要

  • インフラ構成
    • AWSを使います
    • STNSクライアント -> API Gateway + Lambda + DynamoDB

stnsbackend.jpg

DynamoDBテーブル構成

stns-osuser、stns-authorityという2テーブルで管理します。
2テーブルともにnameというカラムがプライマリキーとなります。

stns-osuser

  • ユーザごとに下記の情報を1レコードとして登録します
カラム名 設定例 説明 必須 補足
name miyaz ユーザ名 半角英数字の任意ユーザ名
id 10002 ユーザID
directory /home/miyaz ホームディレクトリ 指定しない場合は/home/{name}となります
keys ssh-rsa 〜〜,ssh-rsa 〜〜〜 公開鍵 公開鍵をカンマ区切りで指定できます
link_users deploy 公開鍵参照ユーザ 指定したユーザの公開鍵をkeysに加えます
setup_commands ["/bin/sh base_setup.sh","/bin/sh custom_setup.sh"] stns-setup実行コマンド stns-setupで実行したいコマンドをJSON(配列)形式で指定可能。詳細後述
setup_variables {\"MAILADDRESS\":\"miyaz@example.com\"} stns-setup実行環境変数 stns-setup実行時に設定するシェル変数をJSON(ハッシュ)形式で指定可能。詳細後述

※「値を指定しない」状態とは、レコードにそのカラムが存在しない、もしくはnullという文字列が指定された状態を指します

stns-authority

  • 環境ごとにsudo可能なユーザを定義します
  • 環境を識別する文字列をstnsクライアント設定(libnss_stns.conf)のBasic認証ユーザ名として指定します
  • 一致するレコードがない場合はname=defaultというレコードを使用します(そのため、defaultレコードは必須)
カラム名 設定例 説明 必須 補足
name ec-prod 環境を識別する文字列
superusers miyaz sudo可能ユーザ カンマ区切りで指定されたユーザをadmin(10001)セカンダリグループとして追加します

※対象サーバのsudoersに、adminグループのNOPASSWORD sudo権限が付与されている前提となります(ansibleで設定してください)
※全ユーザはデフォルトでoperator(10000)グループに属します

stns-setupについて

stnsを使用してsshログインしたユーザはstns-setupというコマンドが使えるようになります。
このコマンド実行時に実際に何を実行するかをstnsバックエンドからのレスポンスで指定できます。
参考事例

stns-osuserテーブルのsetup_commandsの指定有無に関わらず、デフォルトで ~/.stns-setup.shを実行します。
実行時にコマンドに渡すシェル変数を、setup_varibalesで指定することができます。
例えば、setup_varibalesに{"MAILADDRESS":"miyaz@example.com"}を指定している場合に
stns-setupコマンドで実行されるコマンドラインは下記のようになります。

env MAILADDRESS=miyaz@example.com /bin/sh /home/miyaz/.stns-setup.sh

この場合、.stns-setup.sh内でMAILADDRESS変数を使って必要な処理を行うことができます。
その他にもSlackユーザ名やGitHubユーザ名などを登録しておくといろいろ使えるかもしれません。

例えば下記のようなことに使えます。

  • 開発環境のアラートメール送信先定義を書き換えてアラートメールを自分宛てにする
  • Slack通知スクリプトの通知先を自分宛てのSlackユーザ名に書き換える
  • GitHubユーザ名を .gitconfigに設定して、gitでごにょごにょする

セットアップ手順

以降東京リージョン指定して作業すること

DynamoDB作成

  • stns-osuserテーブル作成
    • プライマリキーname
    • その他デフォルト設定を使用
      • Auto Scaling 無効と表示されている場合はデフォルト設定を外して再作成
  • stns-authorityテーブル作成
    • プライマリキーname
    • その他デフォルト設定を使用
  • 上述のテーブル構成を参照し、必要なユーザ情報を登録しておくこと

Lambda作成

  • 関数を作成

    • 名前[stnsBackend]を指定
    • ランタイム[Node.js 8.10]を指定
    • カスタムロールとしてロール名[lambda_stnsbackend_execution]を入力
      • Actionには ["dynamodb:*"] を指定
      • Resourceには作成した2テーブルのARNを指定
  • コードをzipアップロード

    • 事前に~/.aws/credentials設定とnodebrew等でnodejs(v8.10.0推奨)をインストールしておくこと
    • コードをgit clone
      • git clone https://github.com/miyaz/stns-backend.git; cd stns-backend
    • 必要なnodeモジュール収集
      • npm install
    • デプロイを実行
      • npm run gulp deploy

API Gateway作成

  • 新しいAPIを作成

    • API名[StnsBackend]
    • 説明[stnsバックエンド用lambdaにproxyします]
    • エンドポイントタイプ[地域]
  • リソースの作成

    • プロキシリソースとして設定のチェックを入れて作成
    • 統合タイプ[Lambda関数プロキシ]
    • Lambdaリージョン[ap-northeast-1]
    • Lambda関数[stnsBackend]
  • APIのデプロイ

    • デプロイされるステージ[新しいステージ]
    • ステージ名[prod]
  • APIキー作成

    • 名前[stns_backend_key]
    • APIキー[自動生成]
      • このキーはstnsクライアント(libnss_stns.conf)に指定するので控えておくこと
  • 使用量プラン作成(任意)

    • 名前[stns_backend_plan]
    • スロットリング レート[100] バースト[200]
    • クォータは指定なし
    • APIステージの追加
      • API[StnsBackend] ステージ[prod]
  • カスタムドメイン用ACM発行

    • ドメイン名[stns.example.com](任意)
    • 検証方法[Eメールの検証]を選択
    • 証明書リクエスト実施後届いたメールのリンクをクリックして承認する
  • カスタムドメイン名作成

    • ドメイン名[stns.example.com]
    • エンドポイントの設定[Regional]
    • ACM証明書で作成済み証明書を選択
    • ベースパスマッピング追加
      • パス[/]
      • 送信先[StnsBackend]
      • ステージ[prod]

Route53設定

  • example.comのホステッドゾーンを編集
    • stns.example.comのCNAMEにAPI Gatewayのドメインを指定

サーバ設定

  • sudoersに%admin ALL=(ALL) NOPASSWD:ALLを追記
  • stnsを導入し、libnss_stns.confを下記のように設定
/etc/stns/libnss_stns.conf
api_end_point = ["https://stns.example.com"]

# 環境を識別する名称を指定(stns-authorityテーブルname列で権限チェック)
user = "hoge-service"
password = "dummy"

ssl_verify = true
request_timeout = 3

[request_header]
x-api-key = "API GatewayのAPI認証に使用するキー"

動作確認

  • stns-osuserテーブルに登録されたユーザでsshログインできること
  • stns-authorityテーブルにsuperusers列に指定されたユーザでログインし、sudo lsが実行できること

おわりに

実際に運用してみて、ユーザ追加、権限昇格、削除などが一瞬で反映できるので便利です!!
一元管理することでユーザ/権限の消し忘れなども減るためセキュリティ的にも向上します。
あとは、ユーザ追加、削除などをgitで管理して、pushされたらDynamoDBに反映って
とこまで作ればもっと楽できますね。(今後やる予定)

10
6
0

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
  3. You can use dark theme
What you can do with signing up
10
6