Ingress policing (matching netfilter marks)

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm having issues with policing my incoming traffic by matching packet marks
made by iptables. I've checked as many sites and guides as I can find, and I
seem to be doing the exact same thing as they all are, but there's still no
success. As such, I was wondering if anyone can have a quick look to see if
I've done anything obviously stupid?

Essentially, I can get the egress working fine, matching packets based on
criteria in iptables. However, doing the same for ingress using:
`tc qdisc add dev $DEV handle ffff: ingress`
`tc filter add dev $DEV parent ffff: protocol ip prio 1 handle $MARK_BULK fw
police rate ${DOWNSTREAM}kbit burst ${BURST}kbit drop flowid :1`

does nothing: packets go through the qdisc fine, but nothing matches the
filter:

michael@bob:~$ sudo tc -s -d qdisc show dev ppp0
qdisc ingress ffff: ----------------
 Sent 47169399 bytes 46532 pkts (dropped 0, overlimits 0)

michael@bob:~$ sudo tc -s -d filter show dev ppp0 root
filter parent ffff: protocol ip pref 1 fw
filter parent ffff: protocol ip pref 1 fw handle 0x1e classid :1  police
0x28 rate 600000bit burst 8Kb mtu 2Kb action drop
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

I suspected I just might not be marking things correctly, so I tried u32
matching 0.0.0.0/0 - that worked fine, but for _all_ traffic (as it should).
So I tried marking *every* packet with $MARK_BULK (and verified that the
mark was correct using a log match, and watching the syslog file) in both
prerouting and postrouting chains, yet this didn't help either.

Regardless of what I do, I can't get the above filter to match anything at
all - I'm sure the packets are marked correctly, I just can't match them.
Any ideas?

