
日常生活で便利なアプリを作る【サーバ編】
前回の 設計編 では、アプリ (モナホーム) のざっくりとした構想をご紹介しました。
今回は、アプリを運用するためのサーバ構築とVPN環境の整備についてを サーバ編 としてご紹介します。
- 日常生活で便利なアプリを作る【設計編】
- 日常生活で便利なアプリを作る【サーバ編】 ← 今回
- 日常生活で便利なアプリを作る【コンテナ編】
- 日常生活で便利なアプリを作る【アプリ編】
- 日常生活で便利なアプリを作る【運用編】
- 日常生活で便利なアプリを作る【まとめ】
作業環境
これから紹介する作業は以下の環境で行いました。
項目 | 内容 |
---|---|
PC | MacBook Pro (macOS 15.3.2) |
プロバイダー | auひかり |
ホームルータ | HGW-BL1500HM |
Wi-Fi ルータ | TP-Link Archer BE805 |
方針
- 自宅に 常時稼働のサーバ を構築
- WireGuard を用いて VPN経由でのみ でアクセス
- 基本的には Dockerコンテナ で運用したい
- HTTPS対応
- 独自ドメイン運用
サーバ構成
当初は Raspberry Pi 5 にする予定でしたが、本体価格だけでも 2万円オーバー。
ストレージや冷却対策などを足すとそれなりの構成になります。
諦めかけていたときに見つけたのが インテル プロセッサー N100 です。
省電力なのに普段使いには十分な性能が魅力で、ファンレス で発熱を抑えられるため、静音・常時稼働に最適 と判断。
Amazonで調べると3万円程度で Windows 11 Pro を搭載した中国メーカーのミニPCが数多く販売されていました。
今回はWindowsを使わない予定だったこと、また信頼性の面でやや不安があったため オンボードマザーボード を探しました。
最終的に選んだ自作サーバのパーツはこちら。
種類 | 製品名 |
---|---|
MB | ASRock N100DC-ITX |
RAM | CFD DDR4-3200 16GB ×1枚 |
SSD | シリコンパワー M.2 NVMe SSD 512GB |
OS | Ubuntu Server 22.04 LTS |
電源 | エレコム ACDC-1965NECK ACアダプター |
ケース | RGEEK Mini ITX 小型アルミPCケース |
SATAは2つ あるので、ストレージの増設も可能です。
ただし、65Wを超えそうな場合はACアダプタを買い替える必要があります。
ASUSも似たようなオンボードマザーボードを販売していましたが、通常の電源ユニットを使う必要がありました。
SFX電源ユニットはお高いので断念。
将来的には HDD を2台追加してRAIDでも組もうかなと思っています。
NASとしても使いたいところ…。
費用
約 37,000円
性能を考えると妥当な価格かと思います。
組み立て
組み立ては簡単で マザーボードにメモリとストレージを取り付けるだけ。
ファンレスでも問題ないCPUですが、意外と熱を持つので 120mm ファン を取り付けました。
ネジ固定できないので粘着テープで固定。
蓋をすれば…
あっという間に完成!
配線が少ないのはいいですね。
OSのインストール
OSは Ubuntu Server 24.04.2 LTS を選択しました。
インストーラーの作成方法やインストール手順については、本記事では割愛します。
サーバの環境構築
VPN環境を構築するためにサーバの環境を整えます。
1. SSH接続
インストール時にSSHを有効にしていれば、特に追加で設定する必要はなかったです。
サーバにモニターとキーボードを接続して IPアドレス を確認します。
ip route get 1.1.1.1 | grep -oP 'src \K[0-9.]+'
[ここに表示されます]
Mac に移動してSSH接続します。
ssh [USER_NAME]@[IP_ADDRESS]
2. IPアドレスの固定
DHCP で動的にIPアドレスを取得しているため、サーバのIPアドレスが変わると接続できなくなります。
そのため、ルータ側でIPアドレスを固定しました。
サーバのMACアドレスを確認するには、以下のコマンドを実行します。
ip -o link show | awk '{print $2, $17}' ─╯
lo: 00:00:00:00:00:00
enp1s0: [ここに表示されます]
ルータの設定画面にアクセスして、DHCPの設定から MACアドレスを指定してIPアドレスを固定 にすればOKです。
ルータの設定画面はルータの機種によって異なります。
3. SSHの公開鍵認証
毎回パスワードを入力するのは面倒なので、公開鍵認証を設定します。
ssh-keygen -t ed25519 -C "[USER_NAME] key"
~/.ssh/id_ed25519
に秘密鍵、~/.ssh/id_ed25519.pub
に公開鍵が生成されます。
続いて 公開鍵をサーバにコピー します。
ssh-copy-id -i ~/.ssh/id_ed25519.pub [USER_NAME]@[IP_ADDRESS]
これでサーバにSSH接続する際にパスワードを入力せずに済むようになります。
4. SSHの効率化
毎回IPアドレスを入力するのは面倒なので、SSHの設定ファイルにホスト名を登録します。
vim ~/.ssh/config
以下のようにホスト名を登録します。
Host home-server
HostName [ip_address]
User [user]
IdentityFile [~/.ssh/...id_rsa]
これで以下のコマンドで接続できるようになります。
ssh home-server
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-57-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Sat Apr 5 01:03:10 PM JST 2025
...
5. 便利なツールのインストール
サーバを運用する上で便利なツールをインストールします。
名称 | 説明 |
---|---|
zsh | シェル |
oh-my-zsh | zshの拡張 |
htop | プロセス監視ツール |
bottom | プロセス監視ツール |
vim | エディタ |
docker | コンテナ管理ツール |
docker compose | コンテナ管理ツール |
git | バージョン管理ツール |
ufw | ファイアウォール |
wireguard | VPN |
volta | Node.jsのバージョン管理 |
tmux | ターミナルマルチプレクサ |
lsd | lsの拡張 |
bat | catの拡張 |
fd | findの拡張 |
ripgrep | grepの拡張 |
zoxide | cdの拡張 |
fzf | コマンドラインファジングツール |
httpie | HTTPクライアント |
jq | JSONパーサ |
fail2ban | SSHブルートフォース対策 |
nmap | ネットワークスキャナ |
ufw | ファイアウォール |
最近は Rust 製のツールが多いですね。
機会があれば書いてみたいところです。
これらの詳細は機会があれば別記事にまとめます。
6. ルータをブリッジモードにする
我が家は auひかり のルータ の後ろに TP-Link のルータを接続しています。
このままだと 2重ルータ になってしまうため、TP-Linkのルータをブリッジモードにします。
TP-Link のアプリから簡単にできました。
- Tether アプリを開く
- フッターメニューから「もっと」を選択
- 「動作モード」を選択
- 「アクセスポイントモード」を選択
7. DDNSを構成する
何もしないと グローバルIPアドレスが変わってしまう ため、固定する必要があります。
本来 TP-Link のルータを使っている場合は 無料で DDNS を利用できる のですが、 ブリッジモードにしているので利用できません。
有料のDDNSサービスは使いたくないので Cloudflare を利用します。
https://github.com/favonia/cloudflare-ddns
今回は、cloudflare-ddns を使用してDDNSを構成します。
Dockerコンテナを起動するだけ。
とても簡単です。
cloudflare-ddns:
container_name: cloudflare-ddns
image: favonia/cloudflare-ddns:latest
network_mode: host
restart: always
environment:
- CLOUDFLARE_API_TOKEN=[YOUR_CLOUDFLARE_API_TOKEN]
- DOMAINS=[YOUR_DOMAIN]
- PROXIED=false
- IP6_PROVIDER=none
- CACHE_EXPIRATION=1h
- TZ=Asia/Tokyo
8. ポートの開放
外出先でVPNが利用できるように WireGuardの ポート開放 をします。
WireGuardのポートは デフォルトで51820 です。
なので、UDPのポート 51820 を開放し、NATでサーバのローカルIPアドレスに転送する設定を行います。
ルータの設定画面はルータの機種によって異なります。
9. WireGuardの接続
サーバとクライアントでそれぞれキーを生成します。
サーバ側のキーの生成
wg genkey | tee server_private | wg pubkey > server_public
クライアント側のキーの生成
wg genkey | tee iphone16-pro-max_private | wg pubkey > iphone16-pro-max_public
名前は適当で大丈夫です。
private.key は秘密鍵なので、私以外のユーザには見えないようにします。
chmod 600 *_private.key
最終的にはデバイスごとに用意しました。
lsd ─╯
.rw------- souta-konno souta-konno 45 B Sat Apr 5 14:22:25 2025 ipad-mini_private.key
.rw-rw-r-- souta-konno souta-konno 45 B Sat Apr 5 14:22:25 2025 ipad-mini_public.key
.rw------- souta-konno souta-konno 45 B Thu Apr 3 23:34:29 2025 iphone16-pro-max_private.key
.rw-rw-r-- souta-konno souta-konno 45 B Thu Apr 3 23:34:29 2025 iphone16-pro-max_public.key
.rw------- souta-konno souta-konno 45 B Thu Apr 3 23:34:22 2025 iphone16-pro_private.key
.rw-rw-r-- souta-konno souta-konno 45 B Thu Apr 3 23:34:22 2025 iphone16-pro_public.key
.rw------- souta-konno souta-konno 45 B Thu Apr 3 23:31:03 2025 iphone_private.key
.rw-rw-r-- souta-konno souta-konno 45 B Thu Apr 3 23:31:03 2025 iphone_public.key
.rw------- souta-konno souta-konno 45 B Thu Apr 3 23:25:29 2025 server_private.key
.rw-rw-r-- souta-konno souta-konno 45 B Thu Apr 3 23:25:29 2025 server_public.key
サーバ側の設定
WireGuardのサーバ側の設定を行います。
vimで設定ファイルを作成して接続情報を記載します。
sudo vim /etc/wireguard/wg0.conf
[Interface]
Address = [YOUR_WIREGUARD_SERVER_IP]/24
ListenPort = 51820
PrivateKey = [YOUR_SERVER_PRIVATE_KEY]
[Peer]
PublicKey = [YOUR_CLIENT_PUBLIC_KEY]
AllowedIPs = [YOUR_WIREGUARD_CLIENT_IP]/24
PersistentKeepalive = 25
モバイル回線やNAT環境では一定時間で通信が切断される可能性があるため、PersistentKeepalive = 25
を設定しています。
YOUR_WIREGUARD_SERVER_IP
は VPNトンネルのIPアドレス です。
私は 10.0.0.1/24
にしました。
YOUR_WIREGUARD_CLIENT_IP
は許可するクライアントの VPNトンネルのIPアドレス です。
私は接続順に連番でつけました。
クライアント側の設定
テキストエディタなどを使って設定ファイル home-server.conf
を作成し、QRコードやAirDropなどでiPhoneにインポートできるようにします。
iPhoneにはApp Storeから WireGuard をインストールしておきます。
[Interface]
PrivateKey = [YOUR_CLIENT_PRIVATE_KEY]
Address = [YOUR_WIREGUARD_CLIENT_IP]/24
DNS = 1.1.1.1
[Peer]
PublicKey = [YOUR_SERVER_PUBLIC_KEY]
Endpoint = [YOUR_DDNS_IP]:51820
AllowedIPs = 192.168.0.0/32
PersistentKeepalive = 25
YOUR_DDNS_IP
は Cloudflareで設定したDDNSのホスト名 を指定します。
今回は VPN 上で稼働している Webサービス にアクセスできれば良く、その他の通信は VPN を通す必要はなかったので
AllowedIPs
は 内部のIPアドレスを指定 しました。
全て VPN を経由したい場合は0.0.0.0/0
を指定します。
.conf
が完成したら、私はそのまま AirDrop でiPhoneに転送しました。
サーバ側の起動
sudo systemctl start wg-quick@wg0
クライアント側の起動
iPhoneで WireGuard を起動して取り込んだ設定ファイルを選択します。
接続ボタンを押すと、VPN接続が確立されます👏
10. 外出先でSSH
iPhoneのWi-Fiを切断し、モバイルデータ通信に切り替えます。
VPNを接続してサーバにSSH接続できるか確認します。
繋がれば外出先からVPN経由で自宅サーバに接続できるようになりました!
11. セキュリティ対策
念のため、以下のセキュリティ対策を実施しました。
UFWの設定
ファイアウォールを設定して、不必要なポートは全て遮断 します。
以下のコマンドを実行してUFWを有効にします。
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 51820/udp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
動いているかは以下のコマンドで確認できます。
sudo ufw status verbose
fail2banの設定
SSHのブルートフォース攻撃を防ぐために、fail2ban を設定します。
sudo apt install fail2ban
/etc/fail2ban/jail.local
に設定を追加します。
sudo vim /etc/fail2ban/jail.local
今回は、SSHへのログイン試行が5回失敗した場合に IPをブロック するように設定しました。
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 5
fail2banを再起動して設定を反映します。
sudo systemctl restart fail2ban
最後に
以上で、サーバの構築とVPN環境の構築が完了しました。
次は コンテナ編 に進みます。
Dockerを用いた実行環境の構築を行います。
最後までお読みいただきありがとうございました!