Skip to content

Commit

Permalink
Site updated: 2024-03-06 13:12:29
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanInf committed Mar 6, 2024
1 parent e3951e3 commit b42c13e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 32 deletions.
8 changes: 4 additions & 4 deletions 2024/03/06/记一次有趣的iptables分析经历/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<meta property="og:image" content="https://r0yanx.com/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-13-07-06.png">
<meta property="og:image" content="https://r0yanx.com/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-13-02-39.png">
<meta property="article:published_time" content="2024-03-06T02:02:12.000Z">
<meta property="article:modified_time" content="2024-03-06T05:08:20.839Z">
<meta property="article:modified_time" content="2024-03-06T05:12:16.601Z">
<meta property="article:author" content="r0yanx">
<meta property="article:tag" content="Linux">
<meta name="twitter:card" content="summary">
Expand Down Expand Up @@ -237,7 +237,7 @@ <h1 class="post-title" itemprop="name headline">
<span class="post-meta-item-text">发表于</span>


<time title="创建时间:2024-03-06 10:02:12 / 修改时间:13:08:20" itemprop="dateCreated datePublished" datetime="2024-03-06T10:02:12+08:00">2024-03-06</time>
<time title="创建时间:2024-03-06 10:02:12 / 修改时间:13:12:16" itemprop="dateCreated datePublished" datetime="2024-03-06T10:02:12+08:00">2024-03-06</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
Expand Down Expand Up @@ -270,11 +270,11 @@ <h1 class="post-title" itemprop="name headline">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>事情起因是一次修改家里VPN的路由方式,引发了一次关于iptables nat规则的思考。</p>
<h3 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h3><p>网络环境如下图,笔记本电脑通过VPN访问远程内网设备。<br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-11-37-59.png"><br>在VPN服务器中,通过一条NAT规则,将10段地址转为VPN服务器内网地址<code>192.168.200.10</code>以实现对内网设备的访问。VPN服务器与家里的内网设备不在同一个子网,两个子网间通过网关路由器进行转发,这样可以通过路由器做ACL规则以进行安全防护。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>

<a id="more"></a>
<h3 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h3><p>某天因为有了需要家里内网终端访问远程的笔记本电脑的需求,即192.168.100.0/24段对10.0.0.0/24段主动发起连接的需求。显然,在之前的网络结构中,只能实现VPN客户端对家里内网的单向访问,并无法实现互访。</p>
<p>要实现双向访问也并不难,这点以前就实现过类似需求,只需要把VPN服务器的MASQUERADE NAT规则去除,然后在家里的网关路由增加一条下面的规则即可:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># VPN SERVER 删除NAT规则</span></span><br><span class="line">iptables -D POSTROUTING 1</span><br><span class="line"></span><br><span class="line"><span class="comment"># 路由器设置规则</span></span><br><span class="line">route add -net 10.0.0.0/24 gw 192.168.100.10</span><br></pre></td></tr></table></figure>
<p>数据包流转如下:<br>| ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST |<br>|—|—|—|—|—|—|<br>| 1 | 内网客户端向VPN客户端发起请求,请求发向内网网关 | 192.168.100.20 | 10.0.0.10 | WORK | ROUTE GW |<br>| 2 | 内网网关收到内网客户端请求,根据路由表把数据包转发到VPN服务器 | 192.168.100.20 | 10.0.0.10 | ROUTE GW | VPN SERVER |<br>| 3 | VPN服务器收到数据包,把数据包通过VPN隧道转发到客户端 | 192.168.100.20 | 10.0.0.10 | VPN SERVER | LAPTOP |<br>| 4 | VPN客户端收到请求数据包,发起响应,数据包原路返回 | 10.0.0.10 | 192.168.100.20 | LAPTOP | VPN SERVER |</p>
<p>数据包流转如下:<br> ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST<br>—|—|—|—|—|—<br> 1 | 内网客户端向VPN客户端发起请求,请求发向内网网关 | 192.168.100.20 | 10.0.0.10 | WORK | ROUTE GW<br> 2 | 内网网关收到内网客户端请求,根据路由表把数据包转发到VPN服务器 | 192.168.100.20 | 10.0.0.10 | ROUTE GW | VPN SERVER<br> 3 | VPN服务器收到数据包,把数据包通过VPN隧道转发到客户端 | 192.168.100.20 | 10.0.0.10 | VPN SERVER | LAPTOP<br> 4 | VPN客户端收到请求数据包,发起响应,数据包原路返回 | 10.0.0.10 | 192.168.100.20 | LAPTOP | VPN SERVER </p>
<p>经过上面的规则设置,内网设备与VPN客户端已经可以实现双方ip的直接互访。但是问题也随之出现,考虑到安全问题,我需要设置ACL规则限制VPN客户端的访问范围,原本的方式只需要对VPN服务器的ip地址做ACL限制就行了,现在还需要在VPN服务器规则的基础上加入VPN客户端网段的限制,需要考虑和改动的规则更多了,一一改动显然是不够优雅的,而且也可能导致安全隐患(绕过ACL访问到内网设备)。</p>
<p>所以就准备恢复原本的访问模式,在VPN服务器重新启动NAT。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>
Expand Down
35 changes: 9 additions & 26 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ <h2 class="post-title" itemprop="name headline">
<span class="post-meta-item-text">发表于</span>


