Postfix でメールサーバーを構築

Postfix をインストールしてサーバーからメールを送信できるようにします。今回は送信専用として設定します。

サーバー
LXD ゲスト
CPU
2コア
メモリー
4GB
OS
Ubuntu Server 24.04 LTS 64Bit
apt パッケージ バージョン
postfix 3.8.6-1build2 amd64

パッケージをインストール

以下のコマンドで Postfix をイストールします。

sudo apt install postfix

インストール中に以下の設定をウィザードで確認されるので入力します。

General mail configuration type: Internet Site

System mail name:  example.com

Postfix を設定

以下のコマンドでウィーザードを使って Postfix を設定します。

sudo dpkg-reconfigure postfix

Recipient for root and postmaster mail: <USER_NAME>

Other destinations to accept mail for (blank for none):  <DOMAIN>

Force synchronous updates on mail queue? No

Local networks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.1.0/24

Mailbox size limit (bytes): 0

Local address extension character: +

Internet protocols to use: all

以下のコマンドでメールボックス形式を Maildir に変更します。実際の設定値は /etc/postfix/main.cf に保存されているので、このファイルを直接編集することもできます。

sudo postconf -e 'home_mailbox = Maildir/'

以下のコマンドで外部からの接続を無効にします。

sudo postconf -e 'inet_interfaces = loopback-only'

以下のコマンドで TLS の設定をします。Let’s Encrypt で発行された無料 SSL 証明書を使用しています。

sudo postconf -e 'smtp_tls_security_level = may'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/foo.example.com/privkey.pem'
sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/foo.example.com/cert.pem'
sudo postconf -e 'smtpd_tls_loglevel = 1'
sudo postconf -e 'smtpd_tls_received_header = yes'
sudo postconf -e 'myhostname = mail.example.com'

以下のコマンドで Postfix を再起動します。

sudo systemctl restart postfix.service

メール送信テスト

以下のコマンドでメールを送信してテストします。From アドレスを適切に設定しないと受信側でスパムメールとして識別される恐れがあります。

sendmail -t <<EOF
From: sender@example.com
To: recipient@example.com
Subject: テストメール

これはテストメールの本文です。
EOF

参考

Certbot で無料の SSL を自動発行

Certbot を使用して Let’s Encrypt から無料の SSL 証明書を発行してもらいます。

サーバー
LXD ゲスト
CPU
2コア
メモリー
4GB
OS
Ubuntu Server 24.04 LTS 64Bit
snap パッケージ バージョン
certbot

3.2.0

前提条件

SSL 証明書を発行する条件として外部からポート 80 でサーバーにアクセス可能である必要があります。

パッケージをインストール

以下のコマンドで certbot をイストールします。

sudo snap install --classic certbot

以下のコマンドでバイナリへのシンボリックリンクを作成します。

sudo ln -s /snap/bin/certbot /usr/bin/certbot

ファイアウォールを設定

以下のコマンドで 80 ポートへのアクセスを許可しておきます。

sudo ufw allow 80/tcp

Certbot を設定

以下のコマンドで設定します。

sudo certbot certonly --standalone
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): foo@example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at:
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf
You must agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): foo.example.com
Requesting a certificate for foo.example.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/foo.example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/foo.example.com/privkey.pem
This certificate expires on 2025-05-03.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/etc/letsencrypt/live/foo.example.com/fullchain.pem に証明書が保存されているのでメールサーバー等で使用します。

以降は証明書の期限が切れる前に自動的に更新されます。

参考

パッケージを自動アップデート

unattended-upgrades でパッケージを自動でアップデートするように設定します。

サーバー
LXD ゲスト
CPU
2コア
メモリー
4GB
OS
Ubuntu Server 24.04 LTS 64Bit
パッケージ バージョン
unattended-upgrades 2.9.1+nmu4ubuntu1

パッケージをインストール

通常はすでにインストールされていると思いますが以下のコマンドで unattended-upgrades をイストールします。

sudo apt install unattended-upgrades

自動アップデートの設定

/etc/apt/apt.conf.d/50unattended-upgrades を編集してアップデートを適用する範囲を指定します。(セキュリティパッチのみ、通常のアップデートを含める等) 自動アップデートから序外するパッケージがある場合は Unattended-Upgrade::Package-Blacklist に追加します。

アップデート時にメール通知を送信する場合は Unattended-Upgrade::Mail に記述します。

/etc/apt/apt.conf.d/20auto-upgrades を編集して自動アップデートを有効にします。

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";  

