2022/08/28 RockyLinux8.5





ActiveDirectoryと連携するメールサーバ(SSSDとMBox)

LinuxのメールアカウントをActiveDirectoryで管理する方式です。

1.メールサーバのアカウントをAD上のユーザーと連携できる
2.メールのパスワードをActiveDirectoryで統一管理

などのメリットがあります。
複雑なことに思えますが、やっていることはシンプルで、Linuxのユーザー認証のときローカルユーザーに加えて、ActiveDirectory上もチェックする。ということです

本項では、PostfixにMBox形式を使用する場合の手順です。
MailDir形式を使用する場合の手順は別項「ActiveDirectoryと連携するメールサーバ(SSSDとMailDir)」を参照してください。


認証の仕組み



以前は連携にWinbindを使用した連携を紹介しましたが、Redhatの公式でもActiveDirectoryとの連携にはrealmdとsssdというサービスを使用することとなっています。

Redhat 「realmd を使用した Active Directory ドメインへの接続

sssdは、外部の認証機構(ディレクトリ)へ認証を求める仕組みです。
realmdは、sssdが行うActiveDirectoryとの認証設定を簡素化します。
realmdでは、ドメインクライアントとしてSSSDとWinbindのどちらも使えます。

いまのモダンな環境では、Winbindを使用するのではなく、ActiveDirectoryを外部認証ディレクトリと捉えて、sssdを使用するということなのでしょう。
RHELでの認証と認可の構成」という技術文書に、「SSSDの仕組み」という項目があり、そこに詳しく説明されています。


MBoxはPostfixのデフォルトで採用されていることが多いのですが、ActiveDirectoryとの連携をする場合にはMailDir形式に比べて、少しホームディレクトリの手順が増えます。
もし新規に構築する要件があるのなら、MailDir形式を選択する方が手間が少ないでしょう。

どうしてもMBox形式を維持しなくてはいけない場合は、おそらく既存サーバの移行の場合でしょう。
その場合、POP3しか使わないか、IMAPを使用しているもしくは今後IMAPに移行する可能性がある場合で、方法が変わってきます。

新規に構築 MailDir形式で構築するほうが手間がない
どうしてもMBoxで新規構築したい POP3しか使わない
どうしてもMBoxで新規構築したい
現在IMAPで運用している、もしくは
今後IMAPへ移行するかも
SSSDではなく、自動でホームディレクトリを作ってくれるWinbindで構築した方が無難

さもないと、全ユーザーのホームディレクトリを手作業で作成する方法を考慮。
(今後も、メールアドレス発行ごとにSSHでログインするとか)
現在のMBoxのメールサーバを移行
SSSDを使用せずWinbindで移行するほうが無難
どうしてもSSSDの要件が必要なら、MBoxをMailDirへ変換する手順を検討する

MBoxで運用するなら、SSSDにこだわらず、ホームディレクトリを自動で作成してくれるWinbindで作ったほうが良いでしょう。


構成に必要なものは3つです。
・構築済みのActiveDirectory
・意図した通りに動作するメールサーバ(SMTP・POP)
・sssdとrealmd


1.メールサーバの構築
2.メールの通信試験
3.ドメイン参加の事前準備
4.ActiveDirectoryへドメイン参加
5.Dovecotの取り出しのためホームディレクトリの対応
6.キャッシュの削除





1.メールサーバの構築

MailDir方式とは、1メール1ファイルでディレクトリに保存する方式です。
mbox方式とは、メール全てを1つのファイルに保存する方式です。postfixのデフォルトです。

ActiveDirectoryと連携する場合、MailDirのほうが考慮することが少なく、簡単です。
新規に構築する場合はMailDirを選択する方が無難でしょう。

インストール
#sudo yum install postfix dovecot


Postfixの設定
#sudo vi /etc/postfix/main.cf

mydestination = $myhostname, localhost.$mydomain, example.local (追加)
inet_interfaces = all
inet_protocols = ipv4
mynetworks = localhost (ここではメールボックス用サーバとして)
#home_mailbox = MailBox (コメントアウト確認)
mail_spool_directory = /var/mail  末尾にスラッシュがないとmbox形式



Dovecot設定
各種コンフィグファイルを設定し、POP3のプレーンテキストで認証できる構成とします。
/etc/dovecot/dovecot.conf の編集

