VPNがdefaultルートを書き換えずに全トラフィックを奪う方法とは?OpenVPNの0.0.0.0/1マジックを読み解く

背景 VPNを使ってトラフィックを中継する際、すべての通信をVPN経由にしたい──そんなときに現れるのが謎のルート 0.0.0.0/1 と 128.0.0.0/1。 一見すると「なんだこの中途半端なルートは?」と思われがちですが、これはOpenVPNが採用する非常に巧妙なテクニックです。本記事では、その目的、動作、実際のルーティングテーブルを紐解きながら、この仕組みの裏側を解説します。 ルーティングとは?ip route の基本 Linuxのルーティングテーブルは ip route で確認できます。このテーブルは、「どのIPアドレス宛の通信を、どのネットワークインターフェースから、どのゲートウェイ経由で送るか」という配送ルール一覧です。 $ ip route 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 default via 192.168.1.1 dev eth0 この場合、 192.168.1.0/24 に属する通信は eth0 から直接送られる それ以外(つまりインターネットなど)は 192.168.1.1(ゲートウェイ)を経由して送られる パケットを受信すると、カーネルはルートテーブルの上から順に一致するエントリを探し、一番一致度が高い(= プレフィックスが長い)ルートに従って出力先を決定します。 つまり、 どの通信もまずは「最も具体的な(最長一致の)ルート」を優先する これがVPNのルーティング操作にも大きく関わってきます。 defaultルートとは? default ルート(または 0.0.0.0/0)とは、どのルーティングエントリにも一致しない宛先のパケットをどこに送るかを決めるルールです。いわば「最後の砦」。 # 例: よくある default ルート default via 192.168.1.1 dev eth0 この例では、「どのルートにもマッチしなければ 192.168.1.1 に送れ」となっています。 通常、インターネットへの出口(ISPや上位ルータ)に向かうために使われます。 A (100.64.1.61) ↓ B (100.64.1.27) — VPN Client ↓ C (162.x.x.x) — VPN Server ↓ D (192.168.40.10) ↓ E (192.168.40.130) AからD・Eに通信を通したい。しかし同時に、Aのインターネット通信もVPN(サーバC)経由で出したい。 ...

May 2, 2025 · 2 min · 314 words · Me

Problem_site2site

#背景 VPNを使って拠点間通信(Site-to-Site Routing)を構成していると、 思ったようにパケットが届かないケースがあります。今回は以下の構成で発生した通信不通トラブルと、その解決方法を共有します。 🔧 ネットワーク構成 [A] 100.64.1.61 (100.64.1.0/22) ↓ [B] 100.64.1.27 (OpenVPNクライアント) → VPN → [C] OpenVPNサーバー → [D] 192.168.1.4 (192.168.1.0/24) 目標:AからD(192.168.1.4)への通信を通すこと。 ❗ 問題の症状 BからDには通信可能(VPN経由で192.168.1.4が見える) AからDへの通信は届かない しかしDからAへの通信(返信)は可能 🧠 原因 Aは 192.168.1.0/24 サブネットに属していないため、この宛先へのパケットをデフォルトゲートウェイに送ってしまっていた。 つまり、「行きのルート」が不在だったわけです。 ✅ 解決策:Aに静的ルートを追加 一時的にルートを追加する場合は以下のコマンドを実行: sudo ip route add 192.168.1.0/24 via 100.64.1.27 これで、Aは目的地 192.168.1.4 へのパケットをVPN中継ノードBに送るようになります。 UbuntuでNetplanを使用している場合、/etc/netplan/xxx.yaml を以下のように修正します: network: version: 2 renderer: networkd ethernets: enp3s0: dhcp4: false dhcp6: false addresses: [100.64.1.61/22] routes: - to: default via: 100.64.1.1 - to: 192.168.1.0/24 via: 100.64.1.27 nameservers: addresses: [100.64.1.1, 8.8.8.8, 8.8.4.4] ちなみに、netplan applyをやって疎通できなくなると困ることってありますよね。 そんな時のためにこれがあります ...

