ブログ

  • WSLを使ってメーリングリストを作成(複数ドメイン)

     複数のドメインを運用しているため、mailmanをそれぞれのドメインでも動くようにする。

     postfix+mailmanで複数ドメインに対応する方法はいくつかるようだが、一番単純なメーリングリスト名は全ドメイン共通での設定にする。
     postfix-to-mailman.pyを使えば、配送経路などもちゃんと設定できるらしいが、今回はそこまでしない。

    ・MercuryMailの設定

    別ドメインのメーリングリストで使用するメールアカウントを作成する
    ユーザー名:mydomain2
    そのメールアカウントを、Configurationー”Mercury Core Module Configuration”ー”Local Domains” にドメインメールボックスとして追加する

    Core ModuleーLocal Domains
    追加
      ↓
    DM=mydomain2 ml.mydomain2.net

    ・postfixの設定

     変更なし

    ・mailmanの設定

     別ドメインを仮想ホストとして登録する。

      $ sudo vi /etc/mailman/mm_cfg.py
    DEFAULT_EMAIL_HOST = 'ml.mydomain.com'
     ↓
    DEFAULT_EMAIL_HOST = 'ml.mydomain.com'
    VIRTUAL_EMAIL_HOST1 = 'ml.mydomein2.net'
    
    DEFAULT_URL_HOST   = 'ml.mydomain.com'
     ↓
    DEFAULT_URL_HOST   = 'ml.mydomain.com'
    VIRTUAL_URL_HOST1 = 'ml.mydomain2.net'
    
    POSTFIX_STYLE_VIRTUAL_DOMAINS = [DEFAULT_EMAIL_HOST]
    add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
     ↓
    POSTFIX_STYLE_VIRTUAL_DOMAINS = [DEFAULT_EMAIL_HOST, VIRTUAL_EMAIL_HOST1]
    add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
    add_virtualhost(VIRTUAL_URL_HOST1, VIRTUAL_EMAIL_HOST1)

    ・fetchmailの設定

    ml.mydomain2.netのメールをポーリングするよう追加する。

        $ sudo vi /root/.fetchmailrc
    poll mail.mydomain.com with proto imap envelope "X-Envelope-To"
      localdomains ml.mydomain2.net 
      user "mydomain2" with pass "mailパスワード" to * here

    複数ドメインであっても一つのメールボックスで処理するときは、以下のように記述する

    poll mail.mydomain.com with proto imap envelope "X-Envelope-To"
      localdomains ml.mydomain.com ml.mydomain2.net 
      user "mydomain" with pass "mailパスワード" to * here

    ・注意

     メーリングリストの全体的オプションで、メールの送信に使うホスト名(ドメイン名)を変更した場合に、/var/lib/mailman/data/virtual-mailmanが更新されなかったので、以下のコマンドで強制的に更新する必要があった。

        $ sudo /usr/lib/mailman/bin/genaliases
  • WSLを使ってメーリングリストを作成(外部からの受信)

     現状ではmydomain.com宛の電子メールをmail.mydomain.comという仮想ホストにより受信しドメイン内部に転送している。

     新たにml.mydomain.comという仮想ホストを作成し、@ml.mydomanin.com宛のメールをfetchmailを通してpostfixに渡し、mailmanでメーリングリストの処理をさせる。

    ・DNSの設定

    DNSに以下のレコードを追加する

    @       IN TXT  v=spf1 ip4:xx.xx.xx.xx include:outgoing.com -all
    _dmarc  IN TXT v=DMARC1; p=none; rua=mailto:dmarc_rua@mydomain.com; ruf=mailto:dmarc_ruf@mydomain.com
            IN MX  10 mail.mydomain.com.
    mail    IN A   mydomain.com
    ml      IN A   mydomain.com

     外部へのメールを外部のメールサーバー経由で送っているなら、SPFレコードにそのサーバーを追加しておく。

     メーリングリストはml.mydomain.comのアドレスを使用しているため、サブドメインにもSPFレコードを追加しておく。MAIL FROM:で指定したエンベロープFromのホストのSPFレコードをチェックされるため。

     Amazon SES経由で送る場合は、SPFレコードは必要ないらしい。DMARCのレポートで、policy_evaluatedセクションが<spf>=failとなっていたため気になって調べたが、問題ないらしい。

    https://qiita.com/Moo_Moo_Farm/items/656826526b340694a9d8

    外部向けapache(xampp)の設定変更

     後述のサーバー証明書を更新するために仮想ホストml.mydomain.com を追加する。
     ただし、/.well-knownだけは、win-acmeがチェック時にこのサーバー内を書き換えるため、除外する。

    C:\xampp\apache\conf\extra\httpd-vhost.conf
    ServerAlias ${DOMAIN} ftp.${DOMAIN} mail.${DOMAIN}
     ↓
    ServerAlias ${DOMAIN} ftp.${DOMAIN} mail.${DOMAIN} ml.${DOMAIN}
    
        RewriteCond %{REQUEST_URI} !^/\.well-known
     ↓
        RewriteCond %{REQUEST_URI} !^/\.well-known
        RewriteCond %{HTTPS} off

    ml.mydomain.comは別のapacheで動いているので、リバースプロキシーで飛ばす。

    C:\xampp\apache\conf\extra\httpd-ssd.conf
    <VirtualHost *:443>
        ServerAdmin postmaster@${DOMAIN}
    	ServerName ml.${DOMAIN}
        ErrorLog  "| bin/rotatelogs.exe logs/ml.${DOMAIN}-SSL-error_%Y-%m.log  86400 540"
        CustomLog "| bin/rotatelogs.exe logs/ml.${DOMAIN}-SSL-access_%Y-%m.log 86400 540" combined
        SSLEngine on
        SSLCertificateFile "conf/certs/${DOMAIN}-chain.pem"
        SSLCertificateKeyFile "conf/certs/${DOMAIN}-key.pem"
    	ProxyRequests Off
    	ProxyPass / http://ml.${DOMAIN}:9080/
    	ProxyPassReverse / http://ml.${DOMAIN}:9080/
    </VirtualHost>
    

    サーバー証明書の更新

    既存のサーバー証明書ににml.mydomain.comを追加する

      > win-acme.exe
         A: Manage renewals (1 total)
      Please choose from the menu: a
        D: Show details for the renewal
      Choose an action or type numbers to select renewals: d
        E: Edit renewal
      Choose an action or type numbers to select renewals: e
        2: Source
      Which step do you want to edit?: 2
        2: Manual input
      How shall we determine the domain(s) to include in the certificate?: 2
      Host: mydomanin.com,ftp.mydomanin.com,mail.mydomanin.com,ml.mydomanin.com,www.mydomanin.com
      Friendly name '[Manual] mydomanin.com'. <Enter> to accept or type desired name: mydomanin.com

     追加されたホストのみが確認され新しい証明書が作成される。有効期限は変わらない。

    ・MercuryMailの設定

    全メーリングリストで使用するメールアカウントを作成する
    ユーザー名:mailman
    このメールアカウントを、Configurationー”Mercury Core Module Configuration”ー”Local Domains” にドメインメールボックスとして追加する

    Core ModuleーFiles
    Internet name for this system: mail.mydomain.com
      ↓
    Internet name for this system: mydomain.com
    Core ModuleーLocal Domains
    追加
      ↓
    localhost mail.mydomain.com
    DM=mailman ml.mydomain.com

    ・postfixの設定

     SMTP サーバによる知らないローカル受信者拒否を無効にする(要は知らない名前でも受け付ける)

      $ sudo vi /etc/postfix/main.cf
    #local_recipient_maps =
      ↓
    local_recipient_maps =

    ・mailmanの設定

    なし

    ・farchmailの設定

    なし

  • WSLを使ってメーリングリストを作成(fetchmail編)

     前回までのpostfix+mailmanでUbuntu内、ローカルWindows、および同じネットワーク内の別PCからメーリングリストへの送受信が可能になった。

     ただし、インターネットからのメールは受け付けることはできない。メーリングリスト用のサーバーが外部に露出して無く、MercuryMailも特定のMTAに転送する設定がないせいらしい。

     そこで5日ほど悩んで、何とか実現できそうな方法にたどり着いた。

     外部とはWindowsにxamppを入れて、MercuryMailで通信している。そのMercuryMailにはドメインメールボックスという機能があり、特定のホスト宛てのメールを全て単一のメールボックスに入れることができる。

     そして、fetchmailにはマルチドロップモードという機能があり、1か所に届いたメールを本来の宛先などを読み取って配送する機能がある。

     この二つの機能を組み合わせることで、外部から届いたメールを適切なmailmanの仮想アドレスに届けることができる。

    ・インストール

      $ sudo apt install fetchmail

    ・設定
     rootユーザーでの動作は推奨されていないが、システム上のアプリなのでrootで実行させる。

      $ sudo vi /root/.fetchmailrc
    # ログファイルの指定
    set logfile "/var/log/fetchmail.log"
    # エラーの送信先
    set postmaster postmaster@mydomain.com
    set no bouncemail
    # メールのチェック間隔(秒)
    set daemon 300
    
    # デフォルト設定
    defaults
    # 既読のチェックを行う
      uidl
      # 未読メールの取り込み(ex.全て取り込む場合[fetchall])
      no fetchall
      # サーバ上にメールを残す(ex.削除する場合[no keep])
      keep
      # mimed ecode(8ビットデータに変換しない)
      no mimedecode
      # RFC-822 のアドレスヘッダ (To, From, Cc, Bcc, Reply-To) を書き換えない
      no rewrite
    
    # 外部メールサーバの設定(取り込み元) localdomainsではenvelopeが必要
    poll mail.mydomain.com with proto imap envelope "X-Envelope-To"
      localdomains ml.mydomain.com
      # アカウント名、パスワード、宛先ユーザー
      user "mailman" with pass "mailパスワード" to * here

    設定ファイルを所有者のみRead/Writeにする

      $ sudo chmod 600 /root/.fetchmailrc

    ログファイルはあらかじめ作成しておかないとエラーになるので作成しておく。

      $ sudo touch /var/log/fetchmail.log
      $ sudo chown root:root /var/log/fetchmail.log
      $ sudo chmod 600 /var/log/fetchmail.log

    ・fetchmailの起動
    起動と停止はfetchmail設定ファイルを作成したユーザー(つまりsudo )で起動する

    $ sudo /usr/bin/fetchmail --nosslcertck -f /root/.fetchmailrc

    起動時にはsslを使用しないオプション(–nosslcertck)を指定しないとSTARTTLSで以下のエラーとなる
    fetchmail: POP3< -ERR SSL/TLS services unavailable.
    このオプションはコマンドラインでしか指定できないようなので、起動時は毎回指定する。

    ・fetchmailの停止

      $ sudo fetchmail --quit
    or sudo fetchmail -q

    ・fetchmailの強制フェッチ
    set daemonの設定にかかわらず即座にメールボックスのチェックを行う。

      $ sudo fetchmail

    ・テスト実行

      $ sudo fetchmail --nosslcertck -f /root/.fetchmailrc -v -c

    ・ログの確認

      $ sudo less +F /var/log/fetchmail.log

    ・logrotateの設定

      $ sudo vi /etc/logrotate.d/fetchmail
    /var/log/fetchmail.log {
        su root root
        weekly
        rotate 10
        notifempty
        create 600 root root
        prerotate
            /usr/bin/fetchmail --quit > /dev/null 2>&1
        endscript
        postrotate
            /usr/bin/fetchmail --nosslcertck -f /root/.fetchmailrc > /dev/null 2>&1
        endscript
    
    }

    apache2のlogrotate設定
     postrotate部分でinvoke-rc.dを使うようになっていたが、WSLでは動作しないらしいため置き換える。

      $ sudo vi /etc/logrotate.d/apache2
    -----
    	postrotate
                    if  ps -ef | grep -vw "^`whoami`" | grep -w apache2 > /dev/null 2>&1; then \
                        apache2ctl graceful > /dev/null 2>&1; \
                    fi;
    	endscript
    -----

    cronのログを有効にする

      $ sudo vi /etc/rsyslog.d/50-default.conf
    #cron. /var/log/cron.log
    ↓
    cron.* /var/log/cron.log

    rsyslogを再起動する

      $ sudo /etc/init.d/rsyslog restart

    logrotateは以下のファイル内の日付を見て処理しているので、無理矢理実行させるなら日付を書き換える

    /var/lib/logrotate/status

    おまけ

     新しいメッセージがない時のfatchmailのログにはタイムスタンプがないので、ログを見ただけでは動いているかどうかわかりにくい。

     定期的にタイムスタンプを挿入するスクリプトを動かす。

      $ sudo vi /root/fetchmail_time.sh
    -----
    #!/bin/bash
    sleep 60
    while true
    do
      if [ -w /var/log/fetchmail.log ]; then
        echo '          ' `date '+%Y/%m/%d %H:%M:%S'`>> /var/log/fetchmail.log
      fi
      sleep 3600
    done
    -----
      $ sudo chown root.root /root/fetchmail_time.sh
    
      $ sudo chmod 700 /root/fetchmail_time.sh
    
      $ sudo vi /etc/sudoers.d/auto-start
    %sudo ALL=NOPASSWD: /root/fetchmail_time.sh
    
      $ vi ~/.bash_aliases
        ps -ef | grep -vw "^`whoami`" | grep -w fetchmail_time  || sudo /root/fetchmail_time.sh &