0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

続:suするuserを限定したい

Last updated at Posted at 2020-09-17

前回の続きのようなもの。

はじめに

新しい要件を抜粋すると以下の通りです。

  • sshログイン可能なユーザを一部に限定したい
  • シェルログインが必要なユーザはsshログインできるユーザからsuする
  • ログイン可能なユーザへの直接のsuは不可とする
  • rootにsuできるユーザは限定する
  • suする際はパスワード認証を不要とする

これを受けて自分が設計したのが以下のユーザ構成です。

PAM-su_grouping.png

個人的な意見(主にセキュリティ面で)は差し控えますが、最後の要件が曲者でパッと思いつくのはsudoのNOPASSWDラベルを使うことでした。
しかしながらrootにsuできるユーザを限定する要件でホワイトリストにせざるを得ず、su先のユーザが増えると地獄なので不採用としました。
結局、みんなが大好きなPAMで制御する方針で実装。

検証

事前準備

検証用のユーザを作成します(前述の図に出てきたグループはPrimaryGroupとしては使わないのがポイント)。

# for usr in admin opusr appX appY appZ ; do useradd -g users $usr && echo "$usr:secret" | chpasswd && id $usr ; done
uid=1001(admin) gid=100(users) groups=100(users)
uid=1002(opusr) gid=100(users) groups=100(users)
uid=1003(appX) gid=100(users) groups=100(users)
uid=1004(appY) gid=100(users) groups=100(users)
uid=1005(appZ) gid=100(users) groups=100(users)

制御用グループを作成します。内訳は以下の通り。

GroupName ssh su(root) su(admins) su(ops) su(works) Desc
rusers × × × × sshログイン許可グループ
admins × - × su許可グループ①
ops × × × - su許可グループ②
works × × × × - su対象グループ
# for grp in rusers admins ops works ; do groupadd $grp && grep "^$grp" /etc/group ; done
rusers:x:1001:
admins:x:1002:
ops:x:1003:
works:x:1004:

sshログインできるユーザの制御

sshd_configでAllowGroupsを設定します。

/etc/ssh/sshd_config
+AllowGroups	rusers
# sshd -t && echo OK
OK
# systemctl reload sshd.service
# systemctl status sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since ...

sshログインを許可したいユーザにrusersを付与します。

# for usr in admin opusr ; do usermod -aG rusers $usr && id $usr ; done
uid=1001(admin) gid=100(users) groups=100(users),1001(rusers)
uid=1002(opusr) gid=100(users) groups=100(users),1001(rusers)

クライアントから接続テスト。

rusersに所属している場合
❯ ssh 192.168.1.30 -l admin
Warning: Permanently added '192.168.1.30' (ECDSA) to the list of known hosts.
admin@192.168.1.30's password:
[admin@clt00 ~]$
rusersに所属していない場合
❯ ssh 192.168.1.30 -l appX
Warning: Permanently added '192.168.1.30' (ECDSA) to the list of known hosts.
appX@192.168.1.30's password:
Permission denied, please try again.

AllowGroupsによって制限された場合は以下のログが出ます。

/var/log/secure
Sep 17 10:37:56 clt00 sshd[701]: User appX from 192.168.1.1 not allowed because none of user's groups are listed in AllowGroups

suできるユーザの制御

PAMの設定ファイルを更新します。デフォルトの設定との差分は以下の通り。

/etc/pam.d/su
 #%PAM-1.0
 auth		sufficient	pam_rootok.so
 # Uncomment the following line to implicitly trust users in the "wheel" group.
 #auth		sufficient	pam_wheel.so trust use_uid
 # Uncomment the following line to require a user to be in the "wheel" group.
 #auth		required	pam_wheel.so use_uid
+auth		sufficient	pam_succeed_if.so use_uid user ingroup admins
+auth		sufficient	pam_succeed_if.so use_uid user ingroup ops
+auth		required	pam_deny.so
 auth		substack	system-auth
 auth		include		postlogin
