Ubuntu22.04で肥大化したqcow2を小さくする

virt-sparsifyを使用するためパッケージをインストール。

# apt install libguestfs-tools

下記のコマンドで小さくできる。シンプロビジョニングには/tmp/を使用するので空き容量に注意。

# virt-sparsify /path/to/vm/image.qcow2 /path/to/vm/image2.qcow2

Ubuntu22.04でのOpenVPNサーバーの設定

前提条件

※tun(ルーティング)方式で設定する
※自宅用なのでセキュリティリスク(CAの秘密鍵へのアクセス)を承知した上でOpenVPNサーバーとCAを同じマシンにインストールする

・ Ubuntu: 22.04.1
・ openvpn: 2.5.5
・ easy-rsa: 3.0.8
・ openssl: 3.0.2

サーバー設定手順

openvpnとeasy-rsaをインストールする。

# apt install openvpn easy-rsa

ルート証明書の有効期間(日数)を変更したい場合、事前に下記を参考に環境変数を変更する。

# export EASYRSA_CA_EXPIRE=7300

公開鍵基盤(PKI)を初期化して認証局(CA)を設置する。CA作成時に秘密鍵のパスフレーズを聞いてくる。このパスフレーズは新しい証明書発行時に必要になる。

# cd /usr/share/easy-rsa/
# ./easyrsa init-pki
# ./easyrsa build-ca

認証局(CA)が発行する証明書の有効期間(日数)を変更したい場合、事前に下記を参考に環境変数を変更する。

# export EASYRSA_CERT_EXPIRE=3650

VPNサーバー用の証明書を作成する。
※パスフレーズは不要なのでnopassを指定

# ./easyrsa build-server-full vpn.example.com nopass

Diffie-Hellmanパラメーターファイルを作成する。

# ./easyrsa gen-dh

TLS-AuthのHMACに使用する共通鍵を作成する。

# openvpn --genkey secret /etc/openvpn/server/ta.key

OpenVPNサーバーの設定ファイルをサンプルからコピーする。

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

設定ファイルを下記のように変更する。
※重要そうな箇所のみ記載
※serverにはクライアントに割り当てられるipアドレスを定義
※push(route)にはクライアントにアクセスを許可するサーバーのプライベートネットワークを指定
※push(redirect-gateway)でクライアントのIPトラフィックがVPNを通過するよう設定
※push(dhcp-option DNS)でクライアントが使用するDNSサーバーを指定
※client-to-clientでクライアント同士の通信を許可
※duplicate-cnで同じ証明書を使用した複数のクライアント接続を許可(非推奨)

port 7716
proto udp
dev tun
ca /usr/share/easy-rsa/pki/ca.crt
cert /usr/share/easy-rsa/pki/issued/vpn.example.com.crt
key /usr/share/easy-rsa/pki/private/vpn.example.com.key
dh /usr/share/easy-rsa/pki/dh.pem
server 172.16.1.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 192.168.1.11"
push "dhcp-option DNS 8.8.8.8"
client-to-client
duplicate-cn
tls-auth server/ta.key 0

IPフォワードを有効にして、異なるネットワーク(NIC)間でパケットが転送されるように設定変更する。

# sed -i "s/#net.ipv4.ip_forward/net.ipv4.ip_forward/g" /etc/sysctl.conf
# sysctl -p

iptablesでIPマスカレードを有効に設定する。

# apt install iptables-persistent
# iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -o [デバイス] -j MASQUERADE
# netfilter-persistent save

サービスを有効化して起動する。

# systemctl enable --now openvpn@server

クライアント証明書の発行

クライアントに配る*.ovpnを作成するのが面倒なのでスクリプトを作成した。地味にハマったポイントはTLS-Authの「key-direction 1」サーバーの設定が0なら1にする必要がある。

#!/bin/bash
easyrsa_location=/usr/share/easy-rsa
sample_config_location=/usr/share/doc/openvpn/examples/sample-config-files
takey_location=/etc/openvpn/server/ta.key
server=vpn.example.com
port=7716
echo "作成するユーザーIDを入力してください。"
read -p "ユーザーID:" id
if [ -z "$id" ]; then
    exit 0
fi
fullname=$id.$server
echo
echo "クライアント接続設定ファイル「$id.ovpn」を作成します。"
read -p "Enterキーで続行します。" result
if [ ! -z "$result" ]; then
    exit 0
fi
echo
default_location=$(pwd)
cd $easyrsa_location
./easyrsa build-client-full $fullname nopass
if [ ! $? -eq 0 ]; then
    exit 0;