<time title="创建时间:2024-03-06 10:02:12 / 修改时间:13:08:20" itemprop="dateCreated datePublished" datetime="2024-03-06T10:02:12+08:00">2024-03-06</time>
<time title="创建时间:2024-03-06 10:02:12 / 修改时间:13:12:16" itemprop="dateCreated datePublished" datetime="2024-03-06T10:02:12+08:00">2024-03-06</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
Expand All @@ -251,31 +251,14 @@ <h2 class="post-title" itemprop="name headline">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>事情起因是一次修改家里VPN的路由方式,引发了一次关于iptables nat规则的思考。</p>
<h3 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h3><p>网络环境如下图,笔记本电脑通过VPN访问远程内网设备。<br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-11-37-59.png"><br>在VPN服务器中,通过一条NAT规则,将10段地址转为VPN服务器内网地址<code>192.168.200.10</code>以实现对内网设备的访问。VPN服务器与家里的内网设备不在同一个子网,两个子网间通过网关路由器进行转发,这样可以通过路由器做ACL规则以进行安全防护。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>

<h3 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h3><p>某天因为有了需要家里内网终端访问远程的笔记本电脑的需求,即192.168.100.0/24段对10.0.0.0/24段主动发起连接的需求。显然,在之前的网络结构中,只能实现VPN客户端对家里内网的单向访问,并无法实现互访。</p>
<p>要实现双向访问也并不难,这点以前就实现过类似需求,只需要把VPN服务器的MASQUERADE NAT规则去除,然后在家里的网关路由增加一条下面的规则即可:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># VPN SERVER 删除NAT规则</span></span><br><span class="line">iptables -D POSTROUTING 1</span><br><span class="line"></span><br><span class="line"><span class="comment"># 路由器设置规则</span></span><br><span class="line">route add -net 10.0.0.0/24 gw 192.168.100.10</span><br></pre></td></tr></table></figure>
<p>数据包流转如下:<br>| ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST |<br>|—|—|—|—|—|—|<br>| 1 | 内网客户端向VPN客户端发起请求,请求发向内网网关 | 192.168.100.20 | 10.0.0.10 | WORK | ROUTE GW |<br>| 2 | 内网网关收到内网客户端请求,根据路由表把数据包转发到VPN服务器 | 192.168.100.20 | 10.0.0.10 | ROUTE GW | VPN SERVER |<br>| 3 | VPN服务器收到数据包,把数据包通过VPN隧道转发到客户端 | 192.168.100.20 | 10.0.0.10 | VPN SERVER | LAPTOP |<br>| 4 | VPN客户端收到请求数据包,发起响应,数据包原路返回 | 10.0.0.10 | 192.168.100.20 | LAPTOP | VPN SERVER |</p>
<p>经过上面的规则设置,内网设备与VPN客户端已经可以实现双方ip的直接互访。但是问题也随之出现,考虑到安全问题,我需要设置ACL规则限制VPN客户端的访问范围,原本的方式只需要对VPN服务器的ip地址做ACL限制就行了,现在还需要在VPN服务器规则的基础上加入VPN客户端网段的限制,需要考虑和改动的规则更多了,一一改动显然是不够优雅的,而且也可能导致安全隐患(绕过ACL访问到内网设备)。</p>
<p>所以就准备恢复原本的访问模式,在VPN服务器重新启动NAT。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>

