title: redsocks + iptables behavior
body: <p>The following is the network topology of the test bed where I use <code>redsocks</code> and <code>iptables</code> to access youtube from LAN, provided that I have a ssh dynamic forwarding established between <code>Linux</code> and <code>VPS</code>:</p>
  
  <pre><code>                         |
                   outside | inside firewall
                           |
                           |        LAN 192.168.1.0/24
                           |        ----+--------------------+-----------
                           |            |.2                  | .3
              +-----+      |     +------+----+          +----+----+
              |     |      |     |           |          |         |
  Youtube &lt;--&gt;| VPS &lt;============&gt;   Linux   |          | Windows |
              |     |      |     |           |          |         |
              +-----+      |     +-----------+          +---------+
                           |
                           |
  </code></pre>
  
  <p>The Linux box and Windows box are on the same LAN inside the firewall, which blocks any access to say Youtube. The VPS is outside the firewall and it can access Youtube. From within the Linux box I can <code>ssh -D</code> to the VPS, making VPS acts as a SOCKS5 proxy. </p>
  
  <p>To further make the SOCKS5 proxy "transparent" to the processes (e.g., browser) on the Linux box, I did the following:</p>
  
  <ul>
  <li>run a SOCKS5 client software <code>redsocks</code> to talk with the SOCKS5 server, for handling the SOCKS5 protocols.</li>
  <li>add some iptable rules, to direct youtube-bound traffic to  <code>redsocks</code> process</li>
  </ul>
  
  <p>This works fine for the Linux box itself:</p>
  
  <pre><code>echo 1 &gt; /proc/sys/net/ipv4/ip_forward
  /sbin/iptables -F -t nat
  /sbin/iptables -t nat -X REDSOCKS
  /sbin/iptables -t nat -N REDSOCKS
  /sbin/iptables -t nat -A OUTPUT -d $YOUTUBE -j REDSOCKS
  /sbin/iptables -t nat -A REDSOCKS -p TCP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
  /sbin/iptables -t nat -A REDSOCKS -p UDP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
  /sbin/iptables -t nat -A REDSOCKS -p ICMP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
  /sbin/iptables -t nat -A REDSOCKS -j RETURN
  </code></pre>
  
  <p>Now I want let Windows box also to access Youtube "transparently", with some software configuration. My idea is as the following:</p>
  
  <ul>
  <li>Change the routing table on Windows machine such that all Youtube-bound traffic will be routed to the Linux box (192.168.1.2)</li>
  <li>Setup iptables "somehow" to do SNAT for the Youtube-bound traffic from Windows</li>
  </ul>
  
  <p>After some tests, I encountered the following problem:</p>
  
  <ul>
  <li>the REDIRECT (or DNAT) target only applicable for PREROUTING/OUTPUT hooks (e.g., in the iptable settings for redsocks, the <code>REDSOCKS</code> chain is hooked on <code>OUTPUT</code> chain)</li>
  <li>the SNAT (or MASQUERADE) target only applicable for POSTROUTING hook</li>
  </ul>
  
  <p>What I want to do for the Windows machine is firstly SNAT and then REDIRECT, but as SNAT is happening on POSTROUTING hook, it seems it's too later (in the packet processing flow) to have it to be processed by PREROUTING/OUTPUT hooks...</p>
  
  <p>Is there a way out here?</p>
  
  <p>PS 1. I found a working solution (below in the reply from myself), although I don't really understand why it worked.</p>
  
  <p>PS 2. I started looking into source code of <code>redsocks</code>, one thing I found so far is that <code>redsocks</code> use <code>getsockopt(,SO_ORIGINAL_DST,)</code> to obtain the destination address before DNAT. What's not clear to me is the following processing, and src/dst ip address of the return packet from <code>redsocks</code>. Don't know if there is an introduction about <code>redsocks</code> implementation...</p>