メインコンテンツへスキップ
  1. 記事/

WireGuardでセルフホストサービスを保護する方法

Ixonae
著者
Ixonae
目次

注意: この記事は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 ACCEPT

VPNを使ってインターネットに接続できるようにしたい場合は、以下のコマンドが使えます(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...をクリックすると、以下の画面が表示されるはずです(クライアントが自動的に鍵ペアを生成してくれます)。

Adding an empty tunnel from the WireGuard client
WireGuardクライアントから空のトンネルを追加

設定を以下のように変更します(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 = 25

AddressはVPNネットワーク内でのクライアントIPになります。AllowedIPsオプションにより、VPN経由でどのIPアドレスにアクセスするかを指定できます。ここではVPNネットワークにアクセスしたいだけですが、すべてのトラフィックをVPN経由にしたい場合は0.0.0.0/0と記述する必要があります。

設定を保存しますが、サーバー側の設定でクライアントを許可する必要があるため、まだ接続は機能しません。

サーバー側の設定
#

サーバー側の設定は非常にシンプルです。/etc/wireguard/wg0.confファイルを編集し、以下の行を追加するだけです:

[Peer]
PublicKey = eF3ZRuLDG9Ih5yxTFLyGyosx4qlAvad388ITieSwL34=
AllowedIPs = 10.90.0.2/32

AllowedIPsはクライアントに割り当てたいアドレス(ここでは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 running

WireGuardサーバーを再起動したくない場合は、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=" remove

WireGuardの活用
#

動作するサーバーができたので、サービスを外部からアクセスできないようにすることができます。

最もセキュアな管理方法は、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アドレスでクライアントを追加します(前のパート「クライアントの設定/サーバー側の設定」を参照)。

VPN / WireGuard / Tunnels / Add Tunnel
VPN / WireGuard / Tunnels / Add Tunnel

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

VPN / WireGuard / Tunnels
VPN / WireGuard / Tunnels

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

VPN / WireGuard / Peers / Add Peer
VPN / WireGuard / Peers / Add Peer

変更を保存して適用します。また、Settingsメニューに移動してWireGuardを有効にすることを忘れないでください。すべてが完了したら、Status / Wireguardメニューでトンネルが動作していることを確認できるはずです。

関連トラフィックをWireGuard経由でルーティングする
#

動作するトンネルができたので、10.90.0.0/24へのすべてのトラフィックをリダイレクトします。

Interfaces / Interface AssignmentsWG1という名前のインターフェースを作成し、以下のように設定します:

Interfaces / Interface Assignments
Interfaces / Interface Assignments
Interfaces / WG1
Interfaces / WG1

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

System / Routing / Gateways
System / Routing / Gateways

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

Firewall / NAT / Outbound rule
Firewall / NAT / Outbound rule

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

Firewall / Rules / LAN -&gt; new Rule
Firewall / Rules / LAN -> new Rule

DNSリゾルバー
#

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

Services / DNS Resolver / General Settings / Host Override
Services / DNS Resolver / General Settings / Host Override

ソース
#

クレジット
#