May 2, 2025 · 3 min · 619 words · Me

Site2site_vpn2

事始め site2site routingができるようになり、vpn_clientのネットワーク内のサーバとvpn_server間で通信ができるようになったわけだが。 今回、新たにもう一つvpn_clientをつなぎ、新しいローカルネットワークをこのVPNネットワークに参加させようとしたわけだ。 しかしこれがうまくいかない。 環境の整理 ネットワークA : 100.64.0.0/22 ネットワークB : 192.168.1.0/24 で、以下のような設定をvpn_serverに書き込むわけです。 port 1194 proto udp dev tun ca ca.crt cert server.crt key server.key dh dh.pem crl-verify crl.pem ifconfig-pool-persist ipp.txt server 10.8.0.0 255.255.255.0 # client側から通信させたい、server側のLanセグメントを指定 push "redirect-gateway def1 bypass-dhcp" push "route 10.8.0.0 255.255.255.0" push "dhcp-option DNS 8.8.8.8" # server側から通信させたい、client側のlanセグメントを指定 client-config-dir /etc/openvpn/ccd route 100.64.0.0 255.255.252.0 route 192.168.3.0 255.255.255.0 #fragment 1400 #mssfix tun-mtu 1400 client-to-client keepalive 10 120 comp-lzo user nobody group nogroup persist-key persist-tun status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log verb 3 duplicate-cn これをやればA -> vpn_server B -> vpn_serverにつながると思っていた。 ...

February 22, 2025 · 6 min · 1073 words · Me

MTLS_on_OVPN

公開鍵暗号の体系を完全に理解した はい、鍵交換アルゴリズム、署名アルゴリズム、暗号アルゴリズム、暗号モード、ハッシュ の5つのセット(暗号スイート)を指定して通信を暗号化する。それが、俺が知っている暗号体系の全てです。 でですね、openVPNでクライアントとサーバの通信を暗号化しますよね。 その時に色々と証明書を発行すると思うんですよ。ただ、俺はどの証明書がどのように用いられるのかが全くわかっていなかった。 だから、今回、改めてopenVPNでクライアントとサーバを構築する際の証明書の役割などを確認したいと思う。 過去の僕の記事 basic client site to site routeing いつも参考にしている記事 qiita では追っていきましょう 認証局 (CA) の設立 ここから始まっているっぽいんだよね。 $ ./easyrsa init-pki init-pki complete; you may now create a CA or requests. Your newly created PKI dir is: path/to/easy-rsa/easyrsa3/pki CA証明書の生成 $ ./easyrsa build-ca パスフレーズが聞かれる。 ここで、秘密鍵と公開鍵がすでに生成されている。認証局のね サーバ証明書の生成 $ ./easyrsa build-server-full server nopass ここで、CA証明書を生成したときのパスフレーズを再び入力する。 これでおそらく、サーバの公開鍵に署名がされる。(CSRも済んでいる) DH鍵の生成 ここでDH鍵が生成されるのか。なぜだ??TLSでのDH鍵は毎回違うものが使われるのではないのか!? なるほど、chatGPTに聞いたのであっているかはわからんが、この段階で生成されるものは、DHパラメータ(素数と生成元)だね。 これは納得だね。 つまり、 y = g ^ (x) mod p の、pとgが生成される。で、サーバとクライアントはお互い適当にxを選ぶわけですわ。はい完全理解。 ちなみに、ecdhを使って鍵交換をすることもできます。 証明書失効リストの生成(こちら、参照しているページでは間違っているので注意が必要) $ ./easyrsa gen-crl こちらも、CAの秘密鍵で署名するわけですね。 クライアント用秘密鍵の生成 $ cd easy-rsa/easyrsa3 $ ./easyrsa build-client-full username はい、ここでクライアントの証明書と秘密鍵を生成するわけですね。 で、証明書はCAが認証する必要があるので、再びパスフレーズを入れる感じになります。 ...

October 22, 2024 · 1 min · 155 words · Me