注意: この記事はLLMによって英語から翻訳されたものです。正確性については保証いたしかねますので、あらかじめご了承ください。英語の原文はこちら。
セルフホスティングは素晴らしいですが、問題があります。新しいサービスをインストールすればするほど、サーバーの攻撃対象面が増え、ハッキングされるリスクを避けるためにアップデートなどにより注意を払う必要があります。
この記事では、セルフホストサービスにさらなるセキュリティをもたらし、迅速なアップデートの必要性に対するストレスを軽減する方法の一つを紹介します。サービスをインターネットに直接公開せずに、簡単にアクセスできるようにします。これを実現するために、WireGuardサーバーを設定し、接続方法を説明し、未接続ユーザーがサービスにアクセスできないよう制限し、pfSenseを使用してローカルネットワーク内のすべてのマシンからサーバー上のサービスにアクセスできるようにします。
なお、VPNサーバーと保護したいサービスが同じサーバー上にあることを前提としています。そうでない場合は、ファイアウォールの設定を少し調整する必要があります。
WireGuardサーバーのインストール#
最初のステップは、WireGuardサーバーをインストールし、公開鍵/秘密鍵のペアを生成することです。
sudo apt-get install wireguard
cd /etc/wireguard
umask 077
wg genkey > wg0.key
wg pubkey < wg0.key > wg0.pub次に、以下の設定で/etc/wireguard/wg0.confファイルを作成します。Addressフィールドを使用して、VPNに接続するクライアントのIPが10.90.0.2から10.90.0.254の間になるよう定義していますが、お好みの範囲を使用できます(既に使用されている範囲と重複しないよう注意してください)。
[Interface]
PostUp = wg set %i private-key /etc/wireguard/%i.key
Address = 10.90.0.1/24
ListenPort = 51822これが完了したら、systemdサービスを追加し、サーバーを起動し、正常に動作していることを確認します:
sudo systemctl enable wg-quick@wg0.service
sudo systemctl start wg-quick@wg0.service
sudo systemctl status wg-quick@wg0.service今回のケースでは、VPNをインターネットアクセスに使用しないため、クライアントがサーバーに接続できるようにWireGuardポートを開放するだけで十分です。
sudo iptables -t filter -A INPUT -p udp --dport 51822 -j ACCEPTVPNを使ってインターネットに接続できるようにしたい場合は、以下のコマンドが使えます(eth0はインターネット接続に使用しているインターフェース名に置き換えてください)。
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o eth0 -j MASQUERADEクライアントの設定#
クライアント側の設定#
次に、サーバーに正しく接続できるかテストしましょう。WireGuardクライアントでAdd Empty Tunnel...をクリックすると、以下の画面が表示されるはずです(クライアントが自動的に鍵ペアを生成してくれます)。

