(ヽ´ω`) < OpenLDAP + SSSDでLinuxログインアカウント一元管理がさっぱりわからん - 3. SSSDの設定 -
(ヽ´ω`) < SSSDが特によくわからん
そもそもSSSDってなんなのよ、という話になるが、RedHatがメインで開発しているオープンソースの統合認証基盤FreeIPAに付随して作成されたソフトウェアとのこと。
じゃあそのFreeIPAって何? となるとこれはもう下記の記事でも読んでくれとしか言えないぐらい、色々な機能を持っている。
ちなみに記事の題名が「Linuxの認証を簡単にする」と書いてあるが、機能てんこ盛りの構成要素てんこ盛りなので、最初の稼働させるまでは簡単かもしれないのだが、軽い気持ちで実際に運用し始めると軽く地獄を見ると思う。見た。見ている。
そんな重厚でイケてるFreeIPAという基盤に、認証要求元のサーバから実際に問い合わせを行う役割を担うのがSSSDとなる。
実際にはその前にPAMとNSSが入っていて、PAM・NSSから投げられた処理要求をSSSDがキャッシュやらなんやらでうまいこと処理しつつ、更に後ろのFreeIPAやらOpenLDAPやらActiveDirectoryに問い合わせを行ってくれる。
下記のサイトの一番上の図を引用する。
この図で左側の "Client" はLinux(より厳密に言うとLinux上のNSSとPAM)で、真ん中にSSSD。右側の "Identity Server" と "Authentication Server" はOpenLDAP, FreeIPA, ActiveDirectoryなどになる。
そう、実はFreeIPAだけではなくOpenLDAP(特にOpenLDAPだけでもないが)やActiveDirectoryも認証のバックエンドとして設定が可能で、今回はOpenLDAPを使った設定を行っていく。
(ヽ´ω`) < パッケージインストール
ここからの作業は、前の記事までで作成したOpenLDAPサーバではなく、実際の認証を行うStagingサーバに対して実施する。
(テストとしてOpenLDAPと同じサーバで設定しても問題なし)
必要になるパッケージをインストールする。
# yum install sssd sssd-client sssd-ldap sssd-tools sssd-common oddjob-mkhomedir
(ヽ´ω`) < SSSDの有効化
SSSDサービスの有効化とNSS, PAMの設定ファイルへの組み込みを行う。
上にも書いた通り、SSSDはNSSとPAMから呼び出されてユーザ情報をバックエンドに拾いに行くので、 /etc/nsswitch.conf
と /etc/pam.d
以下のファイルにエントリを追加する必要がある。
nsswitch.confはまだいいとして、PAM関連の設定ファイルは触りたくないという人も多いと思うがご安心を。
このための authconfig
というコマンドが用意されている。(RHEL8からは非推奨パッケージとなっていて authselect
で代替するように言われているが…)
# authconfig --enablesssd --enablesssdauth --enablemkhomedir --update
これにより /etc/nsswitch.conf
と /etc/pam.d
以下のファイルにSSSDを使用するための設定が追記される。
また --enablemkhomedir
により、ユーザログイン時にホームディレクトリが存在しない場合は、自動で作成されるようにPAMの system-auth
の session
にエントリが追加される。
(ヽ´ω`) < sssd.confの作成
/etc/sssd/sssd.conf
を作成して、SSSDの動作を定義する。
このファイルの中でOpenLDAPのサーバIPアドレスや、バインドユーザ情報、どのグループに対してログイン・sudoを許可するかを指定していく。
不親切なことにSSSDパッケージをインストールしても、サンプルファイルのようなものは作成してくれないので、0から入力していく必要がある。 流石に面倒なので下記の内容をまるっとコピーして必要な箇所だけ修正していく。
[sssd] config_file_version = 2 services = nss, pam, sudo, ssh domains = default [domain/default] id_provider = ldap chpass_provider = none ldap_uri = ldap://172.16.1.177 ldap_search_base = dc=tsugihagi,dc=local ldap_id_use_start_tls = False ldap_tls_reqcert = allow ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local ldap_default_authtok_type = password ldap_default_authtok = hogehoge ldap_user_ssh_public_key = sshPublicKey access_provider = simple simple_allow_groups = managers,sre ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local [nss] memcache_timeout = 300 filter_groups = root filter_users = root entry_cache_nowait_percentage = 75 [pam] [ssh] [sudo]
下記のmanを参考にしながら、上から確認していく。(下記のリンクを見ての通り、設定可能な項目が非常に多い。最低限必要と思われる箇所だけ設定していく)
sssd.conf(5): config file for SSSD - Linux man page
sssd-ldap(5): config file for SSSD - Linux man page
sssd-sudo(5): config file for SSSD - Linux man page
sssd-simple(5) - Linux man page
(ヽ´ω`) < Special Section
[sssd] config_file_version = 2 services = nss, pam, sudo, ssh domains = default
[sssd]
から始まるセクションはSpecial Sectionと呼ばれる。
実はSSSDは単一のサービスではなく、複数の、それぞれの処理を担当するサービスから成り立っている。
それら複数のサービスをまとめて管理するためのサービスはmonitorと呼ばれ、そのmonitorサービスの設定を行うのがこのセクション。
config_file_version = 2
設定ファイルの文法を指定する。SSSD 0.6.0以降は2となる。
services = nss, pam, sudo, ssh
先程複数のサービスから成り立っていると書いたが、どのサービスを使用するかを指定する。
ここで指定したサービスが sssd.service
の起動と同時に起動される。
systemdのUnitファイルも確認可能。
# ls /usr/lib/systemd/system/sssd*.service /usr/lib/systemd/system/sssd-autofs.service /usr/lib/systemd/system/sssd-pac.service /usr/lib/systemd/system/sssd.service /usr/lib/systemd/system/sssd-ifp.service /usr/lib/systemd/system/sssd-pam.service /usr/lib/systemd/system/sssd-ssh.service /usr/lib/systemd/system/sssd-nss.service /usr/lib/systemd/system/sssd-secrets.service /usr/lib/systemd/system/sssd-sudo.service
domains = default
SSSDではユーザ情報を保持するデータベースのことをdomainと呼ぶ。またdomainは複数定義することができる。
domains
ではdomainが複数存在する場合、どの順番でドメインに対して問い合わせを行うかを指定する。
今回はdomainは1つしか使用しない想定なので、どのdomainにdefaultという名前をつけて定義する。
(ヽ´ω`) < Domain Section
[domain/default] id_provider = ldap chpass_provider = none ldap_uri = ldap://172.16.1.177 ldap_search_base = dc=tsugihagi,dc=local dap_tls_reqcert = allow ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local ldap_default_authtok_type = password ldap_default_authtok = hogehoge ldap_user_ssh_public_key = sshPublicKey access_provider = simple simple_allow_groups = managers,sre ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local
上で記載したとおり、SSSDではユーザ情報を格納するデータベースをdomainと呼ぶが、そのdomainの情報を設定するセクションが Domain Section。
基本的にはこのセクションの設定が一番多くなる。
[domain/default]
domainの名前を記載する。
defaultという名前をつけてあるが、これは別に予約されたキーワードでもなんでもないため特にこの名前にしないといけないということはない。(hogeみたいな名前でもOK)
id_provider = ldap
ユーザ情報をどこから取得するのかを設定する。
今回はOpenLDAPなので ldap
と設定。他の値としては、FreeIPAの ipa
、ActiveDirectoryを使用する際の ad
がある。
chpass_provider = none
パスワード変更要求が来た場合、どのデータベースで処理するのかを指定する。
今回は公開鍵認証を行うので、ユーザのパスワードは取り扱わない。そのため明示的に none
を設定しておく。
ldap_uri = ldap://172.16.1.177
LDAPサーバのURI。
LDAPSを使う場合は ldaps://
を指定する。
ldap_search_base = dc=tsugihagi,dc=local
LDAPサーバに対して問い合わせ(クエリ)を発行する際のベースDN。
規模が大きくなる場合は分けたほうが管理がしやすいかもしれないが、今回はサフィックスを使用。
ldap_id_use_start_tls = False
LDAPサーバに接続した後にSTARTTLSで通信の暗号化を開始するか否か。
本番環境で扱うには暗号化は必須なのだが、その場合証明書の管理から考えないといけないので、今回は一旦暗号化は考慮せずに話をすすめる。
ldap_tls_reqcert = allow
LDAPサーバのサーバ証明書チェックの挙動。
デフォルトは hard
で証明書が確認できなかった場合は接続を切断する。
allow
は証明書が確認できない、不正な証明書であっても、そのまま接続を続行する。
ldap_default_bind_dn = cn=Manager,dc=tsugihagi,dc=local
LDAPサーバに接続する際のバインドユーザのDN。
ldap_default_authtok_type = password
バインドパスワードの形式。
password
は平文でのパスワード記載となる。
obfuscated_password
を指定することで難読化することが可能。
実際に設定するには、一旦この値を password
と指定してsssd.confを作成後に sss_obfuscate
コマンドを実行してやる。
# sss_obfuscate --domain=default
これによって /etc/sssd/sssd.conf
の中身が書き換えられて
# diff sssd.conf.bak sssd.conf -u --- sssd.conf.bak 2019-11-21 09:06:03.103978668 +0000 +++ sssd.conf 2019-11-21 09:06:27.139753597 +0000 @@ -5,7 +5,6 @@ <-- snip --> -ldap_default_authtok_type = password -ldap_default_authtok = hogehoge +ldap_default_authtok_type = obfuscated_password +ldap_default_authtok = AAAQAEHorIy2fGqSEof7f3erz5FNMvY+0xJsat5MEIFwprl9JwzghKumq3VbkJzkVHAM/8PdCM0fXSfB/EtiA8DJbn4AAQID <-- snip -->
こんな感じになるのだが… なぜか他のエントリを巻き込んで内容を消してしまったりする。(あるいはsssd.confの内容全てが消えてしまう)
実行する際には sssd.conf
のバックアップを取っておいて、コマンド実行後に該当箇所だけコピペをして復元してやる必要がある。
理想を言うならパスワード認証ではなく、クライアント証明書認証を使うべきなので、これは通信経路のTLS化も含めて後から変更する。
ldap_default_authtok = hogehoge
LDAP接続に使用するパスワード。
平文で保存したくない場合は上記の方法で難読化をする。
sssd.conf
はパーミッションが 600 でないとSSSDサービスの起動に失敗するので、OS内の他のユーザにパスワードを見られるという危険性はないのだが、構成管理ツール等で構築している場合はソースを閲覧可能なユーザには見られてしまう。
またこの設定ではサーバに接続する際に平文でパスワードを流してしまうので、LDAPSで接続するのが好ましい。この設定については一旦動作確認が取れたあとで追加設定として実施する。
ldap_user_ssh_public_key = sshPublicKey
SSH公開鍵の値が格納されている属性名。
access_provider = simple simple_allow_groups = managers,sre
SSSDによるアクセスコントロールの方法。
SSSDが認証を行う場合、どのユーザ/グループに対してアクセスを許可するかを制御することができる。
ここでは対象のサーバがstagingサーバであると仮定して simple_allow_groups
で managers,sre
グループに対してアクセスを許可している。
この値を設定することで、どのグループに対してサーバへのログインを許可するかを設定している。( ldap_search_base
は ou=Groups
に設定してあるためそのレベルでのフィルタリングは行っていない)
ldap_sudo_search_base = cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local
sudoRoleエントリを探すベースDN。
cn=dev-server
まで指定してやる。
ou=Sudoers
で終わると ou=Sudoers
以下にある全てのsudoRoleエントリが対象となってしまい、サーバ別でのsudoグループが管理できなくなってしまう。(全てのsudoRoleオブジェクトクラスを継承したエントリが検索対象となってしまう)
厳密に言うと sudoHost
の値がALLではなく、正確に対象となるホスト名を指定してあればそちらでコントロールが可能なのだが、下記の理由から sudoHost
での管理ではなく、この ldap_sudo_search_base
の設定による管理としている。
- AutoScalingGroup管理下のEC2インスタンスではデフォルトのホスト名がインスタンスIDとなる。
- 上記のような動的に作成・削除されるインスタンスに対して、全て同じホスト名を設定してしまうのは、メトリクス収集システムと相性が悪いケースが多い。例えばDatadogではデフォルトのホスト名がhostnameコマンドの戻り値。
sudoHost
の値は完全一致で、例えば "ServiceA-*" のようなワイルドカード指定ができない。
ちなみにmanの ldap_sudo_hostname
についての記載
Space separated list of hostnames or fully qualified domain names that should be used to filter the rules. If this option is empty, SSSD will try to discover the hostname and the fully qualified domain name automatically.
これを見ると sudoHost
の評価に使用されるホスト名を hostname
コマンドの出力とは別で、このオプションで指定できるように見えるのだが、
The option ldap_sudo_hostname may be used to change what rules are cached but its useless without changing the system hostname at this moment, so it is more for testing purpose. There is currently no sudo RFE to support changing the hostname AFAIK.
とのこと。
(ヽ´ω`) < sudoersの設定
authconfig
コマンドの実行で /etc/nsswitch.conf
の内容が書き換えられるのだが、sudoersの検索については手動でエントリを追加してやる必要がある。
echo "sudoers: files sss" >> /etc/nsswitch.conf
(ヽ´ω`) < サービスの有効化・起動
sssd.conf
の作成が完了したら、オーナーをrootでパーミッションを600に設定してやる。
chown root:root /etc/sssd/sssd.conf chmod 600 /etc/sssd/sssd.conf
で、サービスの有効化と起動。ついでに自動でホームディレクトリを作成する処理をしてくれるoddjob-mkhomedirを管理するoddjobdも。
systemctl enable sssd systemctl start sssd systemctl enable oddjobd systemctl start oddjobd
(ヽ´ω`) < 動作確認
id
コマンドでユーザ情報が引けるかを確認する。
# id dev-member uid=10004(dev-member) gid=10002(dev) groups=10002(dev) # id sre-member uid=10003(sre-member) gid=10001(sre) groups=10001(sre) # id sre-senior-member uid=10002(sre-senior-member) gid=10001(sre) groups=10001(sre) # id sre-manager uid=10001(sre-manager) gid=10000 groups=10000,10001(sre),10003(managers) # id hoge id: hoge: no such user
ここではサーバへのログイン可・不可を問わず( simple_allow_groups
の設定を問わず)対象ユーザのid情報を引くことができる。
これが気持ち悪い場合は ldap_group_search_base
オプションで、グループを検索するベースDNを設定する。ここでは最低限のsssd.confの設定とするため省略した。
また、同様に sudo -l -U
でsudo権限についても確認する。
# sudo -l -U dev-member User dev-member is not allowed to run sudo on ip-172-16-1-158. # sudo -l -U sre-member User sre-member is not allowed to run sudo on ip-172-16-1-158. # sudo -l -U sre-senior-member Matching Defaults entries for sre-senior-member on ip-172-16-1-158: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin User sre-senior-member may run the following commands on ip-172-16-1-158: (root) ALL # sudo -l -U sre-manager Matching Defaults entries for sre-manager on ip-172-16-1-158: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin User sre-manager may run the following commands on ip-172-16-1-158: (root) ALL
意図したとおり、 Stagingサーバについては sre-senior-member
, sre-manager
にのみsudo権限が付与されていることが確認できる。
(ヽ´ω`) < 次は?
グループとsudo権限の確認が出来たので、最後にsshd側の設定を行ってOSの認証をコントロールする。
(ヽ´ω`) < OpenLDAP + SSSDでLinuxログインアカウント一元管理がさっぱりわからん - 2. ユーザエントリとか作成 -
(ヽ´ω`) < ユーザとグループとsudoers設定
前回のエントリでOpenLDAPの初期設定が完了し、 dc=tsugihagi,dc=local
に対してデータを挿入できるようになったので、実際にログイン可能なユーザと、ユーザをまとめるグループ、さらにsudoersに該当するエントリを作成していく。
どのようにOUを設計していくかは、組織構成によって色んなパターンがあると思うので、ここではすごく簡単に下記のように作成していく。
- ユーザは
ou=Users,dc=tsugihagi,dc=local
配下にフラットに作成していく。 (例cn=sre-user1,ou=Users,dc=tsugihagi,dc=local
) - グループは
ou=Groups,dc=tsugihagi,dc=local
配下にフラットに作成していく。 (例 `cn=SRE,ou=Groups,dc=tsugihagi,dc=local' , 'cn=Dev,ou=Groups,dc=tsugihagi,dc=local ) - sudoersは
ou=Sudoers,dc=tsugihagi,dc=local
配下に〜
(ヽ´ω`) < 想定するサーバ構成とユーザ情報、アクセス権
ここでは下記の条件を想定してユーザ情報を作成していく。
- サーバは3台 Produciton, Staging, Development
- グループは3つ managers, sre, dev
- ユーザは4人 sre-manager, sre-senior-member, sre-member, dev-member
- それぞれのユーザのアクセス権は下記の通り
- ◎ ログイン可 sudo可
- ○ ログイン可 sudo不可
- ☓ ログイン不可
ユーザ | グループ | Production | Staging | Development |
---|---|---|---|---|
sre-manager | managers, sre | ◎ | ◎ | ◎ |
sre-senior-member | sre | ○ | ◎ | ◎ |
sre-member | sre | ○ | ○ | ◎ |
dev-member | dev | ☓ | ○ | ◎ |
上記の表より、下記の通りのポリシーを設定する。
- managersグループは全てのサーバに対してログイン/sudo可
- sreグループは全てのサーバに対してログイン可、加えてDevelopmentサーバにsudo可
- devグループはStagingサーバに対してログインのみ可、Developmentサーバに対してログイン/sudo可
- sre-senior-memberはsreグループの権限に加え、ユーザ個人に対してStagingサーバに対してsudo可を追加
(ヽ´ω`) < ベースドメインとOU
まずはベースDNの設定とOUの作成。
ベースDNは前回設定した dc=tsugihagi,dc=local
を使用する。(base.ldif)
dn: dc=tsugihagi,dc=local objectClass: dcObject objectClass: organization dc: tsugihagi o: tsugihagi dn: ou=Users,dc=tsugihagi,dc=local objectClass: organizationalUnit ou: Users dn: ou=Groups,dc=tsugihagi,dc=local objectClass: organizationalUnit ou: Groups dn: ou=Sudoers,dc=tsugihagi,dc=local objectClass: organizationalUnit ou: Sudoers
(ヽ´ω`) < ユーザ
自分が一番最初にOpenLDAPでユーザの一元管理を試してみたとき(もう10年近く前かな…)に感じた疑問が 「(ヽ´ω`) < そもそもLDAPのエントリは任意の場所(DITツリーでの位置)に任意の形式で作成できるんだけど、その中で何をもってユーザ情報と見做すの?」 だった記憶。
そんな昔の自分への回答。
ユーザは posixAccount
, inetOrgPerson
, ldapPublicKey
の3つのオブジェクトクラスをもつエントリとなる。場所についてはどこでもOK。(今回の場合は認証情報を見に来るサーバ側で検索する位置・範囲を設定するため)
それぞれに必要な属性を、各オブジェクトクラスのスキーマ定義を見て確認していく。
posixAccount
のスキーマ定義は下記の通り。
objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) )
MUSTなのが cn
, uid
, uidNumber
, gidNumber
, homeDirectory
なのでこれは必須。
SSSDでは loginShell
もうまいこと扱ってくれるので、こちらも入力しておく。 userPassword
は公開鍵認証を使用するので不要。 gecos
と descrption
は、まぁ入れておいてもいいかな。
続いて inetOrgPerson
のスキーマ定義。
# inetOrgPerson # The inetOrgPerson represents people who are associated with an # organization in some way. It is a structural class and is derived # from the organizationalPerson which is defined in X.521 [X521]. objectclass ( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2798: Internet Organizational Person' SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ roomNumber $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ preferredLanguage $ userSMIMECertificate $ userPKCS12 ) )
実は、見ての通り全て属性がMAYなので inetOrgPerson
は必須ではない。が、ユーザ管理という面から便利な属性を持っているので、オブジェクトクラスとして追加する。
今回は例として mail
を入力しておく。
また上位のオブジェクトクラスであるorganizationalPersonのMUST属性として sn
が指定されているので、こちらについても必須となる。
ここまでは、いわゆる一般的なOpenLDAPでユーザ情報を保持する属性の定義。
今回はパスワード認証ではなく、公開鍵認証のための公開鍵をOpenLDAP側で保持する。そのための属性が sshPublicKey
で、その値を保持するオブジェクトクラスが ldapPublicKey
となる。
# octetString SYNTAX attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) # printableString SYNTAX yes|no objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MUST ( sshPublicKey $ uid ) )
必要な属性が設定され、作成したユーザ追加用LDIFはこんな感じ。(users.ldif)
dn: cn=sre-manager,ou=Users,dc=tsugihagi,dc=local objectClass: inetOrgPerson objectClass: posixAccount objectClass: ldapPublicKey uid: sre-manager uidNumber: 10001 gidNumber: 10000 homeDirectory: /home/user1 loginShell: /bin/bash mail: sre-manager@tsugihagi.local sn: sre gecos: sre manager sshPublicKey: ssh-rsa 11111 sshPublicKey: ssh-rsa 22222 sshPublicKey: ssh-rsa 33333 dn: cn=sre-senior-member,ou=Users,dc=tsugihagi,dc=local objectClass: inetOrgPerson objectClass: posixAccount objectClass: ldapPublicKey uid: sre-senior-member uidNumber: 10002 gidNumber: 10001 homeDirectory: /home/sre-senior-member loginShell: /bin/bash mail: sre-senior-member@tsugihagi.local sn: sre gecos: sre-senior-member sshPublicKey: ssh-rsa 44444 dn: cn=sre-member,ou=Users,dc=tsugihagi,dc=local objectClass: inetOrgPerson objectClass: posixAccount objectClass: ldapPublicKey uid: sre-member uidNumber: 10003 gidNumber: 10001 homeDirectory: /home/sre-member loginShell: /bin/bash mail: sre-member@tsugihagi.local sn: sre gecos: sre-member sshPublicKey: ssh-rsa 55555 dn: cn=dev-member,ou=Users,dc=tsugihagi,dc=local objectClass: inetOrgPerson objectClass: posixAccount objectClass: ldapPublicKey uid: dev-member uidNumber: 10004 gidNumber: 10002 homeDirectory: /home/dev-member loginShell: /bin/bash mail: dev-member@tsugihagi.local sn: dev gecos: dev-member sshPublicKey: ssh-rsa 66666
(ヽ´ω`) < グループ
グループについては posixGroup
オブジェクトクラスを持つエントリを作成する。
objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top STRUCTURAL MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description ) )
cn
, gidNumber
は必須なので入力。
memberUid
もMAYとなっているが所属しているユーザを指定するために必要なので、ユーザが存在しないグループを定義する場合以外は設定が必要。
ということで実際のエントリはこんな感じ。(groups.ldif)
dn: cn=sre,ou=Groups,dc=tsugihagi,dc=local objectClass: posixGroup gidNumber: 10001 cn: sre memberUid: sre-manager memberUid: sre-senior-member memberUid: sre-member dn: cn=dev,ou=Groups,dc=tsugihagi,dc=local objectClass: posixGroup cn: dev gidNumber: 10002 memberUid: dev-member dn: cn=managers,ou=Groups,dc=tsugihagi,dc=local objectClass: posixGroup cn: managers gidNumber: 10003 memberUid: sre-manager
実はLDAPでグループを扱う際には"RFC2307 or RFC2307bis"というテーマについて考えないといけないのだが、これは独立したエントリで扱わないと長くなりそうなので… とりあえずここでは 「グループはposixGroupオブジェクトクラスを持ったエントリ内に、ユーザ名(memberUid)が列挙されて定義される」 と覚えておく。
(ヽ´ω`) < sudoers
sudoersはダウンロードした sudo.schema
に定義されている sudoRole
オブジェクトクラスを持つエントリを作成。
objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) )
cn
のみがMUSTとなっているが、sudoersファイルに記載されるような、こんな内容
## Allows people in group wheel to run all commands %wheel ALL=(ALL) NOPASSWD: ALL
を実現するには sudoHost
, sudoCommand
, sudoOption
のような他の属性を入力していく必要がある。
ここで NOPASSWD: ALL
を実現するためには
sudoOption: NOPASSWD
と書けば良さそうに思えるが、これはNG。正しくは
sudoOption: !authenticate
と書く必要がある。
困ったことに、この設定は sudoers.ldap
のmanにも記載がなかったので、どうしたものか戸惑ったのだが、下記のページがすごく参考になった。
このページに下記のような記載があったので、
The sudoers package contains a perl-script called sudoers2ldif, this script is provided in the /usr/share/doc/sudoers/ directory.
早速使ってみようと思って調べてみたが見当たらない。
sudo
パッケージの内容を見てみると、 cvtsudoers
と何やらそれらしい名前が。
# rpm -ql sudo <-- snip --> /usr/bin/cvtsudoers <-- snip --> /usr/share/man/man1/cvtsudoers.1.gz <-- snip -->
man cvtsudoers
してみるとDescriptionには
cvtsudoers can be used to convert between sudoers security policy file formats. The default input format is sudoers. The default output format is LDIF. It is only possible to convert a sudoers file that is syntactically correct.
とのことなので、早速試してみる。
-b
オプションでベースとなるDNを指定してやる。ここでは ou=Sudoers,dc=tsugihagi,dc=local
の配下にエントリを作成していくので、こんな感じ。
# cvtsudoers -b "ou=Sudoers,dc=tsugihagi,dc=local" /etc/sudoers dn: cn=defaults,ou=Sudoers,dc=tsugihagi,dc=local objectClass: top objectClass: sudoRole cn: defaults description: Default sudoOption's go here sudoOption: !visiblepw sudoOption: always_set_home sudoOption: match_group_by_gid sudoOption: always_query_group_plugin sudoOption: env_reset sudoOption: env_keep=COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS sudoOption: env_keep+=MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE sudoOption: env_keep+=LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES sudoOption: env_keep+=LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE sudoOption: env_keep+=LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY sudoOption: secure_path=/sbin:/bin:/usr/sbin:/usr/bin dn: cn=root,ou=Sudoers,dc=tsugihagi,dc=local objectClass: top objectClass: sudoRole cn: root sudoUser: root sudoHost: ALL sudoRunAsUser: ALL sudoCommand: ALL sudoOrder: 1 dn: cn=%wheel,ou=Sudoers,dc=tsugihagi,dc=local objectClass: top objectClass: sudoRole cn: %wheel sudoUser: %wheel sudoHost: ALL sudoRunAsUser: ALL sudoCommand: ALL sudoOrder: 2 dn: cn=ec2-user,ou=Sudoers,dc=tsugihagi,dc=local objectClass: top objectClass: sudoRole cn: ec2-user sudoUser: ec2-user sudoHost: ALL sudoRunAsUser: ALL sudoOption: !authenticate sudoCommand: ALL sudoOrder: 3
3つ目のエントリを見て分かる通り、sudoersファイルでの指定と同様に %
をプレフィックスとして付与することで、グループに対してsudo権を設定することができる。
ここで指定するグループは /etc/group
で管理されるグループは当然として、前項で定義したOpenLDAP上のグループに対しても適用が可能。
cvtsudoers
の出力は上記のとおりだが、ローカルで定義されているユーザ・グループ対するsudoersはローカルのファイルで定義すべきで、ここでは実際に追加するエントリは下記の通りとなる。
dn: cn=production-server,ou=Sudoers,dc=tsugihagi,dc=local objectClass: sudoRole cn: production-server sudoHost: ALL sudoCommand: ALL sudoUser: %managers dn: cn=staging-server,ou=Sudoers,dc=tsugihagi,dc=local objectClass: sudoRole cn: staging-server sudoHost: ALL sudoCommand: ALL sudoUser: %managers sudoUser: sre-senior-member dn: cn=dev-server,ou=Sudoers,dc=tsugihagi,dc=local objectClass: sudoRole cn: dev-server sudoHost: ALL sudoCommand: ALL sudoUser: %managers sudoUser: %sre sudoUser: dev-member
cnの値がサーバ名になっていることがわかると思う。
権限をどの単位で管理するかは既存のポリシーや組織によってまちまちだと思うが、ここではファイルによるsudoers管理と同様に、サーバからみてどのユーザ・グループに権限を付与するか、という視点で設定する。
(ヽ´ω`) < LDIF流し込み
作成された base.ldif
, users.ldif
, groups.ldif
, sudoers.ldif
をOpenLDAPに流し込んでいく。
ここで注意、改めて olcDatabase={2}hdb,cn=config
の設定を見てもわかるとおり、 olcAccess
属性が設定されていない。
[root@ip-172-16-1-209 ~]# ldapsearch -Y EXTERNAL -H ldapi:/// -b "olcDatabase={2}hdb,cn=config" SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 # extended LDIF # # LDAPv3 # base <olcDatabase={2}hdb,cn=config> with scope subtree # filter: (objectclass=*) # requesting: ALL # # {2}hdb, config dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap olcDbIndex: objectClass eq,pres olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub olcSuffix: dc=tsugihagi,dc=local olcRootDN: cn=Manager,dc=tsugihagi,dc=local olcRootPW: {SSHA}SFlHUkAMFkH6xUPA61IEqDnTY2lN2YwF
この状況では、全てのユーザはread権限を持つが書き込み権限を持つのはRootDNのみとなる。
そのため書き込みのために発行する ldapadd に渡すオプションは下記のとおりとなる。
# ldapadd -D "cn=Manager,dc=tsugihagi,dc=local" -whogehoge -H ldap://127.0.0.1 -f base.ldif # ldapadd -D "cn=Manager,dc=tsugihagi,dc=local" -whogehoge -H ldap://127.0.0.1 -f users.ldif # ldapadd -D "cn=Manager,dc=tsugihagi,dc=local" -whogehoge -H ldap://127.0.0.1 -f groups.ldif # ldapadd -D "cn=Manager,dc=tsugihagi,dc=local" -whogehoge -H ldap://127.0.0.1 -f sudoers.ldif
実際にエントリが書き込まれたかを確認。
# ldapsearch -Y EXTERNAL -H ldapi:/// -b "dc=tsugihagi,dc=local"
ここまででOpenLDAP側の設定は完了。
続いて実際に認証が行われる側、SSHDが稼働しているサーバ側のSSSD設定を行っていく。
(ヽ´ω`) < OpenLDAP + SSSDでLinuxログインアカウント一元管理がさっぱりわからん - 1. OpenLDAP初期設定 -
(ヽ´ω`) < ログインアカウント一元管理したいよね、公開鍵で
多分Linuxのアカウントを一元管理したい、あるいはできるようにしろと上から命令されてググってみたけど古い情報も多くて涙目の人に送る。
何回かのエントリに分けて投稿するが、最終的にこんな感じのことができるようになる想定。
- 複数台のLinuxサーバに対して、それぞれユーザを作成しなくてもログインが可能になる
- ログイン情報はOpenLDAPで一元管理
- ユーザの所属グループも
- 各サーバのsudoersも
- もう今更パスワード認証にも戻れないので公開鍵認証でお願いします
(ヽ´ω`) < まずはOpenLDAP側の設定について
実際に設定するにはSSSDやらNSSやらPAMやらといろいろと設定が必要になるのだが、それは後回しにしておいてOpenLDAP側の設定。
OSはみんな大好きAmazon Linux2で。多分、CentOS7までならほとんど一緒なはず。8からは389 Directory Serverに置き換えられてるかも。
(ヽ´ω`) < インストール
サーバの設定を流し込んだり確認するのに ldap***
系のコマンドを使用するので、 openldap-clients
もインストールしておく。
# yum install openldap-servers openldap-clients
(ヽ´ω`) < 管理者ユーザのパスワード作成とルートサフィックス変更
下記の記事でも書いたのだが、ちょっと前のバージョンまでは /etc/openldap/slapd.conf
に設定を記載する素直な子だったのだが、2.3以降では ldifファイルからデータを読み込ませる方式に変わってしまった。
slapd.conf
による設定も完全に無効というわけではなく、推奨しないながらも可能なようなので、ディストリビューションによっては slapd.conf
が残されているようだが、Amazon Linux2では消えているようだ。
インストール直後のデフォルト設定から、自分の環境に合わせた内容に変更。
と簡単に言ってしまったが、そもそもOpenLDAPなんてよくわからんという人が多いと思うので、一旦は小難しいことは置いておいて、
tsugihagi.local
というグループのようなものを作る(デフォルトではmy-domain.comに設定されている)- 管理者はManagerという名前(これはデフォルトと同じ)
という設定を行う。
まずはパスワード作成 slappasswd
コマンドでパスワードを生成してメモしておく。
# slappasswd New password: (パスワードを入力) Re-enter new password: (パスワードを再入力) {SSHA}SFlHUkAMFkH6xUPA61IEqDnTY2lN2YwF (ここでは hogehoge というパスワード設定)
次にルートサフィックスを dc=tusgihagi, dc=local
、管理者を cn=Manager,dc=tsugiahgi,dc=local
としたLDIFファイルを作成。
# 下記内容をinit.ldifという名前で保存 dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcSuffix olcSuffix: dc=tsugihagi,dc=local dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcRootDN olcRootDN: cn=Manager,dc=tsugihagi,dc=local dn: olcDatabase={2}hdb,cn=config changetype: modify add: olcRootPW olcRootPW: {SSHA}SFlHUkAMFkH6xUPA61IEqDnTY2lN2YwF
作成した init.ldif
を流し込む。(デフォルトでローカルのrootユーザは各Backendに対して書き込みが可能)
# ldapmodify -Y EXTERNAL -H ldapi:/// -f init.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={2}hdb,cn=config" modifying entry "olcDatabase={2}hdb,cn=config" modifying entry "olcDatabase={2}hdb,cn=config"
(ヽ´ω`) < スキーマ追加
インストール直後の状態では、Linuxのユーザ情報を保持するためのスキーマ情報が読み込まれていないので、手動で読み込んでやる必要がある。
基本的なスキーマファイルは /etc/openldap/schema
ディレクトリに存在するのだが、今回はさらに
- sudo権限を管理するためのオブジェクト用スキーマ
- 公開鍵認証のための属性用スキーマ
が必要となる。
cosine, inetorgperson, nisスキーマのインストール
基本的なスキーマファイルは /etc/openldap/schema
ディレクトリ以下に揃っているので、下記の通り ldapadd
で追加してやる。
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
sudo用スキーマのインストール
ありがたいことにスキーマファイルからLDIFに変換されたものがGithub上に存在するのでそちらを使わせてもらう。
# curl -L https://raw.githubusercontent.com/Lullabot/openldap-schema/master/sudo.ldif -o /etc/openldap/schema/sudo.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/sudo.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=sudo,cn=schema,cn=config"
ちなみにsudo用のスキーマは sudo
パッケージに付属している。
下記のスキーマは OpenLDAP 用の形式になっており、 sudo のソースやバイナリの配布には schema.OpenLDAP として収録されている。その schema.OpenLDAP ファイルをスキーマ・ディレクトリ (たとえば /etc/openldap/schema) にそのままコピーし、適切な include 行を slapd.conf に追加して、 slapd をリスタートすればよい。
## バージョンが違うかもしれないのでそれぞれの環境で場所チェック # rpm -ql sudo | grep schema.OpenLDAP /usr/share/doc/sudo-1.8.23/schema.OpenLDAP
すでに説明したとおり slapd.conf
は存在せず、ldifファイルをschemaファイルから変換しなくてはいけないので、今回はそのままダウンロードして楽をさせてもらった。
公開鍵認証用スキーマのインストール
公開鍵認証に必要な openssh-lpk-openldap.ldif
は openssh-ldap
パッケージに付属している。
yum install openssh-ldap rpm -ql openssh-ldap | grep openssh-lpk-openldap.ldif cp /usr/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.ldif /etc/openldap/schema
パッケージがインストールできたら流し込み。
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/openssh-lpk-openldap.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=openssh-lpk,cn=schema,cn=config"
これにてOpenLDAPの初期設定は完了。
ぶっちゃけそんなに大したことはやってなくて、スキーマの追加が少し特殊なぐらい。
(ヽ´ω`) < slapd.confはオワコン
流石にお金払ってProにしたのに記事を書かないのもアレなので、まずは一本目。
(ヽ´ω`) < っていうかolcってなんだよ
数年ぶりにOpenLDAPを触ってみたところ、slapd.confによる設定がオワコンになっていた。 代わりになにやらolcというのを使う必要があるらしい。 これはなんだと調べてみると、どうやらOpenLDAPサーバの設定値をOpenLDAPサーバ自体で保持する仕組みらしい。
OpenLDAP 2.3 and later have transitioned to using a dynamic runtime configuration engine, slapd-config(5). slapd-config(5)
- is fully LDAP-enabled
- is managed using the standard LDAP operations
- stores its configuration data in an LDIF database, generally in the /usr/local/etc/openldap/slapd.d directory.
- allows all of slapd's configuration options to be changed on the fly, generally without requiring a server restart for the changes to take effect.
という感じでOpenLDAPの設定をLDAP操作で、LDIF形式で、さらに設定変更の反映をサーバの再起動無しで行えるとのこと。 MySQLのVARIABLESみたいなものか。
olcとはOpenLDAP Configurationの略で動的コンフィグで使用されるobjectClassやattributeのprefixの値らしい。
Configuration directives are specified as values of individual attributes. Most of the attributes and objectClasses used in the slapd configuration have a prefix of "olc" (OpenLDAP Configuration) in their names.
(ヽ´ω`) < 実際の設定方法は?
さて、olcというか動的コンフィグが何かはわかったのでその設定方法だ。
ということで、みんな大好きCentOS7に試しに入れてみると、 /etc/openldap/
配下に slapd.d
というディレクトリが存在する。
slapd.conf残っとるやんけ! と思ったらldap.confだった。
slapd.dを覗いて見ると、何やらよくわからない命名規則のディレクトリとファイルが並んでいる。 ファイルの中身を見てみると、たしかにLDIFファイルだ。 なるほど、ではこのファイルを編集して初期設定を行うのかと思ったらどうやらそうではないらしい。
Note: Although the slapd-config(5) system stores its configuration as (text-based) LDIF files, you should never edit any of the LDIF files directly. Configuration changes should be performed via LDAP operations, e.g. ldapadd(1), ldapdelete(1), or ldapmodify(1).
で、多くの日本語の解説ページは「エラーは出ますけど直接編集します」とか書いてあったりするので、このあたりもうちょい調べてみた。
上記Quick Start Guideの項番9によると
Import the configuration database You are now ready to import your configration database for use by slapd(8), by running the command: su root -c /usr/local/sbin/slapadd -n 0 -F /usr/local/etc/slapd.d -l /usr/local/etc/openldap/slapd.ldif
LDIFファイルの内容を元にconfiguration databaseを作成できるとのこと。
しかし /etc/openldap/
にそれらしいLDIFファイルは見当たらない、ということで探してみると /usr/share/openldap-servers/slapd.ldif
がそれっぽい。
試しにolcSuffixとolcRootDNの値を変更してみる。
--- /usr/share/openldap-servers/slapd.ldif.org 2019-08-22 13:46:45.604588841 +0000 +++ /usr/share/openldap-servers/slapd.ldif 2019-08-22 13:48:50.928660767 +0000 @@ -141,8 +141,8 @@ objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: hdb -olcSuffix: dc=my-domain,dc=com -olcRootDN: cn=Manager,dc=my-domain,dc=com +olcSuffix: dc=tsugihagi,dc=net +olcRootDN: cn=Manager,dc=tsugihagi,dc=net olcDbDirectory: /var/lib/ldap olcDbIndex: objectClass eq,pres olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
更新したLDIFファイルはslapaddコマンドで、slapd.dディレクトリ配下に書き出しできる。 のだが、どうやら上書きはできないらしく、予めslapd.dの中を消さないとだめっぽい。 slapaddで書き出しを行う際にはslapd、つまりOpenLDAPのプロセスは停止しておいたほうが良いとのこと。(初期設定のタイミングのみ。設定の変更は稼働中のOpenLDAPに対してldapadd/ldapmodifyを使う)
slapadd -n0 -l /usr/share/openldap-servers/slapd.ldif -F /etc/openldap/slapd.d
-l
オプションでLDIFファイルを、-F
オプションで書き出し先のディレクトリを指定する。 -n0
はLDAPデータベースの設定順序とかそのあたりの理解が必要なので、また別のエントリで。殆どの場合では -n0
で設定しておけばOK。
で、上記コマンドで生成されたファイルから、変更箇所のdiffを抜き出しものがこちら。
diff -ur slapd.d/cn=config/olcDatabase={2}hdb.ldif slapd.d.new/cn=config/olcDatabase={2}hdb.ldif --- slapd.d/cn=config/olcDatabase={2}hdb.ldif 2019-08-22 13:18:29.316749668 +0000 +++ slapd.d.new/cn=config/olcDatabase={2}hdb.ldif 2019-08-22 13:52:34.375781992 +0000 @@ -1,18 +1,18 @@ # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. -# CRC32 e7a20b3c +# CRC32 78d1520c dn: olcDatabase={2}hdb objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap -olcSuffix: dc=my-domain,dc=com -olcRootDN: cn=Manager,dc=my-domain,dc=com +olcSuffix: dc=tsugihagi,dc=net +olcRootDN: cn=Manager,dc=tsugihagi,dc=net olcDbIndex: objectClass eq,pres olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub structuralObjectClass: olcHdbConfig -entryUUID: 13823ef0-592b-1039-9ce6-2f4b436ed340 +entryUUID: d6756af0-592f-1039-83ee-d772cea2dae7 creatorsName: cn=config -createTimestamp: 20190822131829Z -entryCSN: 20190822131829.327604Z#000000#000#000000 +createTimestamp: 20190822135234Z +entryCSN: 20190822135234.386164Z#000000#000#000000 modifiersName: cn=config -modifyTimestamp: 20190822131829Z +modifyTimestamp: 20190822135234Z
CRCやUUID、タイムスタンプが更新されて、その差分が出ているため少し見にくいが、想定通りolcSuffixとolcRootDNが指定した値に書き換わっている。
ということで、これで起動すれば ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif"
などと怒られなくて済む。
(ヽ´ω`) < slapd.confからの移行はどうしたらええの?
ちなみに、slapd.confでの設定も実はできたりする。
The older style slapd.conf(5) file is still supported, but its use is deprecated and support for it will be withdrawn in a future OpenLDAP release. Configuring slapd(8) via slapd.conf(5) is described in the next chapter.
とのことで2.4ではまだサポートするけど、Deprecatedだし将来的には廃止するよとのこと。
実際に slapd --help
を実行してみると。
slapd --help slapd: invalid option -- '-' usage: slapd options -4 IPv4 only -6 IPv6 only -T {acl|add|auth|cat|dn|index|passwd|test} Run in Tool mode -c cookie Sync cookie of consumer -d level Debug level -f filename Configuration file -F dir Configuration directory -g group Group (id or name) to run as -h URLs List of URLs to serve -l facility Syslog facility (default: LOCAL4) -n serverName Service name -o <opt>[=val] generic means to specify options; supported options: slp[={on|off|(attrs)}] enable/disable SLP using (attrs) -r directory Sandbox directory to chroot to -s level Syslog level -u user User (id or name) to run as -V print version info (-VV exit afterwards, -VVV print info about static overlays and backends)
と、 -f
オプションでslapd.confを指定することで使えるようだが、いつ使用できなくなるかわからないものを使い続けるのも心臓に悪い。
slapd.confの内容を元に、slapd.ldifを書き直すのが無難だろう。
実は
Configuration directives are specified as values of individual attributes. Most of the attributes and objectClasses used in the slapd configuration have a prefix of "olc" (OpenLDAP Configuration) in their names. Generally there is a one-to-one correspondence between the attributes and the old-style slapd.conf configuration keywords, using the keyword as the attribute name, with the "olc" prefix attached.
とあるように、slapd.confのキーワードをパスカルケースにして olc
をprefixとして付与してやることで、ほとんどの設定はそのまま移行が可能。( suffix
-> olcSuffix,
rootdn->
olcRootDN`)
更にもっと簡単な方法として、slapd.confを元にslapd.dディレクトリに書き出す方法がある。
先述のslapaddコマンドでは -l
オプションでLDIFファイルを指定したが、これを -f
でslapd.confを渡してやればOK。
-f slapd.conf specify an alternative slapd.conf(5) file.
-F confdir specify a config directory. If both -f and -F are specified, the config file will be read and converted to config directory format and written to the specified directory.
さらにさらに、既に初期設定を完了して運用してしまっているが、万が一の再構築に備えてLDIFに落としておきたい場合は slapcat -n0
で、現在の設定を元にLDIFファイルを出力してくれる。
(ヽ´ω`) < 結局、動的コンフィグは嬉しいのか
confファイルを廃してLDIFの文法一本に絞れること、ldapmodifyなどの統一されたツールで操作が行えること、特に再起動不要で設定が反映できることなんかは良いと思う。 OpenLDAPは歴史が長く、slapd.conf時代の解説ページが多いので少し戸惑うかもしれないが、次のバージョンでslapd.confのサポートが完全に切られたりしても大丈夫なように備えておきましょう。
(ヽ'ω`) < 明日から本気を出す
(ヽ'ω`) < もう4年も前なのか…
OpenLDAP絡みの調べ物をしていて、それなりに色々と動かせるようになったので、せっかくなのでブログに書こうと思って久しぶりに開いてみたら最終更新が4年前だった…
ということで、再度はてなブログProにアップグレードして、独自ドメインを設定してみる。
肝心の記事は明日… いや、週末には…
(ヽ'ω`) < iOS8.4にしたらSMTP AUTHでSSL接続ができない…
(ヽ'ω`) < さすがAppleさんやでぇ…
みんな大好きAppleのソフトウェアアップデート。iOS8での802.1xのWEP暗号化サポートの時もそうだったけど、基本的にえげつないぐらいバッサリいく。「俺らがやらねぇとテメーらいつまでたってもセキュリティガバガバで使い続けるじゃねぇか!」 というポリシーには共感ができる。
で、今回の問題。 「iOS8.4、OS X v10.10.4にしたらSSLを使っているサービスに接続できなくなった。」
(ヽ'ω`) < 何が起こった?
まず自分が確認したのが、SMTP AUTHのサービスに突然接続できなくなったとの相談を受けた。 その人が使ってるSMTP AUTHのサーバを見せてもらうと、何やらSSLのエラーが大量に出ている。
で、Appleのフォーラムを見てみると同じ症状で悩んでる管理者の人がPostしていた。ユーザじゃなくて管理者ってのが泣ける。
SMTP with SSL completely broken after iOS 8.4 u... | Apple Support Communities
そこからのリンクで、これ
Logjam攻撃への対策として、DHパラメータの長さが2048bit以上じゃないとダメになったっぽい。
(ヽ'ω`) < んで、どうしたらいいのさ
このサイトを参考にしてDHパラメータのファイルを作成して、オプションで追加してやる。 Logjam: PFS Deployment Guide
自分ところに相談があったのと、上記フォーラムではたまたまSMTPのSSL接続だったけど、Appleのアナウンスからは
Services that might use these types of connections include: * Enterprise Wi-Fi (802.1X) * Secure email connections * Secure web connections (HTTPS) * Secure Internet printing (IPP over TLS/SSL)
ということで、SSL/TLSが絡むサービスほぼすべてが対象っぽいです。
記事の題名ではSMTP AUTHと書いたものの、別に暗号化は強制ではないので後ろ向きな解決方法としてはクライアント側で暗号化を無効にするというのも(サーバ側が対応していれば)ありと言えば… いや、無いだろ。
(ヽ'ω`) < Javaの例外サイト・リストが追加できない
(ヽ'ω`) < なんでボタンが押せないんだよ!!!
網走刑務所も真っ青の鬼実行制限で有名なブラウザ上のJava実行。セキュリティレベルが「非常に高い」「高い」しか設定項目がないのことに狂気を感じるところですが、カレーを食べに行ったら激辛と超辛しかなかったみたいな。
で、その制限を回避させるためには例外サイト・リストに追加しなければいけないわけなんですが、何故かサイトリストの追加・削除ボタンがグレイアウト(無効化)されいて押せない。(したの画面SSは他のPCで撮ったので押せるように見えています)
(ヽ'ω`) < 設定ファイルを直接編集
色々と設定を変更してもどーもうまく行かないので、直接例外サイト・リストの情報が保存されているファイルを編集する。
このページの最下部、"Manage Access to the Exception Site List"の情報を元に調べてみると、
C:\Users\<ユーザ名>\AppData\LocalLow\Sun\Java\Deployment\security\exception.sites
このファイルがそれらしい。で、このファイルを右クリック→プロパティで「読み込み専用」にチェックが入っていると、編集ができない、時もあるらしいのだが、今回は該当せず。
1行1URLのフォーマットでファイルに
https://*.google.co.jp/ http://*.yahoo.co.jp/
みたいな感じで、追加・保存。これで改めて、確認してみるがやっぱりダメ。
(ヽ'ω`) < 設定ファイルの場所を明示的に指定してやる
他の正常に動作するPCで同じ操作を試してみると、問題なく情報が更新されるので、ファイルの場所と内容自体に問題はないはず。ひょっとすると、別のファイルを読み込みにいってるのか? と思い、exception.sitesファイルの場所を指定するオプションを探してみた。
すると、Deployment Configuration File and Propertiesに記載されている、deployment.user.security.exception.sitesがそれっぽい。
ということで、
C:\Users\<ユーザ名>\AppData\LocalLow\Sun\Java\Deployment\deployment.properties
に、下記の内容を追記。
deployment.user.security.exception.sites=C\:\\Users\\<ユーザ名>\\AppData\\LocalLow\\Sun\\Java\\Deployment\\security\\exception.sites
\を重ねてエスケープするのと、:もバックスラッシュでエスケープする点に注意。
これで確認するとOKだけれども、結局、追加・削除ボタンが押せない理由は不明のまま。
(ヽ'ω`) < tsugi☆hagi
ところで、なんでサイトリストじゃなくて、サイト・リストなんですかね。つのだ☆ヒロ的な。そういえば虎舞流も一時期THE TRA☆BRYUとかって改名してたけど、どんな判断だ。