<p>但是我还没在网关上面删除10.0.0.0/24的静态路由,突发奇想试试内网客户端(DATA SERVER) ping 一下VPN客户端,发现是能ping通的!<br>而VPN客户端无法ping通内网客户端(DATA SERVER)。这好像误打误撞实现了我的需求,但是又不太对劲。</p>
<p>经过抓包分析,发现由内网客户端向VPN客户端发起请求时,VPN客户端的回应包不会被VPN服务器做NAT。</p>
<p>由此产生了本文的疑问,<strong>为什么明明符合了NAT规则,而iptables没有源地址为10.0.0.0/24的数据包作SNAT?</strong></p>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p>首先抓取VPN客户端(LAPTOP) ping 内网客户端(DATA SERVER)的数据包。</p>
<p>数据包流转如下(来自抓包分析):<br>| ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST |<br>| — | — | :—: | :—: | :—: | :—: |<br>| 1 | VPN客户端(LAPTOP)向DATA SERVER发起请求,数据包发向VPN服务器 | 10.0.0.10 | 192.168.100.30 | LAPTOP | VPN SERVER |<br>| 2 | VPN服务器匹配到符合SNAT规则的数据包,将源ip修改为VPN服务器的内网ip,即192.168.200.10,再根据路由表将数据包转发到网关路由器 | 192.168.200.10 | 192.168.100.30 | VPN SERVER | ROUTE GW |<br>| 3 | 网关路由器根据ACL规则,禁止转发该数据包到目标网段,将数据包丢弃 | 192.168.200.10 | 192.168.100.30 | - | - |</p>
<p>所以VPN客户端无法ping通内网客户端(DATA SERVER),但是可以ping通内网客户端(WORK)。</p>
<p>再看下从内网客户端(DATA SERVER)ping VPN客户端(LAPTOP)的数据包:<br>| ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST |<br>| — | — | :—: | :—: | :—: | :—: |<br>|1 | 内网客户端(DATA SERVER)向 VPN客户端(LAPTOP)发起icmp请求,数据包发送到网关路由器 | 192.168.100.30 | 10.0.0.10 | DATA SERVER | ROUTE GW |<br>|2 | 网关路由器根据路由表,将数据包转发到VPN服务器,因为ACL配置了允许规则,数据包可以进行转发 | 192.168.100.30 | 10.0.0.10 | ROUTE GW | VPN SERVER |<br>|3 | VPN服务器将数据包转发到VPN客户端 | 192.168.100.30 | 10.0.0.10 |VPN SERVER |LAPTOP|<br>|4 | VPN客户端(LAPTOP)收到icmp请求,向内网客户端(DATA SERVER)发送icmp响应 | 10.0.0.10 | 192.168.100.30 | LAPTOP|VPN SERVER |<br>|5 | VPN服务器收到数据包,没有经过NAT就把数据包发送到网关路由器 | 10.0.0.10 | 192.168.100.30 | VPN SERVER |ROUTE GW |<br>|6 | 网关路由器收到数据包,根据路由表把数据包发送到内网客户端(DATA SERVER)|10.0.0.10 | 192.168.100.30 |ROUTE GW |DATA SERVER|</p>
<p>整个过程中奇怪的是从内网客户端(DATA SERVER)ping VPN客户端(LAPTOP)过程中,VPN客户端(LAPTOP)回应icmp请求时,VPN服务器收到数据包,是符合SNAT规则的,但是没有经过NAT就把数据包发送到网关路由器。</p>
<h3 id="破案"><a href="#破案" class="headerlink" title="破案"></a>破案</h3><p>根据上面的分析过程,可以推断,iptables在做SNAT的时候会先进行回话方向的判断的,即符合源ip规则发起的会话时会进行SNAT,若会话发起方不匹配源ip规则,则不会进行SNAT而是直接进行转发。</p>
<p><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-12-57-31.png"></p>
<p>那么为什么会有这样的机制了,直接搜索snat相关的机制都是说能做源地址转发让终端上网之类的,没能解答我的疑问。</p>
<p>最终经过Google搜索<code>iptables nat sessions</code>找到一个论坛的问答解决了我的疑问。<br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-12-47-42.png"></p>
<p>题主正好提出了与我相同的疑问。<br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-13-01-25.png"></p>
<p><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-13-07-06.png"><br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-13-02-39.png"></p>
<p>原文:<a target="_blank" rel="noopener" href="https://unix.stackexchange.com/questions/484868/in-iptables-does-masquerade-match-only-on-new-connections-syn-packets">https://unix.stackexchange.com/questions/484868/in-iptables-does-masquerade-match-only-on-new-connections-syn-packets</a></p>

