LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (http://www.linuxquestions.org/questions/linux-networking-3/)
-   -   Iptables and TCP - ACK PSH FIN URGP=0 problem (http://www.linuxquestions.org/questions/linux-networking-3/iptables-and-tcp-ack-psh-fin-urgp%3D0-problem-887848/)

nightg0at 06-22-2011 09:43 PM

Iptables and TCP - ACK PSH FIN URGP=0 problem
 
I have an issue with iptables blocking countless TCP packets claiming that they match the rule:
Code:

$IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID INPUT " --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A INPUT -m state --state INVALID -j DROP

These packets all have the ACK PSH FIN flags set.
Are these actually invalid?
I see them from even legitimate traffic like google.

I am considering adding a rule to unblock them since it happens so frequently.
A rule such as
Code:

$IPTABLES -A INPUT --tcp-flags ACK,PSH,FIN ACK,PSH,FIN -m state --state ESTABLISHED,RELATED -j ACCEPT
I believe would be what I'm looking for but I wonder if there are any negative security implications of allowing them.

I also read somewhere that it could be an issue of the PSH flag preventing iptables from examining them properly which prevents iptables from recognizing them as ESTABLISHED or RELATED.

If thats the case, then the above rule won't help.
I'm kind of confused here.

Thanks,
ng

lisle2011 06-23-2011 11:47 AM

iptables problem
 
It seems that you are sending everything to be dropped and logged with the first two statements.

The second statement reverses the "send everything to drop and log" but can't work if it comes after

here is a suggestion: Get rid of (comment out) all those three statements and replace with these specific statements.

# Stealth Scans and TCP State Flags

# All of the bits are cleared
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# SYN and FIN are both set

# ---------------------------------------------- #
# Using Connection State to By-Pass Rule Checking

if [ "$CONNECTION_TRACKING" = "1" ]; then
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# using the state module alone, INVALID will break protocols that use
# bi-directional connections or multiple connections or exchanges,
# unless an ALG is provided for the protocol. At this time, FTP and
# IRC are the only protocols with ALG support.

$IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "INVALID input: "
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state INVALID -j LOG --log-prefix "INVALID output: "
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
fi

# --------------------------------------------- #
# Source Address Spoofing and Other Bad Addresses

# Refuse spoofed packets pretending to be from the external interface's IP Address
$IPTABLES -A INPUT -i $INTERNET -s $IPADDR -j DROP

# Refuse packets claiming to be from a Class A private network
$IPTABLES -A INPUT -i $INTERNET -s $CLASS_A -j DROP

# Refuse packets claiming to be from a Class B private network
$IPTABLES -A INPUT -i $INTERNET -s $CLASS_B -j drop

# Refuse packets claiming to be from a Class C private network
$IPTABLES -A INPUT -i $INTERNET -s $CLASS_C -j DROP

# Refuse packets claiming to be from the loopback device
$IPTABLES -A INPUT -i $INTERNET -s $LOOPBACK -j DROP

# Refuse malformed broadcast packets
$IPTABLES -A INPUT -i $INTERNET -s $BROADCAST_DEST -j LOG
$IPTABLES -A INPUT -i $INTERNET -s $BROADCAST_DEST -j DROP

$IPTABLES -A INPUT -i $INTERNET -d $BROADCAST_SRC -j LOG
$IPTABLES -A INPUT -i $INTERNET -d $BROADCAST_SRC -j LOG

if [ "DHCP_CLIENT" = "0" ]; then
# Refuse directed broadcasts used to map networks and in Denial Of Service (DOS) attacks
$IPTABLES -A INPUT -i $INTERNET -d $SUBNET_BASE -j DROP
$IPTABLES -A INPUT -i $INTERNET -d $SUBNET_BROADCAST -j DROP

# Refuse limited brooadcasts
$IPTABLES -A INPUT -i $INTERNET -d $BROADCAST_DEST -j DROP
fi

# Refuse Class D Multicast addresses, illegal as a source address
$IPTABLES -A INPUT -i $INTERNET -s $CLASS_D_MULTICAST -j DROP
$IPTABLES -A INPUT -i $INTERNET -p ! udp -d $CLASS_D_MULTICAST -j DROP
$IPTABLES -A INPUT -i $INTERNET -p udp -d $CLASS_D_MULTICAST -j ACCEPT

# Refuse Class E reserved IP addresses
$IPTABLES -A INPUT -i $INTERNET -s $CLASS_E_RESERVED_NET -j DROP

if [ "$DHCP_CLIENT" = "1" ]; then
$IPTABLES -A INPUT -i $INTERNET -p udp -s $BROADCAST_SRC --sport 67 -d $BROADCAST_DEST --dport 68 -J ACCEPT
fi

# Refuse addresses deefined as reserved by IANA
# 0.*.*.* - Can't be blaocked unilaterally with DHCP
# 169.254.0.0/16 - Link Local Networks
# 192.0.2.0/24 -TEST-NET

$IPTABLES -A INPUT -i $INTERNET -s 0.0.0.0/8 -j DROP
$IPTABLES -A INPUT -i $INTERNET -s 169.254.0.0/16 -j DROP
$IPTABLES -A INPUT -i $INTERNET -s 192.0.2.0/24 -j DROP

# ---------------------------------------------- #

$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# SYN and RST are both set
$IPTABLES -A INPUT -p tcp --tcp-flags SYN.RST SYN,RST -j DROP

#FIN and RST are both set
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP

# FIN is the only bit set, without the expected ACK
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP

# PSH is the only bit set, without the expected ACK
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP

#URG is the only bit set, without the expected ACK
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP

Hopefully you will start working properly.

...

nightg0at 06-23-2011 01:51 PM

I decided to go with a "Bad TCP Packets" approach. I keep a close eye on my iptables logs so if I find any one them that cause trouble with legitimate traffic I'll remove the rules. I do already have a IANA Reseved block list and broadcast blocks included in my rules although I have not listed them below. I'm really looking to stop scanners and bad packets, which is what I was hoping the INVALID rule would do, but I am finding it does not really.

This is the generic portion of my rules:
Code:

#!/bin/sh
IPTABLES=/usr/sbin/iptables
IP6TABLES=/usr/sbin/ip6tables
MODPROBE=/sbin/modprobe
EXTIF=eth0


## Flush existing rules and set chain policy setting to DROP
echo "[+] Flushing existing iptables rules..."
# Delete all rules.
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

# Delete all (non-builtin) user-defined chains.
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X

# Zero all packet and byte counters.
$IPTABLES -Z
$IPTABLES -t nat -Z
$IPTABLES -t mangle -Z

# Set default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

# User defined chains
$IPTABLES -N BAD_TCP_IN
$IPTABLES -N BAD_TCP_OUT

### Load connection-tracking modules
$MODPROBE ip_conntrack
$MODPROBE iptable_nat
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_nat_ftp

RLIMIT="-m limit --limit 3/s --limit-burst 8"


echo "[+] Tune Netfilter proc"

# Enable protection against SYN flood attacks.
#echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Ignore all ICMP ECHO requests (i.e. disable PING).
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

# Ignore ICMP ECHO requests to broadcast/multicast addresses only.
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Log packets with impossible addresses.
echo 0 > /proc/sys/net/ipv4/conf/all/log_martians

# Don't log invalid responses to broadcast frames, they just clutter the logs.
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# Don't accept or send ICMP redirects.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
# Don't accept source routed packets.
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

# Turn on IP forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward


echo "[+] Setting up IP6TABLES..."
$IP6TABLES -F
$IP6TABLES -t mangle -F

# Delete all (non-builtin) user-defined chains.
$IP6TABLES -X
$IP6TABLES -t mangle -X

# Zero all packet and byte counters.
$IP6TABLES -Z
$IP6TABLES -t mangle -Z

# Set default policies
$IP6TABLES -P INPUT DROP
$IP6TABLES -P OUTPUT DROP
$IP6TABLES -P FORWARD DROP

# User defined chains
$IP6TABLES -N BAD_TCP_IN
$IP6TABLES -N BAD_TCP_OUT


echo "[+] Setting up BAD_TCP_IN chain..."
                                ###### Bad Packets ######
$IPTABLES -A BAD_TCP_IN -p TCP ! --syn -m state --state NEW -j LOG --log-prefix "DROP BAD1" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP ! --syn -m state --state NEW -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL NONE -j LOG --log-prefix "DROP BAD2" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL NONE -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ALL -j LOG --log-prefix "DROP BAD3" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ALL -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "DROP BAD4" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "DROP BAD5" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "DROP BAD6" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,RST SYN,RST -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "DROP BAD7" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags RST,FIN RST,FIN -j LOG --log-prefix "DROP BAD9" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags RST,FIN RST,FIN -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,URG SYN,URG -j LOG --log-prefix "DROP BAD10" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags SYN,URG SYN,URG -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,PSH -j LOG --log-prefix "DROP BAD11" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,PSH -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,ACK,PSH -j LOG --log-prefix "DROP BAD12" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,ACK,PSH -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,FIN FIN -j LOG --log-prefix "DROP BAD13" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,FIN FIN -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,PSH PSH -j LOG --log-prefix "DROP BAD14" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,PSH PSH -j DROP
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,URG URG -j LOG --log-prefix "DROP BAD15" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ACK,URG URG -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD16" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK -m state --state NEW,RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL PSH,ACK -m state --state RELATED -j LOG --log-prefix "DROP BAD17" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL PSH,ACK -m state --state RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL RST -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD18" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL RST -m state --state NEW,RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN -m state --state ESTABLISHED -j LOG --log-prefix "DROP BAD19" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN -m state --state ESTABLISHED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,ACK -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD20" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL SYN,ACK -m state --state NEW,RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,ACK -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD21" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,ACK -m state --state NEW,RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL RST,ACK -m state --state RELATED -j LOG --log-prefix "DROP BAD23" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL RST,ACK -m state --state RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK,PSH,RST -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD24" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK,PSH,RST -m state --state NEW,RELATED -j DROP

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,PSH,ACK -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD25" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL FIN,PSH,ACK -m state --state NEW,RELATED -j DROP

                                ###### INPUT chain ######
echo "[+] Setting up INPUT chain..."
### BAD_TCP
$IPTABLES -A INPUT -p tcp -j BAD_TCP_IN

### ICMP
$IPTABLES -A INPUT -p icmp --fragment -j LOG --log-prefix "ICMP FRAGMENT " --log-ip-options
$IPTABLES -A INPUT -p icmp --fragment -j DROP
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j LOG --log-prefix "ECHO REQUEST " --log-ip-options
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j DROP

### State Tracking
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


### ACCEPT rules

# Loopback
$IPTABLES -A INPUT -p tcp -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
$IPTABLES -A INPUT -p udp -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

...

### Defaut ####
$IPTABLES -A INPUT -j LOG --log-prefix "DROP INPUT " --log-ip-options --log-tcp-options --log-tcp-sequence

The output chain is similar. So far this has been working for me quite well.

Every month or so I try to search around and see if I find ways to improve it and try not to get complacent about them.
Along with this I also use psad and fwsnort.
I havent looked at pset yet though. Thats on my to-do list.

lisle2011 06-24-2011 07:57 PM

iptables problem
 
Scanning itself is not preventable, the trick is to not let the scanner know you have an active port.

i.e an ACK packet sent to a listening port would respond with a RST. This tells the scanner the port is active and now the evil black hat can do more.

Dropping the packet because it is not part of an established connection is a good policy because the scanner gets back nothing.

Hosts responding with an RST can help the scanner map the network.

Silently dropping the unwanted packet is quite useful. Logging it might be a waste of resources, I mean, what are you going to do?

If you find lots of logging with failed connection attempts don't worry, they failed, you have logged them. Your system along with everyone else is being attacked on a daily basis. This is unfortunately the nature of the internet.

The next step after your firewall would be something like tripwire and perhaps tiger to determine if you have been breached and what damage was done. Setting all this is up after the fact (of being breached) is a waste of time, you need a fresh system and you set up all your security before you plug in to the internet.

As a note, wireless is inherently insecure and requires you pay particular attention. USB has some issues which I am digging into as does bluetooth.

Stay vigilant.

nightg0at 06-25-2011 02:44 PM

The logging for the bad packets is mostly to evaluate how the rules are effecting my normal traffic.
I also have a router firewall and a gateway firewall, so if those are doing thier jobs, scans should not reach this machine outside the forwarded ports. It could also mean another machine on my internal LAN is breached. Thats why I log them. They are not logged on my gateway.
I also deploy OSSEC agents, tripwire, psad, fwsnort, and SPI + key authentication for my SSH.
I also plan on moving setting up a snort system on my SPAN port as well as a central logging and management server to play around with things like nagios and and such and will be experimenting with grsecurity hardened sources.
I do not use wireless nor bluetooth.

You are right about the RST scans.
For forwarded TCP they could reveal my ports.
Wouldnt they be blocked as not established? Even though they are ACKs they shouldnt be in my established traffic tables right?
The rule
Code:

$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK -m state --state NEW,RELATED -j LOG --log-prefix "DROP BAD16" --log-ip-options --log-tcp-options --log-tcp-sequence
$IPTABLES -A BAD_TCP_IN -p TCP --tcp-flags ALL ACK -m state --state NEW,RELATED -j DROP

should filter them out right?

I should also maybe put something in there to block ICMP Port Unreachables when forwarded UDP ports are off.

lisle2011 06-26-2011 07:56 PM

ACK Scans
 
You should not see anything unless you choose to also log the event, log the event then drop the bad packet. Your doing fine. It's tough keeping out the bad guys but you can certainly get them to move on to another victim.


All times are GMT -5. The time now is 03:07 PM.