listen = *       :: を削除して*だけに変更
protocols = pop3       imap lmtpを削除してpop3だけに


/etc/dovecot/conf.d/10-auth.conf の編集

disable_plaintext_auth = no


/etc/dovecot/conf.d/10-mail.conf の編集

mail_location = mbox:~/mail:INBOX=/var/mail/%u


/etc/dovecot/conf.d/10-ssl.conf の編集

#ssl = required    #コメントアウト

この時点ではまだローカルユーザーで動作することを想定し、ホームディレクトリにmailディレクトリを生成する設定にしてあります。(mail_locationの項目)
AD用の調整は後で加えます。


サービスの起動と設定をします。
#sudo systemctl restart postfix
#sudo systemctl start dovecot
#sudo systemctl enable postfix
#sudo systemctl enable dovecot
もちろん、必要に応じてファイアウォールで25/110ポートを開放しなければいけません。

#firewall-cmd --get-active-zones
public
  interfaces: enp0s3

現在のFirewallゾーンで、SMTP/POP3サービスが許可されているか確認
#firewall-cmd --list-all
public (active)
(略)
  services: dhcpv6-client ssh
  ports:
(略)

現在のFirewallゾーンにSMTPとPOP3サービス許可を追加
#firewall-cmd --add-service=smtp,pop3
success

#firewall-cmd --get-services
public (active)
(略)
  services: dhcpv6-client smtp pop3 ssh
  ports:
(略)

設定を永続化
#firewall-cmd --runtime-to-permanent
success




2.メールの通信試験

ユーザーを作成し、試験します。
#sudo useradd -s /sbin/nologin user1
#sudo passwd user1

仮メールを送信し、ファイルが生成されているか確認します。
#mail -s TestMail user1@example.local
test (本文)
. (ドットで修了)

#ls /var/mail
 user1
popでメールが取り出せるか、メーラーかtelnetで確認します。
#telnet localhost 110
user user1
+OK
pass user1P@ssword
+OK Logged in.
list
+OK 1 messages:
1 823
.
retr 1
(メールの内容の表示)
この時点でメールが正常に送受信できない場合、
・サービスが起動していない
・ファイアウォールでポートが締まっている
・メール送信が成功していなくて、まだメールが1通もない
が考えられます。




3.ドメイン参加の事前準備


前提条件として、DNSの設定がドメインコントローラに向いている必要があります。


必要なパッケージはまとめて事前にインストールしておきます。
#sudo yum install realmd sssd adcli
パッケージが不足していると、realmコマンドを使ってActiveDirectoryへドメイン参加する際、
「 realm: Couldn't join realm: Necessary packages are not installed: oddjob, oddjob-mkhomedir, sssd, adcli 」
と怒られます。
このうち、oddjob、oddjob-mkhomedirは、realmのインストール時に依存関係で解決されます。


インストール後、まずはドメインコントローラへ通信確認をします。
DNSの指定がADへ向けられている必要があります。
#realm discover dc1.example.local

example.local
  type: kerberos
  realm-name: EXAMPLE.LOCAL
  domain-name: example.local
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: oddjob
  required-package: oddjob-mkhomedir
  required-package: sssd
  required-package: adcli
  required-package: samba-common-tools





4.ActiveDirectoryへドメイン参加


ActiveDirectoryへドメイン参加します。

まずはLinuxのホスト名から変更しておきましょう。

realmでドメイン参加すると、現在のホスト名がActiveDirectory上のメンバサーバ名となります。
(Winbindのときはsmb.confで指定したnetbiosNameがメンバサーバ名に使用されました)
ドメイン参加した場合、ホスト名は重要になってくるので、忘れず変更しておきます。
#sudo hostnamectl set-hostname mailsv
#hostname
mailsv
#cat /etc/hostname
mailsv


次にドメイン参加します。
ADサーバのfqdnを入力します。無論、DNSがADサーバへ向いている必要があります。
ドメインのAdministratorのパスワードが尋ねられます。
#sudo realm join dc1.example.local
Password for Administrator: *****

ドメインのアカウントが登録されました。




