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
  )