参考

LXD で新しい仮想マシンを作成

LXD で新しくサーバーとして使用する仮想マシンを作成した際のメモです。

サーバー
HPE ProLiant MicroServer Gen10 Plus
CPU
4コア
メモリー
32GB
OS
Ubuntu Server 24.04 LTS 64Bit
パッケージ バージョン
lxd 5.21.2-084c8c8

新しい仮想マシンを作成

以下のコマンドでイメージサーバーの一覧を表示します。

lxc remote list

以下のコマンドでイメージサーバー ubuntu で利用可能なイメージの一覧を表示します。

lxc image list ubuntu:

以下のコマンドで新しい仮想マシンを作成します。

lxc init <IMAGE_SERVER>:<IMAGE_NAME> <INSTANCE_NAME> [FLAGS]
lxc init ubuntu:24.04 <CONTAINER_NAME> --device root,size=20GiB --config limits.cpu=2 --config limits.memory=4GiB
–vm
コンテナではなく VM を作成する
–device root,size=20GiB
メインドライブのサイズを20GiBに設定
–config limits.cpu=2
CPU コア数を 2 に設定
–config limits.memory=4GiB
メモリサイズを 4GiB に設定

ネットワークをブリッジ接続に変更

以下のコマンドでデフォルトの nat 接続からブリッジ接続に変更します。(物理ネットワークデバイスが eno1 の場合)

lxc config device remove <CONTAINER_NAME> eth0
lxc config device add <CONTAINER_NAME> eth0 nic nictype=macvlan parent=eno1 name=eth0

デフォルトユーザー名の変更

作成したインスタンスを起動して、以下のコマンドでデフォルトのユーザー名 ubuntu を任意の <NEW_USERNAME> に変更します。

lxc exec <CONTAINER_NAME> -- usermod -l <NEW_USERNAME> -d /home/<NEW_USERNAME> -m ubuntu

以下のコマンドでグループ名も変更します。

lxc exec <CONTAINER_NAME> -- groupmod -n <NEW_USERNAME> ubuntu

以下のコマンドでパスワードを変更します。

lxc exec <CONTAINER_NAME> -- passwd <NEW_USERNAME>

以下のコマンドで sudo ユーザーの設定も変更します。

lxc exec <CONTAINER_NAME> -- bash -c "echo '<NEW_USERNAME> ALL=(ALL) ALL' > /etc/sudoers.d/<NEW_USERNAME>"

以下のコマンドで ubuntu に sudo 権限を与えているファイルを削除します。

lxc exec <CONTAINER_NAME> -- rm /etc/sudoers.d/90-cloud-init-users

以下のコマンドで新しいユーザーの SSH 公開鍵を登録します。

lxc exec <CONTAINER_NAME> -- bash -c "echo 'ssh-ed25519 AAAAC... newusername@example.com' > /home/<NEW_USERNAME>/.ssh/authorized_keys"

Cloud-Init を無効化

このまま再起動すると Cloud-Init が再度 ubuntu ユーザーを作成してしまうので、Cloud-Init を以下のコマンドで無効化します。

lxc exec <CONTAINER_NAME> -- touch /etc/cloud/cloud-init.disabled
lxc exec <CONTAINER_NAME> -- systemctl disable cloud-init

以下のコマンドで Cloud-Init を削除します。

lxc exec <CONTAINER_NAME> -- apt remove --purge -y cloud-init

以下のコマンドで設定ファイルを削除します。

lxc exec <CONTAINER_NAME> -- rm -rf /var/lib/cloud/

SSH サーバーの設定を変更

作成した仮想マシンに SSH で接続し、SSH サーバーの設定を変更します。

sudo vim /etc/ssh/sshd_config

以下を変更・追加します。

Port 2222
LogLevel VERBOSE
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
MaxSessions 1
PubkeyAuthentication yes
PermitEmptyPasswords no
X11Forwarding no
AllowUsers <NEW_USERNAME>

以下のコマンドでファイアウォールの設定を変更します。

sudo ufw allow 2222/tcp
sudo ufw enable

以下のコマンドで SSH サーバーを再起動して設定を反映します。

sudo systemctl restart ssh

新しいポートで接続できない場合は一度仮想マシンを再起動します。

sudo reboot

IP アドレスを変更

以下のコマンドで接続されているネットワークインターフェースを確認します。

ip link show

netplan の設定ファイルを変更して静的 IP を割り当てます。

sudo vim /etc/netplan/50-cloud-init.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      gateway4: 192.168.1.1
      nameservers:
        addresses:
          - 192.168.1.1