<!--noindex-->
<div class="post-button">
<a class="btn" href="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/#more" rel="contents">
阅读全文 &raquo;
</a>
</div>
<!--/noindex-->


</div>

Expand Down
4 changes: 2 additions & 2 deletions search.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3143,11 +3143,11 @@ st->op1->op2->op3->op4->e</textarea><textarea id="flowchart-0-options" style="di
<content><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>事情起因是一次修改家里VPN的路由方式,引发了一次关于iptables nat规则的思考。</p>
<h3 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h3><p>网络环境如下图,笔记本电脑通过VPN访问远程内网设备。<br><img data-src="/2024/03/06/%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%9C%89%E8%B6%A3%E7%9A%84iptables%E5%88%86%E6%9E%90%E7%BB%8F%E5%8E%86/2024-03-06-11-37-59.png"><br>在VPN服务器中,通过一条NAT规则,将10段地址转为VPN服务器内网地址<code>192.168.200.10</code>以实现对内网设备的访问。VPN服务器与家里的内网设备不在同一个子网,两个子网间通过网关路由器进行转发,这样可以通过路由器做ACL规则以进行安全防护。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>

<a id="more"></a>
<h3 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h3><p>某天因为有了需要家里内网终端访问远程的笔记本电脑的需求,即192.168.100.0/24段对10.0.0.0/24段主动发起连接的需求。显然,在之前的网络结构中,只能实现VPN客户端对家里内网的单向访问,并无法实现互访。</p>
<p>要实现双向访问也并不难,这点以前就实现过类似需求,只需要把VPN服务器的MASQUERADE NAT规则去除,然后在家里的网关路由增加一条下面的规则即可:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># VPN SERVER 删除NAT规则</span></span><br><span class="line">iptables -D POSTROUTING 1</span><br><span class="line"></span><br><span class="line"><span class="comment"># 路由器设置规则</span></span><br><span class="line">route add -net 10.0.0.0/24 gw 192.168.100.10</span><br></pre></td></tr></table></figure>
<p>数据包流转如下:<br>| ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST |<br>|—|—|—|—|—|—|<br>| 1 | 内网客户端向VPN客户端发起请求,请求发向内网网关 | 192.168.100.20 | 10.0.0.10 | WORK | ROUTE GW |<br>| 2 | 内网网关收到内网客户端请求,根据路由表把数据包转发到VPN服务器 | 192.168.100.20 | 10.0.0.10 | ROUTE GW | VPN SERVER |<br>| 3 | VPN服务器收到数据包,把数据包通过VPN隧道转发到客户端 | 192.168.100.20 | 10.0.0.10 | VPN SERVER | LAPTOP |<br>| 4 | VPN客户端收到请求数据包,发起响应,数据包原路返回 | 10.0.0.10 | 192.168.100.20 | LAPTOP | VPN SERVER |</p>
<p>数据包流转如下:<br> ID | 步骤 | IP SRC | IP DST | MAC SRC | MAC DST<br>—|—|—|—|—|—<br> 1 | 内网客户端向VPN客户端发起请求,请求发向内网网关 | 192.168.100.20 | 10.0.0.10 | WORK | ROUTE GW<br> 2 | 内网网关收到内网客户端请求,根据路由表把数据包转发到VPN服务器 | 192.168.100.20 | 10.0.0.10 | ROUTE GW | VPN SERVER<br> 3 | VPN服务器收到数据包,把数据包通过VPN隧道转发到客户端 | 192.168.100.20 | 10.0.0.10 | VPN SERVER | LAPTOP<br> 4 | VPN客户端收到请求数据包,发起响应,数据包原路返回 | 10.0.0.10 | 192.168.100.20 | LAPTOP | VPN SERVER </p>
<p>经过上面的规则设置,内网设备与VPN客户端已经可以实现双方ip的直接互访。但是问题也随之出现,考虑到安全问题,我需要设置ACL规则限制VPN客户端的访问范围,原本的方式只需要对VPN服务器的ip地址做ACL限制就行了,现在还需要在VPN服务器规则的基础上加入VPN客户端网段的限制,需要考虑和改动的规则更多了,一一改动显然是不够优雅的,而且也可能导致安全隐患(绕过ACL访问到内网设备)。</p>
<p>所以就准备恢复原本的访问模式,在VPN服务器重新启动NAT。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE</span><br></pre></td></tr></table></figure>
Expand Down

0 comments on commit b42c13e

Please sign in to comment.