💡

wireguard VPN構築 nftableの設定 ufwは無効化

に公開

WireGuardで「ハンドシェイクはできるがDNS解決できずインターネットに出られない」という症状悩まされ試行錯誤。

  1. サーバー側のNAT (マスカレード) 設定に問題あり?

Ubuntu 24 以降は iptables より nftables ベースの ufw/netfilter がメインになっていて、従来のiptables設定例をそのまま流用すると動かないことがある様子


確認すること(WireGuardサーバー側)

  1. IP転送を有効化
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1

恒久化するなら /etc/sysctl.conf に以下を追加

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

これでもまだつながらない


  1. NAT (マスカレード) 設定 (nftables)確認

まず現在のテーブルを確認

sudo nft list ruleset

WireGuardインターフェイスが wg0、VPSの出口が eth0 だと仮定すると、以下を追加します

sudo nft add table ip nat
sudo nft 'add chain ip nat POSTROUTING { type nat hook postrouting priority 100 ; }'
sudo nft add rule ip nat POSTROUTING oifname "eth0" ip saddr 10.6.0.0/24 counter masquerade

10.6.0.0/24 → WireGuardで設定したアドレスレンジに合わせる

eth0 → VPSの外向きNICに置き換える

NICは ip a で確認

保存して永続化:

sudo sh -c "nft list ruleset > /etc/nftables.conf

これでもまだできない


  1. 最近のUbuntuなら確認すべきこと

NATルールがiptables前提で設定していると、Ubuntu 25では無視されることも

AllowedIPs が 10.6.0.0/24 のみ だと、サーバーアクセスはできるがインターネットに出られない

DNSを指定していないと、ハンドシェイクは通るけど名前解決できない


クライアントは AllowedIPs = 0.0.0.0/0 で全トラフィックをVPNへ流す設定になっているのに、名前解決できない → インターネットに出られない。
この場合 WireGuard自体はOKだけど、サーバーのパケット転送 or NAT がうまくいってない 可能性が高い。
さらに Ubuntu 24/25 系だと ufw と nftables が混在して「iptablesのつもりで書いたルールが効かない」トラブルあり。


  1. 切り分け手順

VPN内での疎通確認

クライアントから

ping 10.6.0.1

サーバーのwg0アドレス
これが通るなら WireGuard トンネルは正常。

次に

ping 8.8.8.8

これが通らなければ NAT/ルーティングが原因

ping google.com 

これがダメなら DNS 設定の問題。


  1. ufw を使っている場合

まずは ufwを一時的に無効化 して VPN が通るか確認

sudo ufw disable

自分はこれでVPNからインターネットに出れるようになりました

つまり WireGuard自体は正しく動いていて、ufwがNATやフォワードをブロックしていた という状況です。


  1. 対処の方向性

ufwを無効にするのは一番簡単ですが、実運用ではセキュリティ的に微妙です。

Ubuntu 24/25(nftablesベース)の場合:

Ubuntu 24以降は ufw が nftables を使っているため、上記ルールは無視されるケースが多い様子
この場合は /etc/ufw/before6.rules や /etc/ufw/before.nft に追加するか、素直に nftables で直接マスカレードを設定した方が安定します。


実用的な回避策

セキュリティを ufw に任せず、nftables で直接管理する


nftables で WireGuard 用ファイアウォールを構築する流れ

  1. ufw を完全に無効化
sudo systemctl disable --now ufw

  1. nftables 基本設定

設定ファイルを編集

/etc/nftables.conf

既存のルールを全消去して最小構成にする場合

table inet filter {
    chain input {
        type filter hook input priority 0;

        # 既存の接続は許可
        ct state established,related accept

        # ループバック
        iifname "lo" accept

        # WireGuard ポート許可
        udp dport 51820 accept

        # SSH (必要ならポート番号を調整)
        tcp dport 22 accept

        # その他は拒否
        reject with icmp type port-unreachable
    }

    chain forward {
        type filter hook forward priority 0;
        ct state established,related accept
        iifname "wg0" oifname "eth0" accept
        iifname "eth0" oifname "wg0" accept
    }

    chain output {
        type filter hook output priority 0;
        accept
    }
}

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100;

        # wg0 から外に出る通信はマスカレード
        oifname "eth0" ip saddr 10.6.0.0/24 masquerade
    }
}

置き換える箇所

eth0 → VPSの外向きNIC名(例: ens3, enp1s0 など)

10.6.0.0/24 → WireGuardのアドレスレンジ


  1. 適用 & 永続化
sudo nft flush ruleset
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables

  1. 動作確認

クライアントから順にチェック:

ping 10.6.0.1        # サーバーのwg0
ping 8.8.8.8         # 外部IP
ping google.com      # DNS解決

💡 メリット

ufwとiptablesを気にせず nftables一本化

ルールが明確でトラブルシュートしやすい

将来的に WireGuard 以外のポート制御も簡単に追加できる

Discussion