(I'll copy my entire configs below for reference if needed.)

Cheers!
Michael



####################### CONFIG FILES - firewall #######################

#!/bin/bash

###########################################################################
#
# Custom functions and configuration
#

RetrieveIP() {
	nic="$1"
	TEMP=""

	if ! /sbin/ifconfig | grep $nic > /dev/null; then
		echo -e "\n\n interface $nic does not exist...  Aborting!"
		exit 1;
	fi

	TEMP=`ifconfig $nic | awk '/inet addr/ { gsub(".*:", "", $2) ; print
$2 }'`

	if [ "$TEMP" = '' ]; then
		echo "Aborting: Unable to determine the IP of $nic ... DHCP
problem?"
		exit 1
	else
		echo "$TEMP"
	fi
}


#### 1.1 Internet Configuration.
INET_IFACE="ppp0"
INET_IP=`RetrieveIP $INET_IFACE`

#### 1.2 Local Area Network configuration.
LAN_IFACE="eth0"
LAN_IP=`RetrieveIP $LAN_IFACE`
LAN_IP_RANGE="192.168.0.0/24"

#### 1.4 Localhost Configuration.
LO_IFACE="lo"
LO_IP="127.0.0.1"

#### 1.5 IPTables Configuration.
IPTABLES="/sbin/iptables"

#### 1.6 Misc Configuration.
#MARK_FORWARD=$[2#00000001]
#MARK_PRIORITY=$[2#00000010]
#MARK_GENERAL=$[2#00000100]
#MARK_BULK=$[2#00001000]

MARK_FORWARD=1
MARK_PRIORITY=10
MARK_GENERAL=20
MARK_BULK=30

DUMPER_IP="192.168.0.6"


###########################################################################
#
# Firewall START function
#

firewall_start ()
{
	######## 3.1 Required proc configuration

	# Enable forwarding
	echo 1 > /proc/sys/net/ipv4/ip_forward

	# no IP spoofing
	if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
	then
		for i in /proc/sys/net/ipv4/conf/*/rp_filter
		do
			echo 1 > $i
		done
	fi

	# Disable Source Routed Packets
	for i in /proc/sys/net/ipv4/conf/*/accept_source_route
	do
		echo 0 > $i
	done


	######## 
	######## 4. rules set up.
	######## 

	######## 4.1 Filter table


	#### 4.1.1 Set policies

	$IPTABLES -P INPUT DROP
	$IPTABLES -P OUTPUT DROP
	$IPTABLES -P FORWARD DROP


	#### 4.1.2 Create userspecified chains

	# Create chain for bad tcp packets
	$IPTABLES -N bad_tcp

	# Create separate chains for ICMP, TCP and UDP to traverse
	$IPTABLES -N tcp_packets
	$IPTABLES -N udp_packets
	$IPTABLES -N icmp_packets
	$IPTABLES -N common


	#### 4.1.3 Create content in userspecified chains

	# bad_tcp chain
	$IPTABLES -A bad_tcp -p tcp --tcp-flags SYN,ACK SYN,ACK -m state
--state NEW -j REJECT --reject-with tcp-reset
	$IPTABLES -A bad_tcp -p tcp ! --syn -m state --state NEW -j LOG
--log-prefix "New not syn:"
	$IPTABLES -A bad_tcp -p tcp ! --syn -m state --state NEW -j DROP

	# TCP rules
	$IPTABLES -A tcp_packets -p tcp --dport 20 -j common
	$IPTABLES -A tcp_packets -p tcp --dport 21 -j common
	$IPTABLES -A tcp_packets -p tcp --dport 22 -j common
	$IPTABLES -A tcp_packets -p tcp --dport 80 -j common
	$IPTABLES -A tcp_packets -p tcp --dport 443 -j common

	# UDP ports
	#$IPTABLES -A udp_packets -p udp --destination-port 53 -j common

	# ICMP rules
	$IPTABLES -A icmp_packets -p icmp --icmp-type 8 -j common
	$IPTABLES -A icmp_packets -p icmp --icmp-type 11 -j common

	# common chain
	$IPTABLES -A common -p tcp --syn -j ACCEPT
	$IPTABLES -A common -p tcp -m state --state ESTABLISHED,RELATED -j
ACCEPT
	$IPTABLES -A common -p tcp -j DROP
	$IPTABLES -A common -p ! tcp -j ACCEPT


	#### 4.1.4 INPUT chain

	# Bad TCP packets we don't want.
	$IPTABLES -A INPUT -p tcp -j bad_tcp

	# Rules for special networks not part of the Internet
	$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -j ACCEPT
	$IPTABLES -A INPUT -p ALL -i $LO_IFACE -j ACCEPT

	# Rules for incoming packets from the internet.
	$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state
ESTABLISHED,RELATED -j ACCEPT
	$IPTABLES -A INPUT -p tcp -i $INET_IFACE -j tcp_packets
	$IPTABLES -A INPUT -p udp -i $INET_IFACE -j udp_packets
	$IPTABLES -A INPUT -p icmp -i $INET_IFACE -j icmp_packets

	# Log weird packets that don't match the above.
	$IPTABLES -A INPUT -m limit --limit 6/minute --limit-burst 6 -j LOG
--log-level DEBUG --log-prefix "iptables INPUT: "


	#### 4.1.5 FORWARD chain

	# Bad TCP packets we don't want
	$IPTABLES -A FORWARD -p tcp -j bad_tcp

	# Accept the packets we actually want to forward
	$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
	$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
	$IPTABLES -A FORWARD -m connmark --mark $MARK_FORWARD/$MARK_FORWARD
-j ACCEPT
#	$IPTABLES -A FORWARD -j ACCEPT

	# Log weird packets that don't match the above.
	$IPTABLES -A FORWARD -m limit --limit 6/minute --limit-burst 6 -j
LOG --log-level DEBUG --log-prefix "iptables FORWARD: "


	#### 4.1.6 OUTPUT chain

	# Bad TCP packets we don't want.
	$IPTABLES -A OUTPUT -p tcp -j bad_tcp

	# Special OUTPUT rules to decide which IP's to allow.
	$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
	$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
	$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

	# Log weird packets that don't match the above.
	$IPTABLES -A OUTPUT -m limit --limit 6/minute --limit-burst 6 -j LOG
--log-level DEBUG --log-prefix "iptables OUTPUT: "




	######## 4.2 nat table

	#### 4.2.1 Set policies

	#### 4.2.2 Create user specified chains

	#### 4.2.3 Create content in user specified chains

	#### 4.2.4 PREROUTING chain

	# Emule stuff - forward to DUMPER
	$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -p tcp --dport 4662 -d
$INET_IP -j DNAT --to-destination $DUMPER_IP
	$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -p udp --dport 4672 -d
$INET_IP -j DNAT --to-destination $DUMPER_IP
	$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -p tcp --dport 34567
-d $INET_IP -j DNAT --to-destination $DUMPER_IP

	#### 4.2.5 POSTROUTING chain

	# Enable simple IP Forwarding and Network Address Translation
	$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source
$INET_IP

	#### 4.2.6 OUTPUT chain




	######## 4.3 mangle table

	#### 4.3.1 Set policies

	#### 4.3.2 Create user specified chains

	#### 4.3.3 Create content in user specified chains

	#### 4.3.4 PREROUTING chain
	
	# Forwarding marks for packets that have to go to the internal
network
	# Emule
	# Debugging - set EVERYTHING to BULK
#	$IPTABLES -t mangle -A PREROUTING -j MARK --set-mark $MARK_BULK

	$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE -p tcp --dport 4662
-d $INET_IP -j CONNMARK --set-mark $MARK_FORWARD/$MARK_FORWARD
	$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE -p udp --dport 4672
-d $INET_IP -j CONNMARK --set-mark $MARK_FORWARD/$MARK_FORWARD
	$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE -p tcp --dport
34567 -d $INET_IP -j CONNMARK --set-mark $MARK_FORWARD/$MARK_FORWARD
	
	# Shaping and throttling marks for the shaper script (downstream)
	# Priority traffic: All UDP, ICMP, and SSH 
	$IPTABLES -t mangle -A PREROUTING -p udp -j MARK --or-mark
$MARK_PRIORITY
	$IPTABLES -t mangle -A PREROUTING -p icmp -j MARK --or-mark
$MARK_PRIORITY
	$IPTABLES -t mangle -A PREROUTING -p tcp --sport 22 -j MARK
--or-mark $MARK_PRIORITY
	$IPTABLES -t mangle -A PREROUTING -p tcp --dport 22 -j MARK
--or-mark $MARK_PRIORITY
	
	# General traffic: Web stuff
	$IPTABLES -t mangle -A PREROUTING -p tcp --dport 80 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A PREROUTING -p tcp --sport 80 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A PREROUTING -p tcp --dport 443 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A PREROUTING -p tcp --sport 443 -j MARK
--or-mark $MARK_GENERAL
	
	# Everything else - put it on BULK traffic
	$IPTABLES -t mangle -A PREROUTING -m mark --mark 0/$[$MARK_BULK |
$MARK_GENERAL | $MARK_PRIORITY] -j MARK --or-mark $MARK_BULK

	# Detection logs. Used for debugging to ensure markings are correct.
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark
$MARK_FORWARD/$MARK_FORWARD -j LOG --log-level DEBUG --log-prefix "IPT -
MARK det FWD"
#	$IPTABLES -t mangle -A PREROUTING -m connmark --mark
$MARK_PRIORITY/$MARK_PRIORITY -j LOG --log-level DEBUG --log-prefix "IPT -
CONN det PRIO"
#	$IPTABLES -t mangle -A PREROUTING -m connmark --mark
$MARK_GENERAL/$MARK_GENERAL -j LOG --log-level DEBUG --log-prefix "IPT -
CONN det GEN"
#	$IPTABLES -t mangle -A PREROUTING -m connmark --mark
$MARK_BULK/$MARK_BULK -j LOG --log-level DEBUG --log-prefix "IPT - CONN det
BULK"

#	$IPTABLES -t mangle -A PREROUTING -m mark --mark
$MARK_PRIORITY/$MARK_PRIORITY -j LOG --log-level DEBUG --log-prefix
"MARK_PRIORITY    "
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark $MARK_PRIORITY -j
LOG --log-level DEBUG --log-prefix "MARK_PRIORITY EX "
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark
$MARK_GENERAL/$MARK_GENERAL -j LOG --log-level DEBUG --log-prefix
"MARK_GENERAL     "
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark $MARK_GENERAL -j
LOG --log-level DEBUG --log-prefix "MARK_GENERAL EX  "
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark
$MARK_BULK/$MARK_BULK -j LOG --log-level DEBUG --log-prefix "MARK_BULK
"
#	$IPTABLES -t mangle -A PREROUTING -m mark --mark $MARK_BULK -j LOG
--log-level DEBUG --log-prefix "MARK_BULK EX     "

#	$IPTABLES -t mangle -A PREROUTING -m connmark --mark
$MARK_FORWARD/$MARK_FORWARD -j LOG --log-level DEBUG --log-prefix
"FORWARDING...  "

	# Debugging - set EVERYTHING to BULK
#	$IPTABLES -t mangle -A PREROUTING -j MARK --set-mark $MARK_BULK


	#### 4.3.5 INPUT chain

	#### 4.3.6 FORWARD chain

	#### 4.3.7 OUTPUT chain

	#### 4.3.8 POSTROUTING chain

	# Shaping and throttling marks for the shaper script (upstream)
	# Priority traffic: TOS packets, all UDP, ICMP, SSH
	$IPTABLES -t mangle -A POSTROUTING -m tos --tos Minimize-Delay -j
MARK --or-mark $MARK_PRIORITY
	$IPTABLES -t mangle -A POSTROUTING -p udp -j MARK --or-mark
$MARK_PRIORITY
	$IPTABLES -t mangle -A POSTROUTING -p icmp -j MARK --or-mark
$MARK_PRIORITY
	$IPTABLES -t mangle -A POSTROUTING -p tcp --dport 22 -j MARK
--or-mark $MARK_PRIORITY
	$IPTABLES -t mangle -A POSTROUTING -p tcp --sport 22 -j MARK
--or-mark $MARK_PRIORITY
    
	# Normal traffic: Web, SSL, ACKs
	$IPTABLES -t mangle -A POSTROUTING -p tcp --dport 80 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A POSTROUTING -p tcp --sport 80 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A POSTROUTING -p tcp --dport 443 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A POSTROUTING -p tcp --sport 443 -j MARK
--or-mark $MARK_GENERAL
	$IPTABLES -t mangle -A POSTROUTING -p tcp -m length --length :64 -j
MARK --or-mark $MARK_GENERAL

	# Bulk traffic: everything else by default
	$IPTABLES -t mangle -A POSTROUTING -m tos --tos Maximize-Throughput
-j MARK --or-mark $MARK_BULK

	# Debugging - set EVERYTHING to BULK
#	$IPTABLES -t mangle -A POSTROUTING -j MARK --set-mark $MARK_BULK
}



firewall_stop ()
{
	# proc configuration

	# Disable forwarding
	echo 0 > /proc/sys/net/ipv4/ip_forward

	# IP spoofing
	if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
	then
		for i in /proc/sys/net/ipv4/conf/*/rp_filter
		do
			echo 0 > $i
		done
	fi


	# reset the default policies in the filter table.
	$IPTABLES -P INPUT ACCEPT
	$IPTABLES -P FORWARD ACCEPT
	$IPTABLES -P OUTPUT ACCEPT

	# reset the default policies in the nat table.
	$IPTABLES -t nat -P PREROUTING ACCEPT
	$IPTABLES -t nat -P POSTROUTING ACCEPT
	$IPTABLES -t nat -P OUTPUT ACCEPT

	# reset the default policies in the mangle table.
	$IPTABLES -t mangle -P PREROUTING ACCEPT
	$IPTABLES -t mangle -P POSTROUTING ACCEPT
	$IPTABLES -t mangle -P INPUT ACCEPT
	$IPTABLES -t mangle -P OUTPUT ACCEPT
	$IPTABLES -t mangle -P FORWARD ACCEPT

	# flush all the rules in the tables.
	$IPTABLES -F
	$IPTABLES -t nat -F
	$IPTABLES -t mangle -F

	# erase all chains that's not default in the tables.
	$IPTABLES -X
	$IPTABLES -t nat -X
	$IPTABLES -t mangle -X
}



case "$1" in
  start)
        firewall_start
        ;;
  stop)
        firewall_stop
        ;;
  restart|force-reload)
        firewall_stop
        sleep 1
        firewall_start
        ;;
  *)
        echo "Usage: firewall {start|stop|restart}" >&2
        exit 3
        ;;
esac







####################### CONFIG FILES - shaper #######################

#!/bin/bash

###########################################################################
#
# Environment variables
#

DEV=ppp0
UPSTREAM=192
DOWNSTREAM=600
BURST=64

#MARK_FORWARD=$[2#00000001]
#MARK_PRIORITY=$[2#00000010]
#MARK_GENERAL=$[2#00000100]
#MARK_BULK=$[2#00001000]

MARK_FORWARD=1
MARK_PRIORITY=10
MARK_GENERAL=20
MARK_BULK=30



###########################################################################
#
# Script functions
#

#### Status report
shaper_status ()
{
	tc -s class ls dev $DEV
	tc -s qdisc ls dev $DEV
}


#### Stop function
shaper_stop ()
{
	tc qdisc del dev $DEV root 2> /dev/null
	tc qdisc del dev $DEV ingress 2> /dev/null
}


###########################################################################
#
# Start function
#

shaper_start ()
{
	#### Upstream

	# Install HTB qdisc with three classes and rate limting
	tc qdisc add dev $DEV root handle 1: htb default 30 r2q 2
	tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPSTREAM}kbit
ceil ${UPSTREAM}kbit burst 8k cburst 2k
	tc class add dev $DEV parent 1:1 classid 1:10 htb rate
$[4*$UPSTREAM/10]kbit ceil ${UPSTREAM}kbit prio 1
	tc class add dev $DEV parent 1:1 classid 1:20 htb rate
$[3*$UPSTREAM/10]kbit ceil ${UPSTREAM}kbit prio 2
	tc class add dev $DEV parent 1:1 classid 1:30 htb rate
$[3*$UPSTREAM/10]kbit ceil $[6*$UPSTREAM/10]kbit prio 3 burst 1024 cburst
1024

	# Install qdiscs to maximise the efficiency of each class
	tc qdisc add dev $DEV parent 1:10 handle 10: pfifo limit 25
	tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
	tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10

	# Apply filtering based on packets matched in the firewall
	tc filter add dev $DEV parent 1: prio 1 protocol ip handle
$MARK_PRIORITY fw flowid 1:10
	tc filter add dev $DEV parent 1: prio 2 protocol ip handle
$MARK_GENERAL fw flowid 1:20
	tc filter add dev $DEV parent 1: prio 3 protocol ip handle
$MARK_BULK fw flowid 1:30

	#### Downstream

	# Attach ingress qdisc
	tc qdisc add dev $DEV handle ffff: ingress

	# Police everything but high priority traffic
#	tc filter add dev $DEV parent ffff: protocol ip prio 1 handle
$MARK_BULK fw police rate ${DOWNSTREAM}kbit burst ${BURST}kbit drop flowid
:1

tc filter add dev $DEV parent ffff: protocol ip prio 1 handle $MARK_BULK fw
police rate ${DOWNSTREAM}kbit burst ${BURST}kbit drop flowid :1

#tc filter add dev $DEV parent ffff: protocol ip prio 1 u32 match ip src
0.0.0.0/0 police rate ${DOWNSTREAM}kbit burst ${BURST}kbit drop flowid :1

#tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src
0.0.0.0/0 police rate ${DOWNSTREAM}kbit burst ${BURST}kbit drop flowid :1

#	tc filter add dev $DEV parent ffff: protocol ip handle $MARK_BULK \
#		fw flowid :1 police rate ${DOWNSTREAM}kbit burst ${BURST}
action drop
}


case "$1" in
	start)
		shaper_start
		;;
	stop)
		shaper_stop
		;;
	restart|force-reload)
		shaper_stop
		sleep 1
		shaper_start
		;;
	status)
		shaper_status
		;;
	*)
		echo "Usage: adsl-shaper {start|stop|restart|status}" >&2
		exit 3
		;;
esac

_______________________________________________
LARTC mailing list
LARTC@xxxxxxxxxxxxxxx
http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc

[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux