nginx が壊れる前に OpenVPN の SNAT ルールを絞り込む
クライアントは認証するのに何もルーティングされない、あるいは VPN が上がった後にサイトが落ちる。まず tun へのアクセスを確認し、次に変換をプールと一つのインターフェースに限定します。
同じ種類のホストから二つの障害が繰り返し届きます。一つ目ではクライアントが認証した後、トンネルの外へ何も届きません。二つ目では VPN が上がるとサーバー自身のウェブサイトが応答を止めますが、これは巻き添え被害のように見えるためより深刻です。コンテナベースの VPS ではどちらも通常、同じ短いチェックリストに帰着し、順序が重要です。まずデバイス、次に変換、最後に範囲です。
コンテナが tun デバイスを作成できることを確認する
トンネルインターフェースが存在できないなら、他のことは問題になりません。/dev/net/tun が存在し、テストデバイスの作成が成功することを確認してください。多くのプロバイダーはコンテナ内で tun を既定で無効にしています。決して作成されなかったデバイスを、どれだけの firewall 作業でも補えません。
デバイスがなければ、有効にできるのはホストかプロバイダーだけです。別のプランのほうが、一週間続く未解決のサポートスレッドより安く済むことがよくあります。OpenVPN のログを一行でも読む前にこれを確認してください。そうしなければ、パケットを一度も見ないルールの調整に夜を費やすことになります。
このインターフェースで MASQUERADE が何をするかを決める
通常の仮想マシンでは、一般的な外向きルールはメインインターフェースからの POSTROUTING MASQUERADE です。OpenVZ コンテナでは可視デバイスが多くの場合 venet0 で、ルーティングされた NIC ではなくホスト管理の仮想インターフェースであり、MASQUERADE はそこでチュートリアルが想定するようには必ずしも動作しません。
実用的な形は、クライアントがすでに到達しているアドレスへの明示的な変換で、両方向の転送を許可します。サーバー設定からプールを置き換えることは、アドレスを置き換えることと同じくらい重要です。貼り付ける前に各行を読んでください。
iptables -t nat -A POSTROUTING -o venet0 -s 10.8.0.0/24 -j SNAT --to-source 203.0.113.10
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT転送ルールがなければ、変換は行われたままカーネルは転送を拒否し続けます。この組み合わせが、NAT ルールのカウンターは増えるのにクライアントには何も届かないという紛らわしい状態を生みます。二つの FORWARD 行も、同じチェーン内の広い drop ルールより前に置く必要があります。順序は設定の一部であり、実装の詳細ではありません。
ルールを一つのプールと一つのインターフェースに絞る
二つ目の症状には別の原因があります。送信元の制限も出力の制限もない POSTROUTING ルールです。そのようなルールはホストを出るすべてのパケットを書き換えます。
元の送信元に依存するサービスが誤動作します。ローカルプロキシの背後にあるウェブサーバーは応答を止めることがあり、再起動してもルールが経路上に残っているため何も変わりません。ホストが自身の公開アドレスへ送るトラフィックも影響を受け、そのため障害は firewall ではなく DNS や証明書の問題のように見えることがあります。このルールはほぼ確実に一つ目の症状を直すために追加されました。
解決策は、一致条件をトンネルプールと外向きインターフェースに狭め、複数を覆うために一つのルールを広げるのではなく、プールごとに一つのルールを追加することです。
ルールを永続化し、他に誰が所有しているかを把握する
手で追加したルールは再起動で消えるため、iptables-save で保存するか、インストールされている場所では netfilter-persistent で管理してください。復元が OpenVPN の起動前に実行されることを確認します。その後、インシデントの最中に隙間を見つけるのではなく、一度意図的に再起動してください。
コンテナホストでは、永続化ファイルが書き込み可能なコンテナストレージにあり、プロバイダーが起動時にフィルタリングを置き換えないことも確認してください。一部のプラットフォームはコンテナの外でポリシーを管理し、そこではローカルルールが無視されるか、ホスト自身のルールと衝突します。
カウンターと一つのキャプチャしたフローで検証する
接続したクライアントから、外部サービスが報告する公開アドレスを確認します。サーバーのアドレスと一致すれば変換は機能しており、一致しなければパケットは別の経路で出ているか、まったく出ていません。次に、サーバー上でホストされるサービスと公共インターネット上のサービスの両方を試してください。同じルールセットを通る経路が異なるためです。
サーバー上で iptables -t nat -L -v -n を使って NAT と FORWARD ルールのパケットカウンターを読み、キャプチャで一つのフローを観察します。クライアントのアドレスがキャプチャに現れ、応答が続かなければ、隙間は戻り経路かプロバイダーのフィルタリングにあり、クライアントプロファイルにはありません。キャプチャした送信元をルールが変換する先のアドレスと比較してください。不一致は別のルールが先に一致したことを意味します。観察した一つのフローは、設定を一ページ読むより多くのことを決着させます。
プール、変換後のアドレス、インターフェース名を変更記録にまとめておきます。一つのプールに正しいルールは、次のプールを誤って変換します。