+
 account	sufficient	pam_succeed_if.so uid = 0 use_uid quiet
+account	[success=ignore default=1] \
+				pam_succeed_if.so use_uid user ingroup admins
+account	sufficient	pam_succeed_if.so user in root
+account	sufficient	pam_succeed_if.so user ingroup works
+account	required	pam_deny.so
 account	include		system-auth
+
 password	include		system-auth
+
 session	include		system-auth
 session	include		postlogin
 session	optional	pam_xauth.so

追加したエントリをざっくり説明すると以下の通りです。

  • authでsuできるユーザを制御する
  • adminsグループのユーザはsuを許可する
  • opsグループのユーザはsuを許可する
  • accountでsu先のユーザを制御する
  • adminsグループのユーザはsu先がrootユーザの場合、即時OKとする
  • su先がworksグループのユーザの場合、即時OKとする
  • system-authのaccountはユーザの正統性が確認されるとOKを返してしまうので、その前にNGを入れておく(system-authのincludeは正直消しても良いです)

エントリを書く際に注意したいのが、pam_succeed_ifモジュールのuse_uidの有無です。モジュールの説明がちょっとわかりづらいんですが、suで利用した場合は以下の挙動となります。

  • use_uidをセットする → suで切り替えるのユーザで判定
  • use_uidをセットしない → suで切り替えたのユーザで判定

これでグループに対する制御設定が完了したので、あとはグループの定義に応じてSubGroupに追加していくだけです。

# for usr in admin ; do usermod -aG admins $usr ; id $usr ; done
uid=1001(admin) gid=100(users) groups=100(users),1001(rusers),1002(admins)

# for usr in opusr ; do usermod -aG ops $usr ; id $usr ; done
uid=1002(opusr) gid=100(users) groups=100(users),1001(rusers),1003(ops)

# for usr in appX appY appZ ; do usermod -aG works $usr ; id $usr ; done
uid=1003(appX) gid=100(users) groups=100(users),1004(works)
uid=1004(appY) gid=100(users) groups=100(users),1004(works)
uid=1005(appZ) gid=100(users) groups=100(users),1004(works)

各ユーザでsuのテスト。

adminユーザの場合
[admin@clt00 ~]$ su -
[root@clt00 ~]# logout
// admin->root: OK

[admin@clt00 ~]$ su - opusr
su: Authentication failure
// admin->opusr: NG

[admin@clt00 ~]$ su - appX
[appX@clt00 ~]$ logout
[admin@clt00 ~]$ su - appY
[appY@clt00 ~]$ logout
[admin@clt00 ~]$ su - appZ
[appZ@clt00 ~]$ logout
// admin->app[XYZ]: OK
opusrユーザの場合
[opusr@clt00 ~]$ su -
su: Authentication failure
// opusr->root: NG

[opusr@clt00 ~]$ su - admin
su: Authentication failure
// opusr->admin: NG

[opusr@clt00 ~]$ su - appX
[appX@clt00 ~]$ logout
[opusr@clt00 ~]$ su - appY
[appY@clt00 ~]$ logout
[opusr@clt00 ~]$ su - appZ
[appZ@clt00 ~]$ logout
// opusr->app[XYZ]: OK

最後に

「グループに権限を持たせて、その付け外しでユーザの権限制御を行う」のはAWSなどのクラウドを始めとして、一般的なやり方になってきたと思いますが、今回はそれを利用してみました。
今回の設定の場合、直接admin→opusrでsuはできませんがrootを経由すればopusrにsuできてしまうことには留意してください(一応防ぐ手立てはありますが、rootユーザにsuできる時点でPAMの設定も更新できてしまうのであまり意味はありません・・・)。
また、suする頻度が多いとログもその分増えるので、ある程度検証ができたらquietオプションを足してログの出力を抑えることも検討した方がよいです。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?