インスタンスを再起動

設定を終えたら以下のコマンドで仮想マシンを再起動します。

lxc exec <CONTAINER_NAME> -- reboot

参考

VMware ESXi から LXD へ乗り換え

VMware が ESXi のフリーライセンスの提供を終了することになったので、LXD に乗り換えることにしました。

サーバー
HPE ProLiant MicroServer Gen10 Plus
CPU
4コア
メモリー
32GB
OS
Ubuntu Server 24.04 LTS 64Bit

LXD をインストール

以下のコマンドで LXD をインストールします。ほとんどの質問には Enter キーだけを押してデフォルトを適用します。

sudo snap install lxd
sudo lxd init

Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=30GiB]: 800GiB
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]: yes
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

ファイアウォールの設定

LXD が持っている自前のファイアウォールが Ubuntu のファイアウォールと干渉するので無効にする。

lxc network set lxdbr0 ipv4.firewall false
lxc network set lxdbr0 ipv6.firewall false

ufw コマンドで LXD のブリッジネットワークのルーティングを許可する。

# allow the guest to get an IP from the LXD host
sudo ufw allow in on lxdbr0 to any port 67 proto udp
sudo ufw allow in on lxdbr0 to any port 547 proto udp

# allow the guest to resolve host names from the LXD host
sudo ufw allow in on lxdbr0 to any port 53

# allow the guest to have access to outbound connections
CIDR4="$(lxc network get lxdbr0 ipv4.address | sed 's|\.[0-9]\+/|.0/|')"
CIDR6="$(lxc network get lxdbr0 ipv6.address | sed 's|:[0-9]\+/|:/|')"
sudo ufw route allow in on lxdbr0 from "${CIDR4}"
sudo ufw route allow in on lxdbr0 from "${CIDR6}"

一通り設定が終わったら再起動をして再起動後も LXD が動作していることを確認します。

Web インターフェースの設定

http://192.168.1.101:8443 にブラウザからアクセスして指示に従ってクライアント用の証明書の作成を行います。インストール時にポートを変更している場合は設定したポートでアクセスします。

証明書の設定が完了して Web インターフェースにアクセスできるようになったら、 Settings タブで “core.trust_password” を設定します。このパスワードはインポート作業が終了したら削除します。

ESXi から Windows 仮想マシンをインポート

必要なファイルを準備

以下のコマンドで virt-2v2 をインストールし、必要なファイルを取得します。

sudo apt install virt-v2v
sudo mkdir /usr/share/virtio-win
cd /usr/share/virtio-win
sudo wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

以下のコマンドで rhsrvany を取得します。

mkdir ~/tmp
cd ~/tmp
sudo apt install rpm2cpio
wget -nd -O srvany.rpm https://kojipkgs.fedoraproject.org//packages/mingw-srvany/1.1/4.fc38/noarch/mingw32-srvany-1.1-4.fc38.noarch.rpm