fi
cd $default_location
cp $sample_config_location/client.conf $id.ovpn
sed -i "s/my-server-1 1194/$server $port/g" $id.ovpn
sed -i "s/ca ca.crt/#ca ca.crt/g" $id.ovpn
sed -i "s/cert client.crt/#cert client.crt/g" $id.ovpn
sed -i "s/key client.key/#key client.key/g" $id.ovpn
sed -i "s/tls-auth ta.key 1/#tls-auth ta.key 1\nkey-direction 1/g" $id.ovpn
echo "" >>$id.ovpn
# CA
echo "<ca>" >>$id.ovpn
grep -A 100 'BEGIN CERTIFICATE' $easyrsa_location/pki/ca.crt >>$id.ovpn
echo "</ca>" >>$id.ovpn
echo "" >>$id.ovpn
# Key
echo "<key>" >>$id.ovpn
grep -A 100 'BEGIN PRIVATE KEY' $easyrsa_location/pki/private/$fullname.key >>$id.ovpn
echo "</key>" >>$id.ovpn
echo "" >>$id.ovpn
# Cert
echo "<cert>" >>$id.ovpn
grep -A 100 'BEGIN CERTIFICATE' $easyrsa_location/pki/issued/$fullname.crt >>$id.ovpn
echo "</cert>" >>$id.ovpn
echo "" >>$id.ovpn
# TLS-auth
echo "<tls-auth>" >>$id.ovpn
cat $takey_location >>$id.ovpn
echo "</tls-auth>" >>$id.ovpn
echo "" >>$id.ovpn
echo "作成が完了しました。"

実行可能にしてスクリプトを実行すれば対話型でクライアント用の*.ovpnを作成できる。作成された*.ovpnのパーミッションには気をつけが方が良い。

# chmod +x build-client-ovpn.sh
# ./build-client-ovpn.sh

クライアント証明書の更新

更新が可能になる期間を変更したい場合、事前に下記を参考に環境変数を変更する。

# export EASYRSA_CERT_RENEW=365

これも面倒なので更新用のスクリプトを作成した。

#!/bin/bash
easyrsa_location=/usr/share/easy-rsa
sample_config_location=/usr/share/doc/openvpn/examples/sample-config-files
takey_location=/etc/openvpn/server/ta.key
server=vpn.example.com
port=7716
echo "更新するユーザーIDを入力してください。"
read -p "ユーザーID:" id
if [ -z "$id" ]; then
    exit 0
fi
fullname=$id.$server
echo
if [ ! -f "$easyrsa_location/pki/issued/$fullname.crt" ]; then
    echo "既存の証明書が見つかりませんでした。"
    exit 1
fi
echo "クライアント接続設定ファイル「$id.ovpn」を再作成します。"
read -p "Enterキーで続行します。" result
if [ ! -z "$result" ]; then
    exit 0
fi
echo
default_location=$(pwd)
cd $easyrsa_location
./easyrsa renew $fullname nopass
if [ ! $? -eq 0 ]; then
    exit 0;
fi
cd $default_location
cp $sample_config_location/client.conf $id.ovpn
sed -i "s/my-server-1 1194/$server $port/g" $id.ovpn
sed -i "s/ca ca.crt/#ca ca.crt/g" $id.ovpn
sed -i "s/cert client.crt/#cert client.crt/g" $id.ovpn
sed -i "s/key client.key/#key client.key/g" $id.ovpn
sed -i "s/tls-auth ta.key 1/#tls-auth ta.key 1\nkey-direction 1/g" $id.ovpn
echo "" >>$id.ovpn
# CA
echo "<ca>" >>$id.ovpn
grep -A 100 'BEGIN CERTIFICATE' $easyrsa_location/pki/ca.crt >>$id.ovpn
echo "</ca>" >>$id.ovpn
echo "" >>$id.ovpn
# Key
echo "<key>" >>$id.ovpn
grep -A 100 'BEGIN PRIVATE KEY' $easyrsa_location/pki/private/$fullname.key >>$id.ovpn
echo "</key>" >>$id.ovpn
echo "" >>$id.ovpn
# Cert
echo "<cert>" >>$id.ovpn
grep -A 100 'BEGIN CERTIFICATE' $easyrsa_location/pki/issued/$fullname.crt >>$id.ovpn
echo "</cert>" >>$id.ovpn
echo "" >>$id.ovpn
# TLS-auth
echo "<tls-auth>" >>$id.ovpn
cat $takey_location >>$id.ovpn
echo "</tls-auth>" >>$id.ovpn
echo "" >>$id.ovpn
echo "作成が完了しました。"

実行可能にすれば対話型で更新ができる。作成された*.ovpnのパーミッションには気をつけが方が良い。

# chmod +x renew-client-ovpn.sh
# ./renew-client-ovpn.sh

Ubuntuを使ってWindows11のHDD(500GB)からSSD(256GB)のクローンを作成する

500GBのHDDから256GBのSSDに換装するのが目的。

BitLockerが有効な場合な無効化する
HDD全体のイメージバックアップを取る
HDDの使用領域を250GB程度に収める

gpartedをインストールして起動し、必要なパーティションの終了セクタが500,000,000(256GB÷512)程度以下なるように調整して、それ以降のセクタを削除する。

# apt install gparted

事前にlsblkなどでデバイスパスを把握し、ddコマンドでコピーする。
※countの値は256GB÷1024k

# dd if=/dev/[コピー元] of=/dev/[コピー先] bs=1024k count=256k status=progress

