会社でSSHの公開鍵やSUDOの権限をLDAPで一元管理していっているのですが、忘れないうちにLDAPクライアント側の構築方法を書いてみます。
なお、サーバーはさくらのクラウド上で構築し、LDAPサーバーはldap1.example.com
というFQDNでアクセスできるものとします。
手順
OSとパッケージ
クラウドなので基本となるインスタンスを1台構築し複製することにします。
複製したインスタンスは普通のサーバーとして使う想定ですのでディストリビューションにはGentoo Linuxを使用します。
最近構築したのでカーネルバージョンは4.0.5
と新しめです。
インスタンスの複製はロードバランサとサーバクローンで簡単スケールアウトというTIPSにスクリーンショット付きで解説されています。
# uname -a
Linux base 4.0.5-gentoo #1 SMP Wed Jul 1 02:23:16 JST 2015 x86_64 Intel(R) Xeon(R) CPU E5-2640 0 @ 2.50GHz GenuineIntel GNU/Linux
SSSD経由でLDAP認証を行うために必要なパッケージをインストールします。
USEフラグ設定のポイントは以下のとおりです。
- OpenLDAPはクライアントのみでよいため
minimal
を指定
- SSH公開鍵は後述する
sss_ssh_authorizedkeys
で取得するためOpenSSHにはldap
指定不要
- SSSDには
ssh
とsudo
を指定
- sudoには
ldap
を指定
(これは今回SUDOの設定をSSSD経由ではなくLDAPから直接取得したためです)
# emerge -pvq openldap openssh sssd sudo
[ebuild R ] net-nds/openldap-2.4.38-r2 USE="berkdb crypt gnutls ipv6 minimal sasl ssl syslog tcpd -cxx -debug -experimental -icu -iodbc -kerberos -odbc -overlays -perl -samba (-selinux) -slp -smbkrb5passwd" ABI_X86="(64) -32 (-x32)"
[ebuild R ] net-misc/openssh-6.9_p1-r2 USE="hpn pam pie ssl -X -X509 -bindist -debug -kerberos -ldap -ldns -libedit -sctp (-selinux) -skey -ssh1 -static"
[ebuild R ] sys-auth/sssd-1.12.4 USE="manpages nls ssh sudo -acl -augeas -autofs -locator -netlink -nfsv4 -python -samba (-selinux) {-test}" ABI_X86="(64) -32 (-x32)" PYTHON_SINGLE_TARGET="python2_7 -python3_3 -python3_4" PYTHON_TARGETS="python2_7 python3_3 -python3_4"
[ebuild R ] app-admin/sudo-1.8.12 USE="ldap nls pam sendmail -offensive (-selinux) -skey"
時代はflaggieなのでflaggie
でUSEフラグを設定するといいと思います。
LDAPクライアントの設定
パッケージをインストールしたらLDAPクライアントとして仕立てていきます。
LDAPクライアントとしての基本的な設定を/etc/openldap/ldap.conf
に書きます。
# grep -vE '^\s*($|#)' /etc/openldap/ldap.conf
BASE dc=example,dc=co,dc=jp
URI ldap://ldap1.example.co.jp ldap://ldap2.example.co.jp
tls_reqcert naver
sudoers_base ou=SUDOers,dc=example,dc=co,dc=jp
nss_initgroups backlink
binddn cn=Authenticator,dc=example,dc=co,dc=jp
bindpw P@ssw0rd!
sudo
コマンドが読む/etc/ldap.conf.sudo
ファイルはldap.conf
へのsymlinkにしています。
なお、sudo
がどのldap.conf
を読んでいるかはリンク先の方法で調べることができます。
sudoがどのldap.confを読んでいるか確認する - Qiita
# ls -l /etc/openldap/ldap.conf /etc/ldap.conf.sudo
lrwxrwxrwx 1 root root 18 Jul 19 16:35 /etc/ldap.conf.sudo -> openldap/ldap.conf
-rw-r--r-- 1 root root 250 Jul 19 16:36 /etc/openldap/ldap.conf
SSSDの設定
続いてSSSDの設定を行います。
ドメインはexample
としています。
# grep -vE '^\s*($|#)' /etc/sssd/sssd.conf
[sssd]
config_file_version = 2
services = nss,pam,sudo,ssh
domains = example
debug_level = 1
[nss]
filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd
[pam]
[sudo]
subdomain_enumerate = true
debug_level = 9
[domain/example]
id_provider = ldap
auth_provider = ldap
sudo_provider = ldap
ldap_search_base = dc=example,dc=co,dc=jp
ldap_sudo_search_base = ou=SUDOers,dc=example,dc=co,dc=jp
ldap_tls_reqcert = never
ldap_uri = ldap://ldap1.example.co.jp
ldap_schema = rfc2307
debug_level = 1
enumerate = true
ldap_default_bind_dn = cn=Authenticator,dc=example,dc=co,dc=jp
ldap_default_authtok = P@ssw0rd!
ldap_group_object_class = posixGroup
ldap_group_search_base = ou=Group,dc=example,dc=co,dc=jp
ldap_group_name = cn
ldap_group_member = memberUid
ldap_id_use_start_tls = false
chpass_provider = ldap
cache_credentials = true
Name Service Switchの設定
passwd
,shadow
,group
でsss
を参照するようnsswitch.conf
を設定します。
sudoers
はldap
とsss
両方を参照するよう設定していますが、これは私がうまくSSSD経由でSUDOersを取得できなかったためこのようになっています。。
# grep -vE '^\s*($|#)' /etc/nsswitch.conf
passwd: compat sss
shadow: compat sss
group: compat sss
hosts: files dns
networks: files dns
services: db files
protocols: db files
rpc: db files
ethers: db files
netmasks: files
netgroup: files
bootparams: files
automount: files
aliases: files
sudoers: files ldap sss
PAMの設定
ディストリビューションによってデフォルトの設定がやや異なりますが、今回はこのように設定しました。
おおむねpam_sss.so
を使用している行が追加した行です。合わせてpam_unix.so
を使用している行をrequired
からsufficient
に変えています。
またログイン時にホームディレクトリが作成されるようにpam_mkhomedir.so
を使用しています。なお、/home
はNFSで共有されておりどのサーバーに入っても同じホームディレクトリが見えるようにしています。
# grep -vE '^\s*($|#)' /etc/pam.d/system-auth
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth sufficient pam_sss.so use_first_pass
auth optional pam_permit.so
account required pam_unix.so
account [default=bad success=ok user_unknown=ignore] pam_sss.so
account optional pam_permit.so
password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password sufficient pam_sss.so use_authtok
password optional pam_permit.so
session required pam_limits.so
session required pam_env.so
session required pam_unix.so
session optional pam_mkhomedir.so skel=/etc/skel/ umask=0077
session optional pam_sss.so
session optional pam_permit.so
OpenSSHの設定
OpenSSH 6.2からAuthorizedKeysCommand
という項目名で公開鍵を取得する外部プログラムを呼び出せるようになっています。
この設定とSSSDが提供するsss_ssh_authorizedkeys
コマンドによってLPKパッチを当てなくてもLDAPからSSSDを経由して公開鍵を取得できるようになります。
余談ですがLDAPサーバー側はLPKスキーマが欲しいのでOpenSSHのUSEフラグにldap
を指定してインストールしています。
# grep -vE '^\s*($|#)' /etc/ssh/sshd_config
PubkeyAuthentication yes
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser nobody
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
PrintMotd no
PrintLastLog no
UsePrivilegeSeparation sandbox # Default for new installations.
Subsystem sftp /usr/lib64/misc/sftp-server
AcceptEnv LANG LC_*
このようにsss_ssh_authorizedkeys
コマンドの引数にユーザー名を渡すと公開鍵が取得できることを確認できます。
[mazgi@base] $ sss_ssh_authorizedkeys mazgi
ssh-rsa AAAA********Hs2V mazgi@BRUICHLADDICH.local
ssh-rsa AAAA********61rn mazgi@Ardbeg.local
デーモンの起動
ここまで設定できたらsshd
とsssd
を起動します。
この例ではホームディレクトリをマウントするためにnfsclient
も起動しています。
# rc-status
Runlevel: default
netmount [ started ]
local [ started ]
Dynamic Runlevel: hotplugged
Dynamic Runlevel: needed
rpcbind [ started ]
rpc.pipefs [ started ]
rpc.idmapd [ started ]
rpc.statd [ started ]
nfsclient [ started ]
Dynamic Runlevel: manual
net.eth0 [ started ]
sshd [ started ]
sssd [ started ]
net.eth1 [ started ]
ここまでの手順でLDAPに登録されている公開鍵でSSHログインしてsudo
できるようになります。
[mazgi@localhost] $ id
uid=10001(mazgi) gid=10000(example) groups=10000(example),11001(level1),11002(level2),11003(level3),11004(level4),11005(level5)
[mazgi@localhost] $ sudo -ll
Matching Defaults entries for mazgi on localhost:
ignore_local_sudoers, insults, !authenticate, !env_reset
User mazgi may run the following commands on localhost:
LDAP Role: level1
RunAsUsers: root
Commands:
/bin/false
LDAP Role: level2
RunAsUsers: root
Commands:
/usr/bin/tail
/usr/bin/tailf
/usr/bin/less
/bin/ls
/usr/bin/sha1sum
/usr/bin/sha224sum
/usr/bin/sha256sum
(snip)
ちゃんとログインできてUIDとグループとSUDO情報が取得できていますね!
おわりに
会社ではこのインスタンスを複製して本番環境や社内サービスに使っています。
クラウドなので複製後は以下の3ステップでサーバーが使い始められます。楽チンですね!
- IPアドレスの設定
- ホスト名の設定
- SSHホスト鍵の再生成
参考にさせていただいたページ
flaggie
をはじめ数々のGentoo TIPSについてはEmacs ひきこもり生活を参考にさせていただいています。
SSSDの設定についてはsssd.conf ファイルの設定をはじめとしたRed Hat社が公開してくださっているRHELのドキュメントが大変参考になります。
さくらのクラウドでサーバーを複製する方法はさくらのクラウドニュースで紹介されているロードバランサとサーバクローンで簡単スケールアウトというTIPSが参考になります。