rpm2cpio srvany.rpm | cpio -idmv
sudo mkdir /usr/share/virt-tools
sudo mv ./usr/i686-w64-mingw32/sys-root/mingw/bin/*exe /usr/share/virt-tools/

以下のコマンドで Windows 仮想マシンを LXD にインポートできる形式にコンバートします。Linux 仮想マシンも同じコマンドでコンバートできます。

mkdir ./os
sudo virt-v2v --block-driver virtio-scsi -o local -of raw -os ./os -i vmx ./test-vm.vmx

[   0.0] Setting up the source: -i vmx ./test-vm.vmx
[   1.0] Opening the source
[  13.5] Inspecting the source
[  15.1] Checking for sufficient free disk space in the guest
[  15.1] Converting Windows 10 Pro to run on KVM
virt-v2v: This guest has virtio drivers installed.
[  24.7] Mapping filesystem data to avoid copying unused and blank areas
[  25.6] Closing the overlay
[  25.7] Assigning disks to buses
[  25.7] Checking if the guest needs BIOS or UEFI to boot
virt-v2v: This guest requires UEFI on the target to boot.
[  25.7] Setting up the destination: -o disk -os ./os
[  26.8] Copying disk 1/1
  100% [****************************************]
[ 275.0] Creating output metadata
[ 275.0] Finishing off

DLX へインポート

マイグレーションツール bin.linux.lxd-migrate.x86_64 をダウンロードして実行パーミッションを付与します。

cd ~/tmp
wget https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxd-migrate.x86_64
chmod u+x ./bin.linux.lxd-migrate.x86_64

マイグレーションツールを実行して仮想マシンをインポートします。

sudo ./bin.linux.lxd-migrate.x86_64

Please provide LXD server URL: https://192.168.1.101:8443
Certificate fingerprint: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
ok (y/n)? y
1) Use a certificate token
2) Use an existing TLS authentication certificate
3) Generate a temporary TLS authentication certificate
Please pick an authentication mechanism above: 3
Your temporary certificate is:
-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----
It is recommended to have this certificate be manually added to LXD through `lxc config trust add` on the target server.
Alternatively you could use a pre-defined trust password to add it remotely (use of a trust password can be a security issue).
Would you like to use a trust password? [default=no]: yes
Trust password: [core.trust_password に設定したパスワード]
Remote LXD server:
  Hostname: lxd-server
  Version: 5.21.1
Would you like to create a container (1) or virtual-machine (2)?: 2
Name of the new instance: test-vm
Please provide the path to a disk, partition, or image file: /path/to/disk/image/test-vm-sda (コンバートしたディスクファイルを指定する)
Does the VM support UEFI Secure Boot? [default=no]:
Instance to be created:
  Name: test-vm
  Project: default
  Type: virtual-machine
  Source: /path/to/disk/image/test-vm-sda
  Config:
    security.secureboot: "false"
Additional overrides can be applied at this stage:
1) Begin the migration with the above configuration
2) Override profile list
3) Set additional configuration options
4) Change instance storage pool or volume size
5) Change instance network
Please pick one of the options above [default=1]: 3
Please specify config keys and values (key=value ...): limits.cpu=2
Instance to be created:
  Name: test-vm
  Project: default
  Type: virtual-machine
  Source: /path/to/disk/image/test-vm-sda
  Config:
    limits.cpu: "2"
    security.secureboot: "false"
Additional overrides can be applied at this stage:
1) Begin the migration with the above configuration
2) Override profile list
3) Set additional configuration options
4) Change instance storage pool or volume size
5) Change instance network
Please pick one of the options above [default=1]: 3
Please specify config keys and values (key=value ...): limits.memory=4GB
Instance to be created:
  Name: test-vm
  Project: default
  Type: virtual-machine
  Source: /path/to/disk/image/test-vm-sda
  Config:
    limits.cpu: "2"
    limits.memory: 4GB
    security.secureboot: "false"
Additional overrides can be applied at this stage:
1) Begin the migration with the above configuration
2) Override profile list
3) Set additional configuration options
4) Change instance storage pool or volume size
5) Change instance network
Please pick one of the options above [default=1]: 4
Please provide the storage pool to use: default
Do you want to change the storage size? [default=no]:
Instance to be created:
  Name: test-vm
  Project: default
  Type: virtual-machine
  Source: /path/to/disk/image/test-vm-sda
  Storage pool: default
  Config:
    limits.cpu: "2"
    limits.memory: 4GB
    security.secureboot: "false"
Additional overrides can be applied at this stage:
1) Begin the migration with the above configuration
2) Override profile list
3) Set additional configuration options
4) Change instance storage pool or volume size
5) Change instance network
Please pick one of the options above [default=1]: 5
Please specify the network to use for the instance: lxdbr0
Instance to be created:
  Name: test-vm
  Project: default
  Type: virtual-machine
  Source: /path/to/disk/image/test-vm-sda
  Storage pool: default
  Network name: lxdbr0
  Config:
    limits.cpu: "2"
    limits.memory: 4GB
    security.secureboot: "false"
Additional overrides can be applied at this stage:
1) Begin the migration with the above configuration
2) Override profile list
3) Set additional configuration options
4) Change instance storage pool or volume size
5) Change instance network
Please pick one of the options above [default=1]: 1
Transferring instance: test-vm: 1.03GB (257.25MB/s)
Instance test-vm successfully created

Web インターフェース上からインポートした仮想マシンを起動して動作を確認します。

ネットワーク接続を変更

lxdbr0 を使用してネットワークに接続すると NAT 経由の接続になりますが、以下のコマンドでブリッジ接続に変更できます。

lxc config device remove test-vm eth0  
lxc config device add test-vm eth0 nic nictype=macvlan parent=eno1

仮想マシンをホスト起動時に自動起動

lxc config set test-vm boot.autostart true

トラブルシュート

起動時に failed to load Boot0001 “UEFI QEMU QEMU HARDDISK” エラー

元の仮想マシンが UEFI ではなくレガシー BIOS 設定だった場合に発生しました。以下のコマンドでレガシー BIOS 設定に変更することで起動できました。

lxc config set micro-dyn-onl security.secureboot false
lxc config set micro-dyn-onl security.csm true

Windows 10 の時刻が再起動後にずれる

ホスト側の Ubuntu の時刻が UTC にセットされているのに、ゲスト側の Windows がそれをローカルのタイムゾーンの時刻として認識するのが問題のようです。以下のパスにあるレジストリキー RealTimeIsUniversalQWORD (64-bit) として追加し 1 にセットして再起動します。(DWORD (32-bit) だと動作しませんでした。)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

参考

海外在住者の JGC 規約変更 (2000マイル引き落とし) 2023年

JAL JGC の規約に変更があり、海外在住者は毎年2000マイルの支払いをする必要が生じるとの連絡がありました。しかし JAL に問い合わせると回避策があるそうなのでご紹介します。

JAL からのお知らせ

2023年の1月にメールでお知らせが来ていました。

JAL からのお知らせメール

リンク先のページには以下の記述があります。

JGC 規約変更

CLUB-A カード は JAL カードの一種で2000マイルの支払いは必要ないと思うのですが、確信が持てなかったので JAL のカスタマーサポートへ電話してみました。

JAL カスタマーサポートの回答

このまま放置すると毎年2000マイルの支払いが追加で必要になるとのこと。ただし 現在の CLUB-A カードを JGC カードへ切り替えればマイルの支払いは必要ないということでした。

他に以下の情報も教えてもらえました。

  • 2000マイルの引き落としは毎年4月1日
  • 2000マイルが引き落とせなかった場合は JGC 資格剥奪となる

ということで、質問した電話でそのまま CLUB-A カードを JGC カードへ切り替える書類の郵送をお願いしました。

申し込み書類

2週間ほどで “JALグローバルクラブ会員申込書(JALカード会員用)” と “JALカード海外住所変更届” という書類が日本から郵送されてきました。初回の申し込みと同じように返信用の封筒も入っていました。ありがたいですね。

注意事項を読んで記入し返信用封筒で返送しました。

カード到着

申込書の送付から1ヶ月程度で新しいカードが EMS で送られてきました。

この JGC のロゴが入ったカードに変更することで2000マイルの支払いは必要なくなります。

規約だけ読むとよくわかりませんが持っているカードを見ればわかりやすいですね。

切り替えがまだの方はお早めに。😀

OpenWrt で UPnP を使用する

ポート開放に UPnP を使用しないといけない状況になったので、OpenWrt のルーターに miniupnpd をインストールして、特定の IP にのみ UPnP の利用を許可するようにしました。

実行環境

ルーター
Linksys WRT1900ACS
ファームウェア
OpenWrt 22.03.2
パッケージ バージョン
miniupnpd-nftables 2022-08-31-68c8ec50-1

必要なパッケージをインストール

  1. ルーターの Web コンソールへアクセス
  2. メニューの System -> Software をクリック
  3. “Update lists…” をクリック
  4. Filter に “miniupnpd” と入力
  5. リストから “miniupnpd-nftables” をインストール

設定を編集

以下がインストール時に作成される設定ファイルです。/etc/config/upnpd

config upnpd config
        option enabled          0
        option enable_natpmp    1
        option enable_upnp      1
        option secure_mode      1
        option log_output       0
        option download         1024
        option upload           512
#by default, looked up dynamically from ubus
#       option external_iface   wan
        option internal_iface   lan
        option port             5000
        option upnp_lease_file  /var/run/miniupnpd.leases
        option igdv1            1

config perm_rule
        option action           allow
        option ext_ports        1024-65535
        option int_addr         0.0.0.0/0       # Does not override secure_mode
        option int_ports        1024-65535
        option comment          "Allow high ports"

config perm_rule
        option action           deny
        option ext_ports        0-65535
        option int_addr         0.0.0.0/0
        option int_ports        0-65535
        option comment          "Default deny"

option enabled を変更して UPnP を有効にします。

config upnpd config
        option enabled          1

このままではルーターに接続されたすべてのデバイスが UPnP を使用できてしまうので、最初の perm_rule セクションを以下の様に変更します。この場合 192.168.1.101 にのみ UPnP の使用を許可しています。

config perm_rule
        option action           allow
        option ext_ports        1024-65535
        option int_addr         192.168.1.101/32
        option int_ports        1024-65535
        option comment          "Allow high ports"

設定ファイルを変更後、以下のコマンドで miniupnpd を有効化します。

/etc/init.d/miniupnpd restart
/etc/init.d/miniupnpd enable

/etc/init.d/miniupnpd restart 実行時に以下のエラーがでましたが、その後の再起動では表示されなくなりました。

Automatically including '/usr/share/nftables.d/table-post/20-miniupnpd.nft'
Automatically including '/usr/share/nftables.d/chain-post/dstnat/20-miniupnpd.nft'
Automatically including '/usr/share/nftables.d/chain-post/forward/20-miniupnpd.nft'
Automatically including '/usr/share/nftables.d/chain-post/srcnat/20-miniupnpd.nft'

Include '/usr/share/miniupnpd/firewall.include' failed with exit code -9

動作しているか確認

ルーターのポート 5000 にアクセスして確認します。例: http://192.168.1.1:5000/rootDesc.xml

miniupnpd が動作していれば XML ファイルを閲覧できます。

UPnPCJ という UPnP を使用してポートを開放するツールのポート開放テスト機能を使用してテストします。

UPnPCJ を使用したテスト結果

参考

マイナンバーカードを受領した日に返納してもマイナポイントはもらえるのか?

久しぶりに日本へ帰国して住民票を入れ直しマイナンバーカードの申請をしました。

住民票を入れてからマイナンバーカードの申請書が届いて実際にカードを受領するまでに7週間かかり、オーストラリアへの帰国ギリギリになってしまいました。

マイナンバーカードを受領した日にマイナポイントの受取を申請し、受領日に住民票を海外へ移すとどうなるか試してみました。

住民票を海外へ移すとマイナンバーカードは返納する必要があります。返納といってもカードに返納した旨が記録されるだけで、マイナンバーカード自体はそのまま所有者が保管することになります。

結論から言うと、受領日に返納してもマイナポイント 20,000 ポイントは受け取ることができました。

経緯

  • 1日目 10:00 – マイナンバーカード受け取り
  • 1日目 11:00 〜 12:00 – スマホでマイナポイント受取申請
  • 1日目 16:00 – 市役所で海外への転出を申請。市役所側ではまだマイナンバーカードの受取が記録されておらず未所持者として記録されていたので、今日受け取ったばかりだと伝える。転出予定日は1週間後に指定。
  • 1日目 16:45 – まだマイナカードを使用してマイナポータルへログインできる事を確認。返納手続き後すぐにカードの証明証が失効するわけではないらしい。
  • 2日目 08:45 – マイナポイント 15,000 ポイントの受け取りを確認 (健康保険証 + 公金受取口座)
  • 2日目 10:00 – PayPay チャージで 5,000 ポイント受取を確認
  • 転出予定日 + 5日目: マイナカードを使用してマイナポータルへログインできない事を確認。カードの証明証が失効しているらしい。

結論

受領日に返納してもマイナポイント 20,000 ポイントは受け取ることができます。マイナカードの利用者証明用電子証明書は転出予定日までは失効しないらしく、転出予定日までは問題なくマイナポイントとマイナポータルのアプリで使用できました。

アプリ画面

1日目 健康保険証と公金受取口座登録直後 (マイナポイントアプリ)
1日目 健康保険証と公金受取口座登録直後 (マイナポータルアプリ)
2日目 健康保険証と公金受取口座登録分のポイントを獲得 (マイナポータルアプリ)
転出予定日+5日目 電子証明書の失効 (マイナポイントアプリ)
転出予定日+5日目 電子証明書の失効 (マイナポータルアプリ)

OpenWrt に SSH でログインした時にメールで通知する

予期していない SSH ログインを検知するために、 SSH でユーザーがログインした時にメールで通知を行うようにしました。

実行環境

ルーター
Linksys WRT1900ACS
OS
OpenWrt 22.03.2
パッケージ バージョン
msmtp 1.8.19-1

msmtp をインストール

ルーターからメールを送信するために SMPT クライアントをインストールします。

Postfix のような完全な MTA をインストールすることもできますが、ソフトウェアのサイズが大きい、定期的なディスクアクセスが発生する等の OpenWrt で使うには不向きな点があります。このため、SMPT クライアントから外部のメールサーバーを経由してメールを送信します。

以下のコマンドで msmtp をインストールします。

# opkg update
# opkg install msmtp

ファイル /etc/msmtprc を編集して以下の行を追加、変更します。パスワードを平文で設定ファイルに書くことになるので、 msmtp のために新しく送信専用のフリーメールアドレスを取得しました。

host           smtp.gmail.com
port           587
from           username@gmail.com
auth           on
user           username
password       PASSWORD

gmail を使う場合は以下のような設定ファイルになります。PASSWORD は記号を含まない英数字が無難です。

# Example for a system wide configuration file

# A system wide configuration file is optional.
# If it exists, it usually defines a default account.
# This allows msmtp to be used like /usr/sbin/sendmail.
account default

# The SMTP smarthost
host smtp.gmail.com

# Use TLS on port 465
port 587
tls on
tls_starttls off

# Construct envelope-from addresses of the form "user@oursite.example"
from username@gmail.com

auth on
user username
password PASSWORD

# Syslog logging with facility LOG_MAIL instead of the default LOG_USER
syslog LOG_MAIL

さくらメールの場合の例は以下です。

# Example for a system wide configuration file

# A system wide configuration file is optional.
# If it exists, it usually defines a default account.
# This allows msmtp to be used like /usr/sbin/sendmail.
account default

# The SMTP smarthost
host example.sakura.ne.jp

# Use TLS on port 465
port 587
tls on
tls_starttls on

auth on
user router-admin@hogepiyo.com
password myPasswordHere

# Construct envelope-from addresses of the form "user@oursite.example"
from router-admin@hogepiyo.com

# Syslog logging with facility LOG_MAIL instead of the default LOG_USER
syslog LOG_MAIL

msmtp は sendmail コマンドと互換性があるので、シンボリックリンクを設置して sendmail コマンドとしても使えるようにします。

# ln -s /usr/bin/msmtp /usr/sbin/sendmail

以下のコマンドでメール送信のテストをします。”Sender’s Name <username@gmail.com>” と recipient@gmail.com で送信元と受信先を指定します。

# echo -e "Subject: Test mail\n\nThis is a test mail." | sendmail -f "Sender's Name <username@gmail.com>" recipient@gmail.com

メール送信スクリプトを設置

メール送信を行うスクリプト /root/notify-login.sh を以下の内容で作成します。HOST_NAME、RECIPIENT、SENDER を変更して下さい。

#!/bin/sh

HOST_NAME="hogepiyo.com"
RECIPIENT="recipient@gmail.com"
SENDER="OpenWrt <username@gmail.com>"

SOURCE_IP=`echo $SSH_CONNECTION | cut -d " " -f 1`

MESSAGE="To: $RECIPIENT
Subject: '$USER' has logged in '$HOST_NAME'
From: $SENDER

'$USER' has logged in successfully from '$SOURCE_IP' on $HOST_NAME.
Login Time: `date +\"%Y-%m-%d %T %Z\"`

`env`
"

echo "$MESSAGE" | sendmail -t &

パーミッションを変更して実行可能にします。

# chmod 755 /root/notify-login.sh

作成したスクリプトを実行してメールが送信されることを確認します。

# /root/notify-login.sh

/etc/profile ファイルに以下の行を追加して、ログイン時にメールが送信されるようにします。

/root/notify-login.sh

バックアップ設定

/etc/sysupgrade.conf に以下の行を追加してバックアップファイルに作成したスクリプトを含める用に設定します。

/root/

テスト

SSH で再ログインしてメールが送信されることを確認します。

注意

SSH のポートフォワーディングのみを利用する接続ではメールが送信されません。

参考

OpenWrt に OpenVPN サーバーをインストール

OpenWrt のルーターに OpenVPN サーバーをインストールして、ルーターのネットワークへ外部からアクセスできるようにしました。

実行環境

ルーター
Linksys WRT1900ACS
ファームウェア
OpenWrt 22.03.2
パッケージ バージョン
openvpn-openssl 2.5.7-3
openvpn-easy-rsa 3.0.8-4

必要なパッケージをインストール

ルーターへ SSH でアクセスし以下のコマンドを実行しパッケージをインストールします。

opkg update
opkg install openvpn-openssl openvpn-easy-rsa

パラメータを設定

以下のコマンドでパラメータを設定します。

OVPN_DIR="/etc/openvpn"
OVPN_PKI="/etc/easy-rsa/pki"
OVPN_PORT="1194"
OVPN_PROTO="udp"
OVPN_POOL="192.168.8.0 255.255.255.0"
OVPN_DNS="${OVPN_POOL%.* *}.1"
OVPN_DOMAIN="$(uci get dhcp.@dnsmasq[0].domain)"
OVPN_SERV="vpn.hogepiyo.com"

PKI と RSA キーの作成

以下のコマンドでパラメータを設定します。

export EASYRSA_PKI="${OVPN_PKI}"
export EASYRSA_REQ_CN="ovpnca"
export EASYRSA_BATCH="1"
export EASYRSA_CERT_EXPIRE="3650" # Increases the client cert expiry from the default of 825 days to match the CA expiry
export EASYRSA_KEY_SIZE="4096" # Increase key length 

以下のコマンドで PKI とサーバー用の鍵を作成します。

# Remove and re-initialize PKI directory
easyrsa init-pki
 
# Generate DH parameters
easyrsa gen-dh
 
# Create a new CA
easyrsa build-ca nopass
 
# Generate server keys and certificate
easyrsa build-server-full server nopass
openvpn --genkey tls-crypt-v2-server ${EASYRSA_PKI}/private/server.pem

以下のコマンドでクライアント用の鍵を作成します。CLIENT_NAMES にスペース区切りでクライアントキーの名前を入力します。

CLIENT_NAMES='client1 client2 client3 client4 client5'
for cn in $CLIENT_NAMES ; do
  easyrsa build-client-full "${cn}" nopass
  openvpn --tls-crypt-v2 ${EASYRSA_PKI}/private/server.pem \
    --genkey tls-crypt-v2-client "${EASYRSA_PKI}/private/${cn}.pem"
done

ファイアウォールの設定

以下のコマンドでファイアウォールの設定を行い OpenVPN への接続を許可します。

uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.lan.device="tun+"
uci add_list firewall.lan.device="tun+"
uci -q delete firewall.ovpn
uci set firewall.ovpn="rule"
uci set firewall.ovpn.name="Allow-OpenVPN"
uci set firewall.ovpn.src="wan"
uci set firewall.ovpn.dest_port="${OVPN_PORT}"
uci set firewall.ovpn.proto="${OVPN_PROTO}"
uci set firewall.ovpn.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart

OpenVPN 設定ファイルの作成

以下のコマンドで OpenVPN のサーバー用とクライアント用の設定ファイルを作成します。

umask go=
OVPN_DH="$(cat ${OVPN_PKI}/dh.pem)"
OVPN_CA="$(openssl x509 -in ${OVPN_PKI}/ca.crt)"
ls ${OVPN_PKI}/issued \
| sed -e "s/\.\w*$//" \
| while read -r OVPN_ID
do
OVPN_TC="$(cat ${OVPN_PKI}/private/${OVPN_ID}.pem)"
OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)"
OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)"
OVPN_EKU="$(echo "${OVPN_CERT}" | openssl x509 -noout -purpose)"
case ${OVPN_EKU} in
(*"SSL server : Yes"*)
OVPN_CONF="${OVPN_DIR}/${OVPN_ID}.conf"
cat << EOF > ${OVPN_CONF} ;;
user nobody
group nogroup
dev tun
port ${OVPN_PORT}
proto ${OVPN_PROTO}
server ${OVPN_POOL}
topology subnet
client-to-client
keepalive 10 60
persist-tun
persist-key
push "dhcp-option DNS ${OVPN_DNS}"
push "dhcp-option DOMAIN ${OVPN_DOMAIN}"
push "redirect-gateway def1"
push "persist-tun"
push "persist-key"
<dh>
${OVPN_DH}
</dh>
EOF
(*"SSL client : Yes"*)
OVPN_CONF="${OVPN_DIR}/${OVPN_ID}.ovpn"
cat << EOF > ${OVPN_CONF} ;;
user nobody
group nogroup
dev tun
nobind
client
remote ${OVPN_SERV} ${OVPN_PORT} ${OVPN_PROTO}
auth-nocache
remote-cert-tls server
EOF
esac
cat << EOF >> ${OVPN_CONF}
<tls-crypt-v2>
${OVPN_TC}
</tls-crypt-v2>
<key>
${OVPN_KEY}
</key>
<cert>
${OVPN_CERT}
</cert>
<ca>
${OVPN_CA}
</ca>
EOF
done
/etc/init.d/openvpn restart
ls ${OVPN_DIR}/*.ovpn ${OVPN_DIR}/*.conf

設定ファイルをクライアントに適用

ルーターの Web コンソールへアクセスし、System -> Backup / Flash Firmware をクリックし Generate archive ボタンで全ての設定ファイルをダウンロードします。

ダウンロードした圧縮ファイルを解凍し、/etc/openvpn/ 内の *.ovpn ファイルをノートPCやスマホへコピーして接続テストを行います。

参考