#!/bin/sh # nodog.fw networkMatchIface() { _RES=`awk -v "NET=$1" -- ' function ip2int(ip) { ret=0;split(ip,a,"."); for(x in a)ret=or(lshift(ret,8),a[x]); return ret; } BEGIN { i=1; be=-1; } $6 ~ /^[0-9][0-9]*$/ { iface[i]=$1;dest[i]=$2;mask[i]=$8;i++; if(be==-1){if($8~/^[Ff]/ && ($8~/0$/))be=1;else{if($8~/[Ff]$/ && $8~/^0/)be=0;}} } END { n=split(NET,tnet,"/"); if(n==1){ipaddr=ip2int(tnet[1]);} else{if(n==2){tnm=and(xor(lshift(0xffffffff,32-int(tnet[2])),0),0xffffffff);ipaddr=and(ip2int(tnet[1]),tnm);} else{exit(2);}} found=0;cipaddr=0;cnetmask=0;cnetaddr=0;ciface=""; for(i in iface){ if(be==0){ t=dest[i];tnetaddr=or(or(lshift("0x" substr(t,7,2),24),lshift("0x" substr(t,5,2),16)),or(lshift("0x" substr(t,3,2),8),"0x" substr(t,1,2))); t=mask[i];tnetmask=or(or(lshift("0x" substr(t,7,2),24),lshift("0x" substr(t,5,2),16)),or(lshift("0x" substr(t,3,2),8),"0x" substr(t,1,2))); } else { t=dest[i];tnetaddr=or(lshift(int("0x" substr(t,1,4)),16),int("0x" substr(t,5,4))); t=mask[i];tnetmask=or(lshift(int("0x" substr(t,1,4)),16),int("0x" substr(t,5,4))); } if((and(ipaddr,tnetmask)==tnetaddr) && (cnetmask/dev/null 2>&1 if [ $? -ne 0 ]; then insmod $module 2>/dev/null fi done } clearQoS() { # 1 => Ip # 2 => Netmask for ifaceq in $IQdevice; do tc -p filter show dev ${ifaceq} | awk -v "i=$1/$2" ' /^ /{ t=t $0; next } { if(t && index(t,i) && match(t," pref [0-9]+ ")){ print substr(t,RSTART+6,RLENGTH-7) }; t=$0 } END { if(t && index(t,i) && match(t," pref [0-9]+ ")){ print substr(t,RSTART+6,RLENGTH-7) } } ' | while read UserClass; do if [ -n "${UserClass}" ]; then if [ ${UploadRate} -gt 0 ]; then tc filter del dev ${ifaceq} parent 1: pref ${UserClass} protocol ip u32 match ip src $1/$2 classid 1:${UserClass}0 echo "${UserClass}:1:1:1:1:1" | awk \ -v device="${ifaceq}" \ -v linespeed="${UploadRate}" \ -f firewall/tcrules.awk \ | sed 's/ add / del /g' | sed 'x;1!H;$!d;x' | while read CMD; do $CMD; done fi for ifacein in $InternalDevice; do tc filter del dev $ifacein parent 1: pref ${UserClass} protocol ip u32 match ip dst $1/$2 classid 1:${UserClass}0 echo "${UserClass}:1:1:1:1:1" | awk \ -v device="$ifacein" \ -v linespeed="${DownloadRate}" \ -f firewall/tcrules.awk \ | sed 's/ add / del /g' | sed 'x;1!H;$!d;x' | while read CMD; do $CMD; done done fi done done } checkDeviceUpload() { if [ -z "$IMQdevice" ]; then IMQdisabled=1 else IMQdisabled=0 IQdevice=$IMQdevice fi if [ -z "$IFBdevice" ]; then IFBdisabled=1 else IFBdisabled=0 IQdevice=$IFBdevice fi if [ -z "$IQdevice" ]; then IQdevice=$ExternalDevice fi } #----------------------------------- # START FUNCTION #----------------------------------- initialize_fw() { #--------------------------------------------------------------- # Enable IP routing. Required if your firewall is protecting a # network, NAT included #--------------------------------------------------------------- echo "1" > /proc/sys/net/ipv4/ip_forward #--------------------------------------------------------------- # Disable routing triangulation. Respond to queries out # the same interface, not another. Helps to maintain state # Also protects against IP spoofing #--------------------------------------------------------------- echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter # Load all the kernel modules we need loadKernelModules "ipt_TOS xt_mac ipt_ACCOUNT" clear_fw # First mark for unauthorized after mark for authorized # BEGIN ND_m_pre $IPTABLES -t mangle -N ND_m_pre && \ $IPTABLES -t mangle -A ND_m_pre -j MARK --set-mark 4 || exit 2 if [ "$EnableIpset" = 1 ]; then if [ "$EnableIpsetAuth" = "bitmap:ip,mac" ]; then $IPSET create ND_s_permit_in_1 list:set && \ $IPSET create ND_s_permit_in_2 list:set && \ $IPSET create ND_s_permit_in_3 list:set || exit 2 for net in $LocalNetwork; do networkMatchIface $net ifacein netid [ $? -eq 0 ] || exit 1 $IPSET create ND_s_permit_in_1_$netid bitmap:ip,mac range $net && \ $IPSET add ND_s_permit_in_1 ND_s_permit_in_1_$netid && \ $IPSET create ND_s_permit_in_2_$netid bitmap:ip,mac range $net && \ $IPSET add ND_s_permit_in_2 ND_s_permit_in_2_$netid && \ $IPSET create ND_s_permit_in_3_$netid bitmap:ip,mac range $net && \ $IPSET add ND_s_permit_in_3 ND_s_permit_in_3_$netid || exit 2 done $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_1 src,src -j MARK --set-mark 1 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_2 src,src -j MARK --set-mark 2 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_3 src,src -j MARK --set-mark 3 || exit 2 elif [ "$EnableIpsetAuth" = "hash:ip,mac" ]; then $IPSET create ND_s_permit_in_1 hash:ip,mac && \ $IPSET create ND_s_permit_in_2 hash:ip,mac && \ $IPSET create ND_s_permit_in_3 hash:ip,mac && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_1 src,src -j MARK --set-mark 1 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_2 src,src -j MARK --set-mark 2 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_3 src,src -j MARK --set-mark 3 || exit 2 elif [ "$EnableIpsetAuth" = "hash:ip" ]; then $IPSET create ND_s_permit_in_1 hash:ip && \ $IPSET create ND_s_permit_in_2 hash:ip && \ $IPSET create ND_s_permit_in_3 hash:ip && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_1 src -j MARK --set-mark 1 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_2 src -j MARK --set-mark 2 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_3 src -j MARK --set-mark 3 || exit 2 else $IPSET create ND_s_permit_in_1 hash:mac && \ $IPSET create ND_s_permit_in_2 hash:mac && \ $IPSET create ND_s_permit_in_3 hash:mac && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_1 src -j MARK --set-mark 1 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_2 src -j MARK --set-mark 2 && \ $IPTABLES -t mangle -A ND_m_pre -m set --match-set ND_s_permit_in_3 src -j MARK --set-mark 3 || exit 2 fi else $IPTABLES -t mangle -N ND_m_permit_in && $IPTABLES -t mangle -A ND_m_pre -j ND_m_permit_in || exit 2 fi # END ND_m_pre # Allow web hosts and traffic to portal, also manage DNS traffic # BEGIN ND_n_notify if [ "$EnableIpset" != 1 ]; then $IPTABLES -t nat -N ND_n_notify || exit 2 fi # END ND_n_notify # BEGIN ND_n_pre $IPTABLES -t nat -N ND_n_pre || exit 2 if [ "$EnableIpset" = 1 ]; then $IPSET create ND_s_allow_http hash:net && \ $IPTABLES -t nat -A ND_n_pre -p tcp -m multiport --dports 80,443 -m set --match-set ND_s_allow_http dst -j RETURN || exit 2 fi for host in $AuthServiceIP $1 $AllowedWebHosts; do if [ "$EnableIpset" = 1 ]; then # Non torna errore per supportare nell'elenco lo stesso IP $IPSET add ND_s_allow_http $host else #for port in 80 443; do # $IPTABLES -t nat -A ND_n_pre -d $host -p tcp --dport $port -j RETURN #done $IPTABLES -t nat -A ND_n_pre -p tcp -m multiport --dports 80,443 -d $host -j RETURN || exit 2 fi done if [ "$EnableIpset" = 1 ]; then $IPSET create ND_s_notify hash:ip && \ $IPTABLES -t nat -A ND_n_pre -p tcp --dport 80 -m mark ! --mark 4 -m set --match-set ND_s_notify src -j REDIRECT --to-port $ProxyPort || exit 2 else $IPTABLES -t nat -A ND_n_pre -j ND_n_notify || exit 2 fi if [ "$DNSAddr" ]; then if [ "$EnableIpset" = 1 ]; then $IPSET create ND_s_allow_dns hash:ip && \ $IPTABLES -t nat -A ND_n_pre -p udp --dport 53 -m mark --mark 4 -m set --match-set ND_s_allow_dns dst -j RETURN && \ $IPTABLES -t nat -A ND_n_pre -p tcp --dport 53 -m mark --mark 4 -m set --match-set ND_s_allow_dns dst -j RETURN || exit 2 fi for dns in $DNSAddr; do if [ "$EnableIpset" = 1 ]; then $IPSET add ND_s_allow_dns $dns else $IPTABLES -t nat -A ND_n_pre -p udp --dport 53 -m mark --mark 4 -d $dns -j RETURN && \ $IPTABLES -t nat -A ND_n_pre -p tcp --dport 53 -m mark --mark 4 -d $dns -j RETURN || exit 2 fi if [ -z "$dns_item" ]; then dns_item=$dns fi done # Force unauthenticated DNS traffic through fist server. # Of course, only the first rule of this type will match. # But it's easier to leave them all in ATM. for prot in tcp udp; do $IPTABLES -t nat -A ND_n_pre -p $prot --dport 53 -m mark --mark 4 -j DNAT --to-destination $dns_item:53 && \ $IPTABLES -t nat -A ND_n_pre -p $prot --dport 53 -d $FullPrivateNetwork -j DNAT --to-destination $dns_item:53 || exit 2 done else for prot in tcp udp; do $IPTABLES -t nat -A ND_n_pre -p $prot --dport 53 -m mark --mark 4 -j REDIRECT --to-port 53 && \ $IPTABLES -t nat -A ND_n_pre -p $prot --dport 53 -d $FullPrivateNetwork -j REDIRECT --to-port 53 || exit 2 done fi $IPTABLES -t nat -A ND_n_pre -p tcp --dport 80 -m mark --mark 4 -j REDIRECT --to-port $GatewayPort || exit 2 # END ND_n_pre # Accept authorized IP # BEGIN ND_f_permit_ou if [ "$EnableIpset" = 1 ]; then $IPSET create ND_s_permit_ou hash:ip || exit 2 else $IPTABLES -t filter -N ND_f_permit_ou || exit 2 fi # END ND_f_permit_ou # Filter allowed or denied traffic for authorized and not autorized from external devices and networks # BEGIN ND_f_fwd_ou $IPTABLES -t filter -N ND_f_fwd_ou || exit 2 if [ "$EnableIpset" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_ou -m set --match-set ND_s_permit_ou dst -j ACCEPT || exit 2 else $IPTABLES -t filter -A ND_f_fwd_ou -j ND_f_permit_ou || exit 2 fi if [ "$EnableIpset" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_ou -p tcp -m multiport --sports 80,443 -m set --match-set ND_s_allow_http src -j ACCEPT || exit 2 else for host in $AuthServiceIP $1 $AllowedWebHosts; do #for port in 80 443; do # $IPTABLES -t filter -A ND_f_fwd_ou -d $host -p tcp --dport $port -j ACCPET #done $IPTABLES -t filter -A ND_f_fwd_ou -p tcp -m multiport --sports 80,443 -s $host -j ACCEPT || exit 2 done fi if [ "$DNSAddr" ]; then if [ "$EnableIpset" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_ou -m set --match-set ND_s_allow_dns src -j ACCEPT || exit 2 else for dns in $DNSAddr; do $IPTABLES -t filter -A ND_f_fwd_ou -s $dns -j ACCEPT || exit 2 done fi fi $IPTABLES -t filter -A ND_f_fwd_ou -j DROP || exit 2 # END ND_f_fwd_ou # Block RFC1918 traffic # BEGIN ND_f_RFC1918 if [ "$BlockRFC1918" = 1 ]; then $IPTABLES -t filter -N ND_f_RFC1918 for net in $FullPrivateNetwork; do $IPTABLES -t filter -A ND_f_RFC1918 -d $net -j ACCEPT || exit 2 done $IPTABLES -t filter -A ND_f_RFC1918 -d 10.0.0.0/8 -j RETURN && \ $IPTABLES -t filter -A ND_f_RFC1918 -d 172.16.0.0/12 -j RETURN && \ $IPTABLES -t filter -A ND_f_RFC1918 -d 192.168.0.0/16 -j RETURN && \ $IPTABLES -t filter -A ND_f_RFC1918 -d 127.0.0.0/8 -j RETURN && \ $IPTABLES -t filter -A ND_f_RFC1918 -j ACCEPT || exit 2 fi # END ND_f_RFC1918 # Lock down more ports for public users, if specified. Port restrictions are not applied to co-op and owner class users # There are two philosophies in restricting access: # That Which Is Not Specifically Permitted Is Denied # That Which Is Not Specifically Denied Is Permitted # If "IncludePorts" is defined, the default policy will be to deny all traffic, and only allow the ports mentioned # If "ExcludePorts" is defined, the default policy will be to allow all traffic, except to the ports mentioned # If both are defined, ExcludePorts will be ignored, and the default policy # will be to deny all traffic, allowing everything in IncludePorts, and issue a warning # BEGIN ND_f_ports if [ "$IncludePorts" ]; then if [ "$ExcludePorts" ]; then echo "WARNING: ExcludePorts and IncludePorts are both defined" echo "Ignoring 'ExcludePorts'. Please check your configuration" fi $IPTABLES -t filter -N ND_f_ports || exit 2 for port in $IncludePorts; do $IPTABLES -t filter -A ND_f_ports -p tcp --dport $port -j ACCEPT && \ $IPTABLES -t filter -A ND_f_ports -p udp --dport $port -j ACCEPT || exit 2 done $IPTABLES -t filter -A ND_f_ports -p tcp -j DROP && \ $IPTABLES -t filter -A ND_f_ports -p udp -j DROP || exit 2 elif [ "$ExcludePorts" ]; then $IPTABLES -t filter -N ND_f_ports || exit 2 for port in $ExcludePorts; do $IPTABLES -t filter -A ND_f_ports -p tcp --dport $port -j DROP && \ $IPTABLES -t filter -A ND_f_ports -p udp --dport $port -j DROP || exit 2 done fi # END ND_f_ports # Filter allowed or denied traffic for authorized and not autorized from internal devices and networks # BEGIN ND_f_fwd_in $IPTABLES -t filter -N ND_f_fwd_in || exit 2 $IPTABLES -t filter -A ND_f_fwd_in -p tcp -m state --state INVALID -j DROP if [ "$BlockRFC1918" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_in -m mark --mark 2 -j ND_f_RFC1918 || exit 2 else $IPTABLES -t filter -A ND_f_fwd_in -m mark --mark 2 -j ACCEPT || exit 2 fi if [ "$EnableIpset" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_in -p tcp -m multiport --dports 80,443 -m set --match-set ND_s_allow_http dst -j ACCEPT || exit 2 else for host in $AuthServiceIP $1 $AllowedWebHosts; do #for port in 80 443; do # $IPTABLES -t filter -A ND_f_fwd_in -d $host -p tcp --dport $port -j ACCPET #done $IPTABLES -t filter -A ND_f_fwd_in -p tcp -m multiport --dports 80,443 -d $host -j ACCEPT || exit 2 done fi if [ "$DNSAddr" ]; then if [ "$EnableIpset" = 1 ]; then $IPTABLES -t filter -A ND_f_fwd_in -p udp --dport 53 -m set --match-set ND_s_allow_dns dst -j ACCEPT && \ $IPTABLES -t filter -A ND_f_fwd_in -p tcp --dport 53 -m set --match-set ND_s_allow_dns dst -j ACCEPT || exit 2 else for dns in $DNSAddr; do $IPTABLES -t filter -A ND_f_fwd_in -p tcp --dport 53 -d $dns -j ACCEPT && \ $IPTABLES -t filter -A ND_f_fwd_in -p udp --dport 53 -d $dns -j ACCEPT || exit 2 done fi fi if [ -n "$IncludePorts" -o -n "$ExcludePorts" ]; then $IPTABLES -t filter -A ND_f_fwd_in -m mark --mark 3 -j ND_f_ports || exit 2 fi $IPTABLES -t filter -A ND_f_fwd_in -j DROP || exit 2 # END ND_f_fwd_in # Filter input traffic for captive # BEGIN ND_f_in $IPTABLES -t filter -N ND_f_in || exit 2 for src in $AuthServiceIP; do for ifaceout in $ExternalDevice; do $IPTABLES -t filter -A ND_f_in -i $ifaceout ! -s $src -p tcp --dport $GatewayPort -j DROP || exit 2 done done # supporto anti DoS sul captive portal if [ $DosPrevention -gt 0 ]; then for ifacein in $InternalDevice; do $IPTABLES -t filter -A ND_f_in -p tcp -i $ifacein --dport $GatewayPort -m state --state NEW -m recent --set --name NoDog && \ $IPTABLES -t filter -A ND_f_in -p tcp -i $ifacein --dport $GatewayPort -m state --state NEW -m recent --update --name NoDog \ --seconds $DosTimeInterval --hitcount `expr $DosAllowTries + 1` -j DROP || exit 2 done fi # END ND_f_in # Account traffic # BEGIN ND_m_acc_in ND_m_acc_ou $IPTABLES -t mangle -N ND_m_acc_in && \ $IPTABLES -t mangle -N ND_m_acc_ou || exit 2 # -------------------------------------------------------------------------------------------------------------------------------------------------- # Automatically sets the proper value of MSS (Maximum Segment Size) of TCP SYN packets that the firewall sees of all outgoing packets. # -------------------------------------------------------------------------------------------------------------------------------------------------- # The MSS value is used to control the maximum size of packets for specific connections. Under normal circumstances, this means the size of # the MTU (Maximum Transfer Unit) value, minus 40 bytes. This is used to overcome some ISP's and servers that block ICMP fragmentation needed # packets, which can result in really weird problems which can mainly be described such that everything works perfectly from your firewall/router, # but your local hosts behind the firewall can't exchange large packets. This could mean such things as mail servers being able to send small mails, # but not large ones, web browsers that connect but then hang with no data received, and ssh connecting properly, but scp hangs after the initial # handshake. In other words, everything that uses any large packets will be unable to work. # -------------------------------------------------------------------------------------------------------------------------------------------------- # Normal MTU for ethernet is 1500 bytes, therefore minus 40 bytes MSS is 1460 bytes. MSS only has to be set properly in the SYN packet. # -------------------------------------------------------------------------------------------------------------------------------------------------- # The --clamp-mss-to-pmtu automatically sets the MSS to the proper value, hence you don't need to explicitly set it. It is automatically set to PMTU # (Path Maximum Transfer Unit) minus 40 bytes, which should be a reasonable value for most applications. # -------------------------------------------------------------------------------------------------------------------------------------------------- if [ $MaxSegmentSize -gt 0 ]; then for iface in $ExternalDevice; do $IPTABLES -t mangle -A ND_m_acc_ou -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu || exit 2 done fi if [ "$EnableIpset" = 1 ]; then $IPTABLES -t mangle -A ND_m_acc_in -m set --match-set ND_s_allow_http src -j RETURN && \ $IPTABLES -t mangle -A ND_m_acc_ou -m set --match-set ND_s_allow_http dst -j RETURN || exit 2 else for host in $AuthServiceIP $1 $AllowedWebHosts; do $IPTABLES -t mangle -A ND_m_acc_in -s "$host" -j RETURN && \ $IPTABLES -t mangle -A ND_m_acc_ou -d "$host" -j RETURN || exit 2 done fi for net in $LocalNetwork; do $IPTABLES -t mangle -A ND_m_acc_in -s "$net" -j RETURN && \ $IPTABLES -t mangle -A ND_m_acc_in -d "$net" -j ACCOUNT --addr "$net" --tname "$net" && \ $IPTABLES -t mangle -A ND_m_acc_ou -d "$net" -j RETURN && \ $IPTABLES -t mangle -A ND_m_acc_ou -s "$net" -j ACCOUNT --addr "$net" --tname "$net" || exit 2 done # END ND_m_acc_in ND_m_acc_ou # Masquering # BEGIN ND_n_post $IPTABLES -t nat -N ND_n_post || exit 2 if [ "$AvoidMasqueradeAuthServiceIP" = "1" ]; then $IPTABLES -t nat -A ND_n_post -d $AuthServiceIP -j RETURN || exit 2 fi $IPTABLES -t nat -A ND_n_post -j MASQUERADE || exit 2 # END ND_n_post $IPTABLES -t filter -A INPUT -j ND_f_in || exit 2 for net in $LocalNetwork; do networkMatchIface $net ifacein [ $? -eq 0 ] || exit 1 ifaceinout=0 for ifaceout in $ExternalDevice; do if [ "$ifacein" = "$ifaceout" ]; then ifaceinout=1 fi done if [ "$ifaceinout" == "1" ]; then for ifaceout in $ExternalDevice; do $IPTABLES -t filter -A FORWARD -i $ifacein -s $net -o $ifaceout -j ND_f_fwd_in && \ $IPTABLES -t filter -A FORWARD -i $ifaceout -d $net -o $ifacein -j ND_f_fwd_ou && \ $IPTABLES -t mangle -A POSTROUTING -o $ifaceout -s $net -j ND_m_acc_ou || exit 2 done $IPTABLES -t mangle -A PREROUTING -i $ifacein -s $net -j ND_m_pre && \ $IPTABLES -t nat -A PREROUTING -i $ifacein -s $net -j ND_n_pre && \ $IPTABLES -t mangle -A POSTROUTING -o $ifacein -d $net -j ND_m_acc_in || exit 2 else for ifaceout in $ExternalDevice; do $IPTABLES -t filter -A FORWARD -i $ifacein -s $net -o $ifaceout -j ND_f_fwd_in && \ $IPTABLES -t filter -A FORWARD -i $ifaceout -d $net -o $ifacein -j ND_f_fwd_ou && \ $IPTABLES -t mangle -A POSTROUTING -o $ifaceout -s $net -j ND_m_acc_ou || exit 2 done $IPTABLES -t mangle -A PREROUTING -i $ifacein -s $net -j ND_m_pre && \ $IPTABLES -t nat -A PREROUTING -i $ifacein -s $net -j ND_n_pre && \ $IPTABLES -t mangle -A POSTROUTING -o $ifacein -d $net -j ND_m_acc_in || exit 2 fi if [ $RouteOnly -eq 0 ]; then for ifacemsq in $MasqueradeDevice; do $IPTABLES -t nat -A POSTROUTING -o $ifacemsq -s $net -j ND_n_post || exit 2 done fi done # -------------------------------------------------------------------------- [ -S /tmp/evfwdsock ] && /usr/sbin/fwevhandler i # Bandwidth limits # -------------------------------------------------------------------------- if [ $EnableBandwidthLimits -gt 0 ]; then if [ $IMQdisabled -eq 0 ]; then extra_modules=ipt_IMQ fi if [ $IFBdisabled -eq 0 ]; then extra_modules="ifb em_u32 act_connmark act_mirred sch_ingress" fi loadKernelModules "xt_CONNMARK xt_CLASSIFY sch_red sch_sfq sch_hfsc cls_basic cls_fw cls_u32 $extra_modules" if [ ${UploadRate} -gt 0 ]; then for ifaceq in ${IQdevice}; do [ $IMQdisabled -eq 0 -o $IFBdisabled -eq 0 ] && ifconfig ${ifaceq} up txqueuelen 5 tc qdisc del dev ${ifaceq} root tc qdisc add dev ${ifaceq} root handle 1: hfsc default 10 tc class add dev ${ifaceq} parent 1: classid 1:1 hfsc sc rate ${UploadRate}kbit ul rate ${UploadRate}kbit echo "${ReservedClass}:${ReservedPriority}:${ReservedAverageRate}:${ReservedPacketSize}:${ReservedDelay}:${ReservedRatio}" | awk \ -v device="${ifaceq}" \ -v linespeed="${UploadRate}" \ -f firewall/tcrules.awk \ | while read CMD; do $CMD; done tc filter del dev ${ifaceq} parent 1: protocol ip pref 1 fw done fi for ifacein in $InternalDevice; do if [ ${UploadRate} -gt 0 ]; then if [ $IMQdisabled -eq 0 ]; then for ifaceq in ${IQdevice}; do $IPTABLES -t mangle -D PREROUTING -i $ifacein -j IMQ --todev ${ifaceq:3:1} $IPTABLES -t mangle -I PREROUTING 1 -i $ifacein -j IMQ --todev ${ifaceq:3:1} done fi fi ifconfig $ifacein up txqueuelen 5 tc qdisc del dev $ifacein root tc qdisc add dev $ifacein root handle 1: hfsc default 10 tc class add dev $ifacein parent 1: classid 1:1 hfsc sc rate ${DownloadRate}kbit ul rate ${DownloadRate}kbit echo "${ReservedClass}:${ReservedPriority}:${ReservedAverageRate}:${ReservedPacketSize}:${ReservedDelay}:${ReservedRatio}" | awk \ -v device="$ifacein" \ -v linespeed="${DownloadRate}" \ -f firewall/tcrules.awk \ | while read CMD; do $CMD; done tc filter del dev $ifacein parent 1: protocol ip pref 1 fw if [ ${UploadRate} -gt 0 ]; then if [ $IFBdisabled -eq 0 ]; then tc qdisc add dev $ifacein handle ffff: ingress for ifaceq in ${IQdevice}; do tc filter add dev $ifacein parent ffff: protocol ip prio 1 u32 \ match u32 0 0 flowid 1:1 \ action connmark \ action mirred egress redirect dev ${ifaceq} done fi fi done # -------------------------------------------------------------------------- fi ( echo RouteOnly=$RouteOnly echo DNSAddr=$DNSAddr echo IncludePorts=$IncludePorts echo ExcludePorts=$ExcludePorts echo AllowedWebHosts=$AllowedWebHosts echo ExternalDevice=$ExternalDevice echo InternalDevice=$InternalDevice echo LocalNetwork=$LocalNetwork echo GatewayPort=$GatewayPort echo ProxyPort=$ProxyPort echo AuthServiceIP=$AuthServiceIP echo MembersOnly=$MembersOnly echo MaxSegmentSize=$MaxSegmentSize echo MasqueradeDevice=$MasqueradeDevice echo AvoidMasqueradeAuthServiceIP=$AvoidMasqueradeAuthServiceIP echo IMQdevice=$IMQdevice echo IFBdevice=$IFBdevice echo UploadRate=$UploadRate echo DownloadRate=$DownloadRate echo UserDelay=$UserDelay echo UserPriority=$UserPriority echo UserUploadRate=$UserUploadRate echo UserPacketSize=$UserPacketSize echo UserAverageRate=$UserAverageRate echo UserDownloadRate=$UserDownloadRate echo ReservedRatio=$ReservedRatio echo ReservedClass=$ReservedClass echo ReservedDelay=$ReservedDelay echo ReservedPriority=$ReservedPriority echo ReservedPacketSize=$ReservedPacketSize echo ReservedAverageRate=$ReservedAverageRate echo EnableBandwidthLimits=$EnableBandwidthLimits echo FullPrivateNetwork=$FullPrivateNetwork echo BlockRFC1918=$BlockRFC1918 echo EnableIpset=$EnableIpset echo EnableIpsetAuth=$EnableIpsetAuth echo DosPrevention=$DosPrevention echo DosAllowTries=$DosAllowTries echo DosTimeInterval=$DosTimeInterval ) > /tmp/nodog_fw.cur.env } access_fw() { cmd=$1 mac=`tr '[A-Z]' '[a-z]' </dev/null # ----------------------------------------------------------------------------------------------------- fi if [ $EnableBandwidthLimits -gt 0 ]; then clearQoS $Ip $Netmask fi fi if [ "$EnableIpset" = 1 ]; then if [ "$cmd" = "-A" ]; then ipsetcmd=add else ipsetcmd=del fi if [ "$EnableIpsetAuth" = "bitmap:ip,mac" ]; then if [ "$action" = "deny" ]; then networkMatchIP $ip "$LocalNetwork" netid [ $? -eq 0 ] || exit 1 $IPSET del -exist ND_s_notify $ip fi $IPSET $ipsetcmd "ND_s_permit_in_${mark}_$netid" $ip,$mac || exit 2 elif [ "$EnableIpsetAuth" = "hash:ip,mac" ]; then $IPSET $ipsetcmd "ND_s_permit_in_$mark" $ip,$mac || exit 2 elif [ "$EnableIpsetAuth" = "hash:ip" ]; then $IPSET $ipsetcmd "ND_s_permit_in_$mark" $ip || exit 2 else $IPSET $ipsetcmd "ND_s_permit_in_$mark" $mac || exit 2 fi $IPSET $ipsetcmd ND_s_permit_ou $ip else # Mark outbound traffic from this node. if [ "$mac" == "00:00:00:00:00:00" ]; then if [ -z "$7" -o "$7" = "$ifacein" ]; then $IPTABLES -t mangle $cmd ND_m_permit_in -s $ip -j MARK --set-mark $mark || exit 2 fi else if [ -z "$7" -o "$7" = "$ifacein" ]; then $IPTABLES -t mangle $cmd ND_m_permit_in -s $ip -m mac --mac-source $mac -j MARK --set-mark $mark || exit 2 fi fi # Mark inbound traffic to this node. $IPTABLES -t filter $cmd ND_f_permit_ou -d $ip -j ACCEPT || exit 2 fi if [ -x /usr/sbin/wifi-disassoc.sh -a "$mac" != "00:00:00:00:00:00" -a "$action" = "deny" ]; then /usr/sbin/wifi-disassoc.sh "$mac" fi if [ $EnableBandwidthLimits -gt 0 ]; then if [ "$action" = "deny" ]; then clearQoS $Ip $Netmask else for ifacein in $InternalDevice; do UserClass=`tc filter show dev $ifacein | awk \ -v base=11 \ 'BEGIN{ n=0 } / flowid /{ sub("^1:","",$NF) sub("0$","",$NF) a[n++]=$NF+0 } END{ isort(a,j) i=0 if(a[i]>base){ p = base } else { while(a[i]+1>=a[i+1]&&ihold){ j-- A[j+1]=A[j] } A[j]=hold } }'` break done if [ ${UserUploadRatio} -gt 0 ]; then for ifaceq in ${IQdevice}; do echo "${UserClass}:${UserPriority}:${UserAverageRate}:${UserPacketSize}:${UserDelay}:${UserUploadRatio}" | awk \ -v device="${ifaceq}" \ -v linespeed="${UploadRate}" \ -f firewall/tcrules.awk \ | while read CMD; do $CMD; done tc filter del dev ${ifaceq} parent 1: protocol ip pref ${UserClass} fw tc filter add dev ${ifaceq} parent 1: pref ${UserClass} protocol ip u32 match ip src $Ip/$Netmask classid 1:${UserClass}0 done fi if [ ${UserDownloadRatio} -gt 0 ]; then for ifacein in $InternalDevice; do echo "${UserClass}:${UserPriority}:${UserAverageRate}:${UserPacketSize}:${UserDelay}:${UserDownloadRatio}" | awk \ -v device="$ifacein" \ -v linespeed="${DownloadRate}" \ -f firewall/tcrules.awk \ | while read CMD; do $CMD; done tc filter del dev $ifacein parent 1: protocol ip pref ${UserClass} fw tc filter add dev $ifacein parent 1: pref ${UserClass} protocol ip u32 match ip dst $Ip/$Netmask classid 1:${UserClass}0 done fi fi fi [ -S /tmp/evfwdsock ] && /usr/sbin/fwevhandler "$action" "$mac" "$ip" } access_fw_check() { # ------------------------------------------------------------ # (CMD) (MAC) (IP) (Class) (UserDownloadRate) (UserUploadRate) # ------------------------------------------------------------ # cmd=$1 mac=`tr '[A-Z]' '[a-z]' < /tmp/nodog_fw.$action } notify_fw() { cmd=$1 mac=`tr '[A-Z]' '[a-z]' </dev/null [ $EnableBandwidthLimits -gt 0 ] || return if [ -f /etc/init.d/qos ]; then /etc/init.d/qos enabled && /etc/init.d/qos stop fi checkDeviceUpload if [ ${UploadRate} -gt 0 ]; then tc qdisc del dev ${IQdevice} root fi for ifacein in $InternalDevice; do tc qdisc del dev $ifacein root done if [ -f /etc/init.d/qos ]; then /etc/init.d/qos enabled && /etc/init.d/qos start fi } reset_fw() { $IPTABLES -t filter -D FORWARD -j ND_f_fwd 2>/dev/null $IPTABLES -t nat -D PREROUTING -j ND_n_pre 2>/dev/null if [ $RouteOnly -eq 0 ]; then $IPTABLES -t nat -D POSTROUTING -j ND_n_post 2>/dev/null fi $IPTABLES -t mangle -D PREROUTING -j ND_m_pre 2>/dev/null } check_arp() { for iface in $InternalDevice; do arping -q -c 1 -I $iface $1 done egrep -q "^$1 " /proc/$$/net/arp exit $? } do_cmd() { # Note: your PATH is inherited from the gateway process if [ -x /usr/sbin/iptables ]; then IPTABLES=/usr/sbin/iptables else IPTABLES="echo iptables" fi if [ -x /usr/sbin/ipset ]; then IPSET=/usr/sbin/ipset else IPSET="echo ipset" fi if [ "$1" != "initialize" -a -r /tmp/nodog_fw.cur.env ]; then source /tmp/nodog_fw.cur.env fi case "$1" in arp) shift; check_arp "$@" ;; # (IP) clear) shift; clear_fw "$@" ;; reset) shift; reset_fw "$@" ;; permit) shift; access_fw "-A" "$@" ;; # (CMD) (MAC) (IP) (Class) (UserDownloadRate) (UserUploadRate) # permit) shift; access_fw_check "-A" "$@" ;; # (CMD) (MAC) (IP) (Class) (UserDownloadRate) (UserUploadRate) deny) shift; access_fw "-D" "$@" ;; # (CMD) (MAC) (IP) (Class) # deny) shift; access_fw_check "-D" "$@" ;; # (CMD) (MAC) (IP) (Class) notify) shift; notify_fw "-A" "$@" ;; # (CMD) (MAC) (IP) notified) shift; notify_fw "-D" "$@" ;; # (CMD) (MAC) (IP) initialize) shift; initialize_fw "$1" ;; openlist) if [ "$EnableIpset" = 1 ]; then if [ "$EnableIpsetAuth" = "bitmap:ip,mac" ]; then for net in $LocalNetwork; do networkMatchIface $net ifacein netid [ $? -eq 0 ] || exit 1 $IPSET $ipsetcmd "ND_s_permit_in_2_$netid" done elif [ "$EnableIpsetAuth" = "hash:ip,mac" ]; then $IPSET list "ND_s_permit_in_2" elif [ "$EnableIpsetAuth" = "hash:ip" ]; then $IPSET list "ND_s_permit_in_2" else $IPSET list "ND_s_permit_in_2" fi else $IPTABLES -t mangle -L NoCat_Permit -n | awk '/MARK set 0x2/{printf("%s\n", $4)}' | sort -u; # $IPTABLES -t mangle -L NoCat_Permit -n | awk '/MARK set 0x2/{printf("%s\n", $4)}' | sort -u | tee /tmp/nodog_fw.lst; fi ;; esac } #----------------------------------- # END FUNCTION #----------------------------------- export RouteOnly MasqueradeDevice DNSAddr IncludePorts ExcludePorts AllowedWebHosts ExternalDevice \ InternalDevice LocalNetwork GatewayPort ProxyPort AuthServiceIP MembersOnly MaxSegmentSize IPTABLES \ EnableBandwidthLimits IMQdevice IFBdevice UserDelay UserPriority UserUploadRate UserPacketSize \ UserAverageRate UserDownloadRate UploadRate DownloadRate ReservedRatio ReservedClass ReservedDelay \ ReservedPriority ReservedAverageRate ReservedPacketSize DosPrevention DosAllowTries DosTimeInterval \ IMQdisabled IFBdisabled IQdevice AvoidMasqueradeAuthServiceIP # ------------------------------------------------------------ # load eventuale script configuration (NON piace a Ghivizzani) # ------------------------------------------------------------ # if [ -n "$FW_CONF" -a -s "$FW_CONF" ]; then # . $FW_CONF # fi # ------------------------------------------------------------ # --------------------------------------------------------------------------------------------------------------------------------------------------- # RouteOnly Required only if you DO NOT want your gateway to act as a NAT. Give this only if you're running a strictly routed # network, and don't need the gateway to enable NAT for you # # DNSAddr *If* you choose not to run DNS on your internal network, specify the address(es) of one or more domain name server # on the Internet that wireless clients can use to get out. Should be the same DNS that your DHCP server hands out # # IncludePorts Specify TCP ports to allow access to when public class users login. All others will be denied # # ExcludePorts Specify TCP ports to denied access to when public class users login. All others will be allowed. Note that you # should use either IncludePorts or ExcludePorts, but not both. If neither is specified, access is granted to all ports # to public class users. You should *always* exclude port 25, unless you want to run an portal for wanton spam sending. # Users should have their own way of sending mail. It sucks, but that's the way it is. Comment this out *only if* # you're using IncludePorts instead # # AllowedWebHosts List any domains that you would like to allow web access (TCP port 80 and 443) BEFORE logging in (this is thei # pre-'skip' stage, so be careful about what you allow # # ExternalDevice The interface connected to the Internet. Usually 'eth0' or 'eth1' under Linux, or maybe even 'ppp0' if you're running # PPP or PPPoE # # InternalDevice Required if and only if your machine has more than two network interfaces. Must be set to the interface connected to # your local network, normally your wireless card # # LocalNetwork Must be set to the network address and net mask of your internal network. You can use the number of bits in the # netmask (e.g. /16, /24, etc.) or the full x.x.x.x specification # # GatewayPort The TCP port to bind the gateway service to. 5280 is de-facto standard for NoCatAuth. Change this only if you # absolutely need to # # ProxyPort The TCP port to bind the proxy service to. If not defined is set to GatewayPort # # AuthServiceIP The address of your authentication service. You must use an IP address if DNS resolution isn't available at gateway # startup # # MembersOnly Give this if you want to disable public access (i.e. unauthenticated 'skip' button access). You'll also want to # point AuthServiceIP somewhere that doesn't include a skip button (likeat your own Auth server) # # MaxSegmentSize Give this if you want to reduce MTU # MasqueradeDevice maschera il traffico verso il device # AvoidMasqueradeAuthServiceIP evita di mascherare il traffico verso portale autorizzativo # --------------------------------------------------------------------------------------------------------------------------------------------------- RouteOnly=${RouteOnly:-0} MembersOnly=${MembersOnly:-1} GatewayPort=${GatewayPort:-5280} ProxyPort=${ProxyPort:-$GatewayPort} MaxSegmentSize=${MaxSegmentSize:-1} AvoidMasqueradeAuthServiceIP=${AvoidMasqueradeAuthServiceIP:-0} # --------------------------------------------------------------------------------------------------------------------------------------------------- # Gestione dei limiti sulla banda per gli utenti # --------------------------------------------------------------------------------------------------------------------------------------------------- # IMQdevice IMQ device per la gestione del bitrate in upload # IFBdevice IFB device per la gestione del bitrate in upload # UploadRate Upload bit rate per le interfacce interne (in Kbits) # DownloadRate Download bit rate per le interfacce interne (in Kbits) # UserDelay delay accettabile per il traffico utente (default 100, in millisecondi) # UserPriority priorita' del traffico degli utenti (default 5) # UserUploadRate Bit rate in upload di default per gli utenti (in Kbits) # UserPacketSize dimensione massima del pacchetto sull'interfaccia (default 1500, in bytes) # UserAverageRate rate medio per il traffico (default 10) # UserDownloadRate Bit rate in download di default per gli utenti (in Kbits) # ReservedRatio percentuale di banda riservata # ReservedClass classId da utilizzare per il qos (default 1) # ReservedDelay delay accettabile per il traffico riservato (default 200, in millisecondi) # ReservedPriority priorita' per il traffico riservato (default 1, bassa priorita') # ReservedPacketSize dimensione massima del pacchetto sull'interfaccia (default 1500, in bytes) # ReservedAverageRate rate medio per il traffico riservato atto al dimensionamento dei parametri di coda (default 1) # EnableBandwidthLimits abilita la gestione dei limiti sulla banda per gli utenti # FullPrivateNetwork la rete privata utilizzata internamente # BlockRFC1918 blocca il travvico verso le reti private # EnableIpset utilizza ipset per ottimizzazioni # EnableIpsetAuth modalita di autorizzazione sui pacchetti sorgenti: "bitmap:ip,mac", "hash:ip", "hash:ip,mac", "hash:mac" default "bitmap:ip,mac" # # DosPrevention abilita il supporto anti DoS sul captive portal (da impostare ad 1 per attivare il supporto) # DosAllowTries numero massimo di connessioni consentite nella finestra temporale # DosTimeInterval finestra temporale in cui osservare il numero di connessioni per IP # --------------------------------------------------------------------------------------------------------------------------------------------------- IFBdevice=${IFBdevice:-ifb0} UploadRate=${UploadRate:-10240} DownloadRate=${DownloadRate:-10240} UserDelay=${UserDelay:-100} UserPriority=${UserPriority:-5} UserUploadRate=${UserUploadRate:-1024} UserPacketSize=${UserPacketSize:-1500} UserAverageRate=${UserAverageRate:-10} UserDownloadRate=${UserDownloadRate:-10240} ReservedRatio=${ReservedRatio:-10} ReservedClass=${ReservedClass:-1} ReservedDelay=${ReservedDelay:-200} ReservedPriority=${ReservedPriority:-1} ReservedPacketSize=${ReservedPacketSize:-1500} ReservedAverageRate=${ReservedAverageRate:-1} EnableBandwidthLimits=${EnableBandwidthLimits:-0} FullPrivateNetwork=${FullPrivateNetwork:-172.16.0.0/12} BlockRFC1918=${BlockRFC1918:-1} EnableIpset=${EnableIpset:-0} EnableIpsetAuth=${EnableIpsetAuth:-bitmap:ip,mac} DosPrevention=${DosPrevention:-0} DosAllowTries=${DosAllowTries:-5} DosTimeInterval=${DosTimeInterval:-60} { echo "ENVIRONMENT:" echo "-----------------------------------------------------------" env echo "-----------------------------------------------------------" echo "STDERR:" echo "-----------------------------------------------------------" set -x do_cmd "$@" set +x echo "-----------------------------------------------------------" } 2>/tmp/nodog_fw.$$ >&2 exit 0