The art of port forwarding on Linux
Posted by Warith Al Maawali on Mar 23, 2014 in Blog, Linux | 2 comments

In order to be stealth and jump from node to another to cover up your movements sometimes you will need to use port forwarding. Why in Linux because its stable and you have many options that you don’t get on windows.
There are many tools out there but we have picked the ones we have tried as explained below:
- Rinetd Score:3/10 Limitation on number of connections.
- Socat Score:6/10 High ram consumption more connection=more RAM.
- Redir Score:8/10 Same as above but less consumption of RAM for about 20%.
- Haproxy Score:10/10 Is an http, https, and TCP load balancer but can be used to forward Tcp traffic only light usage of CPU and RAM.
- Iptables Score:10/10 Perfect usage is 0 CPU 12 MB RAM including the OS !.
Rinetd:
To install rinetd, we simply run:
sudo apt-get update sudo apt-get install rinetd
rinetd’s configuration file is /etc/rinetd.conf.
nano /etc/rinetd.conf <pre> To forward traffic from your internet node ip 212.72.6.1 port 808 to remote node 62.41.90.2 port 443 add this line: <pre> 212.72.6.1 808 62.41.90.2 443
To forward from all local ips on port 808 to 62.41.90.2 on port 443 :
0.0.0.0 808 62.41.90.2 443
Then we restart rinetd:
/etc/init.d/rinetd restart #or service rinetd restart
Socat:
To install socat, we simply run:
sudo apt-get update sudo apt-get install socat
To run socat and forward traffic from your internet node ip 212.72.6.1 port 808 to remote node 62.41.90.2 port 443 run the following command:
socat TCP4-LISTEN:808,fork TCP4:62.41.90.2:443
To forward traffic from your internet node from port 9090 to remote node 62.41.90.2 port 22 and forward traffic from port 81 to port 21 on ftp.microsft.com run the following command:
socat TCP4-LISTEN:9090,fork TCP4:62.41.90.2:22|socat TCP4-LISTEN:81,fork TCP4:ftp.microsft.com:21
Redir:
To install redir, we simply run:
sudo apt-get update sudo apt-get install redir
To run redir and forward traffic from your internet node ip 212.72.6.1 port 808 to remote node 62.41.90.2 port 443 run the following command:
redir --laddr=212.72.6.1 --lport=808 --caddr=62.41.90.2 --cport=443
To forward traffic from your internet node 212.72.6.1 from port 9090 to remote node 62.41.90.2 port 22 and forward traffic from port 81 to port 21 on ftp.microsft.com run the following command:
redir --laddr=212.72.6.1 --lport=9090 --caddr=62.41.90.2 --cport=22|redir --laddr=212.72.6.1 --lport=81 --caddr=ftp.microsft.com --cport=21
Haproxy:
At the moment haproxy can only be retrieved from sid unstable repository so you need to do the following changes:
nano /etc/apt/sources.list
Add the following:
deb http://ftp.de.debian.org/debian sid main
to
nano /etc/apt/sources.list
To install haproxy, we simply run:
sudo apt-get update sudo apt-get install haproxy
We need to set ENABLED to 1 in order to get all the init scripts working:
nano /etc/default/haproxy
Config it by adding the server details end of listen http-in section:
nano /etc/haproxy/haproxy.cfg
On defaults section change http to tcp:
mode tcp
Then add to accept connection on port 80 and 443 then forward them to 6 different servers:
global stats socket /var/run/haproxy/haproxy.sock mode 0600 level admin #Creates Unix-Like socket to fetch stats log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy user haproxy group haproxy daemon maxconn 99999 defaults log global mode tcp contimeout 500000 clitimeout 500000 srvtimeout 500000 listen http-in option tcplog option logasap contimeout 500000 clitimeout 500000 srvtimeout 500000 maxconn 99999 bind 0.0.0.0:80 bind 0.0.0.0:443 server server-1 ip:port maxconn 5000 server server-2 ip:port maxconn 10000 listen stats 0.0.0.0:1936 mode http #log global maxconn 10 clitimeout 100s srvtimeout 100s contimeout 100s timeout queue 100s stats enable stats hide-version stats refresh 30s stats show-node stats auth admin:your_passwrod_here stats uri /haproxy?stats
Run this command to create the required directory:
mkdir /var/run/haproxy/
To access the statistics report visit the following site and make sure you use your account as set on haproxy.cfg:
http://www.your-haproxy-server-ip.com:11936/haproxy?stats
To run as daemon:
cd /etc/haproxy/ haproxy -f haproxy.cfg -D
Or use the following:
/etc/init.d/haproxy start /etc/init.d/haproxy stop /etc/init.d/haproxy restart
To check the ips of connected clients:
# You need to install netcat first: apt-get install netcat-openbsd # Then run the following command: echo show sess | nc -U /var/run/haproxy/haproxy.sock | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort | uniq -c
Troubleshooting:
For some reasons if the load is to high Haproxy service will stop running so the only way to make sure it will stay alive is to monitor it and restart it using monit tool as the following:
sudo apt-get install monit
Now edit the config file
sudo nano /etc/monit/monitrc # change set daemon 120 to set daemon 5 #uncomment the following lines: set httpd port 2812 and use address localhost # only accept connection from localhost allow localhost # allow localhost to connect to the server and allow admin:monit # require user 'admin' with password 'monit' allow @monit # allow users of group 'monit' to connect (rw) allow @users readonly # allow users of group 'users' to connect readonly # Now go to the end of the file and paste the following: check process haproxy with pidfile /var/run/haproxy.pid start program = "/etc/init.d/haproxy start" stop program = "/etc/init.d/haproxy stop"
Check if your syntax is correct if not you will get an error:
monit -t
Now we are done with the configuration let us run it:
monit
To check the status:
monit status
To reload:
monit reload
After resolving any possible syntax errors, you can start running all of the monitored programs by:
monit start all
If you are getting the following error:
[....] Restarting haproxy: haproxy[ALERT] 221/134103 (1900) : cannot bind socket for UNIX listener (/var/run/haproxy/haproxy.sock). Aborting. [ALERT] 221/134103 (1900) : [/usr/sbin/haproxy.main()] Some protocols failed to start their listeners! Exiting. failed!
Open /etc/haproxy/haproxy.cfg and comment the following line:
stats socket /var/run/haproxy/haproxy.sock mode 0600 level admin #Creates Unix-Like socket to fetch stats
Extra commands for logging purpose only:
create a HAProxy config file for rsyslog:
nano /etc/rsyslog.d/haproxy.conf
Then add the following:
if ($programname == 'haproxy' and $syslogseverity-text == 'info') then -/var/log/haproxy/haproxy-info.log & ~ if ($programname == 'haproxy' and $syslogseverity-text == 'notice') then -/var/log/haproxy/haproxy-notice.log & ~
This will rotate your HAProxy logs daily and keep them for 4 weeks.
nano /etc/logrotate.d/haproxy
Add the following:
/var/log/haproxy/*.log { daily missingok rotate 28 compress delaycompress notifempty create 644 root adm sharedscripts postrotate /etc/init.d/haproxy reload > /dev/null endscript }
Iptables:
To forward using iptables you don’t need to install any tool so to forward traffic from your internet node ip 212.72.6.1 port 808 to remote node 62.41.90.2 port 443 run the following command:
iptables -F iptables -F -t nat echo 1 >| /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 808 -j DNAT --to 62.41.90.2:443 iptables -t nat -A POSTROUTING -j MASQUERADE
List your changes:
iptables -L -t nat
To forward traffic from your internet node 212.72.6.1 from port 9090 to remote node 62.41.90.2 port 22 and forward traffic from port 81 to port 21 on ftp.microsft.com run the following command:
iptables -F iptables -F -t nat echo 1 >| /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 9090 -j DNAT --to 62.41.90.2:22 iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 81 -j DNAT --to 67.215.65.132:21 # You can't use domain names use the ip I will show you later how to automate this iptables -t nat -A POSTROUTING -j MASQUERADE iptables -L -t nat
Display Iptables counters:
watch --interval 0 'iptables -nvL | grep -v "0 0"'
or
while true; do iptables -nvL > /tmp/now; diff -U0 /tmp/prev /tmp/now > /tmp/diff; clear; cat /tmp/diff; mv /tmp/now /tmp/prev; slee p 1; done
Startup script:
For socat, redir, and iptables you will need to put them on a start-up script so they start each time your node boots up.
Create a boot script:
nano /etc/init.d/myfwd
Add the following for socat:
#!/bin/bash socat TCP4-LISTEN:9090,fork TCP4:62.41.90.2:22|socat TCP4-LISTEN:81,fork TCP4:ftp.microsft.com :21
Add the following for redir:
#!/bin/bash redir --laddr=212.72.6.1 --lport=9090 --caddr=62.41.90.2 --cport=22|redir --laddr=212.72.6.1 --lport=81 --caddr=ftp.microsft.com --cport=21
Add the following for iptables:
#!/bin/bash iptables -F iptables -F -t nat echo 1 >| /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 9090 -j DNAT --to 62.41.90.2:22 iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 81 -j DNAT --to 67.215.65.132:21 # You can't use domain names use the ip I will show you later how to automate this iptables -t nat -A POSTROUTING -j MASQUERADE
If you need to get the ip automatically from a domain name you need to use dig command as the following:
sudo apt-get install dnsutils
Then add the following for iptables:
#!/bin/bash iptables -F iptables -F -t nat echo 1 >| /proc/sys/net/ipv4/ip_forward IP_ADDR=$(dig +short ftp.microsft.com| awk 'NR==1') iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 9090 -j DNAT --to 62.41.90.2:22 iptables -t nat -A PREROUTING -p tcp -d 212.72.6.1 --dport 81 -j DNAT --to $IP_ADDR::21 iptables -t nat -A POSTROUTING -j MASQUERADE
Then run the following commands:
cd /etc/init.d chmod a+x myfwd update-rc.d myfwd defaults
Reboot then check your results by the following commands:
socat and redir use:
netstat -antp
To check ip tables you will need to install netstat-nat
sudo apt-get install netstat-nat
Then run:
netstat-nat -D
Custom scripts:
Here are some scripts that we have written to monitor forward status for redir, socat, and iptables.
You will need vnstat to install it:
sudo apt-get install vnstat
The following script will show you cpu + ram + forward counters and status from redir or socat:
Shell script:
#!/bin/sh # Shell script written by W. Al Maawali # (c) 2014 Founder of Eagle Eye Digital Solutions # http://www.digi77.com # http://www.om77.net # script starts here: echo "" echo "" users_online=`uptime` echo "System status: "$users_online echo "======================================================================" echo "" echo "" cat /proc/meminfo |grep Free used_ram=`free | grep Mem | awk '{print $3/$2 * 100.0}'` free_ram=`free | grep Mem | awk '{print $4/$2 * 100.0}'` echo "" echo "Used RAM = %"$used_ram echo "Free RAM = %"$free_ram echo "" echo "" echo "======================================================================" echo "Bandwidth Status:" vnstat -i venet0 -m echo "======================================================================" echo "Getting results......." echo "" echo "" org1_count=`netstat -antp | grep -c '51.219.221.206\|215.165.18.97'` org2_count=`netstat -antp | grep -c '132.71.46.3'` sum=$(($org1_count+$org2_count)) sokatSum=`ps aux | grep -c socat` redirSum=`ps aux | grep -c redir` echo "Org_1 =" $org1_count echo "Org_2 =" $org2_count echo "" echo "Sum =" $sum echo "Redir =" $redirSum echo "Sokat =" $sokatSum echo "" echo "" echo "======================================================================" echo "Server connection by ip numbers:" echo "" netstat -ntu | awk -F"[ :]+" 'NR>2{print $6}'|sort|uniq -c|sort -nr echo "" echo "" echo "======================================================================"
The following script will show you cpu + ram + forward counters and status from iptables:
Shell script:
#!/bin/sh # Shell script written by W. Al Maawali # (c) 2014 Founder of Eagle Eye Digital Solutions # http://www.digi77.com # http://www.om77.net # script starts here: echo "" echo "" users_online=`uptime` echo "System status: "$users_online echo "======================================================================" echo "" echo "" cat /proc/meminfo |grep Free used_ram=`free | grep Mem | awk '{print $3/$2 * 100.0}'` free_ram=`free | grep Mem | awk '{print $4/$2 * 100.0}'` echo "" echo "Used RAM = %"$used_ram echo "Free RAM = %"$free_ram echo "" echo "" echo "======================================================================" echo "Bandwidth Status:" vnstat -i venet0 -m echo "======================================================================" echo "Getting results......." echo "" echo "" org1_count=`netstat-nat -s '51.219.221.206'|wc -l` org1b_count=`netstat-nat -s '215.165.18.97'|wc -l` org1_count=$(($org1_count+$org1b_count)) org2_count=`netstat-nat -s '132.71.46.3'|wc -l` sum=$(($org1_count+$org2_count)) sokatSum=`ps aux | grep -c socat` redirSum=`ps aux | grep -c redir` echo "Org_1 =" $org1_count echo "Org_2 =" $org2_count echo "" echo "Sum =" $sum echo "Redir =" $redirSum echo "Sokat =" $sokatSum echo "" echo "" echo "======================================================================" echo "Server connection by ip numbers:" echo "" netstat -ntu | awk -F"[ :]+" 'NR>2{print $6}'|sort|uniq -c|sort -nr echo "" echo "" echo "======================================================================"
All ips mentioned above are just examples you should use your own ip numbers for the commands to function properly.



Latest posts by Warith Al Maawali (see all)
- Apple iOS Mail Client leaking highly sensitive information - December 27, 2019
- Validating VPN nodes - November 3, 2019
- Migrating from php 5.6 to 7.3 - November 1, 2019
- Linux Kodachi 8.27 The Secure OS - October 20, 2013
- Migrating from Vbulletin to Burning board - March 27, 2016
What does “>|” mean?
This PIPE operator is very useful where the output of first command acts as an input to the second command. For example, pipeline the output of ‘ls -l‘ to ‘less‘ and see the output of the command.