投稿者: chombo

  • WSLを使ってメーリングリストを作成(自動起動)

     いくつかのプロセスは、Ubuntuが起動されるごとに実行しないといけない

     WSLが起動すると、必ずデフォルトユーザーがログインするので、デフォルトユーザーの.bash_aliasesで実行させることにした

      $ vi ~/.bash_aliases
    
    tty
    if [ "$REMOTEHOST" == "" ] && ) [ "`tty`" == "/dev/tty1" ] || [ "`tty`" == "/dev/pts/0" ] ); then
    #                                                  WSL 1                         WSL 2
        # start daemon
        sudo /etc/init.d/rsyslog status          || sudo /etc/init.d/rsyslog start
        sudo /etc/init.d/cron status             || sudo /etc/init.d/cron start
        test -f /var/run/inetd.pid               || sudo /etc/init.d/inetutils-inetd start 
        sudo /etc/init.d/postfix status          || sudo /etc/init.d/postfix start 
        sudo /etc/init.d/apache2 status          || sudo /sbin/apache2ctl start 
        sudo /bin/mkdir -p /var/lock/mailman
        sudo /bin/chown www-data:list /var/lock/mailman
        sudo /bin/chmod g+w /var/lock/mailman
        sudo /bin/mkdir -p /var/run/mailman
        sudo /bin/chown list /var/run/mailman
        sudo /bin/chmod g+w /var/run/mailman
        test -f /var/run/mailman/mailman.pid     || sudo /sbin/mailmanctl start 
        test -f /var/run/fetchmail.pid           || sudo /usr/bin/fetchmail --nosslcertck -f /root/.fetchmailrc
        ps -ef | grep -vw "$USER" | grep -w fetchmail_time || sudo /root/fetchmail_time.sh &
    
        sleep 2
    #    /usr/local/bin/port-forward.sh
        ps ax
        sudo /bin/apt update
    else
        LOGS=(/var/log/fetchmail.log /var/log/mail.log /var/log/mailman/post /var/log/apache2/access.log)
    
        for L in ${LOGS[@]} ; do
            if [[ ! `ps -ef | grep -vw "$USER"` =~ $L ]]; then
                echo sudo tail -F $L
                     sudo tail -F $L
                break
            fi
        done
    fi

    if文の後半はtelnetで接続された順番にログファイルを自動的に表示させている。

    ただし、sudoで実行させているため、パスワードを入力しなくても実行できるようにしておく

        $ sudo vi /etc/sudoers.d/auto-start
    %sudo ALL=NOPASSWD: /etc/init.d/apache2
    %sudo ALL=NOPASSWD: /etc/init.d/cron
    %sudo ALL=NOPASSWD: /etc/init.d/inetutils-inetd
    %sudo ALL=NOPASSWD: /etc/init.d/postfix
    %sudo ALL=NOPASSWD: /etc/init.d/rsyslog
    %sudo ALL=NOPASSWD: /sbin/apache2ctl
    %sudo ALL=NOPASSWD: /sbin/mailmanctl
    %sudo ALL=NOPASSWD: /sbin/service
    %sudo ALL=NOPASSWD: /bin/apt
    %sudo ALL=NOPASSWD: /bin/chmod
    %sudo ALL=NOPASSWD: /bin/chown
    %sudo ALL=NOPASSWD: /bin/ln
    %sudo ALL=NOPASSWD: /bin/ls
    %sudo ALL=NOPASSWD: /bin/mkdir
    %sudo ALL=NOPASSWD: /usr/bin/fetchmail
    %sudo ALL=NOPASSWD: /usr/bin/vi
    %sudo ALL=NOPASSWD: /usr/bin/vim
    %sudo ALL=NOPASSWD: /usr/bin/view
    %sudo ALL=NOPASSWD: /usr/bin/less
    %sudo ALL=NOPASSWD: /usr/lib/mailman/bin/dumpdb
    
        $ sudo chmod 0440 /etc/sudoers.d/auto-start

    ポート番号の変更

    すでにホストマシンでtelnetdやxampp内のapacheが起動しているときはWSLのポート番号を変えることで共存させる。
    なお、10080は最近のWebブラウザーではアクセスできないようにされているようで(ERR_UNSAFE_PORTというエラーが表示される)、他のポートを選ぶ。

    telnetd
      $ sudo vi /etc/services
    telnet		23/tcp
      ↓
    telnet		9023/tcp
    apache2
      $ sudo vi /etc/apache2/sites-available/000-default.conf
    <VirtualHost *:80>
      ↓
    <VirtualHost *:9080>
    
      $ sudo vi /etc/apache2/ports.conf
    Listen 80
      ↓
    Listen 9080
      postfix
        $ sudo vi /etc/postfix/master.conf
    smtp      inet  n       -       y       -       -       smtpd
      ↓
    #smtp      inet  n       -       y       -       -       smtpd
    9025      inet  n       -       y       -       -       smtpd
    mailman
      $ sudo vi /etc/mailman/mm_cfg.py
    DEFAULT_URL_PATTERN = 'http://%s/mailman/'
     ↓
    DEFAULT_URL_PATTERN = 'http://%s:9080/mailman/'
    
    add_virtualhost(VIRTUAL_URL_HOST2, VIRTUAL_EMAIL_HOST2)
     ↓
    add_virtualhost(VIRTUAL_URL_HOST2, VIRTUAL_EMAIL_HOST2)
    SMTPHOST = 'ml.mydomain.com'
    SMTPPORT = 9025
      fetchmail
        $ sudo vi /root/.fetchmailrc
    smtphost ml.mydomain.com/9025

    利用しているポート番号の確認

      $ sudo ss -natup

    ポートマップ

    WSL2のプライベートアドレスは起動するごとに変わる。そのため、外部からWebブラウザーや、telnetで接続できるようにするには、WSL2のポートをホストマシンのポートに接続するスクリプトを実行する。

    WSL内で実行してもよいが、ファイアウォールの設定もあるのでWindows側から行う。

    WSLのバージョンが1の場合は、ファイアウォールやポートフォワードを削除する。

    wsl_port.ps1
    -----
    if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) { Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs; exit }
    
    # All the ports you want to forward separated by comma
    $ports=@(9023, 9025, 9080);
    $ports_a = $ports -join ",";
    
    # Remove Firewall Exception Rules
    try {
    # 初回やWSLのバージョンを1から2にした場合はエラーが出るが、無視してよい
      iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -ErrorAction Ignore";
    } catch {
    }
    
    $ip = bash.exe -c "ip r |tail -n1|cut -d ' ' -f9"
    # ipアドレスが取得できないときはWSL2ではないとみなしポートフォワードを削除する
    if ([string]::IsNullOrEmpty($ip)) {
      foreach ($port in $ports) {
        iex "netsh.exe interface portproxy delete v4tov4 listenport=$port listenaddress=*" > $null;
      }
    
    } else {
      # Adding Exception Rules for inbound and outbound Rules
      iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
      iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
    
      foreach ($port in $ports) {
        iex "netsh.exe interface portproxy add v4tov4 listenport=$port listenaddress=* connectport=$port connectaddress=$ip";
      }
    }
    
    # Show proxies
    iex "netsh.exe interface portproxy show v4tov4";
    
    -----

    Windows起動時にWSLを起動する

    WSL-start.batのショートカットを”C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp”や、 “shell:startup”に置いておくと、Windowsが起動するタイミングでUbuntuを起動し、上のポートマップスクリプトも実行させる。

    WSL-start.bat  
    -----
    start %LOCALAPPDATA%\Microsoft\WindowsApps\ubuntu.exe
    timeout -t 20
    powershell -file wsl_port.ps1
    timeout /t 60 > nul
    -----

    参考:Windows WSL2に外部から直接アクセスするための設定

    https://rcmdnk.com/blog/2021/03/01/computer-windows-network/

    mailmanデータベースをバックアップする

      for /f "usebackq delims=" %%f in (`wsl.exe -- ls /var/lib/mailman/lists/`) do (
        wsl.exe -- sudo /usr/lib/mailman/bin/dumpdb /var/lib/mailman/lists/%%f/config.pck > C:\Temp\config.pck.%%f.txt
      )
    
  • 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の設定

    なし