diff options
Diffstat (limited to 'package/firewall/files/lib')
| -rw-r--r-- | package/firewall/files/lib/core_forwarding.sh | 3 | ||||
| -rw-r--r-- | package/firewall/files/lib/core_init.sh | 15 | ||||
| -rw-r--r-- | package/firewall/files/lib/core_interface.sh | 33 | ||||
| -rw-r--r-- | package/firewall/files/lib/core_redirect.sh | 84 | ||||
| -rw-r--r-- | package/firewall/files/lib/core_rule.sh | 7 | ||||
| -rw-r--r-- | package/firewall/files/lib/fw.sh | 64 | 
6 files changed, 113 insertions, 93 deletions
diff --git a/package/firewall/files/lib/core_forwarding.sh b/package/firewall/files/lib/core_forwarding.sh index b62e18a76..c4a968143 100644 --- a/package/firewall/files/lib/core_forwarding.sh +++ b/package/firewall/files/lib/core_forwarding.sh @@ -27,7 +27,8 @@ fw_load_forwarding() {  		target=zone_${forwarding_dest}_ACCEPT  	} -	local mode=$(fw_get_family_mode ${forwarding_family:-x} ${forwarding_dest:-${forwarding_src:--}} i) +	local mode +	fw_get_family_mode mode ${forwarding_family:-x} ${forwarding_dest:-${forwarding_src:--}} i  	fw add $mode f $chain $target ^ diff --git a/package/firewall/files/lib/core_init.sh b/package/firewall/files/lib/core_init.sh index bce94afe0..e1f80ba3f 100644 --- a/package/firewall/files/lib/core_init.sh +++ b/package/firewall/files/lib/core_init.sh @@ -212,9 +212,6 @@ fw_load_zone() {  	fw add $mode r ${chain}_notrack -	[ $zone_masq == 1 ] && \ -		fw add $mode n POSTROUTING ${chain}_nat $ -  	[ $zone_mtu_fix == 1 ] && \  		fw add $mode f FORWARD ${chain}_MSSFIX ^ @@ -243,6 +240,18 @@ fw_load_zone() {  		done  	} +	# NB: if MASQUERADING for IPv6 becomes available we'll need a family check here +	if [ "$zone_masq" == 1 ]; then +		local msrc mdst +		for msrc in ${zone_masq_src:-0.0.0.0/0}; do +			[ "${msrc#!}" != "$msrc" ] && msrc="! -s ${msrc#!}" || msrc="-s $msrc" +			for mdst in ${zone_masq_dest:-0.0.0.0/0}; do +				[ "${mdst#!}" != "$mdst" ] && mdst="! -d ${mdst#!}" || mdst="-d $mdst" +				fw add $mode n ${chain}_nat MASQUERADE $ { $msrc $mdst } +			done +		done +	fi +  	fw_callback post zone  } diff --git a/package/firewall/files/lib/core_interface.sh b/package/firewall/files/lib/core_interface.sh index c2a5bd7f3..889dcc904 100644 --- a/package/firewall/files/lib/core_interface.sh +++ b/package/firewall/files/lib/core_interface.sh @@ -27,11 +27,9 @@ fw_configure_interface() {  		local chain=zone_${zone}  		local ifname=$3  		local subnet=$4 -		local masq_src=$5 -		local masq_dest=$6 -		local inet onet -		local mode=$(fw_get_family_mode x $zone i) +		local inet onet mode +		fw_get_family_mode mode x $zone i  		case "$mode/$subnet" in  			# Zone supports v6 only or dual, need v6 @@ -62,38 +60,27 @@ fw_configure_interface() {  		fw $action $mode f ${chain}_REJECT reject $ { -o "$ifname" $onet }  		fw $action $mode f ${chain}_REJECT reject $ { -i "$ifname" $inet } -		# NB: if MASQUERADING for IPv6 becomes available we'll need a family check here -		local msrc mdst -		for msrc in ${masq_src:-0.0.0.0/0}; do -			[ "${msrc#!}" != "$msrc" ] && msrc="! -s ${msrc#!}" || msrc="-s $msrc" -			for mdst in ${subnet:-${masq_dest:-0.0.0.0/0}}; do -				[ "${mdst#!}" != "$mdst" ] && mdst="! -d ${mdst#!}" || mdst="-d $mdst" -				fw $action $mode n ${chain}_nat MASQUERADE $ { -o "$ifname" $msrc $mdst } -			done -		done -  		fw $action $mode f ${chain}_MSSFIX TCPMSS  $ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet }  		fw $action $mode f input   ${chain}         $ { -i "$ifname" $inet }  		fw $action $mode f forward ${chain}_forward $ { -i "$ifname" $inet }  		fw $action $mode n PREROUTING ${chain}_prerouting $ { -i "$ifname" $inet }  		fw $action $mode r PREROUTING ${chain}_notrack    $ { -i "$ifname" $inet } +		fw $action $mode n POSTROUTING ${chain}_nat       $ { -o "$ifname" $onet }  	} -	local old_zones old_ifname old_subnets old_masq_src old_masq_dest +	local old_zones old_ifname old_subnets  	config_get old_zones core "${iface}_zone"  	[ -n "$old_zones" ] && {  		config_get old_ifname core "${iface}_ifname"  		config_get old_subnets core "${iface}_subnets" -		config_get old_masq_src core "${iface}_masq_src" -		config_get old_masq_dest core "${iface}_masq_dest"  		local z  		for z in $old_zones; do  			local n  			for n in ${old_subnets:-""}; do  				fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z" -				fw__do_rules del $z $old_ifname $n "$old_masq_src" "$old_masq_dest" +				fw__do_rules del $z $old_ifname $n  			done  			[ -n "$old_subnets" ] || ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall @@ -111,8 +98,6 @@ fw_configure_interface() {  		uci_revert_state firewall core "${iface}_ifname"  		uci_revert_state firewall core "${iface}_subnets"  		uci_revert_state firewall core "${iface}_aliases" -		uci_revert_state firewall core "${iface}_masq_src" -		uci_revert_state firewall core "${iface}_masq_dest"  	}  	[ "$action" == del ] && return @@ -146,17 +131,13 @@ fw_configure_interface() {  	}  	local new_zones= -	local new_masq_src= -	local new_masq_dest=  	load_zone() {  		fw_config_get_zone "$1"  		list_contains zone_network "$iface" || return  		fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name" -		fw__do_rules add ${zone_name} "$ifname" "$aliasnet" "$zone_masq_src" "$zone_masq_dest" +		fw__do_rules add ${zone_name} "$ifname" "$aliasnet"  		append new_zones $zone_name -		append new_masq_src "$zone_masq_src" -		append new_masq_dest "$zone_masq_dest"  		[ -n "$aliasnet" ] || ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall  	} @@ -164,8 +145,6 @@ fw_configure_interface() {  	uci_set_state firewall core "${iface}_zone" "$new_zones"  	uci_set_state firewall core "${iface}_ifname" "$ifname" -	uci_set_state firewall core "${iface}_masq_src" "$new_masq_src" -	uci_set_state firewall core "${iface}_masq_dest" "$new_masq_dest"  }  fw_sysctl_interface() { diff --git a/package/firewall/files/lib/core_redirect.sh b/package/firewall/files/lib/core_redirect.sh index 2f0e38f39..72364a99e 100644 --- a/package/firewall/files/lib/core_redirect.sh +++ b/package/firewall/files/lib/core_redirect.sh @@ -27,53 +27,77 @@ fw_load_redirect() {  	fw_callback pre redirect -	[ -n "$redirect_src" -a -n "$redirect_dest_ip$redirect_dest_port" ] || { -		fw_die "redirect ${redirect_name}: needs src and dest_ip or dest_port" -	} - -	local chain destopt destaddr +	local fwdchain natchain natopt nataddr natports srcdaddr srcdports  	if [ "$redirect_target" == "DNAT" ]; then -		chain="zone_${redirect_src}_prerouting" -		destopt="--to-destination" -		destaddr="$redirect_dest_ip" +		[ -n "$redirect_src" -a -n "$redirect_dest_ip$redirect_dest_port" ] || { +			fw_die "DNAT redirect ${redirect_name}: needs src and dest_ip or dest_port" +		} + +		fwdchain="zone_${redirect_src}_forward" + +		natopt="--to-destination" +		natchain="zone_${redirect_src}_prerouting" +		nataddr="$redirect_dest_ip" +		fw_get_port_range natports "$redirect_dest_port" "-" + +		srcdaddr="${redirect_src_dip:+$redirect_src_dip/$redirect_src_dip_prefixlen}" +		fw_get_port_range srcdports "$redirect_src_dport" ":" + +		list_contains FW_CONNTRACK_ZONES $redirect_src || \ +			append FW_CONNTRACK_ZONES $redirect_src +  	elif [ "$redirect_target" == "SNAT" ]; then -		chain="zone_${redirect_src}_nat" -		destopt="--to-source" -		destaddr="$redirect_src_dip" +		[ -n "$redirect_dest" -a -n "$redirect_src_dip" ] || { +			fw_die "SNAT redirect ${redirect_name}: needs dest and src_dip" +		} + +		fwdchain="${redirect_src:+zone_${redirect_src}_forward}" + +		natopt="--to-source" +		natchain="zone_${redirect_dest}_nat" +		nataddr="$redirect_src_dip" +		fw_get_port_range natports "$redirect_src_dport" "-" + +		srcdaddr="${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" +		fw_get_port_range srcdports "$redirect_dest_port" ":" + +		list_contains FW_CONNTRACK_ZONES $redirect_dest || \ +			append FW_CONNTRACK_ZONES $redirect_dest +  	else  		fw_die "redirect ${redirect_name}: target must be either DNAT or SNAT"  	fi -	list_contains FW_CONNTRACK_ZONES $redirect_src || \ -		append FW_CONNTRACK_ZONES $redirect_src +	local mode +	fw_get_family_mode mode ${redirect_family:-x} ${redirect_src:-$redirect_dest} I -	local mode=$(fw_get_family_mode ${redirect_family:-x} $redirect_src I) +	local srcaddr="${redirect_src_ip:+$redirect_src_ip/$redirect_src_ip_prefixlen}" +	local srcports +	fw_get_port_range srcports "$redirect_src_port" ":" -	local nat_dest_port=$redirect_dest_port -	redirect_dest_port=$(fw_get_port_range $redirect_dest_port) -	redirect_src_port=$(fw_get_port_range $redirect_src_port) -	redirect_src_dport=$(fw_get_port_range $redirect_src_dport) -	local fwd_dest_port=${redirect_dest_port:-$redirect_src_dport} +	local destaddr="${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" +	local destports +	fw_get_port_range destports "${redirect_dest_port:-$redirect_src_dport}" ":"  	[ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp"  	for redirect_proto in $redirect_proto; do -		fw add $mode n $chain $redirect_target $ { $redirect_src_ip $redirect_dest_ip } { \ +		fw add $mode n $natchain $redirect_target ^ { $redirect_src_ip $redirect_dest_ip } { \  			${redirect_proto:+-p $redirect_proto} \ -			${redirect_src_ip:+-s $redirect_src_ip/$redirect_src_ip_prefixlen} \ -			${redirect_src_dip:+-d $redirect_src_dip/$redirect_src_dip_prefixlen} \ -			${redirect_src_port:+--sport $redirect_src_port} \ -			${redirect_src_dport:+--dport $redirect_src_dport} \ +			${srcaddr:+-s $srcaddr} \ +			${srcports:+--sport $srcports} \ +			${srcdaddr:+-d $srcdaddr} \ +			${srcdports:+--dport $srcdports} \  			${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \ -			$destopt ${redirect_dest_ip}${redirect_dest_port:+:$nat_dest_port} \ +			$natopt $nataddr${natports:+:$natports} \  		}  		[ -n "$destaddr" ] && \ -		fw add $mode f zone_${redirect_src}_forward ACCEPT ^ { $redirect_src_ip $redirect_dest_ip } { \ -			-d $destaddr \ +		fw add $mode f ${fwdchain:-forward} ACCEPT ^ { $redirect_src_ip $redirect_dest_ip } { \  			${redirect_proto:+-p $redirect_proto} \ -			${redirect_src_ip:+-s $redirect_src_ip/$redirect_src_ip_prefixlen} \ -			${redirect_src_port:+--sport $redirect_src_port} \ -			${fwd_dest_port:+--dport $fwd_dest_port} \ +			${srcaddr:+-s $srcaddr} \ +			${srcports:+--sport $srcports} \ +			${destaddr:+-d $destaddr} \ +			${destports:+--dport $destports} \  			${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \  		}  	done diff --git a/package/firewall/files/lib/core_rule.sh b/package/firewall/files/lib/core_rule.sh index e1f8d2ae1..1e4afe5af 100644 --- a/package/firewall/files/lib/core_rule.sh +++ b/package/firewall/files/lib/core_rule.sh @@ -26,8 +26,8 @@ fw_load_rule() {  	fw_callback pre rule -	rule_src_port=$(fw_get_port_range $rule_src_port) -	rule_dest_port=$(fw_get_port_range $rule_dest_port) +	fw_get_port_range rule_src_port $rule_src_port +	fw_get_port_range rule_dest_port $rule_dest_port  	local chain=input  	[ -n "$rule_src" ] && { @@ -46,7 +46,8 @@ fw_load_rule() {  		target=zone_${rule_dest}_${target}  	} -	local mode=$(fw_get_family_mode ${rule_family:-x} $rule_src I) +	local mode +	fw_get_family_mode mode ${rule_family:-x} $rule_src I  	local rule_pos  	eval 'rule_pos=$((++FW__RULE_COUNT_'$mode'_'$chain'))' diff --git a/package/firewall/files/lib/fw.sh b/package/firewall/files/lib/fw.sh index aaf3d14ef..3549f8aa4 100644 --- a/package/firewall/files/lib/fw.sh +++ b/package/firewall/files/lib/fw.sh @@ -159,56 +159,62 @@ fw__exec() { # <action> <family> <table> <chain> <target> <position> { <rules> }  		fi  	fi +	local cmdline="$app --table ${tab} --${cmd} ${chn} ${pol} ${pos} ${tgt:+--jump "$tgt"}"  	while [ $# -gt 1 ]; do  		case "$app:$1" in -			ip6tables:--icmp-type) echo -n "--icmpv6-type" ;; -			ip6tables:icmp|ip6tables:ICMP) echo -n "icmpv6" ;; -			iptables:--icmpv6-type) echo -n "--icmp-type" ;; -			iptables:icmpv6) echo -n "icmp" ;; -			*) echo -n "$1" ;; +			ip6tables:--icmp-type) cmdline="$cmdline --icmpv6-type" ;; +			ip6tables:icmp|ip6tables:ICMP) cmdline="$cmdline icmpv6" ;; +			iptables:--icmpv6-type) cmdline="$cmdline --icmp-type" ;; +			iptables:icmpv6) cmdline="$cmdline icmp" ;; +			*) cmdline="$cmdline $1" ;;  		esac -		echo -ne "\0"  		shift -	done | xargs -0 ${FW_TRACE:+-t} \ -		$app --table ${tab} --${cmd} ${chn} ${pol} ${pos} ${tgt:+--jump "$tgt"} +	done + +	[ -n "$FW_TRACE" ] && echo $cmdline >&2 + +	$cmdline +  	fw__rc $?  }  fw_get_port_range() { -	local ports=$1 -	local delim=${2:-:} -	if [ "$3" ]; then -		fw_get_port_range "${ports}-${3}" $delim +	local _var=$1 +	local _ports=$2 +	local _delim=${3:-:} +	if [ "$4" ]; then +		fw_get_port_range $_var "${_ports}-${4}" $_delim  		return  	fi -	local first=${ports%-*} -	local last=${ports#*-} -	if [ "$first" != "$last" ]; then -		echo "$first$delim$last" +	local _first=${_ports%-*} +	local _last=${_ports#*-} +	if [ "$_first" != "$_last" ]; then +		export -- "$_var=$_first$_delim$_last"  	else -		echo "$first" +		export -- "$_var=$_first"  	fi  }  fw_get_family_mode() { -	local hint="$1" -	local zone="$2" -	local mode="$3" +	local _var="$1" +	local _hint="$2" +	local _zone="$3" +	local _mode="$4" -	local ipv4 ipv6 +	local _ipv4 _ipv6  	[ -n "$FW_ZONES4$FW_ZONES6" ] && { -		list_contains FW_ZONES4 $zone && ipv4=1 || ipv4=0 -		list_contains FW_ZONES6 $zone && ipv6=1 || ipv6=0 +		list_contains FW_ZONES4 $_zone && _ipv4=1 || _ipv4=0 +		list_contains FW_ZONES6 $_zone && _ipv6=1 || _ipv6=0  	} || { -		ipv4=$(uci_get_state firewall core ${zone}_ipv4 0) -		ipv6=$(uci_get_state firewall core ${zone}_ipv6 0) +		_ipv4=$(uci_get_state firewall core ${_zone}_ipv4 0) +		_ipv6=$(uci_get_state firewall core ${_zone}_ipv6 0)  	} -	case "$hint:$ipv4:$ipv6" in -		*4:1:*|*:1:0) echo G4 ;; -		*6:*:1|*:0:1) echo G6 ;; -		*) echo $mode ;; +	case "$_hint:$_ipv4:$_ipv6" in +		*4:1:*|*:1:0) export -n -- "$_var=G4" ;; +		*6:*:1|*:0:1) export -n -- "$_var=G6" ;; +		*) export -n -- "$_var=$_mode" ;;  	esac  }  | 
