#!/bin/bash
# curio QoS script 0.31
# par François Simond
# script pour htb et imq iproute2 et bien sur iptables
# iptables : www.netfilter.org
# htb : luxik.cdi.cz/~devik/qos/htb/
# imq : luxik.cdi.cz/~patrick/imq/
# iproute2 : defiant.coinet.com/iproute2/
# pour d'autres détails consultrez le howto: lartc.org
# ce script vous donnera de très hautes performances
# réseau à la maison ou au travail. il est prévu pour
# utiliser la connection internet dans tous les sens
# sans que les applications importantes ne soient ralenties
# 09.04.2002: pre release pour tests
# 01.05.2002: tests et ajustements..
# 03.05.2002: fonctionne efficacement, à voir dans la durée
# dimanche 5 mai: posté chez linuxfr.org
# sous licence GPL
# usage ./qos
# usage ./qos stop
# usage ./qos clear
# ici, le script est finement ajusté pour 512kbit de download # et 128kbit d'upload en ADSL pppoe
# merci d'avance pour le retour sur curio@free.fr
# les versions futures de ce script seront dispos a:
# http://www.hq-studio.net/linux/qos/current-qos
# .. quand je suis pas en train de tester des trucs
# dangereux sur le serveur :)
# vous pouvez surveiller ce qui se passe en tapant:
# # tc -s class show dev interface_qui_vous_interesse
# # tc -s qdisc show dev interface_qui_vous_interesse
IPTABLES="/usr/local/sbin/iptables"
TC="/sbin/tc"
LOGGER="/usr/bin/logger"
IP="/sbin/ip"
MODPROBE="/sbin/modprobe"
# définition des UID des users sous lesquels tournent edonkey
# audiogalaxy (ne jamais les lancer en root !)
UIDDONKEY=1002
UIDAG=525
# si vous n'avez pas installé imq ( parcque beta ),
# mettez cette variable à 1
NOINGRESS="0"
IFINPUT="ppp0"
IFINGRESS="imq0"
IFOUTPUT="ppp0"
$IP link | grep $IFINPUT > /dev/null 2>&1
if [ "$?" != 0 ]; then
echo "probleme: $IFINPUT n'existe pas !"
exit 1
fi
case "$1" in
'stop')
echo Stopping QoS on $IFINGRESS and $IFOUTPUT...
$TC qdisc del dev $IFINGRESS root
$IP link set $IFINGRESS down
$TC qdisc del dev $IFOUTPUT root
$LOGGER "QoS disabled"
;;
'clear')
echo Stopping QoS on $IFINPUT and $IFOUTPUT...
$TC qdisc del dev $IFOUTPUT root
$IPTABLES -F
$IP link set $IFINGRESS down
$IPTABLES -t mangle -F
$TC qdisc del dev $IFINGRESS root
echo Done !
$LOGGER "QoS disabled & iptable rules cleared"
;;
*)
# iptables clean
$IPTABLES -t nat -F
$IPTABLES -F
$IPTABLES -t mangle -F
if [ "$NOINGRESS" == "0" ]; then # mise en place de l'interface imq
$MODPROBE imq numdevs=1
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -j IMQ
fi
# mettez vos rêgles de firewall ici ( l'exemple est assez gentil mais efficace )
# Main configuration, modify to suit your setup. Help can be found at:
# http://www.mplug.org/phpwiki/index.php?MonMothaReferenceGuide
IPTABLES="/usr/local/sbin/iptables" # set to your iptables location, must be set
TCP_ALLOW="80" # TCP ports to allow (port<LOCIP)
UDP_ALLOW="68 6112 6119 4000" # UDP ports to allow (port<LOCIP)
INET_IFACE="ppp0" # the interface your internet's on (one only), must be set
LAN_IFACE="eth1" # the interface(s) your LAN is on
INTERNAL_LAN="192.168.1.5" # The internal LAN (including DMZs but not censored hosts)
MASQ_LAN="192.168.1.5" # the internal network(s) to be masqueraded (this is overridden by MAC_MASQ)
SNAT_LAN="" # Internal networks/hosts to use static NAT (format is <internal ip or network>:<external ip> ) (this is overridden by MAC_SNAT)
DROP="TREJECT" # What to do with packets we don't want: DROP, REJECT, TREJECT (Reject with tcp-reset for TCP), LDROP (log and drop), LREJECT (log and reject), LTREJECT (log and reject with tcp-reset), ULDROP (ULOG and DROP)
DENY_ALL="" # Internet hosts to explicitly deny from accessing your system at all; format is "IP<LOCIP"
DENY_HOSTWISE_TCP="" # Specific hosts to deny access to specific TCP ports; format is "IP>PORT<LOCIP"
DENY_HOSTWISE_UDP="" # Specific hosts to deny access to specific UDP ports; format is "IP>PORT<LOCIP"
BLACKHOLE="" # People you don't want to have anything to do with (equivlent of my old TK_DROP). This is a bidirectional drop.
BLACKHOLE_DROP="DROP" # What to do for the blackholes (same options as DROP directive above)
ALLOW_HOSTWISE_TCP="" # Specific hosts allowed access to specific TCP ports; format is "IP>PORT<LOCIP"
ALLOW_HOSTWISE_UDP="" # Specific hosts allowed access to specific UDP ports; format is "IP>PORT<LOCIP"
TCP_FW="" # TCP port forwards, form is "SPORT:DPORT>DESTIP<LOCIP" <LOCIP may be omitted
UDP_FW="" # UDP port forwards, form is "SPORT:DPORT>DESTIP<LOCIP" <LOCIP may be omitted
MANGLE_TOS_OPTIMIZE="TRUE" # TOS "optimizations" on or off (TRUE/FALSE toggle)
DHCP_SERVER="FALSE" # Set to true if you run a DHCP server. DHCP clients do not need this. This allows broadcasts to the server from potential clients on the LAN to succeede.
BAD_ICMP="5 9 10 15 16 17 18" # ICMP messages to NOT allow in from internet
ENABLE="Y" # Set to 'Y' when it's configured; this is for your own safety
# Flood Params. You will still recieve the packets and the bandwidth will be used, but this will cause floods to be ignored (useful against SYNFLOODS especially)
LOG_FLOOD="2/s" # Limit on logging (for LTREJECT, LREJECT and LDROP, the packet will always take the policy regardless of logging)
SYN_FLOOD="20/s" # GLOBAL limit on SYN packets (servers will probably need even higher sustained rates as this isn't on a per IP basis)
PING_FLOOD="1/s" # GLOBAL limit on ICMP echo-requests to reply to
# Outbound filters
ALLOW_OUT_TCP="" # Internal hosts allowed to be forwarded out on TCP (do not put this/these host/s in INTERNAL_LAN, but do define their method of access [snat, masq] if not a public ip)
PROXY="" # Redirect for Squid or other TRANSPARENT proxy. Syntax to specify the proxy is "host:port".
# Below here is experimental (please report your successes/failures)
MAC_MASQ="" # MAC addresses permitted to use masquerading, leave blank to not use
MAC_SNAT="" # MAC addresses permitted to use static NAT, leave blank to not use (format is <MAC Address>:<external ip> )
TTL_SAFE="" # How many hops packets need to make once they get on your LAN (null disables the mangling) (requires patch from patch-o-matic)
USE_SYNCOOKIES="TRUE" # TCP SynCookies on or off (TRUE/FALSE toggle)
RP_FILTER="TRUE" # Turns rp_filter on or off on all interfaces (TRUE/FALSE toggle)
ACCEPT_SOURCE_ROUTE="FALSE" # Turns accept_source_route on or off on all interfaces (TRUE/FALSE toggle)
SUPER_EXEMPT="" # Hosts which get to bypass the packet filter entirely (be REALLY careful with these)
BRAINDEAD_ISP="TRUE" # Force no fragments, useful if your ISP has a broken firewall or if you are on a tunneled connection (like PPPoE DSL)
ALLOW_HOSTWISE_PROTO="" # Specific hosts allowed access on specific IP protocols; format is "IP>PROTO<LOCIP"
# Only touch these if you're daring (PREALPHA stuff, as in basically non-functional)
DMZ_IFACE="" # Interface your DMZ is on (leave blank if you don't have one)
# ----------------------------------------------------------------------|
# These control basic script behavior; there should be no need to |
# change any of these settings for normal use. |
# ----------------------------------------------------------------------|
FILTER_CHAINS="INETIN INETOUT DMZIN DMZOUT TCPACCEPT UDPACCEPT LDROP LREJECT TREJECT LTREJECT"
UL_FILTER_CHAINS="ULDROP ULREJECT ULTREJECT"
LOOP_IFACE="lo"
# ----------------------------------------------------------------------|
# You shouldn't need to modify anything below here |
# Main Script Starts |
# ----------------------------------------------------------------------|
# Let's load it!
echo "Loading iptables firewall:"
# Configuration Sanity Checks
echo -n "Checking configuration..."
# It's hard to run an iptables script without iptables...
if ! [ -x $IPTABLES ] ; then
echo
echo "ERROR IN CONFIGURATION: ${IPTABLES} doesn't exist or isn't executable!"
exit 4
fi
# Basic interface sanity
for dev in ${LAN_IFACE} ; do
if [ "$dev" = "${DMZ_IFACE}" ] && [ "$dev" != "" ]; then
echo
echo "ERROR IN CONFIGURATION: DMZ_IFACE and LAN_IFACE can't have a duplicate interface!"
exit 1
fi
done
# Create a test chain to work with for system ablilities testing
${IPTABLES} -N SYSTEST
if [ "$?" != "0" ] ; then echo
echo "IPTABLES can't create new chains or the script was interrupted previously!"
echo "Flush IPTABLES rulesets or delete chain SYSTEST and try again."
exit 4
fi
# Check for ULOG support
${IPTABLES} -A SYSTEST -j ULOG > /dev/null 2>&1
if [ "$?" = "0" ] ; then HAVE_ULOG="true"
else
HAVE_ULOG="false" fi
# Check for LOG support
${IPTABLES} -A SYSTEST -j LOG > /dev/null 2>&1
if [ "$?" != "0" ] ; then echo
echo "Your kernel lacks LOG support reqiored by this script. Aborting."
exit 3
fi
# Check for stateful matching
${IPTABLES} -A SYSTEST -m state --state ESTABLISHED -j ACCEPT > /dev/null 2>&1
if [ "$?" != "0" ] ; then echo
echo "Your kernel lacks stateful matching, this would break this script. Aborting."
exit 3
fi
# Check for the limit match
${IPTABLES} -A SYSTEST -m limit -j ACCEPT > /dev/null 2>&1
if [ "$?" != "0" ] ; then
echo
echo "Support not found for limiting needed by this script. Aborting."
exit 3
fi
# Check for REJECT
${IPTABLES} -A SYSTEST -j REJECT > /dev/null 2>&1
if [ "$?" != "0" ] ; then
echo
echo "Support not found for the REJECT target needed by this script. Aborting."
exit 3
fi
# Check DROP sanity
if [ "$DROP" = "" ] ; then
echo
echo "There needs to be a DROP policy (try TREJECT)!"
exit 1
fi
if [ "$DROP" = "ACCEPT" ] ; then
echo
echo "The DROP policy is set to ACCEPT; there is no point in loading the firewall as there wouldn't be one."
exit 2
fi
if [ "$DROP" = "ULDROP" ] || [ "$DROP" = "ULREJECT" ] || [ "$DROP" = "ULTREJECT" ] ; then
if [ "$HAVE_ULOG" != "true" ] ; then
echo
echo "You have selected a ULOG policy, but your system lacks ULOG support."
echo "Please choose a policy that your system has support for."
exit 5
fi
fi
# Problems with blackholes?
if [ "$BLACKHOLE" != "" ] && [ "$BLACKHOLE_DROP" = "" ] ; then
echo
echo "You can't use blackholes and not have a policy for them!"
exit 1
fi
# Has it been configured?
if ! [ "$ENABLE" = "Y" ] ; then
echo
echo "You need to *EDIT YOUR CONFIGURATION* and set ENABLE to Y!"
exit 99
fi
# Flush and remove the chain SYSTEST
${IPTABLES} -F SYSTEST
${IPTABLES} -X SYSTEST
# Seems ok...
echo "passed"
# ===============================================
# ----------------Preprocessing------------------
# ===============================================
# Turn TCP_ALLOW and UDP_ALLOW into ALLOW_HOSTWISE
echo -n "Performing TCP_ALLOW and UDP_ALLOW alias preprocessing..."
if [ "$TCP_ALLOW" != "" ] ; then
for rule in ${TCP_ALLOW} ; do
ALLOW_HOSTWISE_TCP="${ALLOW_HOSTWISE_TCP} 0/0>$rule"
done
fi
if [ "$UDP_ALLOW" != "" ] ; then
for rule in ${UDP_ALLOW} ; do
ALLOW_HOSTWISE_UDP="${ALLOW_HOSTWISE_UDP} 0/0>$rule"
done
fi
echo "done"
# ===============================================
# -------Set some Kernel stuff via SysCTL--------
# ===============================================
# Turn on IP forwarding
if [ "$INTERNAL_LAN" != "" ] ; then
echo -n "Checking IP Forwarding..."
if [ -e /proc/sys/net/ipv4/ip_forward ] ; then
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "enabled."
else
echo "support not found! This will cause problems if you need to do any routing."
fi
fi
# Enable TCP Syncookies
echo -n "Checking IP SynCookies..."
if [ -e /proc/sys/net/ipv4/tcp_syncookies ] ; then
if [ "$USE_SYNCOOKIES" = "TRUE" ] ; then
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo "enabled."
else
echo 0 > /proc/sys/net/ipv4/tcp_syncookies
echo "disabled."
fi
else
echo "support not found, but that's OK."
fi
# Enable Route Verification to prevent martians and other such crud that
# seems to be commonplace on the internet today
echo -n "Checking Route Verification..."
if [ "$INET_IFACE" != "" ] ; then
if [ -e /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter ] ; then
if [ "$RP_FILTER" = "TRUE" ] ; then
echo 1 > /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter
echo -n "activated:${INET_IFACE} "
else
echo 0 > /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter
echo -n "disabled:${INET_IFACE} "
fi
else
echo "not found:${INET_IFACE} "
fi
fi
if [ "$LAN_IFACE" != "" ] ; then
for dev in ${LAN_IFACE} ; do
if [ -e /proc/sys/net/ipv4/conf/$dev/rp_filter ] ; then
if [ "$RP_FILTER" = "TRUE" ] ; then
echo 1 > /proc/sys/net/ipv4/conf/$dev/rp_filter
echo -n "activated:$dev "
else
echo 0 > /proc/sys/net/ipv4/conf/$dev/rp_filter
echo -n "disabled:$dev "
fi
else
echo "not found:$dev "
fi
done
fi
if [ "$DMZ_IFACE" != "" ] ; then
if [ -e /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter ] ; then
if [ "$RP_FILTER" = "TRUE" ] ; then
echo 1 > /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter
echo -n "activated:${DMZ_IFACE} "
else
echo 0 > /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter
echo -n "disabled:${DMZ_IFACE} "
fi
else
echo "not found:${DMZ_IFACE} "
fi
fi
echo
# Tell the Kernel to Ignore Source Routed Packets
echo -n "Refusing SSR Packets via SysCtl..."
if [ "$INET_IFACE" != "" ] ; then
if [ -e /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route ] ; then
if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then
echo "1" > /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route
echo -n "disabled:${INET_IFACE} "
else
echo "0" > /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route
echo -n "activated:${INET_IFACE} "
fi
else
echo "not found:${INET_IFACE} "
fi
fi
if [ "$LAN_IFACE" != "" ] ; then
for dev in ${LAN_IFACE} ; do
if [ -e /proc/sys/net/ipv4/conf/$dev/accept_source_route ] ; then
if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then
echo "1" > /proc/sys/net/ipv4/conf/$dev/accept_source_route
echo -n "disabled:$dev "
else
echo "0" > /proc/sys/net/ipv4/conf/$dev/accept_source_route
echo -n "activated:$dev "
fi
else
echo "not found:$dev "
fi
done
fi
if [ "$DMZ_IFACE" != "" ] ; then
if [ -e /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route ] ; then
if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then
echo "1" > /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route
echo -n "disabled:${DMZ_IFACE} "
else
echo "0" > /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route
echo -n "activated:${DMZ_IFACE} "
fi
else
echo "not found:${DMZ_IFACE} "
fi
fi
echo
# ===============================================
# --------Actual NetFilter Stuff Follows---------
# ===============================================
# Flush everything
# If you need compatability, you can comment some or all of these out,
# but remember, if you re-run it, it'll just add the new rules in, it
# won't remove the old ones for you then, this is how it removes them.
echo -n "Flush: "
${IPTABLES} -t filter -F INPUT
echo -n "INPUT "
${IPTABLES} -t filter -F OUTPUT
echo -n "OUTPUT1 "
${IPTABLES} -t filter -F FORWARD
echo -n "FORWARD "
${IPTABLES} -t nat -F PREROUTING
echo -n "PREROUTING1 "
${IPTABLES} -t nat -F OUTPUT
echo -n "OUTPUT2 "
${IPTABLES} -t nat -F POSTROUTING
echo -n "POSTROUTING "
${IPTABLES} -t mangle -F PREROUTING
echo -n "PREROUTING2 "
${IPTABLES} -t mangle -F OUTPUT
echo -n "OUTPUT3"
echo
# Create new chains
# Output to /dev/null in case they don't exist from a previous invocation
echo -n "Creating chains: "
for chain in ${FILTER_CHAINS} ; do
${IPTABLES} -t filter -F ${chain} > /dev/null 2>&1
${IPTABLES} -t filter -X ${chain} > /dev/null 2>&1
${IPTABLES} -t filter -N ${chain}
echo -n "${chain} "
done
if [ ${HAVE_ULOG} = "true" ] ; then
for chain in ${UL_FILTER_CHAINS} ; do
${IPTABLES} -t filter -F ${chain} > /dev/null 2>&1
${IPTABLES} -t filter -X ${chain} > /dev/null 2>&1
${IPTABLES} -t filter -N ${chain}
echo -n "${chain} "
done fi
echo
# Default Policies
# INPUT policy is drop as of 2.3.7-pre5
# Policy can't be reject because of kernel limitations
echo -n "Default Policies: "
${IPTABLES} -t filter -P INPUT DROP
echo -n "INPUT:DROP "
${IPTABLES} -t filter -P OUTPUT ACCEPT
echo -n "OUTPUT:ACCEPT "
${IPTABLES} -t filter -P FORWARD DROP
echo -n "FORWARD:DROP "
echo
# ===============================================
# -------Chain setup before jumping to them------
# ===============================================
#These logging chains are valid to specify in DROP= above
#Set up LDROP
echo -n "Setting up drop chains chains: "
${IPTABLES} -t filter -A LDROP -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Dropped "
${IPTABLES} -t filter -A LDROP -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Dropped "
${IPTABLES} -t filter -A LDROP -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Dropped " ${IPTABLES} -t filter -A LDROP -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Dropped "
${IPTABLES} -t filter -A LDROP -j DROP
echo -n "LDROP "
#And LREJECT too
${IPTABLES} -t filter -A LREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Rejected "
${IPTABLES} -t filter -A LREJECT -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Rejected "
${IPTABLES} -t filter -A LREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Rejected "
${IPTABLES} -t filter -A LREJECT -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Rejected "
${IPTABLES} -t filter -A LREJECT -j REJECT
echo -n "LREJECT "
#Don't forget TREJECT
${IPTABLES} -t filter -A TREJECT -p tcp -j REJECT --reject-with tcp-reset
${IPTABLES} -t filter -A TREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
${IPTABLES} -t filter -A TREJECT -p icmp -j DROP
${IPTABLES} -t filter -A TREJECT -j REJECT echo -n "TREJECT "
#And LTREJECT
${IPTABLES} -t filter -A LTREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Rejected "
${IPTABLES} -t filter -A LTREJECT -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Rejected "
${IPTABLES} -t filter -A LTREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Rejected "
${IPTABLES} -t filter -A LTREJECT -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Rejected "
${IPTABLES} -t filter -A LTREJECT -p tcp -j REJECT --reject-with tcp-reset
${IPTABLES} -t filter -A LTREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
${IPTABLES} -t filter -A LTREJECT -p icmp -j DROP
${IPTABLES} -t filter -A LTREJECT -j REJECT
echo -n "LTREJECT "
#And ULOG stuff, same as above but ULOG instead of LOG
if [ ${HAVE_ULOG} = "true" ] ; then
${IPTABLES} -t filter -A ULDROP -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_TCP
${IPTABLES} -t filter -A ULDROP -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_UDP
${IPTABLES} -t filter -A ULDROP -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_ICMP ${IPTABLES} -t filter -A ULDROP -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_FRAG
${IPTABLES} -t filter -A ULDROP -j DROP
echo -n "ULDROP "
${IPTABLES} -t filter -A ULREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_TCP
${IPTABLES} -t filter -A ULREJECT -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_UDP
${IPTABLES} -t filter -A ULREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_UDP
${IPTABLES} -t filter -A ULREJECT -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_FRAG
${IPTABLES} -t filter -A ULREJECT -j REJECT
echo -n "LREJECT "
${IPTABLES} -t filter -A ULTREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_TCP
${IPTABLES} -t filter -A ULTREJECT -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_UDP
${IPTABLES} -t filter -A ULTREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_ICMP ${IPTABLES} -t filter -A ULTREJECT -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_FRAG
${IPTABLES} -t filter -A ULTREJECT -p tcp -j REJECT --reject-with tcp-reset
${IPTABLES} -t filter -A ULTREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
${IPTABLES} -t filter -A ULTREJECT -p icmp -j DROP
${IPTABLES} -t filter -A ULTREJECT -j REJECT
echo -n "ULTREJECT "
fi
#newline
echo
# Set up the per-proto ACCEPT chains
echo -n "Setting up per-proto ACCEPT: "
# TCPACCEPT
# SYN Flood "Protection"
${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -m limit --limit ${SYN_FLOOD} -j ACCEPT
${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Possible SynFlood "
${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -j ${DROP}
${IPTABLES} -t filter -A TCPACCEPT -p tcp ! --syn -j ACCEPT
# Log anything that hasn't matched yet and ${DROP} it since it isn't TCP and shouldn't be here
${IPTABLES} -t filter -A TCPACCEPT -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Mismatch in TCPACCEPT "
${IPTABLES} -t filter -A TCPACCEPT -j ${DROP}
echo -n "TCPACCEPT "
#UDPACCEPT
${IPTABLES} -t filter -A UDPACCEPT -p udp -j ACCEPT
# Log anything not UDP and ${DROP} it since it's not supposed to be here
${IPTABLES} -t filter -A UDPACCEPT -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Mismatch on UDPACCEPT "
${IPTABLES} -t filter -A UDPACCEPT -j ${DROP}
echo -n "UDPACCEPT "
#Done
echo
# =================================================
# -------------------Exemptions--------------------
# =================================================
if [ "$SUPER_EXEMPT" != "" ] ; then
echo -n "Super Exemptions: "
for host in ${SUPER_EXEMPT} ; do
${IPTABLES} -t filter -A INPUT -s ${host} -j ACCEPT
${IPTABLES} -t filter -A OUTPUT -d ${host} -j ACCEPT
${IPTABLES} -t filter -A FORWARD -s ${host} -j ACCEPT
${IPTABLES} -t filter -A FORWARD -d ${host} -j ACCEPT
echo -n "${host} "
done
echo
fi
# =================================================
# ----------------Explicit Denies------------------
# =================================================
#Blackholes will not be overridden by hostwise allows
if [ "$BLACKHOLE" != "" ] ; then
echo -n "Blackholes: "
for host in ${BLACKHOLE} ; do
${IPTABLES} -t filter -A INPUT -s ${host} -j ${BLACKHOLE_DROP}
${IPTABLES} -t filter -A OUTPUT -d ${host} -j ${BLACKHOLE_DROP}
${IPTABLES} -t filter -A FORWARD -s ${host} -j ${BLACKHOLE_DROP}
${IPTABLES} -t filter -A FORWARD -d ${host} -j ${BLACKHOLE_DROP}
echo -n "${host} "
done
echo
fi
if [ "$DENY_ALL" != "" ] ; then
echo -n "Denying hosts: "
for rule in ${DENY_ALL} ; do
echo "$rule" | {
IFS='<' read shost dhost
if [ "$dhost" == "" ] ; then
${IPTABLES} -t filter -A INPUT -s ${shost} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -s ${shost} -j ${DROP}
else
${IPTABLES} -t filter -A INPUT -s ${shost} -d ${dhost} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -s ${shost} -d ${dhost} -j ${DROP}
fi
}
echo -n "${rule} " done
echo
fi
if [ "$DENY_HOSTWISE_TCP" != "" ] ; then
echo -n "Hostwise TCP Denies: "
for rule in ${DENY_HOSTWISE_TCP} ; do
echo "$rule" | {
IFS='><' read shost port dhost
echo "$port" | {
IFS='-' read fsp lsp
if [ "$dhost" == "" ] ; then if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INPUT -p tcp -s ${shost} --dport ${fsp}:${lsp} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p tcp -s ${shost} --dport ${fsp}:${lsp} -j ${DROP}
else
${IPTABLES} -t filter -A INPUT -p tcp -s ${shost} --dport ${port} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p tcp -s ${shost} --dport ${port} -j ${DROP}
fi
else
if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INPUT -p tcp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p tcp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j ${DROP}
else
${IPTABLES} -t filter -A INPUT -p tcp -s ${shost} -d ${dhost} --dport ${port} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p tcp -s ${shost} -d ${dhost} --dport ${port} -j ${DROP}
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
if [ "$DENY_HOSTWISE_UDP" != "" ] ; then
echo -n "Hostwise UDP Denies: "
for rule in ${DENY_HOSTWISE_UDP} ; do
echo "$rule" | {
IFS='><' read shost port dhost
echo "$port" | {
IFS='-' read fsp lsp
if [ "$dhost" == "" ] ; then if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INPUT -p udp -s ${shost} --dport ${fsp}:${lsp} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p udp -s ${shost} --dport ${fsp}:${lsp} -j ${DROP}
else
${IPTABLES} -t filter -A INPUT -p udp -s ${shost} --dport ${port} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p udp -s ${shost} --dport ${port} -j ${DROP}
fi
else
if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INPUT -p udp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p udp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j ${DROP}
else
${IPTABLES} -t filter -A INPUT -p udp -s ${shost} -d ${dhost} --dport ${port} -j ${DROP}
${IPTABLES} -t filter -A FORWARD -p udp -s ${shost} -d ${dhost} --dport ${port} -j ${DROP}
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
#Invalid packets are always annoying
echo -n "${DROP}ing invalid packets..."
${IPTABLES} -t filter -A INETIN -m state --state INVALID -j ${DROP}
echo "done"
# ------------------------------------------------------------------------
# Internet jumps to INET chains and DMZ
# Set up INET chains
echo -n "Setting up INET chains: "
${IPTABLES} -t filter -A INPUT -i ${INET_IFACE} -j INETIN
for dev in ${LAN_IFACE} ; do
${IPTABLES} -t filter -A FORWARD -i ${INET_IFACE} -o $dev -j INETIN
done
echo -n "INETIN "
${IPTABLES} -t filter -A OUTPUT -o ${INET_IFACE} -j INETOUT
for dev in ${LAN_IFACE} ; do
${IPTABLES} -t filter -A FORWARD -o ${INET_IFACE} -i $dev -j INETOUT
done
echo -n "INETOUT "
echo
if [ "$BRAINDEAD_ISP" = "TRUE" ] ; then
${IPTABLES} -t filter -A INETOUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
fi
# For now we'll subject the DMZ to the same rules as the internet when going onto the trusted LAN
# And we'll let it go anywhere on the internet
if [ "$DMZ_IFACE" != "" ] ; then
echo -n "Setting up DMZ Chains: "
${IPTABLES} -A OUTPUT -o ${DMZ_IFACE} -j DMZOUT
${IPTABLES} -A FORWARD -i ${LAN_IFACE} -o ${DMZ_IFACE} -j DMZOUT
${IPTABLES} -A FORWARD -i ${INET_IFACE} -o ${DMZ_IFACE} -j ACCEPT
echo -n "DMZOUT "
echo -n "DMZ for Internet Forwarding to INETOUT..."
${IPTABLES} -A DMZOUT -j INETOUT
${IPTABLES} -A INPUT -i ${DMZ_IFACE} -j DMZIN
echo -n "DMZIN "
echo
echo -n "DMZ for LAN and localhost Forwarding to INETIN..."
${IPTABLES} -A FORWARD -i ${DMZ_IFACE} -o ${LAN_IFACE} -j DMZOUT
${IPTABLES} -A FORWARD -i ${DMZ_IFACE} -o ${INET_IFACE} -j ACCEPT
${IPTABLES} -A DMZOUT -o ${LAN_IFACE} -j INETIN
echo "done"
echo -n "done"
fi
# ------------------------------------------------------------------------
# Local traffic to internet or crossing subnets # This should cover what we need if we don't use masquerading
# Unfortunately, MAC address matching isn't bidirectional (for
# obvious reasons), so IP based matching is done here
echo -n "Local Traffic Rules: "
if [ "$INTERNAL_LAN" != "" ] ; then
for subnet in ${INTERNAL_LAN} ; do
${IPTABLES} -t filter -A INPUT -s ${subnet} -j ACCEPT
${IPTABLES} -t filter -A FORWARD -s ${subnet} -o ! ${INET_IFACE} -i ! ${INET_IFACE} -j ACCEPT
echo -n "${subnet}:ACCEPT "
done
fi
# 127.0.0.0/8 used to need an entry in INTERNAL_LAN, but routing of that isn't needed
# so an allow is placed on INPUT so that the computer can talk to itself :)
${IPTABLES} -t filter -A INPUT -i ${LOOP_IFACE} -j ACCEPT
echo -n "loopback:ACCEPT "
# DHCP server magic
# Allow broadcasts from LAN to UDP port 67 (DHCP server)
if [ "$DHCP_SERVER" = "TRUE" ] ; then
for dev in ${LAN_IFACE} ; do
${IPTABLES} -t filter -A INPUT -i $dev -p udp --dport 67 -j ACCEPT
done
echo -n "dhcp:ACCEPT"
fi
echo #newline from local traffic rules
if [ "$PROXY" != "" ] ; then
echo -n "Setting up Transparent Proxy to ${PROXY}: "
for subnet in ${INTERNAL_LAN} ; do
echo "$PROXY" | {
IFS=':' read host port
if [ "$host" = "localhost" ] || [ "$host" = "127.0.0.1" ] ; then
${IPTABLES} -t nat -A PREROUTING -s ${subnet} -p tcp --dport 80 -j REDIRECT --to-port ${port}
echo -n "${subnet}:PROXY "
else
${IPTABLES} -t nat -A PREROUTING -s ${subnet} -p tcp --dport 80 -j DNAT --to ${host}:${port}
echo -n "${subnet}:PROXY "
fi
}
done
echo
fi
if [ "$ALLOW_OUT_TCP" != "" ] ; then
echo -n "Internet censorship TCP allows: "
for rule in ${ALLOW_OUT_TCP} ; do
echo "$rule" | {
IFS=':' read intip destip dport
${IPTABLES} -t filter -A FORWARD -s ${intip} -d ${destip} -p tcp --dport ${dport} -o ${INET_IFACE} -j ACCEPT
echo -n "${intip}:${destip} "
}
done
echo
fi
# Set up basic NAT if the user wants it
if [ "$MASQ_LAN" != "" ] ; then
echo -n "Setting up masquerading: "
if [ "$MAC_MASQ" = "" ] ; then
for subnet in ${MASQ_LAN} ; do
${IPTABLES} -t nat -A POSTROUTING -s ${subnet} -o ${INET_IFACE} -j MASQUERADE
echo -n "${subnet}:MASQUERADE "
done
else for address in ${MAC_MASQ} ; do
${IPTABLES} -t nat -A POSTROUTING -m mac --mac-source ${address} -o ${INET_IFACE} -j MASQUERADE
echo -n "${address}:MASQUERADE "
done
fi
echo
fi
if [ "$SNAT_LAN" != "" ] ; then #Static NAT used
echo -n "Setting up static NAT: "
if [ "$MAC_SNAT" = "" ] ; then
for rule in ${SNAT_LAN} ; do
echo "$rule" | {
IFS=':' read host destip
${IPTABLES} -t nat -A POSTROUTING -s ${host} -o ${INET_IFACE} -j SNAT --to-source ${destip}
echo -n "${host}:SNAT "
}
done
else
for rule in ${MAC_SNAT} ; do
echo "$rule" | {
IFS=':' read address destip ${IPTABLES} -t nat -A POSTROUTING -m mac --mac-source ${address} -o ${INET_IFACE} -j SNAT --to-source ${destip}
echo -n "${address}:SNAT "
}
done
fi
echo
fi
#TCP Port-Forwards
if [ "$TCP_FW" != "" ] ; then
echo -n "TCP Port Forwards: "
for rule in ${TCP_FW} ; do
echo "$rule" | {
IFS=':><' read srcport destport host shost
echo "$srcport" | {
IFS='-' read fsp lsp
if [ "$shost" = "" ] ; then
if [ "$lsp" != "" ] ; then
echo "$destport" | {
IFS='-' read fdp ldp
${IPTABLES} -t nat -A PREROUTING -i ${INET_IFACE} -p tcp --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport}
}
else
${IPTABLES} -t nat -A PREROUTING -i ${INET_IFACE} -p tcp --dport ${srcport} -j DNAT --to-destination ${host}:${destport}
fi
else
if [ "$lsp" != "" ] ; then
echo "$destport" | {
IFS='-' read fdp ldp
${IPTABLES} -t nat -A PREROUTING -p tcp -d ${shost} --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport}
}
else
${IPTABLES} -t nat -A PREROUTING -p tcp -d ${shost} --dport ${srcport} -j DNAT --to-destination ${host}:${destport}
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
#UDP Port Forwards
if [ "$UDP_FW" != "" ] ; then
echo -n "UDP Port Forwards: "
for rule in ${UDP_FW} ; do
echo "$rule" | {
IFS=':><' read srcport destport host shost
echo "$srcport" | {
IFS='-' read fsp lsp
if [ "$shost" = "" ] ; then
if [ "$lsp" != "" ] ; then
echo "$destport" | {
IFS='-' read fdp ldp
${IPTABLES} -t nat -A PREROUTING -i ${INET_IFACE} -p udp --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport}
}
else
${IPTABLES} -t nat -A PREROUTING -i ${INET_IFACE} -p udp --dport ${srcport} -j DNAT --to-destination ${host}:${destport}
fi
else
if [ "$lsp" != "" ] ; then
echo "$destport" | {
IFS='-' read fdp ldp
${IPTABLES} -t nat -A PREROUTING -p udp -d ${shost} --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport}
}
else
${IPTABLES} -t nat -A PREROUTING -p udp -d ${shost} --dport ${srcport} -j DNAT --to-destination ${host}:${destport}
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
# =================================================
# -------------------ICMP rules--------------------
# =================================================
if [ "$BAD_ICMP" != "" ] ; then
echo -n "${DROP}ing ICMP messages specified in BAD_ICMP..."
for message in ${BAD_ICMP} ; do
${IPTABLES} -t filter -A INETIN -p icmp --icmp-type ${message} -j ${DROP}
echo -n "${message} "
done
echo
fi
# Flood "security"
# You'll still respond to these if they comply with the limits (set in config)
# There is a more elegant way to set this using sysctl, however this has the
# advantage that the kernel ICMP stack never has to process it, lessening
# the chance of a very serious flood overloading your kernel.
# This is just a packet limit, you still get the packets on the interface and # still may experience lag if the flood is heavy enough
echo -n "Flood limiting: "
# Ping Floods (ICMP echo-request)
${IPTABLES} -t filter -A INETIN -p icmp --icmp-type echo-request -m limit --limit ${PING_FLOOD} -j ACCEPT
${IPTABLES} -t filter -A INETIN -p icmp --icmp-type echo-request -j ${DROP}
echo -n "ICMP-PING "
echo
echo -n "Allowing the rest of the ICMP messages in..."
${IPTABLES} -t filter -A INETIN -p icmp --icmp-type ! echo-request -j ACCEPT
echo "done"
# ================================================================
# ------------Allow stuff we have chosen to allow in--------------
# ================================================================
# Hostwise allows
if [ "$ALLOW_HOSTWISE_TCP" != "" ] ; then
echo -n "Hostwise TCP Allows: "
for rule in ${ALLOW_HOSTWISE_TCP} ; do
echo "$rule" | {
IFS='><' read shost port dhost
echo "$port" | {
IFS='-' read fsp lsp
if [ "$dhost" == "" ] ; then if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INETIN -p tcp -s ${shost} --dport ${fsp}:${lsp} -j TCPACCEPT
else
${IPTABLES} -t filter -A INETIN -p tcp -s ${shost} --dport ${port} -j TCPACCEPT
fi
else
if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INETIN -p tcp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j TCPACCEPT
else
${IPTABLES} -t filter -A INETIN -p tcp -s ${shost} -d ${dhost} --dport ${port} -j TCPACCEPT
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
if [ "$ALLOW_HOSTWISE_UDP" != "" ] ; then
echo -n "Hostwise UDP Allows: "
for rule in ${ALLOW_HOSTWISE_UDP} ; do
echo "$rule" | {
IFS='><' read shost port dhost
echo "$port" | {
IFS='-' read fsp lsp
if [ "$dhost" == "" ] ; then if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INETIN -p udp -s ${shost} --dport ${fsp}:${lsp} -j UDPACCEPT
else
${IPTABLES} -t filter -A INETIN -p udp -s ${shost} --dport ${port} -j UDPACCEPT
fi
else
if [ "$lsp" != "" ] ; then
${IPTABLES} -t filter -A INETIN -p udp -s ${shost} -d ${dhost} --dport ${fsp}:${lsp} -j UDPACCEPT
else
${IPTABLES} -t filter -A INETIN -p udp -s ${shost} -d ${dhost} --dport ${port} -j UDPACCEPT
fi
fi
echo -n "${rule} "
}
}
done
echo
fi
if [ "$ALLOW_HOSTWISE_PROTO" != "" ] ; then
echo -n "Hostwise IP Protocol Allows: "
for rule in ${ALLOW_HOSTWISE_PROTO} ; do
echo "$rule" | {
IFS='><' read shost proto dhost
if [ "$dhost" == "" ] ; then ${IPTABLES} -t filter -A INETIN -p ${proto} -s ${shost} -j ACCEPT
else
${IPTABLES} -t filter -A INETIN -p ${proto} -s ${shost} -d ${dhost} -j ACCEPT
fi
echo -n "${rule} "
}
done
echo
fi
echo -n "Allowing established outbound connections back in..."
${IPTABLES} -t filter -A INETIN -m state --state ESTABLISHED -j ACCEPT
echo "done"
# RELATED on high ports only for security
echo -n "Allowing related inbound connections..."
${IPTABLES} -t filter -A INETIN -p tcp --dport 1024:65535 -m state --state RELATED -j TCPACCEPT
${IPTABLES} -t filter -A INETIN -p udp --dport 1024:65535 -m state --state RELATED -j UDPACCEPT
echo "done"
# =================================================
# ----------------Packet Mangling------------------
# =================================================
# TTL mangling
# This is probably just for the paranoid, but hey, isn't that what # all security guys are? :)
if [ "$TTL_SAFE" != "" ] ; then
${IPTABLES} -t mangle -A PREROUTING -i ${INET_IFACE} -j TTL --ttl-set ${TTL_SAFE}
fi
# Type of Service mangle optimizations (the ACTIVE FTP one will only work for uploads)
# Most routers tend to ignore these, it's probably better to use
# QoS. A packet scheduler like HTB is much more efficient
# at assuring bandwidth availability at the local end than
# ToS is.
if [ "$MANGLE_TOS_OPTIMIZE" = "TRUE" ] ; then
echo -n "Optimizing traffic: "
${IPTABLES} -t mangle -A OUTPUT -p tcp --dport 23 -j TOS --set-tos Minimize-Delay
echo -n "telnet "
${IPTABLES} -t mangle -A OUTPUT -p tcp --dport 22 -j TOS --set-tos Minimize-Delay
echo -n "ssh "
${IPTABLES} -t mangle -A OUTPUT -p tcp --dport 20 -j TOS --set-tos Minimize-Cost
echo -n "ftp-data "
${IPTABLES} -t mangle -A OUTPUT -p tcp --dport 21 -j TOS --set-tos Minimize-Delay
echo -n "ftp-control "
${IPTABLES} -t mangle -A OUTPUT -p udp --dport 4000:7000 -j TOS --set-tos Minimize-Delay
echo -n "diablo2 "
echo
fi
# What to do on those INET chains when we hit the end
echo -n "Setting up INET policies: "
# Drop if we cant find a valid inbound rule.
${IPTABLES} -t filter -A INETIN -j ${DROP}
echo -n "INETIN:${DROP} "
# We can send what we want to the internet
${IPTABLES} -t filter -A INETOUT -j ACCEPT
echo -n "INETOUT:ACCEPT "
echo
# All done!
echo "Done loading the firewall!"
# début de la configuration des marques du firewall
# marques pour le traffic icmp ( pour benchmark uniquement )
$IPTABLES -t mangle -A INPUT -i $IFINPUT -p icmp -j MARK --set-mark 11
if [ "$NOINGRESS" == "0" ]; then ########################### INPUT RULES (INGRESS) ############################
# par défaut on met tout dans la classe par défaut
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -m length --length 0:1500 -j MARK --set-mark 13
# marques du traffic interactif (telnet & ssh)
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 22:23 -j MARK --set-mark 11
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 22:23 -j MARK --set-mark 11
# marques du traffic edonkey
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 4662 -j MARK --set-mark 15
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 4662 -j MARK --set-mark 15
# marques du traffic audiogalaxy
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 1024:5000 --dport 41000:41999 -j MARK --set-mark 16
# marques du traffic web , http et https
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -j MARK --set-mark 17
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 443 -j MARK --set-mark 17
# classement des longs downloads http au même niveau que le traffic ftp - en test -
# utilise le match recent, qui est dans le patch-o-matic d'iptables
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m recent --name web ! --rcheck -j MARK --set-mark 200 2> /dev/null
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m mark --mark 200 -m recent --name web --set 2> /dev/null
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -j MARK --set-mark 17 2> /dev/null
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m recent --name web ! --rcheck --seconds 45 -j MARK --set-mark 18 2> /dev/null
# marques du traffic ftp
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 20 -j MARK --set-mark 18 $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j MARK --set-mark 18
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 20 -j MARK --set-mark 15
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 1024: --sport 1024: -m state --state ESTABLISHED,RELATED -j MARK --set-mark 18
# maques du traffic des radios shoutcast
$IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 8000:8600 -j MARK --set-mark 15
fi
######################### OUTPUT RULES (EGRESS) #############################
# marquage et classement par taille de paquets sortants ( methode d'Emmanuel Roger - www.prout.be )
# remarque: cette méthode réordonne les paquets d'une même connection tcp et peut la ralentir
# dans des cas particuliers ( ici j'ai pas remarqué :), donc si ce script vous ralenti,
# modifiez cette partie ou bien faites une classe pour le traffic qui vous intéresse
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 0:75 -j MARK --set-mark 22
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 76:444 -j MARK --set-mark 23
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 445:1500 -j MARK --set-mark 24
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 0:75 -j MARK --set-mark 22
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 76:520 -j MARK --set-mark 23
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 521:1500 -j MARK --set-mark 24
# marquage du traffic interactif sortant
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --sport 22:23 -j MARK --set-mark 21
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 22:23 -j MARK --set-mark 21
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 22:23 -j MARK --set-mark 21
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 22:23 -j MARK --set-mark 21
# marquage du traffic edonkey sortant
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp ! --syn --sport 4662 -j MARK --set-mark 25
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp ! --syn --dport 4662 -j MARK --set-mark 25
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 4662 -j MARK --set-mark 25
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 4662 -j MARK --set-mark 25
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m owner --uid-owner $UIDDONKEY -j MARK --set-mark 25
# pour garder un ping très bas, on peut forcer une taille plus petite des paquets au traffic edonkey (facultatif)
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --sport 4662 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 4662 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000
$IPTABLES -A OUTPUT -m owner --uid-owner $UIDDONKEY -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000
# marquage du traffic audiogalaxy sortant
$IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 41000:42000 -j MARK --set-mark 26
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 41000:42000 -j MARK --set-mark 26
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m owner --uid-owner $UIDAG -j MARK --set-mark 26
# diminution de la taille des paquets pour audiogalaxy
$IPTABLES -A OUTPUT -m owner --uid-owner $UIDAG -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 768
# marquage du traffic du serveur web local
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 80 -j MARK --set-mark 27
$IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 443 -j MARK --set-mark 27
# declaration des fonctions utilisées pour ajouter des qdisc ou des filtres
function addqdisc {
$TC qdisc add dev $1 parent $2 handle $3 $4 $5 $6 $7 $8
}
function addfilter {
$TC filter add dev $1 parent $2 protocol ip handle $3 fw flowid $4
}
# cleaning
$TC qdisc del dev $IFINGRESS root 2> /dev/null > /dev/null
if [ "$NOINGRESS" == "0" ]; then # règles tc / htb pour le traffic entrant ( ingress )
$TC qdisc add dev $IFINGRESS handle 1:0 root htb default 1
$TC class add dev $IFINGRESS parent 1:0 classid 1:1 htb rate 512kbit ceil 512kbit burst 77k
$TC qdisc add dev $IFINGRESS parent 1:1 handle 10: htb default 203
$TC class add dev $IFINGRESS parent 10: classid 10:1 htb rate 500kbit ceil 500kbit burst 77k
$TC class add dev $IFINGRESS parent 10:1 classid 10:201 htb rate 128kbit ceil 500kbit burst 10k prio 0 # best interactivity for terminal
$TC class add dev $IFINGRESS parent 10:1 classid 10:2 htb rate 384kbit ceil 500kbit burst 67k
$TC class add dev $IFINGRESS parent 10:2 classid 10:203 htb rate 48kbit ceil 500kbit burst 2k prio 1 # medium size packets or generic
$TC class add dev $IFINGRESS parent 10:2 classid 10:205 htb rate 5kbit ceil 512kbit burst 10k prio 8 # edonkey speed limitation
$TC class add dev $IFINGRESS parent 10:2 classid 10:206 htb rate 1kbit ceil 450kbit burst 2k prio 3 # audiogalaxy speed limitation
$TC class add dev $IFINGRESS parent 10:2 classid 10:207 htb rate 260kbit ceil 512kbit burst 100k prio 0 # www client
$TC class add dev $IFINGRESS parent 10:2 classid 10:208 htb rate 6kbit ceil 450kbit burst 2k prio 2 # ftp data, less important than web surf
$TC class add dev $IFINGRESS parent 10:2 classid 10:209 htb rate 260kbit ceil 480kbit burst 50k prio 0 # guaranted bandwidth, sound must be never cut:)
addqdisc $IFINGRESS 10:201 61:0 pfifo limit 20
addqdisc $IFINGRESS 10:203 63:0 sfq quantum 1492 perturb 120
addqdisc $IFINGRESS 10:205 65:0 sfq quantum 1492 perturb 120
addqdisc $IFINGRESS 10:206 66:0 sfq quantum 1492 perturb 120
addqdisc $IFINGRESS 10:207 67:0 sfq quantum 1492 perturb 120
addqdisc $IFINGRESS 10:208 68:0 sfq quantum 1492 perturb 120
addqdisc $IFINGRESS 10:209 69:0 sfq quantum 1492 perturb 120
addfilter $IFINGRESS 10: 11 10:201
addfilter $IFINGRESS 10: 12 10:202
addfilter $IFINGRESS 10: 13 10:203
addfilter $IFINGRESS 10: 15 10:205
addfilter $IFINGRESS 10: 16 10:206
addfilter $IFINGRESS 10: 17 10:207
addfilter $IFINGRESS 10: 18 10:208
addfilter $IFINGRESS 10: 19 10:209
$IP link set $IFINGRESS up
$LOGGER QoS on $IFINPUT for 512k download
echo QoS on $IFINPUT for 512k download
fi
# cleaning
$TC qdisc del dev $IFOUTPUT root 2> /dev/null > /dev/null
# règles tc / htb pour le traffic sortant ( egress )
$TC qdisc add dev $IFOUTPUT root handle 1: htb default 1
$TC class add dev $IFOUTPUT parent 1: classid 1:1 htb rate 124kbit ceil 124kbit burst 7k
$TC class add dev $IFOUTPUT parent 1:1 classid 1:100 htb rate 34kbit ceil 124kbit prio 0 burst 1k # ssh
$TC class add dev $IFOUTPUT parent 1:1 classid 1:101 htb rate 26kbit ceil 124kbit prio 1 burst 1k # petits paquets
$TC class add dev $IFOUTPUT parent 1:1 classid 1:102 htb rate 16kbit ceil 124kbit prio 1 burst 1k # paquets moyens
$TC class add dev $IFOUTPUT parent 1:1 classid 1:103 htb rate 13kbit ceil 124kbit prio 2 burst 128 # gros paquets
$TC class add dev $IFOUTPUT parent 1:1 classid 1:2 htb rate 3kbit ceil 122kbit prio 3 burst 128 ## classe basse priorité
$TC class add dev $IFOUTPUT parent 1:2 classid 1:104 htb rate 2kbit ceil 12kbit prio 8 burst 128 # edonkey
$TC class add dev $IFOUTPUT parent 1:2 classid 1:105 htb rate 1kbit ceil 64kbit prio 3 burst 128 # audiogalaxy
$TC class add dev $IFOUTPUT parent 1:1 classid 1:106 htb rate 33kbit ceil 120kbit prio 2 burst 3k # webserver
addqdisc $IFOUTPUT 1:100 20:0 pfifo limit 3
addqdisc $IFOUTPUT 1:101 21:0 sfq perturb 3
addqdisc $IFOUTPUT 1:102 22:0 pfifo limit 2
addqdisc $IFOUTPUT 1:103 23:0 sfq perturb 180
addqdisc $IFOUTPUT 1:104 24:0 sfq perturb 30
addqdisc $IFOUTPUT 1:105 25:0 sfq perturb 180
addqdisc $IFOUTPUT 1:106 26:0 sfq perturb 10
# en premier, on met les ack au haute priorité (ceci peut aussi se faire avec iptables)
$TC filter add dev $IFOUTPUT parent 1: protocol ip prio 1 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:102
addfilter $IFOUTPUT 1: 21 1:100
addfilter $IFOUTPUT 1: 22 1:101
addfilter $IFOUTPUT 1: 23 1:102
addfilter $IFOUTPUT 1: 24 1:103
addfilter $IFOUTPUT 1: 25 1:104
addfilter $IFOUTPUT 1: 26 1:105
addfilter $IFOUTPUT 1: 27 1:106
$LOGGER QoS on $IFOUTPUT for 128k upload
echo QoS on $IFOUTPUT for 128k upload
# ippersonnality rules ;)
# $IPTABLES -t mangle -A PREROUTING -i ppp0 -j PERS --tweak dst --local --conf /etc/dreamcast.conf
# $IPTABLES -t mangle -A OUTPUT -o ppp0 -j PERS --tweak src --local --conf /etc/dreamcast.conf
;;
esac
exit
|