OpenVPN でセキュアな接続を確立

OpenVPN を利用して外出先の WiFi 等の安全ではないネットワークから安全な回線に接続できるようにします。

サーバー
LXD ゲスト
CPU
2コア
メモリー
4GB
OS
Ubuntu Server 24.04 LTS 64Bit
apt パッケージ バージョン
openvpn 2.6.12-0ubuntu0.24.04.1
easy-rsa 3.1.7-2

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

以下のコマンドで必要なパッケージをイストールします。

sudo apt install openvpn easy-rsa

サーバーで使う証明書用の CA を作成

以下のコマンドで CA 用の鍵と証明書を作成します。

sudo make-cadir /etc/openvpn/easy-rsa

easy-rsa の設定ファイルを編集します。

sudo vim /etc/openvpn/easy-rsa/vars

EASYRSA_KEY_SIZE の値をデフォルトの 2048 から 4096 に変更して鍵長を長くしておきます。

EASYRSA_CERT_EXPIRE の値をデフォルトの 825 から 3650 にして証明書の有効期限を長くしておきます。

ルートユーザーに変更して以下のコマンドで PKI を作成します。

sudo su -
cd /etc/openvpn/easy-rsa/
./easyrsa init-pki
./easyrsa build-ca

CA 用のキーのパスワードを入力を求められるので入力します。ここでのパスワード入力は秘密鍵が平文で表示されるのを防ぎます。

CA の名前の入力を求められますが Enter キーの入力でデフォルト値を設定します。

サーバー用の鍵と証明書を作成

引き続きルートユーザーで以下のコマンドを実行してサーバー用の鍵を作成します。

作成後に名前の入力を求められますが Enter キーでデフォルト値を設定します。

./easyrsa gen-req <SERVER_NAME> nopass

以下のコマンドで Diffie Hellman パラメーターを作成します。OpenVPN サーバーに必要です。

./easyrsa gen-dh

以下のコマンドでサーバー用の証明書を CA から発行します。発行時に CA の鍵のパスワードを入力します。

./easyrsa sign-req server <SERVER_NAME>

作成した CA の証明書、サーバー用の鍵と証明書、DH パラメーターを /etc/openvpn/ にコピーします。

cp pki/dh.pem pki/ca.crt pki/issued/<SERVER_NAME>.crt pki/private/<SERVER_NAME>.key /etc/openvpn/

クライアント用の証明書を作成

引き続きルートユーザーで以下のコマンドを実行してクライアント用の証明書を作成します。<CLIENT_NAME> 部分を変更して必要なユーザーの数だけ発行します。

./easyrsa gen-req <CLIENT_NAME> nopass
./easyrsa sign-req client <CLIENT_NAME>

クライアント用の証明書の発行が終わったらルートユーザーから一般ユーザーに戻ります。

サーバーを設定

サーバーの設定ファイルをテンプレートからコピーします。

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server.conf

追加のセキュリティ設定 tls-auth で使用するキーを作成します。

cd /etc/openvpn
sudo openvpn --genkey tls-auth ta.key

/etc/openvpn/server.conf を編集してサーバーの設定を変更します。

sudo vim /etc/openvpn/server.conf

以下の鍵と証明書のファイル名が実際に存在しているファイルと一致することを確認します。

ca ca.crt
cert <SERVER_NAME>.crt
key <SERVER_NAME>.key
dh dh.pem

セキュリティ向上のためポートを変更しておきます。

port 11940

以下の行のコメントアウトを解除します。

;tls-auth ta.key 0

VPN 用のサブネットを変更したい場合は以下を変更します。

server 10.8.0.0 255.255.255.0

以下の行のコメントアウトを解除してクライアントが VPN 経由でインターネットへアクセスするようにします。

;push "redirect-gateway def1 bypass-dhcp"

VPN 接続で使用する DNS サーバーの IP を指定します。

push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

以下の行を編集して弱い暗号方式が使用されないようにします。

data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

また以下の行を追加して弱い暗号方式が使用されないようにします。

auth SHA256
tls-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256

ネットワークの設定

/etc/sysctl.conf を編集して以下の行のコメントアウトを解除します。

sudo vim /etc/sysctl.conf
#net.ipv4.ip_forward=1

sysctl を再読み込みします。

