戻る
トップページに戻る
Logo
Gadget Blossom 略してガジェブロ
日常生活で便利なアプリを作る【サーバ編】

日常生活で便利なアプリを作る【サーバ編】


前回の 設計編 では、アプリ (モナホーム) のざっくりとした構想をご紹介しました。

今回は、アプリを運用するためのサーバ構築とVPN環境の整備についてを サーバ編 としてご紹介します。

作業環境

これから紹介する作業は以下の環境で行いました。

項目内容
PCMacBook 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を使わない予定だったこと、また信頼性の面でやや不安があったため オンボードマザーボード を探しました。

最終的に選んだ自作サーバのパーツはこちら。 サーバを作るパーツたち

種類製品名
MBASRock N100DC-ITX
RAMCFD DDR4-3200 16GB ×1枚
SSDシリコンパワー M.2 NVMe SSD 512GB
OSUbuntu 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です。

IPアドレスの固定化 ルータの設定画面はルータの機種によって異なります。

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-zshzshの拡張
htopプロセス監視ツール
bottomプロセス監視ツール
vimエディタ
dockerコンテナ管理ツール
docker composeコンテナ管理ツール
gitバージョン管理ツール
ufwファイアウォール
wireguardVPN
voltaNode.jsのバージョン管理
tmuxターミナルマルチプレクサ
lsdlsの拡張
batcatの拡張
fdfindの拡張
ripgrepgrepの拡張
zoxidecdの拡張
fzfコマンドラインファジングツール
httpieHTTPクライアント
jqJSONパーサ
fail2banSSHブルートフォース対策
nmapネットワークスキャナ
ufwファイアウォール

最近は Rust 製のツールが多いですね。
機会があれば書いてみたいところです。

これらの詳細は機会があれば別記事にまとめます。

6. ルータをブリッジモードにする

我が家は auひかり のルータ の後ろに TP-Link のルータを接続しています。
このままだと 2重ルータ になってしまうため、TP-Linkのルータをブリッジモードにします。

TP-Link のアプリから簡単にできました。

  1. Tether アプリを開く
  2. フッターメニューから「もっと」を選択
  3. 「動作モード」を選択
  4. 「アクセスポイントモード」を選択

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_IPVPNトンネルの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_IPCloudflareで設定したDDNSのホスト名 を指定します。

今回は VPN 上で稼働している Webサービス にアクセスできれば良く、その他の通信は VPN を通す必要はなかったので AllowedIPs内部のIPアドレスを指定 しました。
全て VPN を経由したい場合は0.0.0.0/0 を指定します。

.conf が完成したら、私はそのまま AirDrop でiPhoneに転送しました。

サーバ側の起動

sudo systemctl start wg-quick@wg0

クライアント側の起動

iPhoneで WireGuard を起動して取り込んだ設定ファイルを選択します。
接続ボタンを押すと、VPN接続が確立されます👏 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を用いた実行環境の構築を行います。

最後までお読みいただきありがとうございました!

モナ