wireguard VPN構築 nftableの設定 ufwは無効化
WireGuardで「ハンドシェイクはできるがDNS解決できずインターネットに出られない」という症状悩まされ試行錯誤。
- サーバー側のNAT (マスカレード) 設定に問題あり?
Ubuntu 24 以降は iptables より nftables ベースの ufw/netfilter がメインになっていて、従来のiptables設定例をそのまま流用すると動かないことがある様子
確認すること(WireGuardサーバー側)
- 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
これでもまだつながらない
- 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
これでもまだできない
- 最近の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のつもりで書いたルールが効かない」トラブルあり。
- 切り分け手順
VPN内での疎通確認
クライアントから
ping 10.6.0.1
サーバーのwg0アドレス
これが通るなら WireGuard トンネルは正常。
次に
ping 8.8.8.8
これが通らなければ NAT/ルーティングが原因
ping google.com
これがダメなら DNS 設定の問題。
- ufw を使っている場合
まずは ufwを一時的に無効化 して VPN が通るか確認
sudo ufw disable
自分はこれでVPNからインターネットに出れるようになりました
つまり WireGuard自体は正しく動いていて、ufwがNATやフォワードをブロックしていた という状況です。
- 対処の方向性
ufwを無効にするのは一番簡単ですが、実運用ではセキュリティ的に微妙です。
Ubuntu 24/25(nftablesベース)の場合:
Ubuntu 24以降は ufw が nftables を使っているため、上記ルールは無視されるケースが多い様子
この場合は /etc/ufw/before6.rules や /etc/ufw/before.nft に追加するか、素直に nftables で直接マスカレードを設定した方が安定します。
実用的な回避策
セキュリティを ufw に任せず、nftables で直接管理する
nftables で WireGuard 用ファイアウォールを構築する流れ
- ufw を完全に無効化
sudo systemctl disable --now ufw
- 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のアドレスレンジ
- 適用 & 永続化
sudo nft flush ruleset
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables
- 動作確認
クライアントから順にチェック:
ping 10.6.0.1 # サーバーのwg0
ping 8.8.8.8 # 外部IP
ping google.com # DNS解決
💡 メリット
ufwとiptablesを気にせず nftables一本化
ルールが明確でトラブルシュートしやすい
将来的に WireGuard 以外のポート制御も簡単に追加できる
Discussion