WireGuardのPrivateネットワークのみ許可したウェブサイトホスト

by haturatu

4 min read

こんにちは、無能です。
adminページがパブリックに公開されているとあまりよろしくないですが私の場合現在はadminページに関してはWireGuardのプライベートIPのみ許可しています。その設定の仕方です。

WireGuard側の設定

つまりは複数クライアントを使っている状態になっています。

クライアント側

この場合、wg0の場合はAllowedIPs = 0.0.0.0/0, ::/0なので全てのトラフィックをWireGuardネットワークを通ります。
ただし、この場合はサーバ側でこの10.1.0.22に対してはサーバ側のNATを通すルールを記載する必要があります。なぜならそのままだと、このIPはWireGuardのプライベートネットワークから出ることができない為です。
簡易的に要約するとこうなります。

  • wg0
    • 全てのネットワークを通る
    • 内部DNSに問い合わせる
    • WireGuardサーバ側でNATを通すルールを記載しないと出れない
  • wg1
    • WireGuardのプライベートIPのみをルーティングする
      • 10.1.0.0/24のCIDR値の範囲内のみ通す
    • 内部DNSに問い合わせる

wg0.conf :

[Interface]
PrivateKey = Client Private Key
Address = 10.1.0.22/24
DNS = 10.1.0.1

[Peer]
PublicKey = Server PubKey
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = WireGuard Server Endpoint:51820
PreSharedKey = PreSharedKey

wg1.conf :

[Interface]
PrivateKey = Client Private Key
Address = 10.1.0.21/24
DNS = 10.1.0.1

[Peer]
PublicKey = Server PubKey
AllowedIPs = 10.1.0.0/24
Endpoint = WireGuard Server Endpoint:51820
PreSharedKey = PreSharedKey

サーバ側

[Interface]
ListenPort = 51820
Address = 10.1.0.1/24
PrivateKey = Server PrivKey

~~~

[Peer] 
PublicKey = Client PubKey
PreSharedKey = PreSharedKey
AllowedIPs = 10.1.0.21/32
PersistentKeepalive = 25

[Peer] 
PublicKey = Client PubKey
PreSharedKey = PreSharedKey
AllowedIPs = 10.1.0.22/32 
PersistentKeepalive = 25

こうなります。

WireGuardサーバ側のNATルール

これはBSD系の特権ですがpfでNATルールを記載します。

# 変数定義
wireguard_clients="{ 10.1.0.4, 10.1.0.22 }"
wanint="vtnet0"
wg_ports="{51820}"

# $wireguard_clients から出てくるトラフィックを、WAN インターフェース($wanint)の IP に書き換えてインターネットに出す
# NAPTの設定
nat on $wanint inet from $wireguard_clients to any -> $wanint

# 外部から WAN 側に来る WireGuard の接続(UDP 51820)を許可
pass in on $wanint proto udp from any to $wanint port $wg_ports

これによって、WireGuardのプライベートIP自体がWireGuardサーバ側のNATを通ることができるようになります。

Nginxの設定

a.soulminingrig.comがこのサイトのLumeCMS自体のAdminページ自体の設定です。
allow 10.1.0.0/16;でWireGuardネットワークのみ許可し、それ以外はdeny all;します。

server {
    listen 80;
    server_name a.soulminingrig.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name a.soulminingrig.com;
    client_max_body_size 500M;

    location / {
        allow 10.1.0.0/16;
	    deny all;

        proxy_pass http://10.1.0.20:3001/;
        include proxy_headers.conf;
        proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504 http_403 http_404;
        proxy_connect_timeout 3s;
        proxy_read_timeout 15s;
    }
    include common_error_pages.conf;
    include ssl_common.conf;

    ssl_certificate /usr/local/etc/letsencrypt/live/a.soulminingrig.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /usr/local/etc/letsencrypt/live/a.soulminingrig.com/privkey.pem; # managed by Certbot
}

なぜ、NATルールを記載しているのにWireGuardサーバ側のPublic IPとして認識されずにIP制限かけれるの?

という質問があるかもしれません。
(勝手に作った)

NATルールにはこう記載しています。

nat on $wanint inet from $wireguard_clients to any -> $wanint

つまりは、on $wanintということはWAN インターフェースを通るパケットにのみ NAT を適用されます。
ちょっとややこしいですが、わかりやすいようにifconfigしてみましょう。

vtnet0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4c079b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,TXCSUM_IPV6>
        ether aa
        inet aa netmask 0xfffffe00 broadcast aa
        inet6 aa prefixlen 64 scopeid 0x1
        inet6 aa prefixlen 64
        media: Ethernet autoselect (10Gbase-T <full-duplex>)
        status: active
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
pflog0: flags=0 metric 0 mtu 33152
        options=0
        groups: pflog
wg0: flags=10080c1<UP,RUNNING,NOARP,MULTICAST,LOWER_UP> metric 0 mtu 1420
        options=80000<LINKSTATE>
        inet 10.1.0.1 netmask 0xffffff00
        groups: wg
        nd6 options=109<PERFORMNUD,IFDISABLED,NO_DAD>

そう、あくまでWireGuardは仮想NICなのでWireGuard上の場合のインターフェイスはwg0です。
この場合、wg0を通ってくるため proxy_pass10.1.0.20:3001であればこの仮想NIC経由でパケットが通ることになります。

10.1.0.22 -> allow 10.1.0.0/16(10.1.0.0 ~ 10.1.255.255)のルールにマッチする -> Nginxのproxy_pass10.1.0.20なのでプライベートネットワーク内で完結する
この間、wg0上の仮想NIC内で全て完結しているためこのプライベート通信が可能となります。

終わりに

と、いう訳ですがいかがでしょうか?
実際、GNU/Linuxのルール記載が個人的に嫌いなのでBSD系のpfはこういう意味でもめちゃくちゃ楽なのですが・・・。
それではまた。よろしくお願いします。

PGP --- Contact --- Machines --- cat -v