sudo sysctl -p /etc/sysctl.conf

sudo sysctl -p /etc/sysctl.conf以下のコマンドでファイアウォールの設定を変更して OpenVPN 用のポートを開放します。

sudo ufw allow 11940/udp

OpenVPN のサブネットから外部ネットワークへのルーティングをするために NAT を設定します。/etc/ufw/before.rules を編集して以下 “*filter” の直前、設定ファイルの上部に追加します。サブネットとネットワークインターフェースは環境に合わせて変更します。

# START OPENVPN RULES
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client network to be NAT'd
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

/etc/default/ufw 内の DEFAULT_FORWARD_POLICY を “ACCEPT” に設定してパケットの転送を許可します。

DEFAULT_FORWARD_POLICY="ACCEPT"

UFW を再起動します。

sudo ufw disable
sudo ufw enable

サーバーを起動

OpenVPN サーバーを起動します。設定を変更した後は restart をします。

sudo systemctl start openvpn@server

以下のコマンドでログを確認できます。”Initialization Sequence Completed” が表示されていれば正常に起動しています。

sudo journalctl -u openvpn@server -xe

/etc/default/openvpn を変更して OpenVPN サーバーを自動で起動するようにします。

sudo vim /etc/default/openvpn

以下の行のコメントアウトを解除してすべてのサーバー設定を自動起動するようにします。個別に設定ファイル名を指定することもできます。

AUTOSTART="all"

設定を反映させるために systemd を再読み込みします。

sudo systemctl daemon-reload

以下のコマンドで OpenVPN が作成した tun0 インターフェースを確認します。

ip addr show dev tun0

クライアント設定ファイルを作成

以下の内容のシェルスクリプトを generate-client-configs.sh として作成し実行権限を与えます。OUTPUT_DIR 等必要があれば変更します。

#!/bin/bash
# This script generates inline OpenVPN client configuration files
# for the given client names. It assumes that the client certificate
# and key are stored in separate directories.
#
# Usage:
#   ./generate-client-configs.sh client1 client2

# Common files (adjust paths as needed)
CA_FILE="/etc/openvpn/easy-rsa/pki/ca.crt"
TA_FILE="/etc/openvpn/ta.key"

# Directories where client certificates and keys are stored
CERT_DIR="/etc/openvpn/easy-rsa/pki/issued"
KEY_DIR="/etc/openvpn/easy-rsa/pki/private"

# Directory where the output configuration files will be stored
OUTPUT_DIR="./openvpn-client-configs"

# Prefix of client config file name
OUTPUT_FILE_PREFIX="my-openvpn-"

# Server information
SERVER_ADDRESS="example.com"
PORT=11940

# Base configuration template
BASE_CONFIG=$(cat <<EOF
client
dev tun
proto udp
remote ${SERVER_ADDRESS} ${PORT}
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
auth SHA256
tls-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
verb 3
EOF
)

# Function to embed file content in inline tags
embed_file() {
    local tag="$1"
    local file="$2"
    echo "<${tag}>"
    cat "${file}"
    echo "</${tag}>"
    echo ""
}

# Check if at least one client name is provided
if [ "$#" -eq 0 ]; then
    echo "Usage: $0 client_name1 [client_name2 ...]"
    exit 1
fi

# Create the output directory if it doesn't exist
mkdir -p "${OUTPUT_DIR}"

# Generate configuration file for each client provided as argument
for client in "$@"; do
    CLIENT_CERT="${CERT_DIR}/${client}.crt"
    CLIENT_KEY="${KEY_DIR}/${client}.key"

    # Check if all required files exist
    for file in "$CA_FILE" "$CLIENT_CERT" "$CLIENT_KEY" "$TA_FILE"; do
        if [ ! -f "$file" ]; then
            echo "Error: Required file '$file' not found for client '${client}'." >&2
            continue 2
        fi
    done

    OUTPUT_FILE="${OUTPUT_DIR}/${OUTPUT_FILE_PREFIX}${client}.ovpn"

    # Write the base configuration to the output file
    echo "${BASE_CONFIG}" > "${OUTPUT_FILE}"
    echo "" >> "${OUTPUT_FILE}"

    # Embed certificate and key files inline
    {
        embed_file "ca" "${CA_FILE}"
        embed_file "cert" "${CLIENT_CERT}"
        embed_file "key" "${CLIENT_KEY}"
        embed_file "tls-auth" "${TA_FILE}"
        echo "key-direction 1"
    } >> "${OUTPUT_FILE}"

    echo "Client config file '${OUTPUT_FILE}' created successfully."
