1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
#!/bin/bash
# Authors: Steven Shiau <steven _at_ clonezilla org>, Ceasar Sun <ceasar _at_ nchc org tw>
# License: GPL
#
# set the iptables NAT
# clean the old tables
#
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
# Borrow some codes from /etc/init.d/iptables in RedHat.
IPTABLES=iptables
IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6
PROC_IPTABLES_NAMES=/proc/net/${IPV}_tables_names
NAT_RULES_FOR_RH=$SYSCONF_PATH/iptables
NAT_RULES_FOR_DEBIAN=$SYSCONF_PATH/drbl-nat.up.rules
NAT_RULES_FOR_SUSE=$SYSCONF_PATH/SuSEfirewall2
#
flush_n_delete() {
# Flush firewall rules and delete chains.
[ -e "$PROC_IPTABLES_NAMES" ] || return 1
# Check if firewall is configured (has tables)
tables=`cat $PROC_IPTABLES_NAMES 2>/dev/null`
[ -z "$tables" ] && return 1
echo -n $"Flushing firewall rules: "
ret=0
# For all tables
for i in $tables; do
# Flush firewall rules.
$IPTABLES -t $i -F;
let ret+=$?;
# Delete firewall chains.
$IPTABLES -t $i -X;
let ret+=$?;
# Set counter to zero.
$IPTABLES -t $i -Z;
let ret+=$?;
done
[ $ret -eq 0 ] && echo "success" || echo "failure"
}
# save rules
save_rules() {
# Save the rules.
if [ -e /etc/debian_version ]; then
# Debian
# We have to save our rules.
iptables-save > $NAT_RULES_FOR_DEBIAN
chmod 600 $NAT_RULES_FOR_DEBIAN
elif [ -e /etc/SuSE-release ]; then
# SuSE
# we already set that in /etc/sysconfig/SuSEfirewall2, so it not necessary
continue
elif [ -n "$(command -v systemctl 2>/dev/null)" -a -e "/lib/systemd/system/iptables.service" ]; then
# for FC 17, add by Ceasar
echo "Save iptables service ,run :iptables-save"
iptables-save > $NAT_RULES_FOR_RH
else
# RH-like, we use its service
/etc/init.d/iptables save
fi
}
# set not to unload iptables module
set_not_unload_iptables_module_RH() {
if [ ! -f $SYSCONF_PATH/iptables-config ]; then
echo 'IPTABLES_MODULES_UNLOAD="no"' > $SYSCONF_PATH/iptables-config
else
if grep -E -q "^[#\s]*IPTABLES_MODULES_UNLOAD=.*" $SYSCONF_PATH/iptables-config; then
perl -p -i -e "s/^[#\s]*IPTABLES_MODULES_UNLOAD=.*/IPTABLES_MODULES_UNLOAD=\"no\"/" $SYSCONF_PATH/iptables-config
else
echo 'IPTABLES_MODULES_UNLOAD="no"' >> $SYSCONF_PATH/iptables-config
fi
fi
}
do_stop_iptables() {
echo "Now stop the NAT service..."
if [ -e /etc/debian_version ]; then
# Debian
# We have to use the code borrowed from RH.
flush_n_delete
elif [ -e /etc/SuSE-release ]; then
# SuSE
# TODO, can it (the cleaned one) save back to system in SuSE ?
# Now this seems to do nothing.
/etc/init.d/SuSEfirewall2_setup stop
elif [ -n "$(command -v systemctl 2>/dev/null)" -a -e "/lib/systemd/system/iptables.service" ]; then
# for FC 18/21, add by Ceasar
if [ "$(LC_ALL=C firewall-cmd --state 2>/dev/null)" = "running" ]; then
echo "Stop firewalld service ,run :systemctl stop firewalld.service"
systemctl stop firewalld.service
fi
echo "Stop iptables service ,run :systemctl stop iptables.service"
systemctl stop iptables.service
else
# RH-like
/etc/init.d/iptables stop
fi
}
#
check_if_root
# main
usage() {
echo "To generate or clean NAT setting for DRBL clients to access"
echo "Usage: $0 [Options] {generate|clean|regenerate|stop|status}"
echo "Options:"
echo "-a, --all-subnet: Make all subnet can access to this NAT server."
echo "-v, --verbose: Verbose mode."
echo "Example: To generate NAT setting for DRBL clients to access"
echo "$0 generate"
}
# default setting
all_subnet="no"
while [ $# -gt 0 ]; do
case "$1" in
-a|--all-subnet)
all_subnet="yes"
shift;;
-v|--verbose)
shift; verbose="on"
;;
-*) echo "${0}: ${1}: invalid option" >&2
usage >& 2
exit 2 ;;
*) break ;;
esac
done
switch=$1
#
[ -z "$switch" ] && usage && exit 1
#
case "$switch" in
generate)
echo "Now generate the firewall rules for NAT service..."
if [ -f /etc/SuSE-release ]; then
# SuSE
# SuSE has its own wrapper program, we use that.
[ -f $SYSCONF_PATH/SuSEfirewall2 ] && cp -f $SYSCONF_PATH/SuSEfirewall2 $SYSCONF_PATH/SuSEfirewall2.drblsave
client_ip_nets=""
if [ "$all_subnet" = "yes" ]; then
# Exporting whole subnet to clients
subnet_list="$(get-client-ip-list | awk -F"." '{print $1"."$2"."$3}' | sort | uniq )"
for subnet in $subnet_list; do
client_ip_nets="$client_ip_nets ${subnet}.0/24"
done
else
# line by line
for ip in `get-client-ip-list`; do
client_ip_nets="$client_ip_nets $ip/32"
done
fi
DEV_INT="$(grep "^interface=" /etc/drbl/drblpush.conf | sed -e "s/interface=//g")"
# use echo to convert them into one line instead of many lines.
DEV_INT="$(echo $DEV_INT)"
# TODO, eth0 ? auto ? or other variable ?
perl -pi -e "s/^FW_DEV_EXT=.*/FW_DEV_EXT=auto/g" $SYSCONF_PATH/SuSEfirewall2
perl -pi -e "s/^FW_DEV_INT=.*/FW_DEV_INT=\"$DEV_INT\"/g" $SYSCONF_PATH/SuSEfirewall2
perl -pi -e "s/^FW_ROUTE=.*/FW_ROUTE=\"yes\"/g" $SYSCONF_PATH/SuSEfirewall2
perl -pi -e "s/^FW_MASQUERADE=.*/FW_MASQUERADE=\"yes\"/g" $SYSCONF_PATH/SuSEfirewall2
perl -pi -e "s|^FW_MASQ_NETS=.*|FW_MASQ_NETS=\"$client_ip_nets\"|g" $SYSCONF_PATH/SuSEfirewall2
# at least we have to turn on ssh so that dcs can send commands
perl -pi -e "s|^FW_SERVICES_EXT_TCP=.*|FW_SERVICES_EXT_TCP=\"ssh\"|g" $SYSCONF_PATH/SuSEfirewall2
else
# RH-like & Debian
# backup the orig files for RH-like distribution if necessary
# Since it may not only consist of NAT, but also other rules.
# For Debian's $NAT_RULES_FOR_DEBIAN, we are sure it only for NAT. We will overwrite it.
if [ -f $SYSCONF_PATH/iptables ]; then
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "Warning! $SYSCONF_PATH/iptables is renamed as iptables.drblsave!"
echo "Your firewall rules is overwritten!!! We set the NAT for clients to access this DRBL server!"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
mv -f $SYSCONF_PATH/iptables $SYSCONF_PATH/iptables.drblsave
fi
echo "Stop the NAT service first..."
do_stop_iptables
iptables -P FORWARD ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
if [ "$all_subnet" = "yes" ]; then
# Exporting whole subnet to clients
subnet_list="$(get-client-ip-list | awk -F"." '{print $1"."$2"."$3}' | sort | uniq )"
for subnet in $subnet_list; do
iptables -t nat -A POSTROUTING -s ${subnet}.0/24 -j MASQUERADE
done
else
# line by line
for ip in `get-client-ip-list`; do
iptables -t nat -A POSTROUTING -s $ip/32 -j MASQUERADE
done
fi
# Save the rules.
save_rules
# Some bug in kernel 2.6.9, so we do not want to remove the module before
# restart the iptables
# Only for RH-like.
if [ ! -f /etc/debian_version ]; then
set_not_unload_iptables_module_RH
fi
fi
turn_on_ipv4_forward
;;
stop)
do_stop_iptables
;;
clean)
do_stop_iptables
# Save the empty rules to system.
save_rules
;;
regenerate)
$0 clean
$0 genereate
;;
status)
if [ -e /etc/debian_version ]; then
# Debian
cat $NAT_RULES_FOR_DEBIAN
elif [ -e /etc/SuSE-release ]; then
# SuSE
cat $NAT_RULES_FOR_SUSE
else
# RH-like
cat $NAT_RULES_FOR_RH
fi
;;
*)
usage
exit 1
;;
esac
|