VPN ゲートウェイ自身のアドレスで LAN サービスを公開する
転送ポートをクライアントから機器まで、そして戻りまで追跡します。宛先変換の範囲を絞り、そのうえで応答を経路で返すか変換するかを決めます。
ゲートウェイ自身のトンネルアドレスの一つで LAN 機器を公開するのに必要なのは、NAT の一行だけです。それでも接続は失敗します、応答する機器はクライアントのアドレスがそのゲートウェイ経由で到達可能だということを知らないからです。パケットをクライアントから内側へたどり、次に応答を外側へ戻る向きにたどれば、欠けている半分が見えてきます。
クライアントの視点から始める
この例のクライアントは VPN プール 10.62.0.0/24 にいて、ポート 8080 で 10.62.0.1 に接続します。そのアドレスはゲートウェイ自身のものなので、パケットは別のピアではなくゲートウェイのカーネルに届きます。ゲートウェイの背後にある LAN は 172.21.4.0/24 です。ゲートウェイが 172.21.4.10 を持ち、実際に HTTP を提供する機器は 172.21.4.40 です。
別の VPN ピアに属するアドレスは、ゲートウェイのサービスアドレスと置き換えられません。クライアントがピアのアドレスに接続しているなら、ゲートウェイのルールはまったく関与せず、この一連の説明は誤ったケースです。
宛先変換の範囲を意図的に絞る
狭い版は一つのポートを公開し、宛先だけを書き換えます。パケットはプロトコルと送信元を保つので、それこそが残りの道のりを面白くします。
iptables -t nat -A PREROUTING -i tun0 -s 10.62.0.0/24 -d 10.62.0.1 -p tcp --dport 8080 -j DNAT --to-destination 172.21.4.40:80
プロトコルとポートの条件がないルールは広い版で、クライアントが選んだポートをそのまま保ち、アドレスだけを変えます。ホスト全体を公開するつもりなら正当で、一つのサービスが目的なら誤りです。ルールを読み返し、インターフェース名を確認してください。間違ったインターフェースの DNAT ルールは何にも一致せず、ルールがない場合と同じタイムアウトを生み、機器を眺めて一時間を無駄にします。
転送の境界を一致させる
変換はヘッダーを変えるだけで、許可を与えません。既定の破棄ポリシーでは、転送されるフローに独自の許可が必要で、戻りの方向には、おそらくポリシーにすでにある確立済み接続のルールが必要です。
iptables -A FORWARD -i tun0 -o lan0 -d 172.21.4.40 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
すべての DNAT フローを無条件に許可するのはこの設計より広く、後で誰かが追加したマッピングまで通してしまいます。宛先とポートを名指しし、残りは閉じたままにする。転送ルールのカウンターがゼロのまま NAT のカウンターが増えるなら、パケットはあなたのルールより前で破棄されています。二つ目のコピーを足すのではなく、チェーンの順序を読んでください。
機器は何らかの方法で応答しなければならない
変換のあと、機器には 10.62.0.0/24 の送信元が見えます。その応答は既定ゲートウェイへ向かいます、つまり VPN ゲートウェイではなく LAN ルーターであり、何かが別のことを告げない限りそうです。これを直す方法は二つあり、等価ではありません。機器または LAN ルーターの経路は 10.62.0.0/24 を 172.21.4.10 へ送り、クライアントの送信元を保ちます。範囲を絞った送信元変換は、代わりにクライアントをゲートウェイの LAN アドレスの背後に隠します。
ip route add 10.62.0.0/24 via 172.21.4.10 dev eth1
iptables -t nat -A POSTROUTING -s 10.62.0.0/24 -d 172.21.4.40 -o lan0 -p tcp --dport 80 -j SNAT --to-source 172.21.4.10
サービスが何を必要とするかで選びます。クライアントごとのポリシーと意味のあるログには経路で返す形が向き、経路を渡せない機器や、どうしても LAN アドレスを見る必要があるサービスには変換する形が向きます。一つの応答を通すためにグローバルの masquerade ルールに手を伸ばさない。それはすべてのクライアントをすべての宛先から隠し、送信元アドレスに依存するポリシーを静かに壊します。
ゲートウェイ自身から試験しない
ゲートウェイ上で 10.62.0.1 宛てに生成した要求は、入ってくる PREROUTING ではなく OUTPUT チェーンから出ていきます。その失敗や成功はクライアント向けのルールについて何も語らず、人はそこで動いているルールが壊れていると結論づけます。
conntrack -L | grep 172.21.4.40
tcpdump -ni any 'port 8080 or port 80'
実際のクライアント要求を実行し、両方を読みます。conntrack のエントリは適用された変換を示し、キャプチャは要求が LAN へ渡ったか、応答がトンネルへ戻ったかを示します。ルールを変えたあとは新しい接続を使ってください、既存の状態は以前のマッピングを保ち、古いやり方で失敗し続けるからです。最後に、機器のアドレス、転送の許可、応答の経路が同じフローを語っているかという会話全体を確認します。