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