うっかり間違えたホスト名でドメイン参加してしまった場合、後からホスト名を変更してもAD上のコンピュータアカウント名には、反映されませんでした。
一度ドメインから離脱して、ホスト名変えてから再度参加します。
間違えた時は、一度離脱して再度参加

#sudo realm leave
#sudo hostnamectl set-hostname mailsv
#sudo realm join dc1.example.local
Password for Administrator: *****


参加したドメイン情報が表示できるか確認します。
#sudo realm list
example.local
  type: kerberos
  realm-name: EXAMPLE.LOCAL
  domain-name: example.local
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: oddjob
  required-package: oddjob-mkhomedir
  required-package: sssd
  required-package: adcli
  required-package: samba-common-tools
  login-formats: %U@example.local
  login-policy: allow-realm-logins

次に、/etc/krb5.confへ、レルム情報を追加します。
#vi /etc/krb5.conf

includedir /etc/krb5.conf.d/

includedir /var/lib/sss/pubconf/krb5.include.d/
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 dns_lookup_realm = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false
 pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
# default_realm = EXAMPLE.COM
 default_ccache_name = KEYRING:persistent:%{uid}

※defaultに参加したドメインが自動的に追加されている
 default_realm = EXAMPLE.LOCAL

[realms]
# EXAMPLE.COM = {
#  kdc = kerberos.example.com
#  admin_server = kerberos.example.com
# }

※EXAMPLE.LOCALの項目を作成し、kdcなどを追記
 大文字小文字に注意

  EXAMPLE.LOCAL = {
  kdc = dc1.example.local
  kdc = dc2.example.local
  admin_server=dc1.example.local
 }

[domain_realm]
# .example.com = EXAMPLE.COM
# example.com = EXAMPLE.COM
 example.local = EXAMPLE.LOCAL
 .example.local = EXAMPLE.LOCAL
※大文字に注意

OSに依っては、realmでドメイン参加すると、krb5.confが変更されて親切にもドメイン情報が追記されています。(Rocky8.5では追記されていませんでした)
コンフィグで例示されているEXMAP.COMを参考に、kdc情報など入力します。


realmでドメイン参加すると、/etc/sssd/sssd.confが生成されます。
なお、このディレクトリはroot権限者にしか閲覧できません。
なお、realmでドメイン参加しなおすと、このsssd.confは再生成されます。その都度設定しましょう。
#cd /etc/sssd/
#sudo vi sssd.conf

[sssd]
domains = example.local
config_file_version = 2
services = nss, pam

[domain/example.local]
ad_server = dc1.example.local
ad_domain = example.local
krb5_realm = EXAMPLE.LOCAL
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
fallback_homedir = /home/%u@%d
access_provider = permit
use_fully_qualified_namesとは、ユーザー確認の際にユーザー@ドメイン名の形式を指定する設定です。
今回はメールサーバとして使用するため、ユーザー名だけでADへ確認してもらいたいので、use_fully_qualified_namesをオフにします。

access_providerは、Redhat7系でも8系でも動作するように、permitにしました。
Redhat7系ではデフォルトの access_provider = ad で動作するのですが、Redhat8系になるとパスワードの認証が成功しませんでした。
(smtpのメール着信は可能ですが、popで取り出そうとすると認証エラーになります)
そこで、permitにして認証範囲を「全て許可」としています。


以下のコマンドを実行して、/etc/nsswitch.confの認証方式にsssを追加します。
#authconfig --enablesssd --update
と、Redhat本家の「システムサービスの設定」「authconfigからauthselectへのスクリプト変更」にありますが、/etc/nsswitch.confの中を見るとコマンド実行前から、すでにsssの設定があります。
nsswitch.conf以外にも変更しているのかもしれませんが、検証環境でもこのコマンドは実行なしでもADへの認証は利用可能でした。


authselectは使用しない
なお余談ですが、Redhat8以降では認証方式の更新・切り替えにはauthselectコマンドを使用することが推奨されています。
しかし本家では「このコマンドはLDAPなどのIdMを切り替える場合に使用するのであって、SSSD経由でActiveDirectoryと通信する場合は使用する必要はない」とあります。
ActiveDirectory連携の場合、「プロファイルを変更しないことをお勧めします」とも。

Redhatで公開されている「RHELでの認証と認可の構成」という技術文書では、Redhat7系までで指定していたauthconfigの変更コマンドの、authselectとの対応表があります。



