カテゴリー: サーバー管理

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

     当初はsendmail+majordomoを利用してメーリングリストを実現しようとしたが、利用しているUbuntuにmajordomoが用意されていないらしいので、途中から切り替えた。なぜmajordomoかというと、件名に連番をつけたいから。

    ・インストール

    $ sudo apt install postfix
      Internet with smarthostを選択
      mydomain.com

    ・設定

     変更部分のみ

      $ sudo vi /etc/postfix/main.cf
    myhostname = ml.mydomain.com
    mydomain = mydomain.com
    myorigin = $myhostname
    inet_interfaces = all
    mydestination = $myhostname, localhost.$mydomain, localhost
    smtpd_banner = $myhostname ESMTP unknown
    sendmail_path = /usr/sbin/sendmail
    newaliases_path = /usr/bin/newaliases
    mailq_path = /usr/bin/mailq
    setgid_group = postdrop
    html_directory = no
    manpage_directory = /usr/share/man
    sample_directory = /etc/postfix
    readme_directory = /usr/share/doc/postfix
    # ここから設定ファイルの下部に追加する
    smtpd_recipient_restrictions=permit_mynetworks, reject
    
    # 転送先の上位メールサーバ
    relayhost = [smtp.gmail.com]:587
    #relayhost = [email-smtp.ap-northeast-1.amazonaws.com]:587
    # SMTP-AUTH を有効
    smtp_sasl_auth_enable = yes
    # 転送先のサーバのアドレスと認証するユーザ名とパスワードを記述したファイル
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    # 匿名ログインを許可しない
    smtp_sasl_security_options = noanonymous
    # 転送先のサーバの SASL メカニズムに対するフィルタ
    smtp_sasl_mechanism_filter = cram-md5, plain, login
    # 可能ならば TLS 暗号化
    smtp_tls_security_level = may
    # CA証明書(ca-certificates)
    smtp_tls_CApath = /etc/ssl/certs/ca-certificates.crt
    
    # ログ設定(デフォルト値)
    # /var/log/mail.logに出力される
    syslog_facility = mail
    
    # mailman用設定
    recipient_delimiter = +
    owner_request_special = no

    ・SMTP-AUTH
    転送先のサーバのアドレスと認証するユーザ名とパスワードを行ごとに記述する。
    複数行に羅列でき、main.cfで指定されたものが使われるらしい

      $ sudo vi /etc/postfix/sasl_passwd
    [smtp.gmail.com]:587 xxxx@gmail.com:yyyy
    [email-smtp.xxxx.amazonaws.com]:587 xxxx:yyyy

    ファイルのパーミッションを変更する

      $ sudo chmod 600 /etc/postfix/sasl_passwd

    Postfix が参照するデータベースファイルに反映させる

      $ sudo postmap hash:/etc/postfix/sasl_passwd

    ・設定ファイルのエラー確認

      $ sudo postfix -v check
    postfix/postfix-script: warning: symlink leaves directory: /etc/postfix/./makedefs.out
    上のワーニングが出るが無視してよいらしい。いやならシンボリックリンクからハードリンクに変える
      $ sudo rm /etc/postfix/makedefs.out; sudo ln /usr/share/postfix/makedefs.out /etc/postfix/makedefs.out

    ・Postfix を再起動する

      $ sudo service postfix restart
    Windows Defenderファイアウォールからの警告が出たら許可する

    ・ログを確認する

      $ tail -f /var/log/mail.log
      $ tail -f /var/log/mail.err

    ログが出力されない場合、rsyslog のプロセスや設定や状態を確認する

    プロセスの確認
      $ ps aux|grep rsyslog|grep -v grep
    状態の確認
      $ sudo /etc/init.d/rsyslog status
    プロセスの開始
      $ sudo /etc/init.d/rsyslog start

    rsyslogd からimklogのエラーが出るときは、/etc/rsyslogd.conf から
    module(load=”imklog” permitnonkernelfacility=”on”)
    をコメントアウトする

    以下のエラーはWSLの問題らしく消せないらしい

    rsyslogd: set SO_TIMESTAMP failed on '/dev/log': Invalid argument
    rsyslogd: set SO_TIMESTAMP failed on '/var/spool/postfix/dev/log': Invalid argument

    ・デバッグ
     debug_peer_listに指定した範囲に対してのみ、デバッグ情報が出力される

      $ sudo vi /etc/postfix/main.cf
    debug_peer_level = 1 # デフォルトは2
    debug_peer_list = 0.0.0.0/0 # デフォルトは無し

    ・テスト送信

    telnet localhost 25
    MAIL From: user@ml.mydomain.com
    RCPT TO: postmaster@dmyomain.com
    DATA
    From: user@ml.mydomain.com
    Subject: This is the subject field of the email
    This is the message to be sent.
    .
    quit

  • WSLを使ってメーリングリストを作成(Ubuntuのインストール)

    WSL(Windows Subsystem for Linux)はWindows10 21H2以降の64ビット版、およびWindows11には標準装備されているらしい(x86にはインストールされていない)

    ・インストール

    インストールできるディストリビューションの確認

      > wsl.exe -l --online
    インストールできる有効なディストリビューションの一覧を次に示します。
    既定の分布は ' * ' で表されます。
    'wsl --install -d 'を使用してインストールします。
      NAME            FRIENDLY NAME
    * Ubuntu          Ubuntu
      Debian          Debian GNU/Linux
      kali-linux      Kali Linux Rolling
      ...
    (分布というのはdistributionの和訳だろうか?)

     以下、プロンプトとして > がある場合はWindowsのコマンドプロンプトから、$ がある場合はWSLのコンソールから実行することを表わす。

    ・インストールするバージョンを指定する
     指定しないとバージョン2になる
     バージョン2は仮想マシンのため互換性は高いらしいが、IPアドレスが別のプライベートアドレスとなる。

      > wsl.exe --set-default-version 1

    ・ディストリビューションのインストール

      > wsl.exe --install -d Ubuntu
    インストール中: 仮想マシン プラットフォーム
    仮想マシン プラットフォーム はインストールされました。
    インストール中: Linux 用 Windows サブシステム
    Linux 用 Windows サブシステム はインストールされました。
    ダウンロード中: WSL カーネル
    インストール中: WSL カーネル
    WSL カーネル はインストールされました。
    ダウンロード中: Ubuntu
    要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。

    ・Windowsを再起動する

    ・ユーザーの作成
     Windowsの再起動後、Ubuntuを起動するとユーザーの作成が始まる。

        Installing, this may take a few minutes...
        Please create a default UNIX user account. The username does not need to match your Windows username.
        For more information visit: https://aka.ms/wslusers
        Enter new UNIX username:ユーザー名(メールを送受信する時の名前になる)
        New password:xxxxx
        Retype new password:
        passwd: password updated successfully
        Installation successful!
        To run a command as administrator (user "root"), use "sudo <command>".
        See "man sudo_root" for details.
    
        Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)

    ・状態の確認

    $ wsl.exe --status
      既定の配布: Ubuntu
      既定のバージョン: 1
    $ wsl.exe --list --verbose
      NAME STATE VERSION
      * Ubuntu Running 1

    ・起動方法

     プログラムメニューからUbuntuを起動するか、以下を実行する

    %LOCALAPPDATA%\Microsoft\WindowsApps\ubuntu.exe

    ・終了方法

      $ wsl.exe --shutdown
    または
      > wsl.exe --terminate Ubuntu

    ・バックアップ

    > wsl.exe --terminate Ubuntu
    > wsl.exe --export Ubuntu \\Backup\WSL\Ubuntu.tar

    ・リストア

    WSLのバージョンを指定してリストアできる。
    リストア前に。以下に.vhdxファイルがあれば削除しておくらしい
    %LOCALAPPDATA%\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState
    > wsl.exe --terminate Ubuntu
    > wsl.exe --list --verbose
    > wsl.exe --unregister Ubuntu
    > wsl.exe --list --verbose
    > wsl.exe --import Ubuntu %LOCALAPPDATA%\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState "\\Backup\WSL\Ubuntu.tar" --version 1
    > wsl.exe --list --verbose

    デフォルトユーザーを変更
     復元後はデフォルトのユーザーがrootになっているので、作成したユーザーをデフォルトのユーザーに変更する

    > Ubuntu.exe config –default-user ユーザー名

    ・初期化の方法

     ディストリビューションのインストール直後の状態にすることができる。
    Try and Errorしているときに便利。

     WSLを終了させる
      > wsl.exe –terminate Ubuntu

     設定-アプリのUbuntu
      詳細オプション-リセット-リセット
       この時、タスクバーのピン止めは解除される

    ・WSLバージョンの変更

     WSL2ではWin32側とはプライベートIPアドレスを使ってホストPCのポートと被ることが避けられる
     当初はWSL1に変更して同じIPアドレスを使う

      > wsl.exe --list --verbose
    > wsl.exe --terminate Ubuntu
    > wsl.exe --set-version Ubuntu 1
    変換中です。この処理には数分かかることがあります…
    変換が完了しました。

     注意点として、WSL2でポートマップなどを行っていた場合、削除しておかないとマップされたままとなる。

    ・WSLを起動する

     スタートメニュー、または
      > %LOCALAPPDATA%\Microsoft\WindowsApps\ubuntu.exe

    ・WSLディストリビューションの更新

    sudo apt update, sudo apt upgradeで行う
      $ sudo apt update
      $ sudo apt list --upgradable
      $ sudo apt upgrade
    再度、apt updateで確認する
      $ sudo apt update
    All packages are up to date.と表示されていれば終了

    ・追加モジュールのインストール

    telnetd
      $ sudo apt install inetutils-telnetd
      $ sudo vi /etc/inetd.conf
    <off># telnet stream tcp nowait root /usr/sbin/tcpd /usr/sbin/telnetd
     ↓
    telnet stream tcp nowait root /usr/sbin/tcpd /usr/sbin/telnetd
      $ sudo /etc/init.d/inetutils-inetd start
     Windows Defenderファイアウォールの警告が出たら許可する

    ・WSLの設定

      $ sudo vi /etc/wsl.conf
    [network]
    hostname = ml.mydomain.com
    #generateHosts = false
    #renerateResolvConf = false

    これにより、/etc/hostsが以下のように変わる

    127.0.0.1 localhost
    127.0.1.1 domain.com PC1.localdomain PC1
    ↓
    127.0.0.1 localhost
    127.0.1.1 ml.mydomain.com.localdomain ml.mydomain.com

    ・システム環境の設定

    lessでvキーを押したときにviを起動する
      $ sudo update-alternatives --set editor /usr/bin/vim.basic
    

    ・ユーザー環境の設定

    sudo時に同じvi設定を使う
      $ vi ~/.vimrc
    ;color industry
      $ sudo ln -s ~/.vimrc /root/.vimrc

    その他、追加エイリアスなど
    $ vi ~/.bash_aliases
    alias sudo=’sudo ‘ # sudo時もaliasを引き継ぐ
    alias sudol=’sudo –user=list ‘ # listユーザーでsudoを起動
    alias suvi=’sudo vi ‘
    alias lh=’ls -alFH ‘ # -H シンボリックリンク先を表示する

    ・アンインストール方法

    設定-アプリ-アプリと機能で、 ディストリビューション(Ubuntu)を削除する

    ・バックアップスクリプト

    backup_WSL.bat

    @echo off
    echo backup Ubuntu
    
    setlocal enabledelayedexpansion
    rem PROMPTは使用済みの環境変数なので使えない
    set PROMPT_MSG="Ubuntu バックアップ"
    set FILTER="tar (*.tar)^|*.tar"
    set TITLE="保存するファイルを指定してください"
    set DATETIME=%DATE%-%TIME: =0%
    set ARCHIVE_FOLDER=\\LANDISK\usb3\WSL\%COMPUTERNAME%
    
    set DISTR=Ubuntu
    set RUNNING=
    set WSL_VER=
    for /f "usebackq tokens=1-3 delims=," %%a in (`%~dp0GetWslVersion.bat`) do (
      set DISTR=%%a
      set RUNNING=%%b
      set WSL_VER=%%c
    )
    if "!WSL_VER!" == "" (
      echo WSLのバージョンが取得できませんでした。終了します
      goto :EXIT
    )
    
    echo DISTR="!DISTR!" RUNNING="!RUNNING!" WSL_VER="!WSL_VER!"
    
    if not exist "%ARCHIVE_FOLDER%" md "%ARCHIVE_FOLDER%"
    set DEFAULT=%ARCHIVE_FOLDER%\!DISTR!-!WSL_VER!_%DATETIME:~0,4%%DATETIME:~5,2%%DATETIME:~8,2%-%DATETIME:~11,2%%DATETIME:~14,2%%DATETIME:~17,2%.tar
    
    set BACKUP_FILE=
    @echo for /f "usebackq delims=" %%f in (`powershell -file "%~dp0SaveFileDialog.ps1" %PROMPT_MSG% %FILTER% %TITLE% "%DEFAULT%"`) do set BACKUP_FILE=%%f
    
          for /f "usebackq delims=" %%f in (`powershell -file "%~dp0SaveFileDialog.ps1" %PROMPT_MSG% %FILTER% %TITLE% "%DEFAULT%"`) do set BACKUP_FILE=%%f
    
    if "%BACKUP_FILE%" == "" goto :EXIT
    
    echo.
    
    rem 末尾が.tarでなければ.tarを追加する
    if /i not "%BACKUP_FILE:~-4%" == ".tar" set BACKUP_FILE=%BACKUP_FILE%.tar
    echo BACKUP_FILE="%BACKUP_FILE%"
    
    pause
    echo.
    echo RUNNING="!RUNNING!"
    if "!RUNNING!" == "0" goto :SKIP_TERM
    
    wsl.exe --list --verbose
    echo.
    echo Ubuntuを停止します。
    pause
    echo.
    
    wsl.exe --terminate Ubuntu
    
    :SKIP_TERM
    wsl.exe --list --verbose
    echo.
    
    echo バックアップを開始します。
    echo 保存場所:%BACKUP_FILE%
    pause
    echo.
    
    echo %BACKUP_FILE% にバックアップ中です。
    wsl.exe --export Ubuntu %BACKUP_FILE%
    
    wsl.exe --list --verbose
    endlocal
    echo.
    echo バックアップが終了しました。
    pause
    
    exit /b 0
    
    :EXIT
    endlocal
    
    exit /b 1
    

    GetWslVersion.bat(Windowsにnkfのインストールが必要)

    @echo off
    setlocal enabledelayedexpansion
    
    set DISTR=
    set RUNNING=0
    set VER=2
    for /f "usebackq tokens=2-4 delims= " %%a in (`wsl.exe --list --verbose ^| nkf -W16L -s ^| findstr /R "^\*"`) do (
      set DISTR=%%a
      if "%%b" == "Running" set RUNNING=1
      set VER=%%c
    )
    echo !DISTR!,!RUNNING!,!VER!
    
    endlocal
    exit /b 0

    SaveFileDialog.ps1

    Param($InitialDirectory, $Filter, $Title, $FileName)
    
    Add-Type -AssemblyName System.Windows.Forms
    
    $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
    $FileBrowser.InitialDirectory = $InitialDirectory
    $FileBrowser.Filter = $Filter
    $FileBrowser.Title = $Title
    $FileBrowser.RestoreDirectory = $true
    $FileBrowser.FileName = $FileName
    
    if($FileBrowser.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){
        return ($FileBrowser.FileName)
    }else{
        return ("")
    }

    ・復元スクリプト

    restore_WSL.bat

    @echo off
    echo restore Ubuntu
    
    setlocal
    
    set WSL_VER=2
    set UBUNTU_FOLDER=%LOCALAPPDATA%\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState
    if not exist %UBUNTU_FOLDER% set UBUNTU_FOLDER=%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState
    if not exist %UBUNTU_FOLDER% (
        echo no Ubuntu folder! Terminate.
        pause
        exit /b 1
    )
    
    set FILTER="tar (*.tar)^|*.tar"
    set TITLE="復元するファイルを指定してください"
    set ARCHIVE_FOLDER=\\LANDISK\usb3\WSL\%COMPUTERNAME%
    
    set RESTORE_FILE=
    @echo for /f "usebackq delims=" %%f in (`powershell -file "%~dp0OpenFileDialog.ps1" "%ARCHIVE_FOLDER%" %FILTER% %TITLE%`) do set RESTORE_FILE=%%f
    
          for /f "usebackq delims=" %%f in (`powershell -file "%~dp0OpenFileDialog.ps1" "%ARCHIVE_FOLDER%" %FILTER% %TITLE%`) do set RESTORE_FILE=%%f
    
    set FILENAME=
    for %%f in ("%RESTORE_FILE%") do set FILENAME=%%~nf
    if /I "%FILENAME:~0,9%" == "Ubuntu-1_" set WSL_VER=1
    if /I "%FILENAME:~0,9%" == "Ubuntu-2_" set WSL_VER=2
    
    echo.
    echo RESTORE_FILE="%RESTORE_FILE%" version=%WSL_VER%
    pause
    
    echo Ubuntuを停止します。
    echo.
    if "%RESTORE_FILE%" == "" goto :EXIT
    
    if exist "%UBUNTU_FOLDER%\*.vhdx" (
        echo "+.vhdx" exist
        echo delete this?
        echo start explorer.exe "%UBUNTU_FOLDER%"
             start explorer.exe "%UBUNTU_FOLDER%"
        pause
        echo.
        del "%UBUNTU_FOLDER%\*.vhdx"
    )
    
    pause
    
    wsl.exe --list --verbose
    
    echo wsl.exe --terminate Ubuntu
         wsl.exe --terminate Ubuntu
    wsl.exe --list --verbose
    echo.
    echo Ubuntu画面が開いていれば閉じてください。
    pause
    echo.
    
    echo Ubuntu を削除しています。
    echo wsl.exe --unregister Ubuntu
         wsl.exe --unregister Ubuntu
    wsl.exe --list --verbose
    
    echo.
    echo Ubuntu を復元しています。
    echo wsl.exe --import Ubuntu "%UBUNTU_FOLDER%" "%RESTORE_FILE%" --version %WSL_VER%
         wsl.exe --import Ubuntu "%UBUNTU_FOLDER%" "%RESTORE_FILE%" --version %WSL_VER%
    if errorlevel 1 (
        echo ERRORLEVEL=%ERRORLEVEL%
        pause
        exit /b %ERRORLEVEL%
    )
    echo Ubuntu.exe config --default-user [user]
         Ubuntu.exe config --default-user [user]
    wsl.exe --list --verbose
    echo.
    endlocal
    
    echo.
    echo Ubuntu を起動します。
    pause
    echo.
    
    start Ubuntu.exe
    exit /b 0
    
    :EXIT
    endlocal
    
    exit /b 1
    

    OpenFileDialog.ps1

    Param($InitialDirectory, $Filter, $Title)
    
    Add-Type -AssemblyName System.Windows.Forms
    
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = $InitialDirectory
        Filter = $Filter
        Title = $Title
    }
    
    if($FileBrowser.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){
        return ($FileBrowser.FileName)
    }else{
        return ("")
    }
  • WSLを使ってメーリングリストを作成(承前)

     Windows上で、連番をつけてくれるメーリングリストを運営したい。

     昔はLinux上でsendmail+majordomoを使っていたが、Windowsのアプリでは簡単に実現できるのがないようだ。

     そこでWSL(Windows Subsystem for Linux)上でMTAとメーリングリストツールを使って実現できないかと調査した。

     実験環境に構築し、内部から送信すると外部のSMTPサーバーを使ってメーリングリストの配信のみができるようになるのに約10日。

     外部から用意したホストにメールが届き、メーリングリストとして外部に配信できるようになるのにさらに約7日かかった。

     実験環境は、

    Windows10 Home x64 21H2
    メモリ8GB

     最初は、sendmailを入れてメール送信できるようにはなったが、majordomoがUbuntuに用意されていないことに気が付いた。

     仕方がないのでpostfix+mailman+αで実現することにした。

    1. Ubuntuのインストール
    2. postfix編
    3. mailman編
    4. fetchmail編
    5. 外部からの受信
    6. 複数ドメイン
    7. 自動起動
    8. 番外編
    9. 番外編2