設定を以下のように変更します(A.B.C.DをサーバーのIPアドレスに置き換えてください)。
[Interface]
PrivateKey = KCMvn8yRUHBhI5RbIr/iZJn4X3BvjwsNdLmEDKFIaGg=
Address = 10.90.0.2/32
[Peer]
PublicKey = [Paste the content of the server's /etc/wireguard/wg0.pub]
AllowedIPs = 10.90.0.0/24
Endpoint = A.B.C.D:51822
PersistentKeepalive = 25AddressはVPNネットワーク内でのクライアントIPになります。AllowedIPsオプションにより、VPN経由でどのIPアドレスにアクセスするかを指定できます。ここではVPNネットワークにアクセスしたいだけですが、すべてのトラフィックをVPN経由にしたい場合は0.0.0.0/0と記述する必要があります。
設定を保存しますが、サーバー側の設定でクライアントを許可する必要があるため、まだ接続は機能しません。
サーバー側の設定#
サーバー側の設定は非常にシンプルです。/etc/wireguard/wg0.confファイルを編集し、以下の行を追加するだけです:
[Peer]
PublicKey = eF3ZRuLDG9Ih5yxTFLyGyosx4qlAvad388ITieSwL34=
AllowedIPs = 10.90.0.2/32AllowedIPsはクライアントに割り当てたいアドレス(ここでは10.90.0.2)で、公開鍵はWireGuardクライアントが生成したものです。
設定を保存したら、サーバーを再起動すれば接続できるようになるはずです。
# Server side
sudo systemctl restart wg-quick@wg0.service
# Client side to test the connection
ping 10.90.0.1
curl http://10.90.0.1 # If you have a web server runningWireGuardサーバーを再起動したくない場合は、wgコマンドを使用するオプションがあります。ただし、これは何も保存しないため、設定ファイルの編集は必要です。そうしないと、次にサーバーを再起動した際に設定が失われます。
# To add a client
wg set wg0 peer "eF3ZRuLDG9Ih5yxTFLyGyosx4qlAvad388ITieSwL34=" allowed-ips 10.90.0.2/32
# To remove a client
wg set wg0 peer "eF3ZRuLDG9Ih5yxTFLyGyosx4qlAvad388ITieSwL34=" removeWireGuardの活用#
動作するサーバーができたので、サービスを外部からアクセスできないようにすることができます。
最もセキュアな管理方法は、SSHとWireGuardのINPUTポートのみを開放することです。これにより攻撃対象面が非常に小さくなります。サービスにはIP10.90.0.1でアクセスできます。
しかし、VPNアクセスを必要とせずに第三者と何かを共有したい場合があるとしましょう。このようなシナリオでは、Apacheインスタンスをインターネットに公開しますが、Virtual Hostで以下のApache設定を使用します。VPN経由で接続しているか、mygroupグループのユーザーでログインすることを要求します。
<Location />
Require all denied
AuthType Basic
AuthName "Password Required"
AuthUserFile "/path/to/htpasswd"
AuthGroupFile "/path/to/htgroup"
<RequireAny>
Require ip 10.90.0.0/24
Require group mygroup
</RequireAny>
</Location>これの利点は、サーバーを使用する際にBasicAuthに煩わされないこと、また悪意のある攻撃者がパスワードの背後にあるサービスを悪用するリスクを軽減できることです。
pfSenseの設定#
これはすべて素晴らしいですが、すべてのデバイスでWireGuardを設定するのは面倒です。ホームネットワーク内のすべてのデバイスから、サーバーでホストしているサービスにアクセスできるようにできたらどうでしょうか?
pfSenseをお使いの場合、WireGuardトンネルを作成してルーティング設定を行うことで、これを実現できます。(pfSenseのセットアップに関するこちらの記事も参考になるかもしれません。)
WireGuardトンネルの設定#
まず、System/Package Manager/Available Packagesに移動してWireGuardをインストールします。
次に、VPN/WireGuard/Tunnelsで接続を設定します。Add Tunnelをクリックし、Interfaceアドレスを10.90.0.3/32に設定して鍵ペアを生成します。インターフェースを保存し、サーバーにログインしてこの公開鍵とIPアドレスでクライアントを追加します(前のパート「クライアントの設定/サーバー側の設定」を参照)。

インターフェースを作成した後、トンネル一覧に以下の画面が表示されるはずです。

次に、Actions列のAdd Peerアイコンをクリックし、以下のようにPeerを設定します。

変更を保存して適用します。また、Settingsメニューに移動してWireGuardを有効にすることを忘れないでください。すべてが完了したら、Status / Wireguardメニューでトンネルが動作していることを確認できるはずです。
関連トラフィックをWireGuard経由でルーティングする#
動作するトンネルができたので、10.90.0.0/24へのすべてのトラフィックをリダイレクトします。
Interfaces / Interface AssignmentsでWG1という名前のインターフェースを作成し、以下のように設定します:


Add a new gatewayをクリックしてIP10.90.0.3のゲートウェイを作成する必要があります。インターフェースの変更を保存したら、System / Routing / Gatewaysに移動して正しく作成されたことを確認できます。

次に、Firewall / NAT / OutboundでOutbound NATルールを作成します。このルールがインターネットに到達するインターフェースのルールよりも前にあることを確認する必要があります。

最後に、Firewall / Rules / LANで以下のルールを追加します。NATと同様に、トラフィックをWANおよびVPNゲートウェイにリダイレクトするルールよりも前にある必要があります。

DNSリゾルバー#
前述のApache設定のようなものを使用している場合、少し問題があります:DNSエントリがサーバーの内部VPN IPではなく、サーバーのIPアドレスを指しているためです。これを修正する一つの方法は、pfSenseのDNSリゾルバーを使用することです。例えば、git.me.comとcalendar.me.comをVPNネットワーク経由でアクセスしたい場合、Host Overrideを追加して以下のように設定できます。

ソース#
- Using the VPN as the default gateway(Ubuntuドキュメント)
- Wireguard Client Addition without restart(ServerFault)
クレジット#
- カバー画像: Peter Albanese(Unsplash)