verzia 2.54, 2008/01/17 21:47:44 |
verzia 2.63, 2009/01/17 01:37:08 |
|
|
# Licensed under terms of GNU General Public License. |
# Licensed under terms of GNU General Public License. |
# All rights reserved. |
# All rights reserved. |
# |
# |
# $Platon: scripts/shell/firewall/fw-universal.sh,v 2.53 2008-01-17 21:44:30 rajo Exp $ |
# $Platon: scripts/shell/firewall/fw-universal.sh,v 2.62 2009-01-17 01:31:26 rajo Exp $ |
# |
# |
# Changelog: |
# Changelog: |
# 2003-10-24 - created |
# 2003-10-24 - created |
Riadok 33 if [ "x$1" = "xblock" ] || [ "x$QUIET" = |
|
Riadok 33 if [ "x$1" = "xblock" ] || [ "x$QUIET" = |
|
else |
else |
print_info() |
print_info() |
{ |
{ |
echo $* |
echo "$@" |
} |
} |
fi |
fi |
# }}} |
# }}} |
Riadok 70 IFCONFIG="${IFCONFIG:=/sbin/ifconfig}" |
|
Riadok 70 IFCONFIG="${IFCONFIG:=/sbin/ifconfig}" |
|
DEPMOD="${DEPMOD:=/sbin/depmod}" |
DEPMOD="${DEPMOD:=/sbin/depmod}" |
MODPROBE="${MODPROBE:=/sbin/modprobe}" |
MODPROBE="${MODPROBE:=/sbin/modprobe}" |
RMMOD="${RMMOD:=/sbin/rmmod}" |
RMMOD="${RMMOD:=/sbin/rmmod}" |
AWK="${AWK:=/usr/bin/awk}" |
AWK="${AWK:=/usr/bin/gawk}" |
PERL="${PERL:=/usr/bin/perl}" |
PERL="${PERL:=/usr/bin/perl}" |
|
|
|
# shaping |
|
TC="${TC:=/sbin/tc}" |
|
|
# loopback interface |
# loopback interface |
LO_IFACE="${LO_IFACE:=lo}" |
LO_IFACE="${LO_IFACE:=lo}" |
# Hide NAT clients behind firewall |
# Hide NAT clients behind firewall |
NAT_SET_TTL="${NAT_SET_TTL:=no}" |
NAT_SET_TTL="${NAT_SET_TTL:=no}" |
|
|
|
# reject config |
|
ALL_REJECT_INPUT_TCP="${ALL_REJECT_INPUT_TCP:=113}" # by default reject connections to AUTH server |
|
REJECT_WITH="${REJECT_WITH:=tcp-reset}" |
|
|
# |
# |
# CONSTANTS - Do not edit |
# CONSTANTS - Do not edit |
# |
# |
Riadok 98 TRACEROUTE_DEST_PORTS="33434:33523" # Tr |
|
Riadok 105 TRACEROUTE_DEST_PORTS="33434:33523" # Tr |
|
# allow some ICMP packets - needed for ping etc. |
# allow some ICMP packets - needed for ping etc. |
ACCEPT_ICMP_PACKETS="${ACCEPT_ICMP_PACKETS:=echo-reply destination-unreachable echo-request time-exceeded}" |
ACCEPT_ICMP_PACKETS="${ACCEPT_ICMP_PACKETS:=echo-reply destination-unreachable echo-request time-exceeded}" |
|
|
|
# check if all required tools are installed |
|
check_tools() |
|
{ # {{{ |
|
[ -x $AWK ] || (echo "AWK not found: please install gawk" && exit 1); |
|
[ -x $PERL ] || (echo "PERL not found: please install perl" && exit 1); |
|
[ -x $IPTABLES ] || (echo "IPTABLES not found: please install iptables" && exit 1); |
|
[ -x $IPTABLES_SAVE ] || (echo "IPTABLES_SAVE not found: please install iptables" && exit 1); |
|
[ -x $IPTABLES_RESTORE ] || (echo "IPTABLES_RESTORE not found: please install iptables" && exit 1); |
|
} # }}} |
|
|
print_first() |
print_first() |
{ # {{{ |
{ # {{{ |
Riadok 112 get_first_ip_addr() |
|
Riadok 128 get_first_ip_addr() |
|
|
|
read_config_ips() |
read_config_ips() |
{ # {{{ |
{ # {{{ |
PARSE_CONFIG=$1 perl -ne 'if (m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d+)$/g) { print; } elsif ($_ !~ m/^\s*#/ && $_ !~ m/^\s*$/ ) { print STDERR "ERROR: $ENV{PARSE_CONFIG}:$.: ignored string $_\n"; }' $1 |
PARSE_CONFIG=$1 $PERL -ne 'if (m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d+)$/g) { print; } elsif ($_ !~ m/^\s*#/ && $_ !~ m/^\s*$/ ) { print STDERR "ERROR: $ENV{PARSE_CONFIG}:$.: ignored string $_\n"; }' $1 |
} # }}} |
} # }}} |
|
|
# load necessary modules from $MODULES variable |
# load necessary modules from $MODULES variable |
|
|
|
|
if [ -f "$CACHE_FILE" ]; then |
if [ -f "$CACHE_FILE" ]; then |
print_info "Loading rules from cache file $CACHE_FILE" |
print_info "Loading rules from cache file $CACHE_FILE" |
|
|
|
# this has nothing to do with IPtables rules, we need to run them explicitly |
|
forward_on |
|
shaping_on |
|
|
|
# restore IPtables rules |
$IPTABLES_RESTORE -c < $CACHE_FILE; |
$IPTABLES_RESTORE -c < $CACHE_FILE; |
forward_on # this has nothing to do with IPtables rules, we need to run them explicitly |
#echo "exit code $IPTABLES_RESTORE: $?" |
exit 0; |
[ $? -eq 0 ] && exit 0; # exit if load succesfull |
fi |
fi |
} # }}} |
} # }}} |
|
|
Riadok 166 unload_modules() |
|
Riadok 188 unload_modules() |
|
print_iface_status() |
print_iface_status() |
{ # {{{ |
{ # {{{ |
# Print interfaces: |
# Print interfaces: |
print_info "# iface | IP addr | Gateway | broadcast | netmask | HW addr" |
print_info "$(pad7 "# iface") | $(pad15 "IP address") | $(pad15 "Gateway") | $(pad15 "Broadcast") | $(pad15 "Netmask") | HW address"; |
for iface in $interfaces; do |
for iface in $interfaces; do |
IPS="IP_$iface"; |
IPS="IP_$iface"; |
for IP in ${!IPS}; do |
for IP in ${!IPS}; do |
Gateway="Gateway_$iface"; Bcast="Bcast_$iface"; Mask="Mask_$iface"; HWaddr="HWaddr_$iface"; |
Gateway="Gateway_$iface"; |
print_info "$iface | ${IP} | ${!Gateway} | ${!Bcast} | ${!Mask} | ${!HWaddr}" |
Bcast="Bcast_$iface"; |
|
Mask="Mask_$iface"; |
|
HWaddr="HWaddr_$iface"; |
|
print_info "$(pad7 $iface) | $(pad15 ${IP}) | $(pad15 ${!Gateway}) | $(pad15 ${!Bcast}) | $(pad15 ${!Mask}) | ${!HWaddr}"; |
done |
done |
done |
done |
} # }}} |
} # }}} |
Riadok 625 reject_input() |
|
Riadok 650 reject_input() |
|
for port in $ALL_REJECT_INPUT_TCP; do |
for port in $ALL_REJECT_INPUT_TCP; do |
for iface in $INTERFACES; do |
for iface in $INTERFACES; do |
print_info -en " $port($iface)" |
print_info -en " $port($iface)" |
$IPTABLES -A INPUT -i $iface -p TCP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -p TCP --dport $port -j REJECT --reject-with $REJECT_WITH |
done |
done |
done |
done |
print_info " done." |
print_info " done." |
Riadok 635 reject_input() |
|
Riadok 660 reject_input() |
|
for port in $ALL_REJECT_INPUT_UDP; do |
for port in $ALL_REJECT_INPUT_UDP; do |
for iface in $INTERFACES; do |
for iface in $INTERFACES; do |
print_info -en " $port($iface)" |
print_info -en " $port($iface)" |
$IPTABLES -A INPUT -i $iface -p UDP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -p UDP --dport $port -j REJECT --reject-with $REJECT_WITH |
done |
done |
done |
done |
print_info " done." |
print_info " done." |
|
|
print_info -en " $port"`[ ! -z $src_ip ] && echo "[$src_ip]"` |
print_info -en " $port"`[ ! -z $src_ip ] && echo "[$src_ip]"` |
for ip in ${!IPS}; do |
for ip in ${!IPS}; do |
if [ -z $src_ip ]; then |
if [ -z $src_ip ]; then |
$IPTABLES -A INPUT -i $iface -d $ip -p TCP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -d $ip -p TCP --dport $port -j REJECT --reject-with $REJECT_WITH |
else |
else |
$IPTABLES -A INPUT -i $iface -s $src_ip -d $ip -p TCP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -s $src_ip -d $ip -p TCP --dport $port -j REJECT --reject-with $REJECT_WITH |
fi |
fi |
done |
done |
done |
done |
|
|
print_info -en " $port"`[ ! -z $src_ip ] && echo "[$src_ip]"` |
print_info -en " $port"`[ ! -z $src_ip ] && echo "[$src_ip]"` |
for ip in ${!IPS}; do |
for ip in ${!IPS}; do |
if [ -z $src_ip ]; then |
if [ -z $src_ip ]; then |
$IPTABLES -A INPUT -i $iface -d $ip -p UDP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -d $ip -p UDP --dport $port -j REJECT --reject-with $REJECT_WITH |
else |
else |
$IPTABLES -A INPUT -i $iface -s $src_ip -d $ip -p UDP --dport $port -j REJECT --reject-with icmp-port-unreachable |
$IPTABLES -A INPUT -i $iface -s $src_ip -d $ip -p UDP --dport $port -j REJECT --reject-with $REJECT_WITH |
fi |
fi |
done |
done |
done |
done |
|
|
{ # {{{ |
{ # {{{ |
|
|
print_info -en "Accepting ICMP packets:" |
print_info -en "Accepting ICMP packets:" |
# Službu AUTH není dobré filtrovat pomocí DROP, protože to může |
|
# vést k prodlevám při navazování některých spojení. Proto jej |
|
# sice zamítneme, ale vygenerujeme korektní ICMP chybovou zprávu |
|
$IPTABLES -A INPUT -p TCP --dport 113 -j REJECT --reject-with tcp-reset #AUTH server |
|
|
|
# accept only allowed ICMP packets |
# accept only allowed ICMP packets |
for type in $ACCEPT_ICMP_PACKETS; do |
for type in $ACCEPT_ICMP_PACKETS; do |
Riadok 986 accept_loopback() |
|
Riadok 1007 accept_loopback() |
|
|
|
} # }}} |
} # }}} |
|
|
|
# |
|
# Shaping support {{{ |
|
# |
|
# http://koti.welho.com/ntoivol2/shaping/ |
|
# |
|
|
|
shaping_on() |
|
{ # {{{ |
|
|
|
mark_idx=1 |
|
if [ ! -z $SHAPING_IFACE ]; then |
|
for iface in $SHAPING_IFACE; do |
|
echo "Shaping for interface $iface" |
|
shaping_classes="${iface}_SHAPING_CLASSES" |
|
|
|
# root qdisc: 2-band prio with everything defaulting to band 0 |
|
$TC qdisc add dev $iface root handle 1: prio bands 2 priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
|
|
|
for class in ${!shaping_classes}; do |
|
rate="${iface}_SHAPING_RATE_${class}" |
|
latency="${iface}_SHAPING_LATENCY_${class}" |
|
burst="${iface}_SHAPING_BURST_${class}" |
|
netmask="${iface}_SHAPING_NETMASK_${class}" |
|
echo -e "\tshaping \"$class\" traffic: rate=${!rate} burst=${!burst} netmask=${!netmask}" |
|
if [ -z ${!netmask} ]; then |
|
$IPTABLES -t mangle -A OUTPUT -j MARK --set-mark 0x$mark_idx |
|
else |
|
$IPTABLES -t mangle -A OUTPUT -d ${!netmask} -j MARK --set-mark 0x$mark_idx |
|
fi |
|
|
|
if [ -z ${!rate} ]; then |
|
# SFQ for local traffic |
|
$TC qdisc add dev $iface parent 1:$mark_idx handle $((10 + $mark_idx)): sfq perturb 10 |
|
else |
|
# TBF shaping and SFQ for internet traffic |
|
$TC qdisc add dev $iface parent 1:$mark_idx handle $((10 + $mark_idx)): tbf rate ${!rate} burst ${!burst} latency ${!latency} |
|
$TC qdisc add dev $iface parent $((10 + $mark_idx)): handle $((10 * $mark_idx)): sfq perturb 10 |
|
fi |
|
|
|
mark_idx=$(($mark_idx + 1)) |
|
done |
|
done |
|
fi |
|
|
|
} # }}} |
|
|
|
shaping_off() |
|
{ # {{{ |
|
if [ ! -z $SHAPING_IFACE ]; then |
|
echo -en "Shaping turned off for interface" |
|
for iface in $SHAPING_IFACE; do |
|
echo -en " $iface" |
|
$TC qdisc del dev $iface root 2>/dev/null |
|
done |
|
echo ". done" |
|
fi |
|
} # }}} |
|
|
|
shaping_status() |
|
{ # {{{ |
|
if [ ! -z $SHAPING_IFACE ]; then |
|
echo "# Shaping status: " |
|
$TC qdisc list |
|
else |
|
echo "# Shaping turned off" |
|
fi |
|
} # }}} |
|
|
|
# }}} |
|
|
add_banned_ip() |
add_banned_ip() |
{ # {{{ |
{ # {{{ |
echo "# `date '+%Y-%m-%d %X' ` - ${SSH_CLIENT:=local}" >> $DEFAULT_FIREWALL_CONFIG_DIR/BANNED_IP.conf |
echo "# `date '+%Y-%m-%d %X' ` - ${SSH_CLIENT:=local}" >> $DEFAULT_FIREWALL_CONFIG_DIR/BANNED_IP.conf |
Riadok 996 add_banned_ip() |
|
Riadok 1087 add_banned_ip() |
|
cat >> $TMPFILE |
cat >> $TMPFILE |
else |
else |
for IP in $*; do |
for IP in $*; do |
echo $i >> $TMPFILE; |
echo $IP >> $TMPFILE; |
done |
done |
fi |
fi |
read_config_ips $TMPFILE >> $DEFAULT_FIREWALL_CONFIG_DIR/BANNED_IP.conf |
read_config_ips $TMPFILE >> $DEFAULT_FIREWALL_CONFIG_DIR/BANNED_IP.conf |
Riadok 1012 deploy_block() |
|
Riadok 1103 deploy_block() |
|
print_info "Deploying to local rules ..." |
print_info "Deploying to local rules ..." |
add_banned_ip $* |
add_banned_ip $* |
# start the some script twice to refresh rules (new blocked IP's) |
# start the some script twice to refresh rules (new blocked IP's) |
$0 start |
QUIET=yes $0 start |
TMPFILE=`mktemp -t fw-universal.sh-XXXXXX` || exit 1 |
TMPFILE=`mktemp -t fw-universal.sh-XXXXXX` || exit 1 |
trap 'rm -f $TMPFILE' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
trap 'rm -f $TMPFILE' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
for i in $*; do |
for i in $*; do |
Riadok 1135 printf "interfaces=\"%s\"; export inter |
|
Riadok 1226 printf "interfaces=\"%s\"; export inter |
|
|
|
} # }}} |
} # }}} |
|
|
|
# helper function for string padding |
|
str_pad_right() |
|
{ # {{{ |
|
num="$1"; |
|
string="$2"; |
|
count=$(echo -n "$string" | wc -c); |
|
count=$((count + 0)) |
|
while [ $count -lt $num ]; do |
|
string="$string "; |
|
count=$((count + 1)); |
|
done |
|
echo -n "$string" |
|
return; |
|
} # }}} |
|
|
|
pad7() { str_pad_right 7 "$1"; } |
|
pad15() { str_pad_right 15 "$1"; } |
|
|
|
|
|
check_tools |
parse_ifconfig |
parse_ifconfig |
print_iface_status |
print_iface_status |
|
|
|
|
log_forward_drop |
log_forward_drop |
forward_on |
forward_on |
do_ip_accounting |
do_ip_accounting |
|
shaping_off |
|
shaping_on |
configure_special_rules |
configure_special_rules |
$IPTABLES_SAVE -c > $CACHE_FILE |
$IPTABLES_SAVE -c > $CACHE_FILE |
;; |
;; |
|
|
stop) |
stop) |
print_info -n "Stopping $DESC: " |
print_info -n "Stopping $DESC: " |
|
shaping_off |
set_default_policy |
set_default_policy |
remove_chains |
remove_chains |
unload_modules |
unload_modules |
|
|
status) |
status) |
print_iface_status; echo |
print_iface_status; echo |
$IPTABLES -L -nv |
$IPTABLES -L -nv |
|
shaping_status |
;; |
;; |
|
|
purge) |
purge) |