<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Policy-Based-Routing on K-Life Hack | Systems Architecture &amp; DevOps</title><link>https://klifehack.com/en/tags/policy-based-routing/</link><description>Recent content in Policy-Based-Routing on K-Life Hack | Systems Architecture &amp; DevOps</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 21 Oct 2026 10:10:07 +0900</lastBuildDate><atom:link href="https://klifehack.com/en/tags/policy-based-routing/index.xml" rel="self" type="application/rss+xml"/><item><title>Asymmetric Routing Failure When Combining Traefik and Cloudflare WARP, and Packet Trajectory Correction via PBR</title><link>https://klifehack.com/en/p/traefik-warp-asymmetric-routing-pbr/</link><pubDate>Wed, 21 Oct 2026 10:10:07 +0900</pubDate><guid>https://klifehack.com/en/p/traefik-warp-asymmetric-routing-pbr/</guid><description>&lt;p&gt;In infrastructure running multi-homed configurations or tunneling clients on the same host, discrepancies between inbound and outbound communication paths (asymmetric routing) represent failure factors that are difficult to detect. In particular, in designs that expose services externally via containerized reverse proxies while encapsulating outbound traffic from the same host in private tunnels or VPNs, kernel routing decisions typically overwrite the default gateway, resulting in lost SYN-ACK responses to clients.&lt;/p&gt;
&lt;p&gt;This document traces a packet delivery failure caused by routing policy conflicts between a Traefik proxy deployed on a Docker bridge network and a Cloudflare WARP client, and records the verification process of enforcing localized routing tables using Policy-Based Routing (PBR).&lt;/p&gt;
&lt;h2 id="failure-overview-and-inbound-path-verification"&gt;Failure Overview and Inbound Path Verification
&lt;/h2&gt;&lt;p&gt;An issue occurred where external HTTPS requests to a Telegram-integrated clipboard web service (&lt;code&gt;copy.ds2qgd.dedyn.io&lt;/code&gt;) suddenly timed out (&lt;code&gt;ERR_CONNECTION_TIMED_OUT&lt;/code&gt;). To isolate container process downtime and upstream application anomalies, each layer of the inbound pipeline was inspected individually.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;DNS Resolution&lt;/b&gt;: Verified that the FQDN properly pointed to the public WAN IP address of the host environment.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Container Application Layer&lt;/b&gt;: Confirmed that the backend web service container was running and returning HTTP 200 responses via local sockets.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reverse Proxy Layer (Traefik)&lt;/b&gt;: Verified that the container runtime, dynamic routing definitions, Let&amp;rsquo;s Encrypt TLS certificate store, and port bindings were operating normally.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Netfilter / Firewall Layer&lt;/b&gt;: Verified that iptables &lt;code&gt;DNAT&lt;/code&gt; rules generated by the Docker engine and &lt;code&gt;FORWARD ACCEPT&lt;/code&gt; configurations within the &lt;code&gt;DOCKER&lt;/code&gt; chain were normal. Port TCP 443 was also explicitly allowed in host-side UFW.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Physical Interface Verification&lt;/b&gt;: Packet capture performed on the host physical NIC (&lt;code&gt;enp4s0&lt;/code&gt;) confirmed that incoming &lt;code&gt;TCP SYN&lt;/code&gt; packets from external clients reached the edge router and host NIC.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[Client] ---&amp;amp;gt; (TCP 443 SYN) ---&amp;amp;gt; [enp4s0 (Host)] ---&amp;amp;gt; [iptables DNAT] ---&amp;amp;gt; [br-77da1b8f5618] ---&amp;amp;gt; [Traefik 172.20.0.11]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this stage, inbound traffic was confirmed to reach the proxy container normally, identifying that packet drops or routing loss were occurring on the reverse path (egress) side.&lt;/p&gt;
&lt;h2 id="root-cause-egress-asymmetric-routing-via-cloudflare-warp"&gt;Root Cause: Egress Asymmetric Routing via Cloudflare WARP
&lt;/h2&gt;&lt;p&gt;An investigation of the routing policy table of Cloudflare WARP running on the host revealed that the kernel&amp;rsquo;s default return path was being intercepted by the WARP virtual tunnel interface (&lt;code&gt;CloudflareWARP&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id="failure-mechanism"&gt;Failure Mechanism
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Expected Normal Path&lt;/b&gt;: Traefik container (&lt;code&gt;172.20.0.11&lt;/code&gt;) $\rightarrow$ Docker bridge (&lt;code&gt;br-77da1b8f5618&lt;/code&gt;) $\rightarrow$ Host network stack $\rightarrow$ Physical NIC (&lt;code&gt;enp4s0&lt;/code&gt;) $\rightarrow$ Local gateway (&lt;code&gt;192.168.1.1&lt;/code&gt;) $\rightarrow$ Client&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Actual Deflected Path&lt;/b&gt;: Traefik container (&lt;code&gt;172.20.0.11&lt;/code&gt;) $\rightarrow$ Host network stack $\rightarrow$ &lt;b&gt;Cloudflare WARP Virtual Interface&lt;/b&gt; $\rightarrow$ WAN&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For TCP sessions arriving from external clients via the physical NIC (&lt;code&gt;enp4s0&lt;/code&gt;), server &lt;code&gt;SYN-ACK&lt;/code&gt; responses were dispatched externally via the WARP tunnel. Consequently, packets were dropped on the client side and intermediate paths due to source IP address mismatches (NAT inconsistency) or stateful firewall classification as invalid packets, leading to connection timeouts.&lt;/p&gt;
&lt;h2 id="workaround-verification-and-policy-based-routing-pbr-implementation"&gt;Workaround Verification and Policy-Based Routing (PBR) Implementation
&lt;/h2&gt;&lt;h3 id="evaluation-and-rejection-of-connmark-alternative"&gt;Evaluation and Rejection of CONNMARK Alternative
&lt;/h3&gt;&lt;p&gt;As an initial test, a configuration was evaluated that applied a Netfilter connection mark (&lt;code&gt;CONNMARK 0x80000&lt;/code&gt;) to incoming packets on TCP port 443 and bypassed WARP rules using policy routing based on &lt;code&gt;fwmark&lt;/code&gt;. However, due to priority conflicts with the high-priority routing rules registered by WARP, return packets for established sessions could not be deterministically routed to the physical interface. To prevent configuration drift, this Netfilter rule was promptly rolled back.&lt;/p&gt;
&lt;h3 id="surgical-route-enforcement-via-pbr-policy-based-routing"&gt;Surgical Route Enforcement via PBR (Policy-Based Routing)
&lt;/h3&gt;&lt;p&gt;Precise routing rules were applied to force only HTTPS return traffic from Traefik to the physical gateway (the &lt;code&gt;main&lt;/code&gt; table), while keeping all other host and container traffic routed via WARP.&lt;/p&gt;
&lt;h4 id="target-parameters"&gt;Target Parameters
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Source IP address: &lt;code&gt;172.20.0.11&lt;/code&gt; (Traefik internal container IP)&lt;/li&gt;
&lt;li&gt;Ingress bridge interface: &lt;code&gt;br-77da1b8f5618&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Protocol and source port: &lt;code&gt;TCP&lt;/code&gt;, &lt;code&gt;sport 443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Referenced routing table: &lt;code&gt;main&lt;/code&gt; (Standard table with physical gateway &lt;code&gt;192.168.1.1&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ip rule add from 172.20.0.11 iif br-77da1b8f5618 ipproto tcp sport &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt; table main priority &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;```&lt;/span&gt;yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="troubleshooting"&gt;Troubleshooting
&lt;/h2&gt;&lt;p&gt;本構成を本番運用に組み込む際、以下の摩擦点（Friction Points）に対する対処が必要です。&lt;/p&gt;
&lt;h3 id="1-動的評価スクリプトによる判定の偽陰性false-negative"&gt;1. 動的評価スクリプトによる判定の偽陰性（False-Negative）
&lt;/h3&gt;&lt;p&gt;ルーティング適用確認時、&lt;code&gt;ip route get&lt;/code&gt;の出力文字列を単純な正規表現でパースしていた検証スクリプトにおいて、出力順序の微細な変化を検知できず異常終了（FAIL）と判定される事象が発生しました。検証機構を自動化する際は、テキストマッチングに過度に依存せず、カーネルの戻り値判定および実際のパケットキャプチャを併用する必要があります。&lt;/p&gt;
&lt;h3 id="2-ホスト再起動時のルール揮発対策"&gt;2. ホスト再起動時のルール揮発対策
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;ip rule&lt;/code&gt;コマンドで動的に追加したポリシーはカーネルランタイムメモリにのみ保持されるため、ホスト再起動やネットワークデーモンのリロードで消失します。永続化のためには、Netplanまたはsystemd-networkdの設定ファイル、あるいはコンテナ起動前のネットワークフックスクリプトに組み込む必要があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="検証結果とプロトコルログ"&gt;検証結果とプロトコルログ
&lt;/h2&gt;&lt;p&gt;ルーティングルールの適用後、ルーティングサブシステムに対するクエリおよび外部セルラー回線経由でのエンドツーエンド通信テストを実施しました。&lt;/p&gt;
&lt;h3 id="ルーティング照合ログ"&gt;ルーティング照合ログ
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="パケットキャプチャおよびハンドシェイク検証"&gt;パケットキャプチャおよびハンドシェイク検証
&lt;/h3&gt;&lt;p&gt;外部モバイルネットワーク（WAN）から&lt;code&gt;&lt;a class="link" href="https://copy.ds2qgd.dedyn.io" target="_blank" rel="noopener"
 &gt;https://copy.ds2qgd.dedyn.io&lt;/a&gt;&lt;/code&gt;へアクセスし、ホスト物理NIC（&lt;code&gt;enp4s0&lt;/code&gt;）上で&lt;code&gt;tcpdump&lt;/code&gt;を実行しました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;外部クライアントとの間で3ウェイハンドシェイク（&lt;code&gt;SYN&lt;/code&gt; $ightarrow$ &lt;code&gt;SYN-ACK&lt;/code&gt; $ightarrow$ &lt;code&gt;ACK&lt;/code&gt;）、TLSデータ転送、および正常なセッション終了（&lt;code&gt;FIN-ACK&lt;/code&gt;）が物理NIC（&lt;code&gt;enp4s0&lt;/code&gt;）上で完結し、パケットドロップが0件であることが実証されました。&lt;/p&gt;
&lt;h2 id="operational-notes"&gt;Operational Notes
&lt;/h2&gt;&lt;p&gt;オーバーレイネットワークや常時稼働型トンネルクライアント（WARP、Tailscale、WireGuard等）がホスト上で動作している場合、ルーティングの決定権がトンネル側に偏向するリスクを常に考慮する必要があります。接続タイムアウトが発生した際は、アプリケーションログの調査やプロキシの再起動を無作為に繰り返すのではなく、&lt;code&gt;tcpdump&lt;/code&gt;を用いて物理インターフェースにおける往復パケットの到達状況を切り分け、戻り経路の非対称性を診断することが迅速な復旧につながります。&lt;/p&gt;</description></item></channel></rss>