sssdの起動と、認証のコンフィグ確認をします。
ただし、authconfig --testが使用できるのは、7系までです。8系ではauthselectコマンドにとって代わられていますが、testに相当する機能が見つかりません。
#sudo systemctl restart sssd
#sudo systemctl enable sssd
#authconfig --test  (RHEL7まで)

AD認証確認をします。
idコマンドに続き、AD上にあるユーザー名を指定します。
情報がとれたら成功です。
#id user2
uid=106601107(user2) gid=106600513(domain users) groups=106600513(domain users)
もし、「no such user」とユーザーが見つからない旨が表示されたら、ユーザー名をプリンシパルネームで指定してみます。
#id user2@example.local
uid=106601107(user2@example.local) gid=106600513(domain users@example.local) groups=106600513(domain users@example.local)
プリンシパルネームでsidが取得できた場合、前述のsssd.confの「se_fully_qualified_names」の値がtrueになっている可能性があります。コメントアウトするかfalseにする必要があります。

また、パスワード認証が成功するかも確認できます。
#getent passwd user2

Linux上には存在せず、AD上にあるユーザー宛にメールを送信できるかを確認します。
この時点ではADユーザー宛のメールを、サーバが正常に受信してくれるかを試験します。
POPによって取り出せるかは、まだ試験できません。
メールの送信
#telnet 192.168.1.100 25
helo localhost
mail from:admin@exapmle.local
rcpt to:user2@example.local
data
test mail
.
/var/mailに、user2のメールボックスが生まれているかを確認します。





5.Dovecotの取り出しのためホームディレクトリの対応

dovecotはmboxでメール受信する際、デフォルトでユーザーのホームディレクトリを必要とします。
しかし「メールのパスワードをADに確認するだけ」のサーバは、ユーザーのホームディレクトリが作成されるフェーズがありません。
そのためユーザーのホームディレクトリが見つからないので、mboxからのメール取り出しに失敗します。

↓ホームディレクトリがないので、ディレクトリの取得ができなくて失敗するログ
/var/log/maillog

Aug 28 12:04:58 localhost dovecot[4256]: pop3-login: Login: user=<user2>, method=PLAIN, rip=192.168.1.99, lip=192.168.1.10, mpid=4494, session=<qvN9aUTncNLAqAEU>
Aug 28 12:04:58 localhost dovecot[4256]: pop3(user2)<4494><qvN9aUTncNLAqAEU>: Error: Couldn't open INBOX: Permission denied
Aug 28 12:04:58 localhost dovecot[4256]: pop3(user2)<4494><qvN9aUTncNLAqAEU>: Disconnected: Couldn't open INBOX: Permission denied top=0/0, retr=0/0, del=0/0, size=0

原因となる設定はここ
/etc/dovecot/conf.d/10-mail.conf

mail_location = mbox:~/mail:INBOX=/var/mail/%u
ホームディレクトリが必要な理由はdovecotがIMAPで使うINBOXを配置するためです。
ここでいうINBOXとは 10-mail.confの
「 mail_location = mbox:~/mail:INBOX=/var/mail/%u 」 の
INBOX=/var/mail/%u のことではなく
~/mailと指定されている ~mail/.imap/INBOX のことです。



解決方法は主に2つ
1 そもそもPOP3しか使わないのならホームディレクトリが不要の構成にする
2 ホームディレクトリを手作業で維持する


1 そもそもPOP3しか使わないのならホームディレクトリが不要の構成にする

これはDovecotの本家のドキュメントにも記載されています。

ホームディレクトリを必要とするのはIMAPが動作する可能性があるからです。
(今後も)POP3だけなら、そもそもホームディレクトリの設定はいりません。
ホームディレクトリの代わりに、ユーザーが書き込めない空っぽのディレクトリを指定し、INDEXをメモリ上で動作させる設定を加えます。
/etc/dovecot/conf.d/10-mail.conf の編集

mail_location = mbox:/var/empty:INBOX=/var/mail/%u:INDEX=MEMORY
これでPOPでのメール取り出しが可能となります。
メールの取り出し
#telnet 192.168.1.100 110
user user2
+OK
pass user2P@ssword
+OK Logged in.
list
+OK 1 messages:
1 823
.
retr 1
動作しない場合、SELinuxが有効になっていないか確認します。



