mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-10-05 19:18:01 +08:00
1248 lines
46 KiB
Bash
1248 lines
46 KiB
Bash
#!/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<tnetmask)){
|
|
found=1;
|
|
cipaddr=ipaddr;
|
|
cnetmask=tnetmask;
|
|
cnetaddr=tnetaddr;
|
|
ciface=iface[i];
|
|
}
|
|
}
|
|
if(found==0)exit(1);
|
|
printf("%s\t%04x%04x\t%04x%04x\t%04x%04x\n",ciface,rshift(cipaddr,16),and(cipaddr,0xffff),rshift(cnetaddr,16),and(cnetaddr,0xffff),rshift(cnetmask,16),and(cnetmask,0xffff));
|
|
exit(0);
|
|
}' </proc/net/route`
|
|
[ $? -eq 0 ] || return $?
|
|
read $2 $3 $4 $5 _DUMMY <<EOL
|
|
$_RES
|
|
EOL
|
|
return 0
|
|
}
|
|
|
|
networkMatchIP() {
|
|
_RES=`awk -v "IP=$1" -v "NETS=$2" -- '
|
|
function ip2int(ip) {
|
|
ret=0;split(ip,a,".");
|
|
for(x in a)ret=or(lshift(ret,8),a[x]);
|
|
return ret
|
|
}
|
|
END {
|
|
ipaddr=ip2int(IP);
|
|
found=0;cnetmask=0;cnetaddr=0;cnetwork=0;
|
|
split(NETS,NETSa," *");
|
|
for(i in NETSa) {
|
|
if(split(NETSa[i],tnet,"/")!=2)exit(2);
|
|
tnetmask=and(xor(lshift(0xffffffff,32-int(tnet[2])),0),0xffffffff);
|
|
tnetaddr=and(ip2int(tnet[1]),tnetmask);
|
|
if((and(ipaddr,tnetmask)==tnetaddr) && (cnetmask<tnetmask)){
|
|
found=1;
|
|
cnetmask=tnetmask;
|
|
cnetaddr=tnetaddr;
|
|
cnetwork=NETSa[i];
|
|
}
|
|
}
|
|
if(found==0)exit(1);
|
|
printf("%04x%04x\t%04x%04x\t%s\n",rshift(cnetaddr,16),and(cnetaddr,0xffff),rshift(cnetmask,16),and(cnetmask,0xffff),cnetwork);
|
|
exit(0);
|
|
}' </dev/null`
|
|
[ $? -eq 0 ] || return $?
|
|
read $3 $4 $5 _DUMMY <<EOL
|
|
$_RES
|
|
EOL
|
|
return 0
|
|
}
|
|
|
|
loadKernelModules() {
|
|
|
|
for module in $1; do
|
|
lsmod | grep $module >/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]' <<EOT
|
|
$2
|
|
EOT
|
|
`
|
|
ip=$3
|
|
class=$4
|
|
|
|
if [ -z "$class" ]; then
|
|
class=Public
|
|
fi
|
|
|
|
if [ "$class" = "Owner" ]; then
|
|
mark=1
|
|
elif [ "$class" = "Member" ]; then
|
|
mark=2
|
|
elif [ "$class" = "Public" ]; then
|
|
mark=3
|
|
else
|
|
echo "FATAL: Bad class: $class!"
|
|
exit 1
|
|
fi
|
|
|
|
local action=""
|
|
|
|
if [ "$cmd" = "-A" ]; then
|
|
action="permit"
|
|
else
|
|
action="deny"
|
|
fi
|
|
|
|
# Bandwidth limits
|
|
# --------------------------------------------------------------------------
|
|
Ip=""
|
|
Netmask=""
|
|
UserUploadRatio=0
|
|
UserDownloadRatio=0
|
|
|
|
if [ $EnableBandwidthLimits -gt 0 ]; then
|
|
|
|
Ip=`echo $ip | sed 's!/.*!!'`
|
|
Netmask=`echo $ip | sed 's!^.*/!!'`
|
|
|
|
if [ "$Ip" = "$Netmask" ]; then
|
|
Netmask=32
|
|
fi
|
|
|
|
checkDeviceUpload
|
|
|
|
if [ "$action" = "permit" ]; then
|
|
if [ $5 -ne 0 ]; then
|
|
UserDownloadRate = $5
|
|
fi
|
|
if [ $6 -ne 0 ]; then
|
|
UserUploadRate = $6
|
|
fi
|
|
|
|
UserUploadRatio=$(( $UserUploadRate * 100 / ${UploadRate} ))
|
|
UserDownloadRatio=$(( $UserDownloadRate * 100 / ${DownloadRate} ))
|
|
|
|
if [ $UserUploadRatio -gt 100 ]; then
|
|
UserUploadRatio=100
|
|
fi
|
|
if [ $UserDownloadRatio -gt 100 ]; then
|
|
UserDownloadRatio=100
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$action" = "permit" ]; then
|
|
if [ "$EnableIpset" = 1 ]; then
|
|
if [ "$EnableIpsetAuth" = "bitmap:ip,mac" ]; then
|
|
networkMatchIP $ip "$LocalNetwork" netid
|
|
[ $? -eq 0 ] || exit 1
|
|
$IPSET del -exist ND_s_permit_in_1_$netid $ip,$mac
|
|
$IPSET del -exist ND_s_permit_in_2_$netid $ip,$mac
|
|
$IPSET del -exist ND_s_permit_in_3_$netid $ip,$mac
|
|
elif [ "$EnableIpsetAuth" = "hash:ip,mac" ]; then
|
|
$IPSET del -exist ND_s_permit_in_1 $ip
|
|
$IPSET del -exist ND_s_permit_in_2 $ip
|
|
$IPSET del -exist ND_s_permit_in_3 $ip
|
|
elif [ "$EnableIpsetAuth" = "hash:ip" ]; then
|
|
$IPSET del -exist ND_s_permit_in_1 $ip
|
|
$IPSET del -exist ND_s_permit_in_2 $ip
|
|
$IPSET del -exist ND_s_permit_in_3 $ip
|
|
else
|
|
$IPSET del -exist ND_s_permit_in_1 $mac
|
|
$IPSET del -exist ND_s_permit_in_2 $mac
|
|
$IPSET del -exist ND_s_permit_in_3 $mac
|
|
fi
|
|
$IPSET del -exist ND_s_permit_ou $ip
|
|
else
|
|
tFOUND=0
|
|
tDIRTY=0
|
|
tFOUNDMARK=""
|
|
|
|
# restituisce MAC + mark
|
|
$IPTABLES -t mangle -n -L ND_m_permit_in | \
|
|
awk -v i=$ip '/[ \t]MAC /{if($4==i){print tolower($7) " " $10};next } {if($4==i){print "00:00:00:00:00:00 " $8 }}' | \
|
|
while read tMAC tMARK;
|
|
do
|
|
if [ "$tMAC" == "00:00:00:00:00:00" ]; then
|
|
if [ "$mac" == "00:00:00:00:00:00" ]; then
|
|
tFOUND=1
|
|
tFOUNDMARK=$tMARK
|
|
else
|
|
tDIRTY=1
|
|
$IPTABLES -t mangle -D ND_m_permit_in -s $ip -j MARK --set-mark $tMARK
|
|
fi
|
|
else
|
|
if [ "$tMAC" == "$mac" ]; then
|
|
tFOUND=1
|
|
tFOUNDMARK=$tMARK
|
|
else
|
|
tDIRTY=1
|
|
$IPTABLES -t mangle -D ND_m_permit_in -s $ip -m mac --mac-source $tMAC -j MARK --set-mark $tMARK
|
|
fi
|
|
fi
|
|
done
|
|
|
|
[ $tDIRTY -eq 0 -a $tFOUND -eq 1 ] && return
|
|
|
|
if [ $tFOUND -eq 1 ]; then
|
|
if [ "$mac" == "00:00:00:00:00:00" ]; then
|
|
$IPTABLES -t mangle -D ND_m_permit_in -s $ip -j MARK --set-mark $tFOUNDMARK
|
|
else
|
|
$IPTABLES -t mangle -D ND_m_permit_in -s $ip -m mac --mac-source $mac -j MARK --set-mark $tFOUNDMARK
|
|
fi
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------------------------------
|
|
# this command often give this message 'iptables: Bad rule (does a matching rule exist in that chain?)'
|
|
# -----------------------------------------------------------------------------------------------------
|
|
$IPTABLES -t filter -D ND_f_permit_ou -d $ip -j ACCEPT 2>/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]&&i<n-1){
|
|
i++
|
|
}
|
|
p=a[i]+1
|
|
if(p<base){ p=base }
|
|
}
|
|
print p
|
|
}
|
|
function isort(A,n,i,j,hold){
|
|
for(i=2;i<=n;i++){
|
|
j=i
|
|
hold=A[j]
|
|
while(A[j-1]>hold){
|
|
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]' <<EOT
|
|
$2
|
|
EOT
|
|
`
|
|
ip=$3
|
|
# class=$4
|
|
# UserDownloadRate=$5
|
|
# UserUploadRate=$6
|
|
# ------------------------------------------------------------
|
|
|
|
local action=""
|
|
|
|
if [ "$1" = "-A" ]; then
|
|
action="permit"
|
|
else
|
|
action="deny"
|
|
fi
|
|
|
|
local i=1
|
|
|
|
while [ $i -le 2 ]
|
|
do
|
|
access_fw $1 $mac $ip $4 $5 $6
|
|
|
|
# check
|
|
|
|
fail=0
|
|
if [ "$EnableIpset" = 1 ]; then
|
|
if [ "$EnableIpsetAuth" = "bitmap:ip,mac" ]; then
|
|
networkMatchIP $ip "$LocalNetwork" netid
|
|
[ $? -eq 0 ] || exit 1
|
|
$IPSET test ND_s_permit_in_3_$netid $ip,$mac || $IPSET test ND_s_permit_in_2_$netid $ip,$mac || $IPSET test ND_s_permit_in_1_$netid $ip,$mac
|
|
count=$?
|
|
elif [ "$EnableIpsetAuth" = "hash:ip,mac" ]; then
|
|
$IPSET test ND_s_permit_in_3 $ip,$mac || $IPSET test ND_s_permit_in_2 $ip,$mac || $IPSET test ND_s_permit_in_1 $ip,$mac
|
|
count=$?
|
|
elif [ "$EnableIpsetAuth" = "hash:ip" ]; then
|
|
$IPSET test ND_s_permit_in_3 $ip || $IPSET test ND_s_permit_in_2 $ip || $IPSET test ND_s_permit_in_1 $ip
|
|
count=$?
|
|
else
|
|
$IPSET test ND_s_permit_in_3 $mac || $IPSET test ND_s_permit_in_2 $mac || $IPSET test ND_s_permit_in_1 $mac
|
|
count=$?
|
|
fi
|
|
else
|
|
count=`$IPTABLES -t mangle -L ND_m_permit_in -n | grep -c $ip`;
|
|
fi
|
|
|
|
if [ $count -gt 0 ]; then
|
|
if [ "$action" = "deny" ]; then
|
|
fail=1
|
|
fi
|
|
else
|
|
if [ "$action" = "permit" ]; then
|
|
fail=1
|
|
fi
|
|
fi
|
|
|
|
if [ $fail -eq 0 ]; then
|
|
return
|
|
fi
|
|
|
|
i=`expr $i + 1`
|
|
done
|
|
|
|
echo "$ip $mac" > /tmp/nodog_fw.$action
|
|
}
|
|
|
|
notify_fw() {
|
|
cmd=$1
|
|
mac=`tr '[A-Z]' '[a-z]' <<EOT
|
|
$2
|
|
EOT
|
|
`
|
|
ip=$3
|
|
|
|
if [ "$EnableIpset" = 1 ]; then
|
|
if [ "$cmd" = "-A" ]; then
|
|
ipsetcmd=add
|
|
else
|
|
ipsetcmd=del
|
|
fi
|
|
$IPSET $ipsetcmd ND_s_notify $ip || exit 2
|
|
else
|
|
$IPTABLES -t nat "$cmd" ND_n_notify -p tcp --dport 80 -s "$ip" -j REDIRECT --to-port $ProxyPort || exit 2
|
|
fi
|
|
}
|
|
|
|
clear_fw() {
|
|
|
|
(
|
|
$IPTABLES -t filter -D INPUT -j ND_f_in
|
|
$IPTABLES -t filter -L FORWARD -n -v | awk '/ND_f_fwd_in/{system("'$IPTABLES' -t filter -D FORWARD -i " $6 " -o " $7 " -s " $8 " -j " $3);}'
|
|
$IPTABLES -t filter -L FORWARD -n -v | awk '/ND_f_fwd_ou/{system("'$IPTABLES' -t filter -D FORWARD -i " $6 " -o " $7 " -d " $9 " -j " $3);}'
|
|
|
|
$IPTABLES -t filter -F FORWARD
|
|
$IPTABLES -t filter -F ND_f_fwd_in
|
|
$IPTABLES -t filter -F ND_f_fwd_ou
|
|
$IPTABLES -t filter -F ND_f_RFC1918
|
|
$IPTABLES -t filter -F ND_f_ports
|
|
$IPTABLES -t filter -F ND_f_in
|
|
$IPTABLES -t filter -X ND_f_fwd_in
|
|
$IPTABLES -t filter -X ND_f_fwd_ou
|
|
$IPTABLES -t filter -X ND_f_RFC1918
|
|
$IPTABLES -t filter -X ND_f_ports
|
|
$IPTABLES -t filter -X ND_f_in
|
|
$IPTABLES -t filter -F ND_f_permit_ou
|
|
$IPTABLES -t filter -X ND_f_permit_ou
|
|
|
|
$IPTABLES -t nat -L PREROUTING -n -v | awk '/ND_n_pre/ {system("'$IPTABLES' -t nat -D PREROUTING -i " $6 " -s " $8 " -j " $3);}'
|
|
$IPTABLES -t nat -L POSTROUTING -n -v | awk '/ND_n_post/{system("'$IPTABLES' -t nat -D POSTROUTING -o " $7 " -s " $8 " -j " $3);}'
|
|
$IPTABLES -t nat -F ND_n_pre
|
|
$IPTABLES -t nat -F ND_n_post
|
|
$IPTABLES -t nat -X ND_n_pre
|
|
$IPTABLES -t nat -X ND_n_post
|
|
if [ "$EnableIpset" != 1 ]; then
|
|
$IPTABLES -t nat -F ND_n_notify
|
|
$IPTABLES -t nat -X ND_n_notify
|
|
fi
|
|
|
|
$IPTABLES -t mangle -L PREROUTING -n -v | awk '/ND_m_pre/ {system("'$IPTABLES' -t mangle -D PREROUTING -i " $6 " -s " $8 " -j " $3);}'
|
|
$IPTABLES -t mangle -L POSTROUTING -n -v | awk '/ND_m_acc_ou/{system("'$IPTABLES' -t mangle -D POSTROUTING -o " $7 " -s " $8 " -j " $3);}'
|
|
$IPTABLES -t mangle -L POSTROUTING -n -v | awk '/ND_m_acc_in/{system("'$IPTABLES' -t mangle -D POSTROUTING -o " $7 " -d " $9 " -j " $3);}'
|
|
$IPTABLES -t mangle -F ND_m_acc_in
|
|
$IPTABLES -t mangle -F ND_m_acc_ou
|
|
$IPTABLES -t mangle -F ND_m_pre
|
|
$IPTABLES -t mangle -X ND_m_acc_in
|
|
$IPTABLES -t mangle -X ND_m_acc_ou
|
|
$IPTABLES -t mangle -X ND_m_pre
|
|
$IPTABLES -t mangle -F ND_m_permit_in
|
|
$IPTABLES -t mangle -X ND_m_permit_in
|
|
$IPSET -n list | sort | egrep '^ND_s_' | while read S; do $IPSET -! destroy $S; done
|
|
) 2>/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
|