STNSでSudoパスワードをサポートした

STNS 0.0.4、libnss-stns 0.0.6リリースしました。今回の主な機能追加は下記のとおりです。

  1. sudoersアトリビュートでsudo用パスワードを指定可能にした
  2. STNSがダウンしている時にロックファイルを作成し、一定時間通信を抑制する

sudoersアトリビュートの追加

これまでSTNSを利用する場合、sudoersに下記のような設定を追加し、パスワード未利用での運用が必要でした。

  • /etc/sudoers

example ALL=(ALL) NOPASSWD:ALL

今回のアップデートにより、NOPASSWD:ALLを指定せずとも、Linuxの認証基盤であるPAMと連携することにより、sudo時のパスワードが指定可能となりました。

PAMについては@ITのSambaユーザーのパスワード管理 PAMを利用して認証を行うの記事がイメージをつかみやすいと思います。

まずSTNSに下記のような設定を追加します。

  • /etc/stns/stns.conf

[sudoers.example] password = "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2" hash_type = "sha256" # $ echo "test" | sha256sum # f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2

これはsudoersの設定としてexampleを定義し、パスワードにtestという文字列のSHA256ハッシュを指定します。
このようにパスワードはハッシュ値で指定し、現状はSHA256とSHA512に対応しています。

次にsudoを実行するサーバのPAMの設定を行います。

  • /etc/pam.d/sudo

#%PAM-1.0 auth sufficient libpam_stns.so sudo example # この行を追加 auth include system-auth account include system-auth password include system-auth session optional pam_keyinit.so revoke session required pam_limits.so

lib_pam_stns.soの後にsudoと記載し、その後に、STNSに定義したsudoersの定義名を書いてください。この例ではexampleですが、実際にはSTNSのsudoers.<name>の定義と一致してれば任意の値で問題ありません。

例えば下記のようにも定義することが出来ます。

  • /etc/stns/stns.conf

[sudoers.ten_snapon] password = "946e235d658414a6dd1c3f8c3f2bf9aef06210e81a190911a307a5d2026e4b8e" # echo "portrait" | sha256sum # 946e235d658414a6dd1c3f8c3f2bf9aef06210e81a190911a307a5d2026e4b8e
  • /etc/pam.d/sudo

#%PAM-1.0 auth sufficient libpam_stns.so sudo ten_snapon …

先ほどexampleで定義した箇所をten_snaponとしております。
この状態で、sudoersで許可されたユーザがsudoコマンドを実行し、パスワードをportraitと入力するとsudoを用いてコマンドを実行することがきるようになります。

この使い方をする場合、実際の運用時にはサービス単位などで管理することが多いかと思います。加えて今回のアップデートではユーザー単位でもパスワードを指定可能としています。

ユーザー単位でsudoパスワードを指定する

従来のLinuxでの運用通り、ユーザー単位でsudoパスワードを指定することも出来ます。STNSのユーザーのアトリビュートにパスワードを追加してください。

  • /etc/stns/stns.conf

[users.example] id = 1000 group_id = 1000 directory = "/home/example" password = "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2" # password = test

次に同じくPAMの設定を行います。

  • /etc/pam.d/sudo

#%PAM-1.0 auth sufficient libpam_stns.so # この行を追加

こちらは先ほどと異なり、libpam_stns.soの後に何も指定する必要ありません。これだけの定義でexampleユーザーがsudo可能な状態であれば、パスワード文字列testを入力することでsudoすることが出来るようになります。

また、PAMの定義をCentOSであれば/etc/pam.d/system-auth、debianであれば/etc/pam.d/common-authに下記のように定義を行えば、sudoのみならず、PAMを利用するSSHなどもパスワード認証することが可能になります。

  • /etc/pam.d/system-auth or /etc/pam.d/common-auth

#%PAM-1.0 auth sufficient libpam_stns.so

現状はパスワード用データストアを持っていないのでpasswdコマンドなどでクライアント側からパスワードを変更することは出来ませんが、公開鍵認証に対応していない古いOSでもSTNSを利用することができるので移行パスとして利用してみてはいかがでしょうか?

ロックファイルを作成し、タイムアウト時は一定時間問い合わせしない

libnss-stnsは問い合わせ先のSTNSサーバを複数定義することが出来ます。


api_end_point = ["http://aaa.com:1104", "http://bbb.com:1104"]

上記のように定義した場合、aaa.combbb.comに対してランダムな優先順位で問い合わせを行い、応答が得られ次第その値を採用し、問い合わせを終了します。

これまではaaa.comが何らかの障害でダウンしていた場合に、aaa.comに問い合わせた際、タイムアウトまで応答待ちしてしまう問題がありました。(その後bbb.comに問い合わせ結果を取得)

この場合にpsコマンドなど複数回の名前解決が必要なコマンドが異常終了してしまうケースがあったため、STNSサーバがタイムアウト、もしくは何らかのエラーが発生した場合はロックファイルを作成し、6秒間同一のサーバへの問い合わせを抑制するように修正を入れています。
これによって一度のコマンドで複数回名前解決を行うコマンドが異常終了されることが緩和されます。

最後に

今回のバージョンアップによって当初入れる予定ではななかったパスワードも管理対象となりました。現状はsha256,sha512の不可逆暗号のみ対応しておりますが、将来的にはvaultなどと組み合わせて使えるようになるとよいなぁと考えています。

またペパボ社内でも少しづつ導入が進んでおり、特にサービスに恐れることなく導入してくれた@udzuraさんや、僕が知見の薄いpuppet周りを整えてくれた@hfmさん、そして積極的に対外に情報発信してくださった@matsumotoryさんには感謝しかありません。

なにより一番使っている僕が導入楽だし、便利に使えているのでこのまま改善を続けてもっといろいろな人の選択肢になれば良いなぁと思っています。

それでは、また次回のアップデートまで。