Основные возможности:
-
Автоматическое заполнение таблиц маршрутизации на внешних интерфейсах и проверка;
-
Автоматическое создание дополнительного файла настроек SuSEfirewall2 с LOG и DROP правилами на внешних интерфейсах и проверка;
-
Автоматическое создание дополнительного файла настроек SuSEfirewall2 с правилами из файлов /etc/rtxnet/rules/*.conf
(в формате iptables).
Пример cкрипта для настройки таблиц маршрутизации на сервере с 2-мя и более внешними сетевыми интерфейсами.
Cкрипт
/etc/init.d/rtxnet
разработан для автоматического заполнения таблиз маршрутизации.
Описание:
-
Данный скрипт помогает создавать, обновлять и проверять таблицы маршрутизации;
-
Создавать и проверять дополнительные правила межсетевого экрана;
-
Скрипт может запускаться как во время загрузки системы на разных уровнях (по умолчанию 3 и 5), так и в ручном режиме;
-
Предусмотрен автоматический перезапуск скрипта при восстановлении сетевого интерфейса;
-
Сетевые интерфейса для создания таблиц маршрутизации и информация для создания правил межсетевого экрана указываются в файле /etc/rtxnet/rtxnet.conf
.
Изменения:
В версии 1.5 (Срд Дек 2 2009):
- Оптимизирован код
В версии 1.4 (Пнд Июл 20 2009):
- Добавлена возможность указывать шлюз для каждого интерфейса вручную
- Исправлена ошибка заполнения таблиц маршрутизации, когда используется маска подсети отличная от /8, /16 или /24
В версии 1.3:
- Исправлена ошибка заполнения таблиц маршрутизации, возникавшая из-за некорректного определения активного интерфейса при физическом отключении провода.
В версии 1.2:
- Исправлена ошибка, препятствующая удалению пакета, возникавшая из-за некорректной остановки службы.
Пример комплекта скриптов rtxnet:
(Скачать файл можно будет
здесь. ЗЫ Не тыкать! Жать правой кнопкой: сохранить ссылку как...)
Условия:
-
Скрипт /etc/init.d/rtxnet и ссылка на него /usr/sbin/rcrtxnet
-
Файл конфигурации /etc/rtxnet/rtxnet.conf
-
Файлы с правилами /etc/rtxnet/rules/*.conf
-
Скрипт перезапуска при восстановлении интерфейса /etc/sysconfig/network/scripts/rtxnetstart и ссылка на него /etc/sysconfig/network/if-up.d/rtxnetstart
-
Операционная система сервера: openSUSE 10.3-11.2;
-
Режим фаервола SuSEfirewall2: роутинг+маскарадинг из внутренней сети во внешню;
-
Предположим, что на сервере есть 2 внешних сетевых интерфейса, им присвоены статические IP адреса.
(Шлюз по умолчанию - 1-ый адрес из подсети, если не указано вручную как ИмяИнтерфейса:АдресШлюза в файле rtxnet.conf параметр INTERFACE).
-
Для чего это нужно:
- Для корректного роутинга пакетов на внешних интерфейсах не достаточно стандартных настроек, требуется создавать для каждого внешнего интерфейса свою таблицу маршрутизации, где указывать сеть и шлюз.
- Для корректного роутинга между внутренними интерфейсами, необходимо дополнительно редактировать файл /etc/sysconfig/SuSEfirewall2.
- Кроме того желательно создать дополнительные правила для внешних интерфейсов, для запрета прохождения icmp пакетов из внешней сети на адреса 192.168.0.0/16 10.0.0.0/8 127.0.0.0/8
Все это позволяет сделать/проверить скрипт автоматически и сообщить о несоответствии.
-
Особенности работы:
При стартe проверяются и создаются iptables правила для интерфейсов, указанных в конфигурационном файле.
Проверяются и создаются таблицы маршрутизации для интерфейсов, указанных в конфигурационном файле.
Установка:
-
Поместить скрипт rtxnet
в /etc/init.d/
и сделать ссылку командой: ln -s /etc/init.d/rtxnet /usr/sbin/rcrtxnet
-
Поместить файл конфигурации rtxnet.conf
в /etc/rtxnet/
-
Поместить (если необходимо) файлы с дополнительными правилами *.conf
в /etc/rtxnet/rules/
-
Поместить скрипт перезапуска rtxnetstart
в /etc/sysconfig/network/scripts/
и сделать ссылку: ln -s /etc/sysconfig/network/scripts/rtxnetstart /etc/sysconfig/network/if-up.d/rtxnetstart
Текст:
Пример конфигурационного файла rtxnet:
# External interface for create route table eth1 eth2 ...
#INTERFACE="eth1 eth2:194.195.196.197 eth3:194.195.197.196"
INTERFACE="eth1 eth2:194.195.196.197"
# Nets to create DROP rules
#DROPNET="127.0.0.0/8 10.0.0.0/8 192.168.0.0/16"
DROPNET="127.0.0.0/8 10.0.0.0/8 192.168.0.0/16"
# Eable read rules from RULEDIR (/etc/rtxnet/rules/*.conf)
#ENABLERULEDIR="no"
ENABLERULEDIR="yes"
Пример скрипта перезапуска /etc/sysconfig/network/scripts/rtxnetstart:
#!/bin/bash
# this scripts is called with the name of the interface in
# parameter $1
# source configuration file
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
[ ! -f /etc/rtxnet/rtxnet.conf ] && echo "Can't run rtxnet without a /etc/rtxnet/rtxnet.conf configuartion file!" && exit 1
# TODO: should make additional checks here
. /etc/rtxnet/rtxnet.conf
RTTBL_ACTIVATE=`chkconfig rtxnet | 'awk {print $2}'`
if [ "$RTTBL_ACTIVATE" = "on" ]; then
# ok, we are on
INTFFIND="0"
for i in $INTERFACE
do
if [ "$i" = "$1" ]; then
INTFFIND="1"
fi
done
if [ "$INTFFIND" = "1" ]; then
# it's our interface, let's do it
/etc/init.d/rtxnet stop > /dev/null
/etc/init.d/rtxnet start > /dev/null
fi
fi
exit 0
Пример скрипта rtxnet:
#! /bin/sh
#
# Author: Konstantin Nadezhdin <w.homenki.ru>
# Version: 1.5
#
#
# /etc/init.d/rtxnet
#
### BEGIN INIT INFO
# Provides: rtxnet
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: Configure route for ext nets
# Description: Add route for 2 and more external network
### END INIT INFO
test -s /etc/rtxnet/rtxnet.conf && \
. /etc/rtxnet/rtxnet.conf
DAEMON="Route table for 2 and more external network"
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v ditto but be verbose in local rc status
# rc_status -v -r ditto and clear the local rc status
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num><num>
# rc_reset clear local rc status (overall remains)
# rc_exit exit appropriate to overall rc status
. /etc/rc.status
# First reset status of this service
rc_reset
test "$INTERFACE" || { echo -n "Error, you must specify an INTERFACE in /etc/rtxnet/rtxnet.conf"; rc_failed; rc_status -v; rc_exit; }
RULEDIR="/etc/rtxnet/rules"
test "$ENABLERULEDIR" || ENABLERULEDIR="no"
erd="\033[31m"
egr="\033[32m"
eyl="\033[33m"
edf="\033[m"
eok="\t${egr}OK$edf"
eer="\t${erd}Error!$edf"
ewr="\t${eyl}Warning!$edf"
esl="\t${egr}Solve:$edf"
case "$1" in
start)
#$0 checkrules
echo "Create $DAEMON"
for IFXGWX in $INTERFACE; do
IFX=${IFXGWX%%:*}
GWX=${IFXGWX##*:}
if ! /sbin/ip l l $IFX | grep -E ",UP(,|>)" > /dev/null 2>&1; then
echo "$ewr Interface $IFX does not exist or is not up. Route table for $IFX not created."
rc_failed
else
if [ -s /etc/sysconfig/network/ifcfg-$IFX ]; then
. /etc/sysconfig/network/ifcfg-$IFX
if [ "$BOOTPROTO" = "static" ]; then
IPX=${IPADDR%%\/*}
NETX=$(ip route list table main | grep "dev $IFX .* src $IPX" | awk '{print $1}')
test $GWX = $IFXGWX && GWX=$(echo $IPX | sed 's/\.[0-9]{1,3}$/\.1/')
GWXok=$(echo $GWX | sed -r 's/^[0-9]{1,3}(\.[0-9]{1,3}){3}$/GWXok/')
if [ "$GWXok" = "GWXok" ]; then
TX=$(echo $IFX | sed 's/^[a-zA-Z]*/T/')
echo " - Adding route table $TX for $IFX (IP:$IPX NET:$NETX GW:$GWX)"
ip_tbl=$(grep -v "^#\|^25[3-5]\|^0" /etc/iproute2/rt_tables | grep "$TX$" | awk '{print $2}')
if [ "$ip_tbl" = "$TX" ]; then
iprtl=$(ip route list table $TX)
test "$iprtl" && { echo -n " - Clear table $TX:"; ip route flush table $TX; rc_status -v; }
echo -n " - Add net to table $TX:"; ip route add $NETX dev $IFX src $IPX table $TX; rc_status -v
echo -n " - Add gw to table $TX:"; ip route add default via $GWX table $TX; rc_status -v
iprll=$(ip rule list | grep " $TX ")
test "$iprll" && { echo -n " - Delete rule for table $TX:"; ip rule delete table $TX; rc_status -v; }
echo -n " - Add rules to table $TX:"; ip rule add from $IPX table $TX; rc_status -v
else
echo -e "$ewr IP routing table $TX not found in /etc/iproute2/rt_tables. Route table for $IFX not created."
rc_failed
fi
else
echo -e "$ewr GW for interface $IFX is incorrect! Route table for $IFX not created."
rc_failed
fi
else
echo -e "$ewr bootproto for $IFX not static. Route table for $IFX not created."
rc_failed
fi
else
echo -e "$ewr /etc/sysconfig/network/ifcfg-$IFX not found. Route table for $IFX not created."
rc_failed
fi
fi
done
echo -n "Starting $DAEMON"
rc_status -v
;;
stop)
echo "Delete $DAEMON"
for IFXGWX in $INTERFACE; do
IFX=${IFXGWX%%:*}
GWX=${IFXGWX##*:}
if ! /sbin/ip l l $IFX > /dev/null 2>&1; then
echo -e "$ewr interface $IFX does not exist or is not up. Route table for $IFX not deleted."
else
if [ -s /etc/sysconfig/network/ifcfg-$IFX ]; then
. /etc/sysconfig/network/ifcfg-$IFX
if [ "$BOOTPROTO" = "static" ]; then
IPX=${IPADDR%%\/*}
NETX=$(ip route list table main | grep "dev $IFX .* src $IPX" | awk '{print $1}')
test $GWX = $IFXGWX && GWX=$(echo $IPX | sed 's/\.[0-9]{1,3}$/\.1/')
TX=$(echo $IFX | sed 's/^[a-zA-Z]*/T/')
echo " - Deleting route table $TX for $IFX (IP:$IPX NET:$NETX GW:$GWX)"
ip_tbl=$(grep -v "^#\|^25[3-5]\|^0" /etc/iproute2/rt_tables | grep "$TX$" | awk '{print $2}')
if [ "$ip_tbl" = "$TX" ]; then
iprtl=$(ip route list table $TX)
test "$iprtl" && { echo -n " - Table $TX found, flush:"; ip route flush table $TX; rc_status -v; }
iprll=$(ip rule list | grep " $TX ")
test "$iprll" && { echo -n " - Rules for table $TX found, delete:"; ip rule delete table $TX; rc_status -v; }
else
echo -e "$ewr IP routing table $TX not found. Route table for $IFX not deleted."
fi
else
echo -e "$ewr bootproto for $IFX not static. Route table for $IFX not deleted."
fi
else
echo -e "$ewr /etc/sysconfig/network/ifcfg-$IFX not found. Route table for $IFX not deleted."
fi
fi
done
echo -n "Stoping $DAEMON"
rc_status -v
;;
restart)
$0 stop
$0 start
;;
status)
echo -e "Check $DAEMON"
# Check IP forwarding
echo -n "-Check IP forwarding:"
ip_fwd=$(cat /proc/sys/net/ipv4/ip_forward)
if [ "$ip_fwd" = "1" ]; then
echo -e "\t$eok"
else
echo -e "\t$ewr"; echo " -IP forwarding disabled."
echo -e "$esl\
\n\t1. Check /etc/sysconfig/sysctl. Set \"yes\" in IP_FORWARD\
\n\t2. Check /etc/sysconfig/SuSEfirewall2\
\n\t2.1 Add all internal device in: FW_DEV_INT\
\n\t2.2 Set \"yes\" in: FW_ROUTE\
\n\t2.3 Make sure you set Class_Routing to \"int\" in: FW_ALLOW_CLASS_ROUTING\
\n\t3. Restart network and SuSefirewall2."
rc_failed
fi
# Check DROP rules
echo -n "-Check rules in input_ext:"
if [ "$DROPNET" = "" ]; then
echo -e "$ewr"
echo -e "$esl\n\tIf you want check drop rules, you must specify DROPNET in /etc/rtxnet/rtxnet.conf"
else
let i=1
let ok=1
for target in LOG DROP; do
for dropnetx in $DROPNET; do
checkfw=$(iptables -n -L input_ext -v --line-numbers | grep -E "$target .+( +\*){2} +(0\.){3}0/0 +$dropnetx" | awk '{print $1}')
test "$checkfw" = "$i" && let ok=ok+1
let i=i+1
done
done
if [ $i = $ok ]; then
echo -e "$eok"
else
echo -e "$ewr"
echo -e "$esl\n\tNead check fw_custom_after_antispoofing in /etc/sysconfig/scripts/SuSEfirewall2-rtxnet"
rc_failed
fi
fi
if [ "$ENABLERULEDIR" = "yes" ]; then
echo -e "-Check ENABLERULEDIR=\"yes\":$eok"
let i=i+1
echo -e "$eyl\tYou must verify rule file in /etc/rtxnet/rules directory and run: \"rcrtxnet setuprules\"$edf"
fi
#Check SuSEfirewall config
echo -n "-Check SuSEfirewall config:"
checkfwconf=$(grep "^FW_CUSTOMRULES=" /etc/sysconfig/SuSEfirewall2)
if [ "$checkfwconf" = "FW_CUSTOMRULES=\"/etc/sysconfig/scripts/SuSEfirewall2-rtxnet\"" ]; then
echo -e "$eok"
else
echo -e "$ewr"; echo " - $checkfwconf is not correct."
echo -e "$esl\n\tSet manualy FW_CUSTOMRULES=\"/etc/sysconfig/scripts/SuSEfirewall2-rtxnet\" in /etc/sysconfig/SuSEfirewall2"
rc_failed
fi
# Check IP routing
let iprllc=0
let iprtlc=0
let ipi=0
for IFXGWX in $INTERFACE
do
IFX=${IFXGWX%%:*}
GWX=${IFXGWX##*:}
echo -n "-Check IP routing for interface $IFX:"
if ! /sbin/ip l l $IFX > /dev/null 2>&1; then
echo -e "$ewr"; echo " - Interface $IFX does not exist or is not up. Route table for $IFX not listed."
echo -e "$esl Check network configuration."
rc_failed
else
if [ -s /etc/sysconfig/network/ifcfg-$IFX ]; then
. /etc/sysconfig/network/ifcfg-$IFX
if [ "$BOOTPROTO" = "static" ]; then
echo ""
IPX=${IPADDR%%\/*}
NETX=$(ip route list table main | grep "dev $IFX .* src $IPX" | awk '{print $1}')
test $GWX = $IFXGWX && GWX=$(echo $IPX | sed 's/\.[0-9]{1,3}$/\.1/')
TX=$(echo $IFX | sed 's/^[a-zA-Z]*/T/')
echo -e " Route table $eyl$TX$edf for $eyl$IFX$edf (IP:$eyl$IPX$edf NET:$eyl$NETX$edf GW:$eyl$GWX$edf):"
echo " - Net added automaticaly by yast to main table:"
echo -en "$egr"; ip route list table main | grep -e "dev $IFX .* src $IPX"; echo -en "$edf"
# Get IP routing table
ip_tbl=$(grep -v "^#\|^25[3-5]\|^0" /etc/iproute2/rt_tables | grep "$TX$" | awk '{print $2}')
echo -n " - Table $TX list:"
if [ "$ip_tbl" = "$TX" ]; then
iprtl=$(ip route list table $TX)
if [ "$iprtl" != "" ]; then
echo ""
echo -en "$egr"; echo $iprtl; echo -en "$edf"
let iprtlc=iprtlc+1
else
echo -e "$ewr"; echo " - IP table $ip_tbl is clear."
echo -e "$esl\
\n\t1.Add external interfaces (eth1 or eth2 ...) for routing table $ip_tbl in /etc/rtxnet/rtxnet.conf\
\n\t2.Enable and start ${eyl}rtxnet$edf init script from yast or run: ${eyl}chkconfig --add rtxnet & rcrtxnet start$edf"
rc_failed
fi
echo -n " - Rules for table $TX: "
iprll=$(ip rule list | grep " $TX ")
if [ "$iprll" != "" ]; then
echo ""
echo -en "$egr"; echo $iprll; echo -en "$edf"
let iprllc=iprllc+1
else
echo -e "$ewr"; echo " - IP rule for table $ip_tbl not found."
echo -e "$esl\
\n\t1.Add external interfaces (eth1 or eth2 ...) for routing table $ip_tbl in /etc/rtxnet/rtxnet.conf\
\n\t2.Enable and start ${eyl}rtxnet$edf init script from yast or run: ${eyl}chkconfig --add rtxnet & rcrtxnet start$edf"
rc_failed
fi
else
echo -e "$ewr"; echo " - IP routing table $TX not found. Route table for $IFX not listed."
echo -e "$esl\n\tAdd routing table (T1 T2 ...) for each external net in /etc/iproute2/rt_tables"
rc_failed
fi
else
echo -e "$ewr"; echo " - Bootproto for $IFX not static. Route table for $IFX not listed."
echo -e "$esl Set static network IP"
rc_failed
fi
else
echo -e "$ewr"; echo " - /etc/sysconfig/network/ifcfg-$IFX not found. Route table for $IFX not listed."
echo -e "$esl Check network configuration."
rc_failed
fi
fi
let ipi=ipi+1
done
#Check Default GW
echo -e " - Default GW added automaticaly by yast to main table:"
echo -en "$egr"; ip route list table main | grep default; echo -en "$edf"
if [ "$iprtlc$iprllc" = "00" ]; then
rc_failed 3
elif [ "$iprtlc$iprllc" != "$ipi$ipi" ]; then
rc_failed 1
fi
echo -n "$DAEMON is"
rc_status -v
;;
setuprules)
echo "Check fw_custom_after_antispoofing in /etc/sysconfig/scripts/SuSEfirewall2-rtxnet:"
echo -e "\n#START ADDED BY RTXNET" > /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
if [ "$DROPNET" != "" ]; then
echo -n " -Add LOG and DROP rules for $DROPNET in input_ext chain"
echo -e "\nfor target in LOG DROP;do\n\tfor destination in $DROPNET; do\n\t\tiptables -A input_ext -j \$target -d \$destination\n\tdone\ndone\n" >> /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
echo -e "$eok"
else
echo " -If you want add LOG and DROP rules in input_ext, you must specify DROPNET in /etc/rtxnet/rtxnet.conf"
fi
if [ "$ENABLERULEDIR" = "yes" ]; then
for RULEFILE in $RULEDIR/*.conf;
do
echo -n " -Add rules from file $RULEFILE"
cat $RULEFILE >> /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
echo -e "\n" >> /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
echo -e "$eok"
done
else
echo -e "$ewr"
echo -e "$esl\n\tIf you want add rules from file, you must set ENABLERULEDIR=\"yes\" and RULEDIR in /etc/rtxnet/rtxnet.conf"
fi
echo -e "\n#END ADDED BY RTXNET" >> /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
sed '/fw_custom_after_antispoofing/ {
r /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
}' /etc/sysconfig/scripts/SuSEfirewall2-custom > /etc/sysconfig/scripts/SuSEfirewall2-rtxnet
rm /etc/sysconfig/scripts/SuSEfirewall2-rtxnet.tmp
echo -n "Check SuSEfirewall config..."
checkfwconf=$(grep "^FW_CUSTOMRULES=" /etc/sysconfig/SuSEfirewall2)
if [ "$checkfwconf" = "FW_CUSTOMRULES=\"/etc/sysconfig/scripts/SuSEfirewall2-rtxnet\"" ]; then
echo -e "$eok"
else
echo -e "$ewr\n\t$checkfwconf is not correct"
echo -e "$esl\
\n\tSet manualy FW_CUSTOMRULES=\"/etc/sysconfig/scripts/SuSEfirewall2-rtxnet\" in /etc/sysconfig/SuSEfirewall2"
rc_failed
fi
echo -e "\t${eyl}!To take effect with new rules run rcSuSEfirewall2 reload!$edf"
;;
listrules)
echo "List rules in input_ext:"
echo -e "$egr"; iptables -n -L input_ext -v --line-numbers; echo -e "$edf"
;;
*)
echo "Usage: $0 {start|stop|restart|status|setuprules|listrules}"
exit 1
esac
rc_exit