会社で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が参考になります。