コピーが終了したらgdiskでパーティションテーブルを修正する。

# gdisk /dev/[コピー先]
GPT fdisk (gdisk) version 1.0.8

Warning! Disk size is smaller than the main header indicates! Loading
secondary header from the last sector of the disk! You should use 'v' to
verify disk integrity, and perhaps options on the experts' menu to repair
the disk.
Caution: invalid backup GPT header, but valid main header; regenerating
backup header from main header.

Warning! One or more CRCs don't match. You should repair the disk!
Main header: OK
Backup header: ERROR
Main partition table: OK
Backup partition table: ERROR

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: damaged

****************************************************************************
Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk
verification and recovery are STRONGLY recommended.
****************************************************************************

Command (? for help): x

Expert command (? for help): v

Caution: The CRC for the backup partition table is invalid. This table may
be corrupt. This program will automatically create a new backup partition
table when you save your partitions.

Problem: The secondary header's self-pointer indicates that it doesn't reside
at the end of the disk. If you've added a disk to a RAID array, use the 'e'
option on the experts' menu to adjust the secondary header's and partition
table's locations.

Problem: Disk is too small to hold all the data!
(Disk size is 488397168 sectors, needs to be 1953525168 sectors.)
The 'e' option on the experts' menu may fix this problem.

Problem: GPT claims the disk is larger than it is! (Claimed last usable
sector is 1953525134, but backup header is at
1953525167 and disk size is 488397168 sectors.
The 'e' option on the experts' menu will probably fix this problem

Partition(s) in the protective MBR are too big for the disk! Creating a
fresh protective or hybrid MBR is recommended.

Identified 5 problems!

Expert command (? for help): e
Relocating backup data structures to the end of the disk

Expert command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/[コピー先].
The operation has completed successfully.

Windowsのパーティションが見えるようになったら、最後にgpartedで右端に余っている空き領域を利用できるよう設定する。

Ubuntu22.04のgrubでfsckのメッセージだけが表示される問題

plymouthが開始される前に数秒だけ「/dev/nvme0n1p2: clean, 219170/31227904 files, 4614538/124895488 blocks」というメッセージが表示される。ディスクチェックが正常に終了したというfsckからのメッセージらしいけど、格好悪いので非表示にしたい。

Ubuntu 22.04.1

下記の内容でファイルを作成する。

FRAMEBUFFER=y

下記のコマンドを実行する。

# update-initramfs -u

LinuxMint21でスワップ領域を追加する

Linux Mint 21 Vanessa

既存のスワップファイルの容量を変更する場合

※一度スワップ領域がなくなるので物理メモリに余裕がない場合は危険

スワップを一度offにする。

# swapoff --all

新しいスワップファイルを作成する。

# fallocate --length 8G /swapfile
# chmod 600 /swapfile

新しいスワップファイルをスワップ領域としてマークする。

# mkswap /swapfile

スワップを有効化する。

# swapon /swapfile

既存のスワップファイルとは別のスワップファイルを追加する場合

※既存のスワップ領域を活かしたまま追加できるため物理メモリに余裕がない場合に有効

新しいスワップファイルを作成する。

# fallocate --length 4G /swapfile2
# chmod 600 /swapfile2

新しいスワップファイルをスワップ領域としてマークする。

# mkswap /swapfile2

スワップを有効化する。

# swapon /swapfile2

fstabに下記の行を追記して再起動時にスワップが自動的に有効化されるように設定する。

/swapfile2    none    swap    sw    0    0

Ubuntu20.04でディスプレイのRGBを調整する

ノートパソコンのディスプレイの色がなんか変な感じがして、好みの問題かもしれないけど、温かみが足りないと思いRGBを調整した。

下記のコマンドでディスプレイ名を確認する。

$ xrandr

「eDP」という名前だったので、下記コマンドを自動起動するアプリケーションに登録する。

xrandr --output eDP --gamma 1:0.93:0.93

Ubuntu20.04でVirtualBoxの仮想マシンをサービス化する

予め実行ユーザーをvboxusersグループに所属させておく。

# gpasswd -a username vboxusers

下記のファイルを作成する。パーミッションは644で良い。

[Unit]
Description=VirtualBox VM %I
After=network.target virtualbox.service
Before=runlevel2.target shutdown.target

[Service]
[Unit]
Description=VirtualBox VM %I
After=network.target virtualbox.service
Before=runlevel2.target shutdown.target

[Service]
User=username
Group=vboxusers
Type=forking
Restart=no
TimeoutSec=300
IgnoreSIGPIPE=no
KillMode=none
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/usr/bin/VBoxManage startvm %i --type headless
ExecStop=/bin/bash -c '/usr/bin/VBoxManage controlvm %i acpipowerbutton; while [ ! -z "`VBoxManage list runningvms | grep %i`" ]; do sleep 1; done'

[Install]
WantedBy=multi-user.target

win1とwin2という名前の仮想マシンをサービスとして有効にして起動する。

# systemctl enable vbox@win1
# systemctl start vbox@win1
# systemctl enable vbox@win2
# systemctl start vbox@win2