mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-22 14:20:40 +01:00
7d756f51ac
Signed-off-by: Tom Eastep <teastep@shorewall.net>
403 lines
9.6 KiB
Plaintext
403 lines
9.6 KiB
Plaintext
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
|
|
#
|
|
# (c) 1999-2011 - Tom Eastep (teastep@shorewall.net)
|
|
#
|
|
# Options are:
|
|
#
|
|
# -n Don't alter Routing
|
|
# -v and -q Standard Shorewall Verbosity control
|
|
# -t Timestamp progress messages
|
|
# -p Purge conntrack table
|
|
# -r Recover from failed start/restart
|
|
# -V <verbosity> Set verbosity level explicitly
|
|
# -R <restore> Overrides RESTOREFILE setting
|
|
#
|
|
# Commands are:
|
|
#
|
|
# start Starts the firewall
|
|
# refresh Refresh the firewall
|
|
# restart Restarts the firewall
|
|
# reload Reload the firewall
|
|
# clear Removes all firewall rules
|
|
# stop Stops the firewall
|
|
# status Displays firewall status
|
|
# version Displays the version of Shorewall that
|
|
# generated this program
|
|
#
|
|
################################################################################
|
|
# Functions imported from /usr/share/shorewall/prog.header
|
|
################################################################################
|
|
#
|
|
# Find the value 'weight' in the passed arguments then echo the next value
|
|
#
|
|
|
|
find_weight() {
|
|
while [ $# -gt 1 ]; do
|
|
[ "x$1" = xweight ] && echo $2 && return
|
|
shift
|
|
done
|
|
}
|
|
|
|
#
|
|
# Find the interfaces that have a route to the passed address - the default
|
|
# route is not used.
|
|
#
|
|
|
|
find_rt_interface() {
|
|
$IP -4 route list | while read addr rest; do
|
|
case $addr in
|
|
*/*)
|
|
in_network ${1%/*} $addr && echo $(find_device $rest)
|
|
;;
|
|
default)
|
|
;;
|
|
*)
|
|
if [ "$addr" = "$1" -o "$addr/32" = "$1" ]; then
|
|
echo $(find_device $rest)
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
#
|
|
# Echo the name of the interface(s) that will be used to send to the
|
|
# passed address
|
|
#
|
|
|
|
find_interface_by_address() {
|
|
local dev
|
|
dev="$(find_rt_interface $1)"
|
|
local first
|
|
local rest
|
|
|
|
[ -z "$dev" ] && dev=$(find_default_interface)
|
|
|
|
[ -n "$dev" ] && echo $dev
|
|
}
|
|
|
|
#
|
|
# echo the list of networks routed out of a given interface
|
|
#
|
|
get_routed_networks() # $1 = interface name, $2-n = Fatal error message
|
|
{
|
|
local address
|
|
local rest
|
|
|
|
$IP -4 route show dev $1 2> /dev/null |
|
|
while read address rest; do
|
|
case "$address" in
|
|
default)
|
|
if [ $# -gt 1 ]; then
|
|
shift
|
|
fatal_error "$@"
|
|
else
|
|
echo "WARNING: default route ignored on interface $1" >&2
|
|
fi
|
|
;;
|
|
multicast|broadcast|prohibit|nat|throw|nexthop)
|
|
;;
|
|
*)
|
|
[ "$address" = "${address%/*}" ] && address="${address}/32"
|
|
echo $address
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
#
|
|
# Get the broadcast addresses associated with an interface
|
|
#
|
|
get_interface_bcasts() # $1 = interface
|
|
{
|
|
local addresses
|
|
addresses=
|
|
|
|
$IP -f inet addr show dev $1 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u
|
|
}
|
|
|
|
#
|
|
# Delete IP address
|
|
#
|
|
del_ip_addr() # $1 = address, $2 = interface
|
|
{
|
|
[ $(find_first_interface_address_if_any $2) = $1 ] || qtnoin $IP addr del $1 dev $2
|
|
}
|
|
|
|
# Add IP Aliases
|
|
#
|
|
add_ip_aliases() # $* = List of addresses
|
|
{
|
|
local local
|
|
local addresses
|
|
local external
|
|
local interface
|
|
local inet
|
|
local cidr
|
|
local rest
|
|
local val
|
|
local arping
|
|
arping=$(mywhich arping)
|
|
|
|
address_details()
|
|
{
|
|
#
|
|
# Folks feel uneasy if they don't see all of the same
|
|
# decoration on these IP addresses that they see when their
|
|
# distro's net config tool adds them. In an attempt to reduce
|
|
# the anxiety level, we have the following code which sets
|
|
# the VLSM and BRD from an existing address in the same networks
|
|
#
|
|
# Get all of the lines that contain inet addresses with broadcast
|
|
#
|
|
$IP -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do
|
|
case $cidr in
|
|
*/*)
|
|
if in_network $external $cidr; then
|
|
echo "/${cidr#*/} brd $(broadcastaddress $cidr)"
|
|
break
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
do_one()
|
|
{
|
|
val=$(address_details)
|
|
|
|
$IP addr add ${external}${val} dev $interface $label
|
|
[ -n "$arping" ] && qt $arping -U -c 2 -I $interface $external
|
|
echo "$external $interface" >> $VARDIR/nat
|
|
[ -n "$label" ] && label="with $label"
|
|
progress_message " IP Address $external added to interface $interface $label"
|
|
}
|
|
|
|
progress_message "Adding IP Addresses..."
|
|
|
|
while [ $# -gt 0 ]; do
|
|
external=$1
|
|
interface=$2
|
|
label=
|
|
|
|
if [ "$interface" != "${interface%:*}" ]; then
|
|
label="${interface#*:}"
|
|
interface="${interface%:*}"
|
|
label="label $interface:$label"
|
|
fi
|
|
|
|
shift 2
|
|
|
|
list_search $external $(find_interface_addresses $interface) || do_one
|
|
done
|
|
}
|
|
|
|
#
|
|
# Detect the gateway through a PPP or DHCP-configured interface
|
|
#
|
|
detect_dynamic_gateway() { # $1 = interface
|
|
local interface
|
|
interface=$1
|
|
local GATEWAYS
|
|
GATEWAYS=
|
|
local gateway
|
|
|
|
gateway=$(run_findgw_exit $1);
|
|
|
|
if [ -z "$gateway" ]; then
|
|
gateway=$( find_peer $($IP addr list $interface ) )
|
|
fi
|
|
|
|
if [ -z "$gateway" -a -f /var/lib/dhcpcd/dhcpcd-${1}.info ]; then
|
|
eval $(grep ^GATEWAYS= /var/lib/dhcpcd/dhcpcd-${1}.info 2> /dev/null)
|
|
[ -n "$GATEWAYS" ] && GATEWAYS=${GATEWAYS%,*} && gateway=$GATEWAYS
|
|
fi
|
|
|
|
if [ -z "$gateway" -a -f /var/lib/dhcp/dhclient-${1}.lease ]; then
|
|
gateway=$(grep 'option routers' /var/lib/dhcp/dhclient-${1}.lease | tail -n 1 | while read j1 j2 gateway; do echo $gateway ; return 0; done)
|
|
fi
|
|
|
|
[ -n "$gateway" ] && echo $gateway
|
|
}
|
|
|
|
#
|
|
# Detect the gateway through an interface
|
|
#
|
|
detect_gateway() # $1 = interface
|
|
{
|
|
local interface
|
|
interface=$1
|
|
local gateway
|
|
#
|
|
# First assume that this is some sort of dynamic interface
|
|
#
|
|
gateway=$( detect_dynamic_gateway $interface )
|
|
#
|
|
# Maybe there's a default route through this gateway already
|
|
#
|
|
[ -n "$gateway" ] || gateway=$(find_gateway $($IP -4 route list dev $interface | grep ^default))
|
|
#
|
|
# Last hope -- is there a load-balancing route through the interface?
|
|
#
|
|
[ -n "$gateway" ] || gateway=$(find_nexthop $interface)
|
|
#
|
|
# Be sure we found one
|
|
#
|
|
[ -n "$gateway" ] && echo $gateway
|
|
}
|
|
|
|
#
|
|
# Disable IPV6
|
|
#
|
|
disable_ipv6() {
|
|
local foo
|
|
foo="$($IP -f inet6 addr list 2> /dev/null)"
|
|
|
|
if [ -n "$foo" ]; then
|
|
if [ -x "$IP6TABLES" ]; then
|
|
$IP6TABLES -P FORWARD DROP
|
|
$IP6TABLES -P INPUT DROP
|
|
$IP6TABLES -P OUTPUT DROP
|
|
$IP6TABLES -F
|
|
$IP6TABLES -X
|
|
$IP6TABLES -A OUTPUT -o lo -j ACCEPT
|
|
$IP6TABLES -A INPUT -i lo -j ACCEPT
|
|
else
|
|
error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Add an additional gateway to the default route
|
|
#
|
|
add_gateway() # $1 = Delta $2 = Table Number
|
|
{
|
|
local route
|
|
local weight
|
|
local delta
|
|
local dev
|
|
|
|
route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/default //; s/[\]//g'`
|
|
|
|
if [ -z "$route" ]; then
|
|
run_ip route add default scope global table $2 $1
|
|
else
|
|
delta=$1
|
|
|
|
if ! echo $route | fgrep -q ' nexthop '; then
|
|
route=`echo $route | sed 's/via/nexthop via/'`
|
|
dev=$(find_device $route)
|
|
if [ -f ${VARDIR}/${dev}_weight ]; then
|
|
weight=`cat ${VARDIR}/${dev}_weight`
|
|
route="$route weight $weight"
|
|
fi
|
|
fi
|
|
|
|
run_ip route replace default scope global table $2 $route $delta
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Remove a gateway from the default route
|
|
#
|
|
delete_gateway() # $! = Description of the Gateway $2 = table number $3 = device
|
|
{
|
|
local route
|
|
local gateway
|
|
local dev
|
|
|
|
route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/[\]//g'`
|
|
gateway=$1
|
|
|
|
if [ -n "$route" ]; then
|
|
if echo $route | fgrep -q ' nexthop '; then
|
|
gateway="nexthop $gateway"
|
|
eval route=\`echo $route \| sed \'s/$gateway/ /\'\`
|
|
run_ip route replace table $2 $route
|
|
else
|
|
dev=$(find_device $route)
|
|
[ "$dev" = "$3" ] && run_ip route delete default table $2
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Determine the MAC address of the passed IP through the passed interface
|
|
#
|
|
find_mac() # $1 = IP address, $2 = interface
|
|
{
|
|
if interface_is_usable $2 ; then
|
|
qt ping -nc 1 -t 2 -I $2 $1
|
|
|
|
local result
|
|
result=$($IP neigh list | awk "/^$1 / {print \$5}")
|
|
|
|
case $result in
|
|
\<*\>)
|
|
;;
|
|
*)
|
|
[ -n "$result" ] && echo $result
|
|
;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Clear Proxy Arp
|
|
#
|
|
delete_proxyarp() {
|
|
if [ -f ${VARDIR}/proxyarp ]; then
|
|
while read address interface external haveroute; do
|
|
qtnoin $IP -4 neigh del proxy $address dev $external
|
|
[ -z "${haveroute}${g_noroutes}" ] && qtnoin $IP -4 route del $address/32 dev $interface
|
|
f=/proc/sys/net/ipv4/conf/$interface/proxy_arp
|
|
[ -f $f ] && echo 0 > $f
|
|
done < ${VARDIR}/proxyarp
|
|
|
|
rm -f ${VARDIR}/proxyarp
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Remove all Shorewall-added rules
|
|
#
|
|
clear_firewall() {
|
|
stop_firewall
|
|
|
|
setpolicy INPUT ACCEPT
|
|
setpolicy FORWARD ACCEPT
|
|
setpolicy OUTPUT ACCEPT
|
|
|
|
run_iptables -F
|
|
qt $IPTABLES -t raw -F
|
|
|
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
|
|
if [ -n "$DISABLE_IPV6" ]; then
|
|
if [ -x $IP6TABLES ]; then
|
|
$IP6TABLES -P INPUT ACCEPT 2> /dev/null
|
|
$IP6TABLES -P OUTPUT ACCEPT 2> /dev/null
|
|
$IP6TABLES -P FORWARD ACCEPT 2> /dev/null
|
|
fi
|
|
fi
|
|
|
|
run_clear_exit
|
|
|
|
set_state "Cleared"
|
|
|
|
logger -p kern.info "$g_product Cleared"
|
|
}
|
|
|
|
#
|
|
# Get a list of all configured broadcast addresses on the system
|
|
#
|
|
get_all_bcasts()
|
|
{
|
|
$IP -f inet addr show 2> /dev/null | grep 'inet.*brd' | grep -v '/32 ' | sed 's/inet.*brd //; s/scope.*//;' | sort -u
|
|
}
|
|
|
|
################################################################################
|
|
# End of functions in /usr/share/shorewall/prog.header
|
|
################################################################################
|