お知らせ
Ubuntu16.04からUbuntu18.04に移行するとき、この設定(インストール)を終えた後でKopanoのデータを移行すれば良いことが分かったので、新しい記事を投稿しました。もしかしたら、バックアップをとる際のお役に立つかもしれません(実際、このサイトの毎日のバックアップスクリプトを記事ベースで作成して運用しています)。
新たにドメインを作ってサーバーを立てようと思いたったことから、そこでもKopanoをセットアップして使おうと思った。
だが、今回は1から構築じゃん。ハードルが高くて、ついつい後回しにしてたやつだ。
でも、やるなら今だ、今しかない!
やることをざっくり考えると…
- OSインストール直後の色々な初期設定
- Postfixのインストール(メール転送)
- MariaDBのインストール(各種データの保管場所)
- Apacheのインストール(Webサーバー)
- Kopanoのインストール(Exchange互換のシステム)
- Z-Pushのインストール(プッシュ通知)
- 各システムをつなげていく
- 動作確認
- Aliases設定
- Postfixでメール送受信ができるように設定する
- トラブル対策 ※随時追記
となる。まっさらな環境から作っていってみよう。
今回もDynamicDNSで hogeserver.hogeddns.jp が名前解決できる前提。
ここに temp というサーバーを立てて、temp.hogeserver.hogeddns.jp というFQDNとしている。
OSインストール直後の色々な初期設定
IPv6を無効化(うちでは使えないため。これは必須ではない、使えるなら使いたい)。それと、再起動を早くする。0でも良さそうだけど。
/etc/default/grub
GRUB_TIMEOUT=1 GRUB_CMDLINE_LINUX="ipv6.disable=1"
反映して再起動。
$ sudo update-grub $ sudo reboot
タイムゾーンの設定。
$ sudo timedatectl set-timezone Asia/Tokyo
$ timedatectl
Local time: Thu 2019-05-02 17:17:55 JST
Universal time: Thu 2019-05-02 08:17:55 UTC
…
色々アップデート、SSH以外のポートを閉じて再起動。
$ sudo apt update; sudo apt -y dist-upgrade; sudo apt -y autoremove $ sudo ufw allow ssh comment SSH $ sudo ufw enable $ sudo reboot
※テスト環境のため、SSHの鍵設定は行っていない。
Postfixのインストール
パッケージをインストール。
$ sudo apt install postfix postfix-mysql [Postfix Configuration] 質問1 : Internet Site 質問2 : temp.hogeserver.hogeddns.jp ※ここではテスト用のドメインを入力。 通常 hogeserver.hogeddns.jp を利用しているとして、今回はその下位に temp というサブドメインを立ててテスト。 $ getent passwd ※追加された分だけを抜粋 postfix:x:111:114::/var/spool/postfix:/usr/sbin/nologin $ getent group ※追加された分だけを抜粋 ssl-cert:x:113: postfix:x:114: postdrop:x:115:
MariaDBのインストール
パッケージをインストール。
$ sudo apt install mariadb-server $ getent passwd ※追加された分だけを抜粋 mysql:x:112:116:MySQL Server,,,:/nonexistent:/bin/false $ getent group ※追加された分だけを抜粋 mysql:x:116:
Apacheのインストール
パッケージをインストールし、ポート80番を開ける。
http://temp.hogeserver.hogeddns.jp にアクセスしてみる。
$ sudo apt install apache2 $ sudo ufw allow http comment HTTP $ getent passwd ※ここではユーザーが追加されなかった www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin ← 多分こいつが使われる $ getent group ※ここではグループが追加されなかった www-data:x:33: ← 多分こいつが使われる
Kopanoのインストール
パッケージをインストールする。Kopanoはいくつものサービスが協調して動くのだけれども、ライブラリ的な依存関係はない模様。なので個別に設定。
$ sudo apt install kopano-webapp-apache2 kopano-utils kopano-dagent kopano-search kopano-spooler kopano-monitor kopano-gateway kopano-ical [Configuring kopano-server] Configure database for kopano-server with dbconfig-common? ※Google先生の翻訳 これはオプションでdbconfig-commonで処理できます。 あなたが上級データベース管理者であり、この設定を手動で実行したいことを知っている場合、 またはデータベースが既にインストールされ設定されている場合は、このオプションを拒否するべきです。 何をする必要があるかについての詳細は、おそらく/usr/share/doc/ kopano-serverで提供されるべきです。 そうでなければ、おそらくこのオプションを選ぶべきです。 dbconfig-commonでkopano-server用のデータベースを構成しますか? → YES MySQL application password for kopano-server: ※Google先生の翻訳 kopano-serverがデータベースサーバーに登録するためのパスワードを入力してください。 空白のままにすると、ランダムなパスワードが生成されます。 → 空白(どうせ、後でConfigファイルとかで見られるはず) $ getent passwd ※追加された分だけを抜粋 kopano:x:113:117:Kopano,,,:/var/lib/kopano:/usr/sbin/nologin $ getent group ※追加された分だけを抜粋 kopano:x:117:
kopano-webapp-apache2はKopanoのWeb用アプリ。kopano-serverには依存しているが…
kopano-dagentはメールをインポートする際に使うコマンド、kopano-spoolerは保留されたEメールを配信、kopano-searchは検索用のインデックス貼り、kopano-monitorはクオータの監視をする。で、kopano-utilsはユーザー追加とかをするコマンドを含んでいるから絶対に必要。
kopano-gatewayはPOP3, POP3S, IMAP, IMAPSのリスナーになり、kopano-icalはiCal, CalDAVのリスナーになるらしいが、Z-pushするからいらないかな…多分だけど、必要なければインストールしなくても良さそう…。
kopano-serverとkopano-dagentは有効になっていない。このインストールの仕方のせい?何かの間違い?手動で有効化する。
$ sudo systemctl enable kopano-server Synchronizing state of kopano-server.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable kopano-server ※怒られた $ sudo /lib/systemd/systemd-sysv-install enable kopano-server $ sudo /lib/systemd/systemd-sysv-install enable kopano-dagent
これで再起動後も起動するだろう。
Z-Pushのインストール
D-Pushにリブランドされているのかと思いきや、Z-Pushのままで用意されていた。
色々な仕組みに対応しているらしいのだけれど、今回はKopanoを使っているので恐らくこれ。
Z-Push Home / Installation
$ sudo apt install z-push-backend-kopano
各システムをつなげていく
これまでバラバラにインストールしたアプリケーションたちをつないでいく。
┌───────────┐ ┌────┐ │ Apach │ │ Postfix│ └─┬───────┬─┘ └─┬──┘ │ │ │ ┌─┴──┐ ┌─┴──┐ │ │ Kopano ├──┤ Z-push │ │ └─┬──┘ └────┘ │ │ │ ┌─┴───────────────┴──┐ │ MariaDB │ └────────────────────┘
こんなつなぎ方になるから…
- Apach → Kopano
- Kopano → MariaDB
- Postfix → MariaDB
- Apach → Z-push
- Z-push → Kopano
を1つ1つ設定。
Apach → Kopano
いわゆる httpd.conf 的なもので index.php が呼び出せるようにすれば良い。
サブディレクトリでサービスを提供したことで設定が複雑化した過去の反省から、サブディレクトリ形式ではなくサブドメイン形式で定義してみようと思う。
赤文字部分が追加箇所で、黒いところは元々あったやつ。
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80> ServerName temp.hogeserver.hogeddns.jp ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <VirtualHost *:80> ServerName kopano.temp.hogeserver.hogeddns.jp ServerAdmin hogeuser@temp.hogeserver.hogeddns.jp ErrorLog ${APACHE_LOG_DIR}/kopano_error.log CustomLog ${APACHE_LOG_DIR}/kopano_access.log combined # Kopano WebApp Alias / /usr/share/kopano-webapp/ include /etc/kopano/webapp/apache2.conf </VirtualHost>
アクセスしようとしたらエラーが出たので調べてみたら、本来はSSLが必要みたい。
これは以下で回避。SSLの設定は今回のテストの範囲外。
www.pc-howto.com / INSTALLATION: KOPANO – DER „NEUE“ STERN AM GROUPWAREHIMMEL – TEIL 1 (LAMP INSTALLATION)
/etc/kopano/webapp/config.php
# define("INSECURE_COOKIES", false); define("INSECURE_COOKIES", true);
反映。
$ sudo systemctl reload apache2 $ sudo systemctl restart apache2 ← 動きがおかしいときはこれも一応試しておく
http://kopano.temp.hogeserver.hogeddns.jp でアクセスすると、ログイン画面が出てくる。
これでApach → Kopanoの接続はできた。
意図しない形でkopanoが公開されていたので解除。
/etc/apache2/conf-available/kopano-webapp-apache2.conf
confはあんまり考えてなかった…。この中にサイズの大きなファイルをやりとりするための設定等が書かれていたこと、VirtualHostを使ってサブドメインでサービスを提供していることを考慮して、confにあるファイルをインクルードした。
その上で、以下の通りconfを無効化(サブドメインなしでサービスを公開していることになるから)して狙い通りのサービス公開ができるようになった。
2019/06/09追記。
$ sudo a2disconf kopano-webapp-apache2.conf $ sudo systemctl reload apache2
Kopano → MariaDB
データベースユーザーがインストーラーによって作られているので大丈夫だろう。念のため kopano-server を再起動してみた。
$ sudo mysql -u root MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | kopanoserver | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec) MariaDB [(none)]> select Host, User, Password from mysql.user; +-----------+---------------+-------------------------------------------+ | Host | User | Password | +-----------+---------------+-------------------------------------------+ | localhost | root | | | localhost | kopano-server | *B9ACB0B44160269C26AD0831CC234755BA484B40 | +-----------+---------------+-------------------------------------------+ 2 rows in set (0.00 sec) MariaDB [(none)]> Bye $ sudo systemctl restart kopano-server
ユーザーとグループを作ってみりゃ、ちゃんとつながっているかどうかは分かりそうだ。
※passwordのところは、ちゃんとしたパスワードを。-p指定がなければ聞かれると思う。
ubuntu manuals / kopano-admin - Manages Kopano users and stores
$ sudo kopano-admin -c root -p password -e root@temp.hogeserver.hogeddns.jp -f "Adminstrator" -a yes $ sudo kopano-admin -c hogeuser -p password -e hogeuser@temp.hogeserver.hogeddns.jp -f "Hoge User" -a no $ sudo kopano-admin -l User list for Default(3): Username Fullname Homeserver ---------------------------------------------- SYSTEM SYSTEM Kopano root Adminstrator hogeuser Hoge User
SYSTEMは内部ユーザーで、ログインとかはできない。
Postfix → MariaDB
自分の過去記事を見ると3つのファイルをいじる、とある。公式には2つで良さそうだったけど…
Kopano Knowledge Base / Postfix
実際にはmaster.cfをいじらないと、上で作成したrootというユーザーにメールが送れない問題が発生したので、結局3つのファイルをいじる。kopano-dagentはここで間に挟まってるんだなぁ。
/etc/postfix/main.cf
# for Kopano ※ファイルの最後に追記 virtual_alias_maps = mysql:/etc/postfix/mysql-aliases.cf mailbox_command = /usr/sbin/kopano-dagent "$USER" mailbox_transport = kopano: kopano_destination_recipient_limit = 1
/etc/postfix/mysql-aliases.cf ← 新規作成
データベース名、ユーザー名、パスワードは /etc/kopano/debian-db.cfg に答えが書いてある。
熱い情報なので、root以外からは見えないようにchmod で 600 なファイルにする。
# The user name and password to log into the mysql server. user = kopano-server password = *************** hosts = 127.0.0.1 dbname = kopanoserver # For Postfix 2.2 and later The SQL query template. # See mysql_table(5) for details. query = select value from objectproperty where objectid=(select objectid from objectproperty where value='%s' limit 1) and propname='loginname';
/etc/postfix/master.cf
これは実際何をやっているのかが…userに存在しない vmail って書いても正しく動いたりするから、使われないパラメータも書いちゃってるんだと思う。ご容赦。
# for Kopano ※ファイルの最後に追記 kopano unix - n n - 10 pipe flags=DRhu user=kopano argv=/usr/sbin/kopano-dagent -R ${recipient}
権限変更と反映。
$ sudo chmod 600 /etc/postfix/mysql-aliases.cf $ sudo systemctl restart postfix
Apach → Z-push
confファイルに設定を書き入れる。ActiveSyncは本来SSLで暗号化されて使われるべきものだが、今回はテストのためSSLはテストの範囲外とし、80番ポートでやりとりする。
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80> ServerName temp.hogeserver.hogeddns.jp ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <VirtualHost *:80> ServerName kopano.temp.hogeserver.hogeddns.jp ServerAdmin hogeuser@temp.hogeserver.hogeddns.jp ErrorLog ${APACHE_LOG_DIR}/kopano_error.log CustomLog ${APACHE_LOG_DIR}/kopano_access.log combined # Z-pushAlias /Microsoft-Server-ActiveSync /usr/share/z-push/index.php
include /etc/apache2/conf-available/z-push.conf
include /etc/apache2/conf-available/z-push-autodiscover.conf # Kopano WebApp Alias / /usr/share/kopano-webapp/ include /etc/kopano/webapp/apache2.conf </VirtualHost>
※気持ちとしては、Z-PushはWebAppの下に書きたかったけど、WebAppのAliasがルート(/)になっているから、Z-Pushを先に書いておかないとMicrosoft-Server-ActiveSyncにたどり着かないのだった。
※Aliasの先にindex.phpを付けていなかった。付いているのが正しい模様。2019/06/09追記。
また、意図しない形でz-pushが公開されていたので解除。
/etc/apache2/conf-available/z-push.conf
/etc/apache2/conf-available/z-push-autodiscover.conf
confはあんまり考えてなかった…。この中にサイズの大きなファイルをやりとりするための設定等が書かれていたこと、VirtualHostを使ってサブドメインでサービスを提供していることを考慮して、confにあるファイルをインクルードした。
その上で、以下の通り2つのconfを無効化(サブドメインなしでサービスを公開していることになるから)して狙い通りのサービス公開ができるようになった。
2019/06/15再度追記。
$ sudo a2disconf z-push.conf z-push-autodiscover.conf $ sudo systemctl reload apache2
Z-push → Kopano
kopano-backendってのをインストールしているわけで、細かな設定はいらないようになっていた。ユーザー・パスワードはユーザー側が各デバイスで入力する。
ここでの設定はタイムゾーンをちょこっと変えるだけ。
/etc/z-push/z-push.conf.php
// Defines the default time zone, change e.g. to "Europe/London" if necessary
define('TIMEZONE', 'Asia/Tokyo');
動作確認
ここまで設定ができたら再起動して、それぞれが正しくつながったか確認しよう。
$ sudo reboot
http://kopano.temp.hogeserver.hogeddns.jp にアクセスし、作成したユーザーでログインする。そうすると質問されるから、Language: 日本語 だけはしっかり選択して Continue する。そうすると、ログインした後の画面が見られる。
ここまでのところで、Kopanoユーザー同士のメール送受信は問題なくできるようになった。
Aliases設定
さらに…管理者root君は、webmasterだったり、postmasterだったりする。そこであだ名を付ける。
/etc/aliases
# See man 5 aliases for format postmaster: root ← 既に作られていた webmaster: root
反映。
$ sudo newaliases
これで、postmaster@temp.hogeserver.hogeddns.jp と webmaster@temp.hogeserver.hogeddns.jp でメッセージが受けられる。
Postfixでメール送受信ができるように設定する
2004年に発表されたスパム対策技術 S25R を設定したい。
個人的には8年前から利用させていただいており、恐らく不正なメールは転送していない。ログを見れば毎日毎日相当数の不正な要求をはねつけており、ネットワークに不審な動きなし、プロバイダからの警告も一切受けていない。
欠点として、必要なメールも受信できない場合があるのだが、8年利用して7回。気付いたときにはホワイトリストに入れることで、その後は問題なくやりとりができるようになる。利用は一部公共サービスを除いてほとんどが家族間での利用であるが、スパムが届かないので重宝している。
お知らせ: ※2019/06/16追記
S25RによるRejectをLogcheckで検知できる設定を投稿しました。
今回はこれにRealtime Blackhole List(RBL)による対策を加え、まだRBLに登録されていないサーバーからのリクエストを S25R のルールで延期・拒否する。過剰設定だが拒否が S25Rによって引き起こされたのかどうか切り分けやすくなると想定。RBLはSPAMHAUSを利用させていただく。
/etc/postfix/main.cf
#smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) ← Banner: 220 temp.hogeserver.hogeddns.jp ESMTP Postfix (Ubuntu) smtpd_banner = $myhostname ESMTP ← Banner: 220 temp.hogeserver.hogeddns.jp ESMTP もしかしたら、UbuntuでPostfixと表示した方が攻撃意欲が失せる?かも biff = no append_dot_mydomain = no delay_warning_time = 4h readme_directory = no compatibility_level = 2 smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination myhostname = temp.hogeserver.hogeddns.jp alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = $myhostname, temp.hogeserver.hogeddns.jp, localhost.hogeserver.hogeddns.jp, localhost #relayhost = mynetworks = 172.16.0.0/16 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all inet_protocols = ipv4 # for Relay (OP25B) relayhost = [smtp.provider.com]:587 ← 利用しているプロバイダのサーバーを書くところ smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/isp_passwd ← .dbはつけない(付与される)。プロバイダへの接続情報はここに smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_mechanism_filter = cram-md5, plain, login # for Sub domain postfix ※テストのときに親サーバーで使うかも #relay_domains = hogeserver.hogeddns.jp temp.hogeserver.hogeddns.jp #transport_maps = hash:/etc/postfix/transport # for S25R ※スパム対策 smtpd_client_restrictions = ← クライアントへの要求、書いた順に評価される permit_mynetworks ← 許可: mynetworksに含まれる check_client_access regexp:/etc/postfix/white_list ← 独自にOKとしたルール(7件登録) check_client_access regexp:/etc/postfix/white-list.txt ← 提供していただいているホワイトリスト(週1回ダウンロード) reject_rbl_client zen.spamhaus.org ← RBLによる拒否 check_client_access regexp:/etc/postfix/rejections ← S25R拒否条件。論文で説明されているファイルの内容。GENERIC PROTECTION 以下が重要 smtpd_helo_required = yes ← 相手に自己紹介を要求 smtpd_helo_restrictions = ← 相手のHELO・EHLOコマンドを判定 permit_mynetworks ← 許可: mynetrowksに含まれる(効果があるのか未確認) reject_invalid_helo_hostname ← 拒否: ホスト名が不正な形式の場合に拒否 check_helo_access regexp:/etc/postfix/helo_restrictions ↑ 拒否: 拒否ファイルによる。だが、現状中身は空っぽ。 smtpd_sender_restrictions = ← 相手のMAIL FROMコマンドを判定 permit_mynetworks ← 許可: mynetrowksに含まれる(効果があるのか未確認) reject_non_fqdn_sender ← 拒否: fromアドレスがFQDNではない reject_unknown_sender_domain ← 拒否: ウチが最終宛先ではない AND (fromドメインがMXやAレコードを持たない or MXレコード異常) # for Kopano virtual_alias_maps = mysql:/etc/postfix/mysql-aliases.cf mailbox_command = /usr/sbin/kopano-dagent "$USER" mailbox_transport = kopano: kopano_destination_recipient_limit = 1
ホワイトリストは週に1回ダウンロード。システム全体の設定なので、crontabに書き込んでしまう。時間とかを気にしないなら、/etc/cron.weekly にシェルを放り込んでおけば良い。
毎週月曜日の朝4:55にダウンロード。
/etc/crontab
# 分 時 日 月 曜日(0:日曜 1:月曜…) ユーザー 実行するコマンド 55 4 * * 1 root /root/download_whitelist
ホワイトリストをダウンロードするシェル。更新時間を比較して新しければダウンロード。
/root/download_whitelist
#!/bin/sh wget http://www.gabacho-net.jp/anti-spam/white-list.txt -N -P /etc/postfix
S25Rの拒否条件は論文から切り出して作成。
/etc/postfix/rejections
# S25R client rejection specifications for Postfix # Contributed by ASAMI Hideo (Japan), Jun 2004; Jul 2007 # Refer to: http://www.gabacho-net.jp/en/anti-spam/ # # To use this file, add following lines into the /etc/postfix/main.cf file: # # smtpd_client_restrictions = # permit_mynetworks, # check_client_access regexp:/etc/postfix/white_list # check_client_access regexp:/etc/postfix/rejections # # where "rejections" is the name of this file. ※ブラックリスト部分はカット # # *** GENERIC PROTECTION *** # # [rule 0] /^unknown$/ 450 reverse lookup failure, be patient … 最後のところまでコピペ。 # ex.: xdsl-5790.lubin.dialog.net.pl /^(dhcp|dialup|ppp|[achrsvx]?dsl)[^.]*[0-9]/ 450 S25R check, be patient
HELOコマンドの拒否リストも論文ベース。コメントだけだがコピーして作成。
/etc/postfix/helo_restrictions
# Illegal HELO command blocking specification # Provided that your mail server's IP address is 223.12.34.56 and its # acceptable domain name is "example.com", specify as follows: # #/^[?223.12.34.56]?$/ REJECT #/^(.+.)?example.com$/ REJECT
OP25Bに対応したプロバイダを利用しているので、以下に示された方法で設定。
受信したメールはKopanoに放り込まれるので、送信部分だけどうにかすれば良さそう。
パソコンおやじ / OP25B対策(Outbound Port 25 Blocking対策)
main.cf で # for Relay (OP25B) のあたりで書いたことがそれ。
プロバイダへの接続設定はこんな感じで記載。
/etc/postfix/isp_passwd
[smtp.provider.com]:587 UserID:Password
これを書いたら、以下のコマンドでハッシュ化。
/etc/postfix/isp_passwd.dbができあがる。元のファイルは消してもOK。
$ sudo postmap /etc/postfix/isp_passwd
$ sudo chmod 600 /etc/postfix/isp_passwd.db
$ sudo chmod 600 /etc/postfix/isp_passwd ← 消してもOK。今回は取っておいた。
ここまで設定したら、postfixを再起動して設定を反映させる。
$ sudo systemctl restart postfix
設定をしくじっても postfix が mail.err にエラーを出力するのは最初の1回だけだった。
次にエラーが表示されるのは、それが実際に利用されるときになるそうな。時々設定を自動読込することがその設計のベースになっていると想像、すごいけど怖い。
/var/log/mail.log を見てみるとこんな感じ。設定を変えたらkopanoユーザー同士のメール送受信のテストをすべし。
May 4 07:22:18 temp postfix/smtpd[3690]: error: open /etc/postfix/white_list: No such file or directory この間に何度 postfix を再起動してもエラーは出力されないが、メールを自分自身に1通出してみたらエラーが表示された。 May 4 07:35:02 temp postfix/smtpd[4854]: error: open /etc/postfix/white_list: No such file or directory
設定ができたと確信できたら25番ポートを開放。
ルーター配下にいる場合には、25番ポートをこのサーバーに転送すれば、外部からのメールを受け取ることができる。
$ sudo ufw allow smtp comment SMTP
今回、ウチで行ったテストでは25番ポートの転送はできない。何故なら…
┌───────────┐ │ router │ └─────┬─────┘ ├──────────────┐ ┌─────┴─────┐ ┌──────┴───────┐ │従来君 │ │temp君 │ │hogeserver.hogeddns.jp│ │temp.hogeserver.hogeddns.jp │ │ routerから25番ポート │ │hogeserverからメールのリレー│ │ の転送を受けている │ │を25番ポートで待ち受ける │ └───────────┘ └──────────────┘
という、既に運用しているたまにメールが届くかもしれないサーバーがあるから。
外部とのメールのやりとりを試そうと思ったとき、従来君からtempにメールを転送して欲しかったがなかなかうまく行かず、結果的に以下にたどり着いた。
従来君 /etc/postfix/main.cf
# for Sub domain postfix ※テストのときに親サーバーで使うかも relay_domains = hogeserver.hogeddns.jp temp.hogeserver.hogeddns.jp transport_maps = hash:/etc/postfix/transport
従来君 /etc/postfix/transport
# ローカルネットワークについてはsmtpで回す # ここにないものは relayhost の設定が使われる模様 .hogeserver.hogeddns.jp smtp:
従来君でハッシュ化し、反映。
$ sudo postmap /etc/postfix/transport $ sudo systemctl restart postfix
以上の設定で、インターネットからメールが届く環境ができた。
ログを見てみる。
メールが着信したとき(これは従来君のもの、多分tempと一緒)。
May 4 05:51:19 hogeserver postfix/smtpd[42265]: connect from xxxxx.google.com[nnn.nnn.nnn.nnn] May 4 05:51:20 hogeserver postfix/smtpd[42265]: 2D8263601F6: client=xxxxx.google.com[nnn.nnn.nnn.nnn] May 4 05:51:20 hogeserver postfix/cleanup[42269]: 2D8263601F6: message-id=<xxxxxxx@mail.gmail.com> May 4 05:51:20 hogeserver postfix/qmgr[40902]: 2D8263601F6: from=<xxxxx@gmail.com>, size=2628, nrcpt=1 (queue active) May 4 05:51:20 hogeserver postfix/smtpd[42265]: disconnect from xxxxx.google.com[nnn.nnn.nnn.nnn] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7 May 4 05:51:20 hogeserver postfix/pipe[42271]: 2D8263601F6: to=<hogeuser@hogeserver.hogeddns.jp>, relay=kopano, delay=0.5, delays=0.3/0.01/0/0.19, dsn=2.0.0, status=sent (delivered via kopano service) May 4 05:51:20 hogeserver postfix/qmgr[40902]: 2D8263601F6: removed
メールを送信するとき。
May 4 05:54:05 temp postfix/smtpd[6821]: connect from localhost.localdomain[127.0.0.1] May 4 05:54:05 temp postfix/smtpd[6821]: 5440082867: client=localhost.localdomain[127.0.0.1] May 4 05:54:05 temp postfix/cleanup[6825]: 5440082867: message-id=<kcim.xxxxxx@temp.hogeserver.hogeddns.jp> May 4 05:54:05 temp postfix/qmgr[6801]: 5440082867: from=<hogeuser@temp.hogeserver.hogeddns>, size=1811, nrcpt=1 (queue active) May 4 05:54:05 temp postfix/smtpd[6821]: disconnect from localhost.localdomain[127.0.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5 May 4 05:54:05 temp postfix/smtp[6826]: 5440082867: to=<xxxxx@gmail.com>, relay=smtp.provider.com[nnn.nnn.nnn.nnn]:25, delay=0.12, delays=0.02/0.03/0.05/0.02, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 35A553601F6) May 4 05:54:05 temp postfix/qmgr[6801]: 5440082867: removed
メールを転送するとき(従来君)。
May 4 05:54:08 hogeserver postfix/smtpd[42461]: connect from unknown[172.16.nnn.nnn] May 4 05:54:08 hogeserver postfix/smtpd[42461]: 35A553601F6: client=unknown[172.16.nnn.nnn] May 4 05:54:08 hogeserver postfix/cleanup[42464]: 35A553601F6: message-id=<kcim.xxxxxx@temp.hogeserver.hogeddns.jp> May 4 05:54:08 hogeserver postfix/qmgr[40902]: 35A553601F6: from=<hogeuser@temp.hogeserver.hogeddns.jp>, size=1997, nrcpt=1 (queue active) May 4 05:54:08 hogeserver postfix/smtpd[42461]: disconnect from unknown[172.16.nnn.nnn] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5 May 4 05:54:08 hogeserver postfix/smtp[42465]: 35A553601F6: to=<xxxxxx@gmail.com>, relay=smtp.provider.com[nnn.nnn.nnn.nnn]:587, delay=0.46, delays=0.01/0.01/0.19/0.24, dsn=2.0.0, status=sent (250 2.0.0 x43Ks5Nq007425 Message accepted for delivery) May 4 05:54:08 hogeserver postfix/qmgr[40902]: 35A553601F6: removed
メールをS25Rで拒否するとき(従来君)。
Apr 23 01:06:58 hogeserver postfix/smtpd[88302]: connect from D964D5AA.static.ziggozakelijk.nl[217.100.213.170] Apr 23 01:06:59 hogeserver postfix/smtpd[88302]: NOQUEUE: reject: RCPT from D964D5AA.static.ziggozakelijk.nl[217.100.213.170]: 450 4.7.1 <D964D5AA.static.ziggozakelijk.nl[217.100.213.170]>: Client host rejected: S25R check, be patient; from=<webhosting@provider.ne.jp> to=<check212014@gmail.com> proto=ESMTP helo=<rbyisovdjn> Apr 23 01:07:00 hogeserver postfix/smtpd[88302]: lost connection after RCPT from D964D5AA.static.ziggozakelijk.nl[217.100.213.170] Apr 23 01:07:00 hogeserver postfix/smtpd[88302]: disconnect from D964D5AA.static.ziggozakelijk.nl[217.100.213.170] ehlo=1 mail=1 rcpt=0/1 rset=1 commands=3/4 May 2 11:32:25 hogeserver postfix/smtpd[129885]: connect from 60-251-231-190.HINET-IP.hinet.net[60.251.231.190] May 2 11:32:25 hogeserver postfix/smtpd[129885]: NOQUEUE: reject: RCPT from 60-251-231-190.HINET-IP.hinet.net[60.251.231.190]: 450 4.7.1 <60-251-231-190.HINET-IP.hinet.net[60.251.231.190]>: Client host rejected: S25R check, be patient; from=<test@provider.ne.jp> to=<test@gmail.com> proto=SMTP helo=<win2012.domain> May 2 11:32:27 hogeserver postfix/smtpd[129885]: lost connection after RCPT from 60-251-231-190.HINET-IP.hinet.net[60.251.231.190] May 2 11:32:27 hogeserver postfix/smtpd[129885]: disconnect from 60-251-231-190.HINET-IP.hinet.net[60.251.231.190] helo=1 mail=1 rcpt=0/1 commands=2/3 May 4 00:04:50 hogeserver postfix/smtpd[18766]: connect from unknown[220.126.80.28] May 4 00:04:50 hogeserver postfix/smtpd[18766]: NOQUEUE: reject: RCPT from unknown[220.126.80.28]: 450 4.7.1 <unknown[220.126.80.28]>: Client host rejected: reverse lookup failure, be patient; from=<cxnmxvdshje@ebbstudy.com> to=<photo053@hanmail.net> proto=SMTP helo=<__--__> May 4 00:09:51 hogeserver postfix/smtpd[18766]: timeout after DATA from unknown[220.126.80.28] May 4 00:09:51 hogeserver postfix/smtpd[18766]: disconnect from unknown[220.126.80.28] helo=1 mail=1 rcpt=0/1 data=0/1 commands=2/4 とかとか。メール着信や転送するときには(queue active)が表示されるが、これらはキューに入らない。 後、S25Rではないが、こういうのも結構見られる。 May 2 11:56:41 hogeserver postfix/smtpd[724]: connect from unknown[185.234.216.229] May 2 11:56:42 hogeserver postfix/smtpd[724]: disconnect from unknown[185.234.216.229] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4 May 2 12:00:03 hogeserver postfix/anvil[726]: statistics: max connection rate 1/60s for (smtp:185.234.216.229) at May 2 11:56:41 May 2 12:00:03 hogeserver postfix/anvil[726]: statistics: max connection count 1 for (smtp:185.234.216.229) at May 2 11:56:41 May 2 12:00:03 hogeserver postfix/anvil[726]: statistics: max cache size 1 at May 2 11:56:41 1分間の接続要求がおかしなことになっていると見られる。 こんなのがしょっちゅう届くわけで、踏み台にならないように設定には注意したい。
トラブル対策
その後に発生したトラブルと対策を記載。
Androidのアプリケーション Tasks & Notes からタスクを追加できない
※2019/06/15追記
Exchangeに対応しているメモアプリとしてとても重宝している Tasks & Notes 。サーバーをより使いやすくするために思いついたことをタスクとして書き込んでいる。
最初は何の問題もなくアクセスできていたのだけれど、突然タスク追加ができなくなった。恐らく、/etc/apache2/conf-available/z-push.conf を無効化したのに、この設定をdefault-ssl.confでインクルードしないでいたことで、何か条件が変わっていたものと思われる。Kopanoのフォーラムにこんな記事があった。
Incident: Call to undefined function mapi_zarafa_getuser()
書かれている対策を実施したところ問題が発生しなくなったのでメモしておく。
出力されていたログはこれ。
[Sat Jun 15 03:30:00.205359 2019] [php7:error] [pid 30625] [client 172.16.119.30:48800] PHP Fatal error: Uncaught Error: Call to undefined function mapi_zarafa_getuser() in /usr/share/z-push/backend/kopano/mapiprovider.php:1689nStack trace:n#0 /usr/share/z-push/backend/kopano/mapiprovider.php(1107): MAPIProvider->setTask(Resource id #27, Object(SyncTask))n#1 /usr/share/z-push/backend/kopano/importer.php(433): MAPIProvider->SetMessage(Resource id #27, Object(SyncTask))n#2 /usr/share/z-push/backend/kopano/kopanochangeswrapper.php(357): ImportChangesICS->ImportMessageChange(false, Object(SyncTask))n#3 /usr/share/z-push/lib/request/sync.php(1486): KopanoChangesWrapper->ImportMessageChange(false, Object(SyncTask))n#4 /usr/share/z-push/lib/request/sync.php(508): Sync->importMessage(Object(SyncParameters), Array, 'Add', Object(SyncTask), '46', false, false, 1)n#5 /usr/share/z-push/lib/request/requestprocessor.php(112): Sync->Handle(0)n#6 /usr/share/z-push/index.php(107): RequestProcessor::HandleRequest()n#7 {main}n thrown in /usr/share/z-push/backend/kopano/mapiprovider.php on line 1689
対策として、以下の呼び出す関数を修正(赤文字部分を追記)。
… 1689行目で呼び出す関数の名前を修正
// check if there is already an owner for the task, set current user if not
$p = array( $taskprops["owner"]);
$owner = $this->getProps($mapimessage, $p);
if (!isset($owner[$taskprops["owner"]])) {
$userinfo = mapi_zarafa_getuser_by_name($this->store, Request::GetAuthUser());
if(mapi_last_hresult() == NOERROR && isset($userinfo["fullname"])) {
$props[$taskprops["owner"]] = $userinfo["fullname"];
}
}
mapi_setprops($mapimessage, $props);
…
フォーラムには他にも修正すべき箇所が2つあると書かれていた。ここで示されたバージョンと一致しているように見えたが中身が違っている?のか、mapi_zarafa_getuserを呼び出している箇所は他になかった。
もっとも、default-ssl.conf に z-push.conf をインクルードすると問題発生しないようにも思われた。問題が発生したら追加すれば良い程度の対策と思われる。
AppArmorによる阻害
※2019/06/16追記
Logcheckをインストールしてログを読んでいたら、kopano関連の動作がAppArmorで止められていることが分かった。何かの間違いかもしれないし、影響がないことなのかもしれないけど気になたので対策。
出力されていたログはこれ。
Jun 16 03:46:17 hogeserver kernel: [ 44.584357] kauditd_printk_skb: 13 callbacks suppressed
Jun 16 03:46:17 hogeserver kernel: [ 44.584359] audit: type=1400 audit(1560624377.830:25): apparmor="DENIED" operation="capable" profile="/usr/sbin/kopano-dagent" pid=2041 comm="kopano-dagent" capability=24 capname="sys_resource"
Jun 16 03:46:17 hogeserver kernel: [ 44.705486] audit: type=1400 audit(1560624377.950:26): apparmor="DENIED" operation="open" profile="/usr/sbin/kopano-server" name="/etc/ssl/openssl.cnf" pid=2033 comm="kopano-server" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jun 16 03:46:17 hogeserver kernel: [ 44.708748] audit: type=1400 audit(1560624377.950:27): apparmor="DENIED" operation="capable" profile="/usr/sbin/kopano-server" pid=2033 comm="kopano-server" capability=24 capname="sys_resource"
Jun 16 10:48:07 hogeserver kernel: [25354.366753] kauditd_printk_skb: 13 callbacks suppressed
Jun 16 10:48:07 hogeserver kernel: [25354.366756] audit: type=1400 audit(1560649687.157:302): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="lxc-container-default" pid=11921 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.370597] audit: type=1400 audit(1560649687.161:303): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="lxc-container-default-cgns" pid=11921 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.371321] audit: type=1400 audit(1560649687.161:304): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="lxc-container-default-with-mounting" pid=11921 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.372398] audit: type=1400 audit(1560649687.165:305): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="lxc-container-default-with-nesting" pid=11921 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.573799] audit: type=1400 audit(1560649687.365:306): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/sbin/dhclient" pid=11924 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.574676] audit: type=1400 audit(1560649687.365:307): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=11924 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.575384] audit: type=1400 audit(1560649687.365:308): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-helper" pid=11924 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.576463] audit: type=1400 audit(1560649687.369:309): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/lib/connman/scripts/dhclient-script" pid=11924 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.591556] audit: type=1400 audit(1560649687.381:310): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/bin/lxc-start" pid=11926 comm="apparmor_parser"
Jun 16 10:48:07 hogeserver kernel: [25354.693044] audit: type=1400 audit(1560649687.485:311): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/bin/man" pid=11928 comm="apparmor_parser"
対策として以下の権限を付与し、AppArmorを再起動した。
/etc/apparmor.d/local/usr.sbin.kopano-dagent ※空ファイルに以下を追記
capability sys_resource,
/usr/share/kopano-dagent/python/mapiplugin.pyc c,
/usr/share/kopano-dagent/python/wraplogger.pyc c,
/usr/share/kopano-dagent/python/pluginmanager.pyc c,
/usr/share/kopano-dagent/python/plugintemplates.pyc c,
/etc/ssl/openssl.cnf r,
/etc/apparmor.d/local/usr.sbin.kopano-server ※空ファイルに以下を追記
capability sys_resource,
/run/kopano/search.sock rw,
/etc/ssl/openssl.cnf r,
AppArmorのプロファイルを読み込ませる。
$ sudo systemctl reload apparmor
AppAormorの設定にあたり、以下を色々と調べた。
http://manpages.ubuntu.com/manpages/bionic/en/man5/apparmor.d.5.html
http://manpages.ubuntu.com/manpages/bionic/ja/man7/capabilities.7.html
capability=24の権限を与えるにあたり、それが何の権限なのかが分からなかったが…マニュアルからこのファイルにたどり着いて名前が想像できた。
/usr/include/linux/capability.h
#define CAP_SYS_RESOURCE 24
さいごに
Ubuntu(Debian?)がKopanoを取り込んでくれたことで、少なくともUbuntu18.04では相性とかを気にしないでサクッと apt install kopano* できちゃうので、最初にZarafaでサーバーを構築した当時に比べて格段に安心。ありがとうございます!
Kopanoはコミュニティ版を使わせていただいている身。正直なところアップデートに対応できずに置きっぱなしになっている。つーか、ぶっちゃけ、Kopanoのアップデートを一発でやり遂げる自信がなくてメインサーバーはUbuntu16.04のままになっている。どっかで設定方法を整理しておく必要があったから、今回トライしてみた。
Ubuntu18.04における設定方法を詳しく書いているところがどうにも見つからなくて、自分の過去記事ベースで作業したけれども、当時は訳わかんないまんまでやってたことがよく分かった。今となってはちょっと恥ずかしいが、まぁいいや、今もわかんないことあるし、今の俺の役には立ったから。
それと、改めてS25Rの凄さを感じる。発表から10年以上たつのに色あせない鉄壁の守り!個人として約8年にもわたってインターネットにメールサーバーを安心してさらしておけたことに、感謝の気持ちでいっぱいになる。ありがとうございます!
後は新しいサーバーの中身が充実させられるかどうかがポイント。うまくいくといいな。
コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他