2 ホームディレクトリを手作業で維持する

ハッキリ言えばSSSDでMBox形式を、ホームディレクトリとともに維持するのは良い選択ではありません。
本家のマニュアルにも(これはバーチャルドメインに関する説明ですが)、MBox形式とホームディレクトリの共存について「no good」(「安全でグッドな方法はホントにないんだ」)と諦めています。

対応1
一番簡単なホームディレクトリの作成方法は、AD上のユーザーを使ってメールサーバへSSHログインすることです。
こうすれば、ユーザーのホームディレクトリが作成され、/home/ドメインユーザー名/mail/.imap/INBOXが利用できるのでDovecotからメールが取り出せます。
例えば管理者の把握している、システム系メールなどごく少数のメールアカウントをADパスワードと連携させたいだけなら、これで十分です。

対応2
一般社員向けに、それも全社に展開するのなら、個々のホームディレクトリを作るのは手間がかかります。
AD上にユーザーを新規作成するたび、メールサーバへも忘れずSSHログインしてホームディレクトリを作る必要もあります。
メールサーバの移行時も、旧サーバのメールデータ以外にユーザーのホームディレクトリも移行します。
パスワードの分からない運用中のADアカウントが多数あるのなら、SSHによるホームディレクトリ作成はお手上げです。
スクリプトを使用するなどして、全ユーザーのホームディレクトリ相当のディレクトリを手作業で作成するしかないでしょう。

対応3
「全ユーザーのパスワードを使ってSSHでログインする、そして今後もメールアドレス作成のたびにそれを行う」という作業が非現実的なら、「SSSDを使用してMBox形式のメールサーバをActiveDirectoryのパスワード連携する」のは諦めたほうがいいです。
手段としては
・SSSDの使用をやめ、ホームディレクトリを自動生成してくれるWinbindを使用する
・Mbox形式ではなく、ホームディレクトリの制限がないMailDir形式を使用する
 →MBoxからMailDirへ変換する検証をしたほうが有意義でしょう
  別項の「メールサーバのMBox形式をMailDir形式へ変換する」を参照してください。




AD上の認証範囲を制御する

メールアカウントをADと連携させると、AD上の全てのユーザーが、メールアドレスとして着信可能となります。
もしそういった環境が望ましくないなら、特定のユーザーのみをAD連携対象とできます。
/etc/sssd/sssd.conf

[sssd]
domains = example.local
config_file_version = 2
services = nss, pam

[domain/example.local]
ad_server = dc1.example.local
ad_domain = example.local
krb5_realm = EXAMPLE.LOCAL
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
fallback_homedir = /home/%u@%d
access_provider = simple
simple_allow_users = admin
simple_allow_groups = mailgroup
access_providerをsimpleに設定することで、単純なユーザー名やグループ名で許可アカウントを制限できます。
allow_usersとallow_groupsで許可アカウントを指定すれば、AD上のadminと、mailgroupに所属しているユーザーアカウントだけがPOPのパスワード認証に成功します。
mailgroupのメンバーアカウントを変更した場合は、割とすぐに反映されました。

他にも、access_provider=ad と ad_access_filter を組み合わせれば、特定のOU配下のみのユーザーをメールアカウントとすることもできると思います。





キャッシュの削除



sssd.confの値を変更した場合など、sssdを再起動する必要があります。
でもsssd.confを変更したのに、さっきとユーザー認証の成否が変化しなかったります。
例えば設定変更により、認証しない範囲を変更したのに引き続き認証できてしまう、などです。

それはsssdはオフライン(一時的にDCと通信できないなど)の場合でも認証を継続できるよう、認証キャッシュを持っているからです。

Redhat 「SSSDキャッシュの管理」にもありますが、そういう場合はsssdの認証キャッシュを削除します。
キャッシュファイルは /var/lib/sss/db/ にありますが、通常はコマンドから削除します。
全ての認証キャッシュを削除
#sss_cache -E

example.localドメインの認証キャッシュだけ削除
#sss_cache -Ed example.local

特定のユーザーの認証キャッシュを削除
#sss_cache -u user2
認証範囲の設定変更をすぐに反映したい場合、まずはキャッシュを疑ってみましょう。


td




prev.gif