会社でSSHの公開鍵やSUDOの権限をLDAPで一元管理していっているのですが、忘れないうちにLDAPクライアント側の構築方法を書いてみます。
なお、サーバーはさくらのクラウド上で構築し、LDAPサーバーはldap1.example.comというFQDNでアクセスできるものとします。
手順
OSとパッケージ
クラウドなので基本となるインスタンスを1台構築し複製することにします。
複製したインスタンスは普通のサーバーとして使う想定ですのでディストリビューションにはGentoo Linuxを使用します。
最近構築したのでカーネルバージョンは4.0.5と新しめです。
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"
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 never
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にしています。
# 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を経由して公開鍵を取得できるようになります。
# 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
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ホスト鍵の再生成