done

このスクリプトにクライアント用の鍵と証明書を作成した時の <CLIENT_NAME> を引数にして実行します。

sudo ./generate-openvpn-client-configs.sh <CLIENT_NAME_1> <CLIENT_NAME_2> ...

OUTPUT_DIR にクライアント用の設定ファイルが出力されるのでクライアントデバイスへコピーし接続確認をします。この設定ファイルには鍵情報が埋め込まれているのに取り扱いには注意します。

参考

Ubuntu Pro の Livepatch を有効にして再起動回数を減らす

Ubuntu Pro の Livepatch 機能を有効にしてカーネルバージョンアップ等で必要になる再起動の回数を減らします。個人的に利用する場合は5台まで無料で利用できます。

サーバー
LXD ホスト
CPU
4コア
メモリー
32GB
OS
Ubuntu Server 24.04 LTS 64Bit

Ubuntu Pro に登録

個人利用の場合は Ubuntu Community に登録すれば無料で利用できます。Ubuntu Pro のページ下部の Personal から登録します。

Ubuntu Pro を有効化

メールアドレスの確認が終わって登録が完了するとトークンが発行されるので、以下のコマンドで Ubuntu サーバーにトークンを記録して Ubuntu Pro を有効にします。

sudo pro attach <TOKEN>
SERVICE          ENTITLED  STATUS       DESCRIPTION
anbox-cloud      yes       disabled     Scalable Android in the cloud
esm-apps         yes       enabled      Expanded Security Maintenance for Applications
esm-infra        yes       enabled      Expanded Security Maintenance for Infrastructure
landscape        yes       disabled     Management and administration tool for Ubuntu
livepatch        yes       enabled      Canonical Livepatch service
realtime-kernel* yes       disabled     Ubuntu kernel with PREEMPT_RT patches integrated
usg              yes       disabled     Security compliance and audit tools

個人向け無料プランでは利用できない機能がありますが、Livepatch と Expanded Security Maintenance (ESM) は利用できます。

Ubuntu Pro の全機能の状態を確認するには以下のコマンドを実行します。

pro status --all

参考

Fail2ban でセキュリティを向上

Fail2ban をインストールしてブルートフォースアタックからサーバーを保護します。

サーバー
LXD ゲスト
CPU
2コア
メモリー
4GB
OS
Ubuntu Server 24.04 LTS 64Bit
apt パッケージ バージョン
fail2ban 1.0.2-3ubuntu0.1

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

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

sudo apt update
sudo apt install fail2ban

インストール後に自動的にサービスが開始されます。

Fail2ban を設定

/etc/fail2ban/jail.conf  に設定が記述されていますがこのファイルを直接編集せずに、 /etc/fail2ban/jail.local を作成し変更したい値だけを記述します。

sudo vim /etc/fail2ban/jail.local

jail.local に以下の設定を追加して連続してログインに失敗した場合に徐々に bantime を伸ばすようにします。Fail2ban を有効にするサービスを指定します。(sshd) また、アクセス禁止が発生した場合にメールで通知をします。

[DEFAULT]
bantime.increment = true

# Send email notification
action = %(action_mwl)s

# Email recipient
destemail = foo@example.com

[sshd]
enabled = true
port = 2222  # ポートを変更している場合はポート番号を指定

/etc/fail2ban/action.d/sendmail-common.local を作成し sendmail-common.conf に記述されている設定を変更します。デフォルトではサービス開始時と終了時にもメール通知が送信されるため、アクセス禁止が行われた時のみに変更します。

sudo vim /etc/fail2ban/action.d/sendmail-common.local

以下を記述します。

[Definition]

actionstart =

actionstop =

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

sudo systemctl restart fail2ban

アクセス禁止措置が行われることをテスト

存在しないユーザー名で SSH へログインする等してログインに続けて失敗します。

以下のコマンドでログインの失敗回数とアクセス禁止されたIPを確認できます。

sudo fail2ban-client status sshd

参考

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 を使用したテスト結果

参考