{"id":987,"date":"2014-04-27T02:37:23","date_gmt":"2014-04-27T02:37:23","guid":{"rendered":"https:\/\/trouble.org\/?p=987"},"modified":"2014-06-22T16:56:07","modified_gmt":"2014-06-22T16:56:07","slug":"from-a-on-b-to-c-on-d","status":"publish","type":"post","link":"https:\/\/trouble.org\/?p=987","title":{"rendered":"From A on B to C on D"},"content":{"rendered":"<p>I find iptables to be a bit of a beast&#8230; so for posterity (or my own sanity, in case I lost this, I might recover from search engine caches!) this simply forwards a port (A) of a certain protocol from one host (B) to a second port (C) on a 2nd IP (D). Linux only, unless your OS happens to support iptables&#8230; no error checking, although it will echo usage out if you don&#8217;t give it any arguments.<\/p>\n<p>(Slight edit to fix $proto problem on 6\/21\/14, thanks to Eric M!)<\/p>\n<div class=\"codecolorer-container bash blackboard\" style=\"overflow:auto;white-space:nowrap;height:800px;\"><div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><br \/>\n<br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># forward a port with iptables (linux)... usage:<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp; $0 up|down port-1 ipaddr-2 port-2 protocol<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># XXX - warning - it will forward the port on ALL ip addrs other than<\/span><br \/>\n<span class=\"co0\"># the loopback and any VPN interfaces to the destination.<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># E.g.<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp; $0 up 666 192.168.0.2 777 tcp<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp;Would connect anyone going for:<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp; &nbsp; &nbsp; tcp port 666 on any IP that the system answers to<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp;And redirects it instead to:<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp; &nbsp; &nbsp; tcp port 777 on 192.168.0.2<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># If you use &quot;down&quot; you must use the EXACT same arguments as with the &quot;up&quot; <\/span><br \/>\n<span class=\"co0\"># command or won't work (at least, I think... iptables is pretty mysterious... <\/span><br \/>\n<span class=\"co0\"># you could always flush them.<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp;No error checking, although (a) iptables usually will gripe if it doesn't <\/span><br \/>\n<span class=\"co0\"># like your arguments, and (b) it'll print out the usage message if you don't <\/span><br \/>\n<span class=\"co0\"># use exactly 6 arguments.<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># The &quot;up&quot; command will also turn on ipforwarding by running this:<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># &nbsp; &nbsp;echo &quot;1&quot; &gt; \/proc\/sys\/net\/ipv4\/ip_forward<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<span class=\"co0\"># The &quot;down&quot; command WILL NOT set that to 0, if you want that turned off<\/span><br \/>\n<span class=\"co0\"># you have to do it yourself (it might break other things in my system.)<\/span><br \/>\n<span class=\"co0\">#<\/span><br \/>\n<br \/>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">&#91;<\/span> <span class=\"re4\">$#<\/span> <span class=\"re5\">-ne<\/span> <span class=\"nu0\">5<\/span> <span class=\"br0\">&#93;<\/span> ; <span class=\"kw1\">then<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw3\">echo<\/span> <span class=\"st0\">&quot;Usage: $0 up|down port-1 ip-2 port-2 tcp|udp&quot;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw3\">exit<\/span> <span class=\"nu0\">1<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<br \/>\n<span class=\"co0\"># up or down?<\/span><br \/>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">&#91;<\/span> <span class=\"st0\">&quot;X$1&quot;<\/span> = <span class=\"st0\">&quot;Xup&quot;<\/span> <span class=\"br0\">&#93;<\/span> ; <span class=\"kw1\">then<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">direction<\/span>=<span class=\"st0\">&quot;up&quot;<\/span><br \/>\n<span class=\"kw1\">elif<\/span> <span class=\"br0\">&#91;<\/span> <span class=\"st0\">&quot;X$1&quot;<\/span> = <span class=\"st0\">&quot;Xdown&quot;<\/span> <span class=\"br0\">&#93;<\/span> ; <span class=\"kw1\">then<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">direction<\/span>=<span class=\"st0\">&quot;down&quot;<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">echo<\/span> First argument must be either <span class=\"st0\">&quot;up&quot;<\/span> or <span class=\"st0\">&quot;down&quot;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">exit<\/span> <span class=\"nu0\">2<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<br \/>\n<span class=\"re2\">local_port<\/span>=<span class=\"re4\">$2<\/span><br \/>\n<span class=\"re2\">remote_ip<\/span>=<span class=\"re4\">$3<\/span><br \/>\n<span class=\"re2\">remote_port<\/span>=<span class=\"re4\">$4<\/span><br \/>\n<span class=\"re2\">proto<\/span>=<span class=\"re4\">$5<\/span><br \/>\n<br \/>\n<span class=\"co0\"># will not reverse this, as other stuff might break, but ensure it's on!<\/span><br \/>\n<span class=\"kw3\">echo<\/span> <span class=\"st0\">&quot;1&quot;<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"sy0\">\/<\/span>proc<span class=\"sy0\">\/<\/span>sys<span class=\"sy0\">\/<\/span>net<span class=\"sy0\">\/<\/span>ipv4<span class=\"sy0\">\/<\/span>ip_forward<br \/>\n<br \/>\n<span class=\"co0\"># get the ip addrs for a host, in its mind<\/span><br \/>\n<span class=\"re2\">all_ips<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw2\">ifconfig<\/span> <span class=\"sy0\">|<\/span> <span class=\"kw2\">awk<\/span> <span class=\"st_h\">'{if (n) { all[dev] = substr($2, match($2, &quot;:&quot;) + 1); n = 0 }} {if (match($0, &quot;^[^ \\t]&quot;) &amp;&amp; $1 != &quot;lo&quot;) { n = 1; dev = $1; all[dev]=&quot;&quot; }} END { for (i in all) printf(&quot;%s &quot;, all[i]) ; print &quot;&quot;}'<\/span><span class=\"sy0\">|<\/span> <span class=\"kw2\">sed<\/span> <span class=\"st_h\">'s\/,]$\/]\/'<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">&#91;<\/span> <span class=\"re1\">$direction<\/span> = <span class=\"st0\">&quot;up&quot;<\/span> <span class=\"br0\">&#93;<\/span> ; <span class=\"kw1\">then<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span> <span class=\"kw2\">ip<\/span> <span class=\"kw1\">in<\/span> <span class=\"re1\">$all_ips<\/span>; <span class=\"kw1\">do<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> <span class=\"st0\">&quot;forwarding <span class=\"es2\">$proto<\/span> traffic from <span class=\"es2\">$ip<\/span> : <span class=\"es2\">$local_port<\/span> =&gt; <span class=\"es2\">$remote_ip<\/span> : <span class=\"es2\">$remote_port<\/span>&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-A<\/span> PREROUTING &nbsp;<span class=\"re5\">-i<\/span> eth0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">-d<\/span> <span class=\"re1\">$ip<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$local_port<\/span> &nbsp; <span class=\"re5\">-j<\/span> DNAT <span class=\"re5\">--to-destination<\/span> <span class=\"re1\">$remote_ip<\/span>:<span class=\"re1\">$remote_port<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-A<\/span> PREROUTING &nbsp;<span class=\"re5\">-i<\/span> eth0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">-d<\/span> <span class=\"re1\">$ip<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$local_port<\/span> &nbsp; <span class=\"re5\">-j<\/span> DNAT <span class=\"re5\">--to-destination<\/span> <span class=\"re1\">$remote_ip<\/span>:<span class=\"re1\">$remote_port<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-A<\/span> POSTROUTING <span class=\"re5\">-o<\/span> tun0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$remote_port<\/span> <span class=\"re5\">-j<\/span> MASQUERADE<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-A<\/span> POSTROUTING <span class=\"re5\">-o<\/span> tun0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$remote_port<\/span> <span class=\"re5\">-j<\/span> MASQUERADE<br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">done<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span> <span class=\"kw2\">ip<\/span> <span class=\"kw1\">in<\/span> <span class=\"re1\">$all_ips<\/span>; <span class=\"kw1\">do<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> <span class=\"st0\">&quot;disabling forwarding of <span class=\"es2\">$proto<\/span> traffic from <span class=\"es2\">$ip<\/span> : <span class=\"es2\">$local_port<\/span> =&gt; <span class=\"es2\">$remote_ip<\/span> : <span class=\"es2\">$remote_port<\/span>&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-D<\/span> PREROUTING &nbsp;<span class=\"re5\">-i<\/span> tun0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">-d<\/span> <span class=\"re1\">$ip<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$local_port<\/span> &nbsp; <span class=\"re5\">-j<\/span> DNAT <span class=\"re5\">--to-destination<\/span> <span class=\"re1\">$remote_ip<\/span>:<span class=\"re1\">$remote_port<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-D<\/span> PREROUTING &nbsp;<span class=\"re5\">-i<\/span> tun0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">-d<\/span> <span class=\"re1\">$ip<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$local_port<\/span> &nbsp; <span class=\"re5\">-j<\/span> DNAT <span class=\"re5\">--to-destination<\/span> <span class=\"re1\">$remote_ip<\/span>:<span class=\"re1\">$remote_port<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">echo<\/span> iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-D<\/span> POSTROUTING <span class=\"re5\">-i<\/span> eth0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$remote_port<\/span> <span class=\"re5\">-j<\/span> MASQUERADE<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iptables <span class=\"re5\">-t<\/span> nat <span class=\"re5\">-D<\/span> POSTROUTING <span class=\"re5\">-o<\/span> eth0 <span class=\"re5\">-p<\/span> <span class=\"re1\">$proto<\/span> <span class=\"re5\">--dport<\/span> <span class=\"re1\">$remote_port<\/span> <span class=\"re5\">-j<\/span> MASQUERADE<br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">done<\/span><br \/>\n<span class=\"kw1\">fi<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>I find iptables to be a bit of a beast&#8230; so for posterity (or my own sanity, in case I lost this, I might recover from search engine caches!) this simply forwards a port (A) of a certain protocol from one host (B) to a second port (C) on a 2nd IP (D). Linux only, [&hellip;]<\/p>\n","protected":false},"author":44,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31,146,4,6],"tags":[265,270,271],"class_list":["post-987","post","type-post","status-publish","format-standard","hentry","category-code","category-hack","category-security","category-tech","tag-blah-blah","tag-i-hate-iptables","tag-port-forwarding"],"_links":{"self":[{"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/posts\/987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/trouble.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=987"}],"version-history":[{"count":6,"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/posts\/987\/revisions"}],"predecessor-version":[{"id":1010,"href":"https:\/\/trouble.org\/index.php?rest_route=\/wp\/v2\/posts\/987\/revisions\/1010"}],"wp:attachment":[{"href":"https:\/\/trouble.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trouble.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trouble.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}