1. はじめに
Linux Mint環境にWebサーバを移設したことで、セキュアサーバ構築の旅路は終着を迎えるはずでした。しかし、ふと、サーバ冗長化のことを考えたらテコ入れしたい要素が山ほど出てくる訳でして。終わりのない巡礼の道を今日も歩みます。
本記事では以下のOSで動作確認を行っています。
終着の予定だった記事はこちらです。
2. 今回のテーマ
2.1 サーバ構成の冗長化
QEMU用のDebianイメージ、SDカード上の暗号化フォルダをそれぞれ機器間で同期する構成とします。バックアップ側はコールドスタンバイです。
2.2 透過的な接続
サーバ側はAvahiによる名前解決、スマホ側は自己申告(SSHコマンドにより、サーバ側の rclone.conf を更新する)により相互の接続を透過的に行います。どの機器がアクティブであっても、稼働中のサーバとスマホを自動で接続するイメージです。
3. Debianのセットアップ
3.1 QEMUのインストール
以下のソフトウェアをインストールします。Windows環境ではAvahiの代わりにBonjourを使用しますが、dns-sd コマンドが使用可能な場合は不要です。
Qemu-system-x86
QEMU Binaries for Windows (64 bit) - https://qemu.weilnetz.de/w64/
Bonjour Print Services for Windows - https://support.apple.com/ja-jp/106380
# コントロールパネル
# ┗プログラム
# ┗プログラムと機能
# ┗🛡️Windowsの機能の有効化または無効化
⊞ ☑️📁 Hyper-V
Windows環境での dns-sd コマンド運用は、Androidからの名前解決が安定しませんでした。現在、対策を検討中です。
3.2 Debianのダウンロード
以下のコマンドでフォルダを作成してDebianイメージをダウンロードします。
mkdir -p ~/qemu/debian-amd64
cd ~/qemu/debian-amd64
curl -fLO \
https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-amd64.qcow2
mkdir "C:/qemu/debian-amd64"
cd "C:/qemu/debian-amd64"
curl.exe -fLO `
"https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-amd64.qcow2"
3.3 Debianの起動
以下の起動スクリプトを作成してDebianを起動します。
#!/bin/bash
AVAHI_IP="$(ifconfig | grep -o '192\.168\.[0-9.]*' | head -n 1)"
avahi-publish -aR wraith-srv.local "$AVAHI_IP" &
AVAHI_PID="$!"
cd "$(dirname "$0")"
qemu-img create -f qcow2 rclone-cache.qcow2 64G
qemu-system-x86_64 \
-enable-kvm \
-cpu host \
-m 1024 \
-smp cores=4,threads=2 \
-drive if=none,file=debian-13-nocloud-amd64.qcow2,id=hd0,format=qcow2 \
-device virtio-blk-pci,drive=hd0 \
-drive if=none,file=rclone-cache.qcow2,id=hd1,format=qcow2 \
-device virtio-blk-pci,drive=hd1 \
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \
-device virtio-net-pci,netdev=net0 \
-nographic
kill "$AVAHI_PID"
chmod +x ~/qemu/debian-amd64/qemu-launcher.sh
$avahiIP = (Get-NetIPAddress -IPAddress "192.168.*")[0].IPAddress
$avahiArgs = @('-P', '"Wraith Server"', '_http._tcp', '.', '8080',
'wraith-srv.local', $avahiIP)
$avahiProc = Start-Process dns-sd -ArgumentList $avahiArgs -PassThru
cd "$PSScriptRoot"
& "C:/Program Files/qemu/qemu-img.exe" create `
-f qcow2 "rclone-cache.qcow2" 64G
& "C:/Program Files/qemu/qemu-system-x86_64.exe" `
-accel "whpx" `
-cpu "qemu64" `
-m "1024" `
-smp "cores=4,threads=2" `
-drive "if=none,file=debian-13-nocloud-amd64.qcow2,id=hd0,format=qcow2" `
-device "virtio-blk-pci,drive=hd0" `
-drive "if=none,file=rclone-cache.qcow2,id=hd1,format=qcow2" `
-device "virtio-blk-pci,drive=hd1" `
-netdev "user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80" `
-device "virtio-net-pci,netdev=net0" `
-nographic
Stop-Process -Id $avahiProc.Id
3.4 Avahiの動作確認
root でログインしてApacheをインストールします。PCまたはスマホのブラウザから、以下のURLでApacheのデフォルトページが表示されることを確認します。
apt update
apt upgrade
apt install apache2
http://wraith-srv.local:8080/
3.5 SSHの接続設定
続いて、root でSSHサーバをインストールしてユーザを追加します。
apt install openssh-server
adduser --shell /bin/bash --gecos "Debian,,," debian
usermod -aG sudo debian
mkdir -p /home/debian/.ssh
クライアントPCからDebianに接続します。
Host wraith-ssh
HostName wraith-srv.local
User debian
Port 2222
IdentityFile ~/.ssh/id_ed25519
ssh-keygen -t ed25519 -C "$(hostname)"
cat ~/.ssh/id_ed25519.pub
Host wraith-ssh
HostName wraith-srv.local
User debian
Port 2222
IdentityFile ~/.ssh/id_ed25519
ssh-keygen -t ed25519 -C "$(hostname)"
cat "$HOME/.ssh/id_ed25519.pub"
# id_ed25519.pub の中身をコピペ
chown -R debian:debian /home/debian/.ssh
ssh wraith-ssh
ssh wraith-ssh
SSHで接続できたら、以下のコマンドで設定変更します。
sudo hostnamectl set-hostname QEMU-x86-64
sudo timedatectl set-timezone Asia/Tokyo
4. rcloneのセットアップ
4.1 キャッシュフォルダのマウント
rc.local を作成して有効化します。
#!/bin/sh -e
mkfs.ext4 -F /dev/vdb
mkdir -p /home/debian/.cache/rclone
mount /dev/vdb /home/debian/.cache/rclone
chown -R debian:debian /home/debian/.cache
exit 0
[Install]
WantedBy=multi-user.target
sudo apt install e2fsprogs
sudo chmod +x /etc/rc.local
sudo systemctl daemon-reload
sudo systemctl enable rc-local
sudo systemctl start rc-local
4.2 rcloneのインストール
必要なパッケージをインストールしてマウント用のフォルダを作成します。
sudo apt install fuse
sudo apt install rclone
sudo mkdir -p /srv/git
sudo mkdir -p /srv/svn
sudo chown debian:debian /srv/git
sudo chown debian:debian /srv/svn
4.3 rcloneのリモート設定
rcloneでのリモート接続の準備をします。
ssh-keygen -t ed25519 -C "$(hostname)"
cat ~/.ssh/id_ed25519.pub
# id_ed25519.pub の中身をコピペ
mkdir -p ~/symlink/media
mkdir -p ~/symlink/vault/.vault
[shadow-sftp]
type = sftp
host = 10.0.2.2
user = debian
port = 2222
key_file = ~/.ssh/id_ed25519
[shadow-media]
type = alias
remote = shadow-sftp:symlink/media
[shadow-vault]
type = crypt
remote = shadow-sftp:symlink/vault/.vault
password = *** ENCRYPTED ***
4.4 systemdサービスの作成
rcloneマウントのユーザサービスを作成します。
mkdir -p ~/.config/systemd/user
[Unit]
Description=Rclone Mounter for Android Storage
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/bin/mkdir -p %h/rclone/media
ExecStartPre=/usr/bin/mkdir -p %h/rclone/vault
ExecStart=/usr/bin/rclone mount shadow-media: %h/rclone/media \
--vfs-cache-mode writes --daemon
ExecStart=/usr/bin/rclone mount shadow-vault: %h/rclone/vault \
--vfs-cache-mode writes --daemon
ExecStart=/usr/bin/rclone mount shadow-vault:git /srv/git \
--uid 33 --gid 33 --allow-other \
--vfs-cache-mode writes --daemon
ExecStart=/usr/bin/rclone mount shadow-vault:svn /srv/svn \
--uid 33 --gid 33 --allow-other \
--vfs-cache-mode writes --daemon
ExecStop=/usr/bin/fusermount -uz /srv/svn
ExecStop=/usr/bin/fusermount -uz /srv/git
ExecStop=/usr/bin/fusermount -uz %h/rclone/vault
ExecStop=/usr/bin/fusermount -uz %h/rclone/media
[Install]
WantedBy=default.target
- #user_allow_other
+ user_allow_other
loginctl enable-linger debian
systemctl --user daemon-reload
systemctl --user start rclone-mounter
systemctl --user stop rclone-mounter
5. Termuxのセットアップ
5.1 Termuxの初期設定
スマホ画面からポチポチと入力します。
(*) Single mirror Choose a Single mirror to use
(*) default Cached (by cloudflare) variant of packages.termux.dev
pkg upgrade
pkg install openssh
passwd
whoami
sshd
5.2 SSHの接続設定
クライアントPCからTermuxに接続します。
Host termux-ssh
HostName 192.168.x.x
User u0axxx
Port 8022
IdentityFile ~/.ssh/id_ed25519
cat ~/.ssh/id_ed25519.pub
ssh u0axxx@192.168.x.x -p 8022
Host termux-ssh
HostName 192.168.x.x
User u0axxx
Port 8022
IdentityFile ~/.ssh/id_ed25519
cat "$HOME/.ssh/id_ed25519.pub"
ssh "u0axxx@192.168.x.x" -p 8022
# id_ed25519.pub の中身をコピペ
ssh termux-ssh
ssh termux-ssh
TermuxからDebianに接続します。
Host wraith-ssh
HostName wraith-srv.local
User debian
Port 2222
IdentityFile ~/.ssh/id_ed25519
ConnectTimeout 5
ssh-keygen -t ed25519 -C デバイス名
cat ~/.ssh/id_ed25519.pub
# id_ed25519.pub の中身をコピペ
ssh wraith-ssh
cat ~/.ssh/id_ed25519.pub
# id_ed25519.pub の中身をコピペ
5.3 シンボリックリンクの作成
スマホのストレージへのシンボリックリンクを作成します。
termux-setup-storage
ls -l ~/storage/external-1
ln -s /storage/xxxx-xxxx ~/storage/sdcard
mkdir -p ~/symlink
ln -s ~/storage/shared ~/symlink/media
# ln -s ~/storage/sdcard ~/symlink/media
# ln -s ~/storage/external-1 ~/symlink/vault
ln -s ~/storage/sdcard ~/symlink/vault
mkdir -p ~/symlink/vault/.vault
5.4 rcloneの自動マウント
.bashrc にrcloneの自動マウントを仕込みます。
if [[ ! $SSH_CONNECTION ]]; then
termux-wake-lock
sshd
SFTP_HOST="$(ifconfig 2>/dev/null | grep -o '192\.168\.[0-9.]*' | head -n 1)"
SFTP_USER="$(whoami | tr -d '_')"
ssh wraith-ssh '
sed -i '\''/^\[shadow-sftp\]$/,/^\[/ {
/^host =/s/= .*/= '"$SFTP_HOST"'/
/^user =/s/= .*/= '"$SFTP_USER"'/
/^port =/s/= .*/= 8022/
}'\'' ~/.config/rclone/rclone.conf
systemctl --user start rclone-mounter
'
else
USER=termux
HOSTNAME=デバイス名
PS1='\[\e]0;'"$USER@$HOSTNAME"': \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]'"$USER@$HOSTNAME"'\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
fi
if [[ ! $SSH_CONNECTION ]]; then
ssh wraith-ssh '
systemctl --user stop rclone-mounter
STOP_SEC=0
STOP_CMD=":"
while pgrep -x rclone >/dev/null; do
if (( STOP_SEC >= 2 )); then
printf "\rStopping rclone... %ds" "$STOP_SEC"
STOP_CMD="echo"
fi
sleep 1
(( STOP_SEC++ ))
done
$STOP_CMD
'
pkill sshd
termux-wake-unlock
fi
6. Webサーバのセットアップ
6.1 Gitサーバの設定
認証ユーザを設定します。初回のみ -cm オプションです。
sudo htpasswd -cm /etc/apache2/.htpasswd ユーザ名
sudo htpasswd -m /etc/apache2/.htpasswd ユーザ名
.conf ファイルを作成して、モジュールを有効化します。
sudo apt install git
<VirtualHost *:80>
ServerName wraith-srv.local
ServerAlias localhost
# SSLEngine on
# SSLCertificateFile /etc/ssl/certs/client.crt
# SSLCertificateKeyFile /etc/ssl/private/client.key
SetEnv GIT_PROJECT_ROOT /srv/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
<Directory /usr/lib/git-core>
Options +ExecCGI
Require all granted
</Directory>
<Location /git>
AuthType Basic
AuthName "Git Repository"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Location>
</VirtualHost>
sudo a2enmod cgi
sudo a2ensite git.conf
sudo systemctl restart apache2
クライアントのユーザ設定を追加します。
git config --global init.defaultBranch main
git config --global user.name "$(hostname)"
git config --global user.email user@example.com
git config --global credential.helper store
git config --global init.defaultBranch main
git config --global user.name "$(hostname)"
git config --global user.email user@example.com
git config --global credential.helper store
git config --global init.defaultBranch main
git config --global user.name "$(hostname)"
git config --global user.email "user@example.com"
6.2 Gitリポジトリの作成
Gitのベアリポジトリを作成します。Linux系はここで認証を通しておきましょう。
mkdir -p ~/rclone/vault/git/my-first-git
cd ~/rclone/vault/git/my-first-git
git init --bare
git ls-remote http://localhost/git/my-first-git
git ls-remote http://wraith-srv.local:8080/git/my-first-git
以下のURLでアクセスできます。
http://wraith-srv.local:8080/git/my-first-git
6.3 メディアフォルダのGit管理
メディアフォルダ用のリポジトリを作成して、自動更新を仕込みます。
mkdir -p ~/rclone/vault/git/media
cd ~/rclone/vault/git/media
git init --bare
cd ~/rclone/media
git init
git remote add origin http://localhost/git/media
/*
!/.gitignore
!/DCIM/
!/Movies/
.tmfs/
.thumbnails/
git add -A
git commit -m "Initial commit"
git push -u origin main
ssh server-ssh '
export LANG=en_US.UTF-8
cd ~/rclone/media && \
git remote get-url origin && \
git pull && \
git add -A && \
git commit -m "Auto commit" && \
git push
exit 0
'
6.4 SVNサーバの設定
.conf ファイルを修正して、モジュールを有効化します。
sudo apt install subversion
sudo apt install libapache2-mod-svn
- #<Location /svn>
+ <Location /svn>
- #DAV svn
+ DAV svn
- #SVNParentPath /var/lib/svn
+ SVNParentPath /srv/svn
- #AuthType Basic
- #AuthName "Subversion Repository"
- #AuthUserFile /etc/apache2/dav_svn.passwd
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /etc/apache2/.htpasswd
#<LimitExcept GET PROPFIND OPTIONS REPORT>
- #Require valid-user
+ Require valid-user
#</LimitExcept>
- #</Location>
+ </Location>
sudo a2enmod dav
sudo a2enmod dav_svn
sudo systemctl restart apache2
6.5 SVNリポジトリの作成
SVNのリポジトリを作成します。以下のURLでアクセスできます。
mkdir -p ~/rclone/vault/svn
svnadmin create ~/rclone/vault/svn/my-first-svn
http://wraith-srv.local:8080/svn/my-first-svn
6.6 メディアフォルダのSVN管理
メディアフォルダ用のリポジトリを作成して、自動更新を仕込みます。
mkdir -p ~/rclone/vault/svn
svnadmin create ~/rclone/vault/svn/media
cd ~/rclone/media
svn checkout http://localhost/svn/media . --force --username "$(hostname)"
svn add --depth=empty DCIM
svn add --depth=empty Movies
svn propset svn:ignore ".tmfs" DCIM
svn propset svn:ignore ".thumbnails" Movies
svn add --force DCIM
svn add --force Movies
svn commit -m "Initial commit"
ssh server-ssh '
cd ~/rclone/media && \
svn info --show-item url && \
svn update && \
svn add --force DCIM && \
svn add --force Movies && \
svn commit -m "Auto commit"
exit 0
'
7. その他のセットアップ
7.1 クライアントの設定
以下のソフトウェアを使用します。
Git
Subversion
Rabbitvcs-core
Nemo-python
mkdir -p ~/.local/share/nemo-python/extensions
cd ~/.local/share/nemo-python/extensions
curl -fLO \
https://raw.githubusercontent.com/rabbitvcs/rabbitvcs/master/clients/nemo/RabbitVCS.py
Git for Windows - https://gitforwindows.org/
TortoiseGit - https://tortoisegit.org/
TortoiseSVN - https://tortoisesvn.net/
7.2 Debianイメージのコピー
以下の設定とコマンドでファイルのコピーを行います。
[active-sftp]
type = sftp
host = 192.168.x.x
user = ユーザ名
key_file = ~/.ssh/id_ed25519
rclone copy \
active-sftp:qemu/debian-amd64/debian-13-nocloud-amd64.qcow2 \
~/qemu/debian-amd64/ \
-P
rclone copy `
"active-sftp:qemu/debian-amd64/debian-13-nocloud-amd64.qcow2" `
"C:/qemu/debian-amd64/" `
-P
7.3 暗号化フォルダの同期
以下の設定とコマンドでフォルダの同期を行います。
[termux-sftp]
type = sftp
host = 192.168.x.x
user = u0axxx
port = 8022
key_file = ~/.ssh/id_ed25519
[backup-sftp]
type = sftp
host = 192.168.x.x
user = u0axxx
port = 8022
key_file = ~/.ssh/id_ed25519
rclone sync \
termux-sftp:symlink/vault/.vault \
backup-sftp:symlink/vault/.vault \
-P --transfers 1 --checkers 1 --sftp-concurrency 1
rclone sync `
"termux-sftp:symlink/vault/.vault" `
"backup-sftp:symlink/vault/.vault" `
-P --transfers 1 --checkers 1 --sftp-concurrency 1
8. おわりに
究極の自己満足サーバが爆誕しました!手順を読み返してみると、手数がなかなか酷いことになっています。サーバ運用が落ち着いたら、技術的なポイントを個別の記事に切り出してみようかと。忘れた頃にこの記事を参照するのはつらいのでw
| ◀️ 前の記事 | 次の記事 ▶️ |
|---|---|
| セキュアサーバに、なりたいな「ハイ!rclone crypt」⑧WebサーバをPCに移設する | 準備中 |