На разных машинах в моей локальной сети накопилась куча программ,
которым нужен был выход в интернет напрямую. У каждой свой набор портов.
Захотелось на входе иметь минимальную конфигурацию, описывающую
ресурсы, а на выходе набор разрешающих правил для iptables.
В основном были клиент-банки - поэтому и такая терминология в программе.
А так вместо банка можно указывать любой ресурс в формате определенном в
man iptables.
Ограничения, недостатки:
1. использование количества портов для одного ресурса менее 16
2. нельзя указать диапазон портов через двоеточие как в iptables
Оба легко устаняются: первое - есть пример в самом скрипте,
второе через использование другого разделителя для записей на входе,
проверку наличия ":" - использование другого формата вызова iptables. Мне это
не нужно и код не хотел раздувать.
#!/bin/bash
#bkv 2005.10
#Дано:
# Два списка:
# Первый список из записей вида - банк:порты(через запятую)
# Второй список из записей вида - клиент:банки(через запятую)
#Найти:
# Набор разрешающих правил iptables для forward
#Примечания:
# политика FORWARD по умолчанию - "запрещено все, что не разрешенно"
# iptables поддерживает одновременное указание не более 15 портов
#Решение:
# Создадим отдельную цепочку, например, - CLIENTBANK
# Сгенерируем необходимые правила и поместим их в цепочку CLIENTBANK
# Обращения по всем портам из первого списка направим на обработку в CLIENTBANK
# Перед выполнением все правила связаные с цепочкой CLIENTBANK удалим, чтобы не плодить
# правила от многократного запуска
itls="/sbin/iptables"
#Подаем список на обработку awk
#признак первого списка - первое поле BankPorts
#признак второго списка - первое поле ClientBanks
echo -e "\
BankPorts:smtp.mail.ru:25\n\
BankPorts:10.24.70.0/26:22,23\n\
BankPorts:pop.mail.ru:110\n\
BankPorts:bank4.ru:9999,888\n\
BankPorts:bank5.ru:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15\n\
BankPorts:bank6.ru:21,22,23,24,25,26,27,28,29,210,211,212,213,214,215\n\
ClientBanks:192.168.9.0/16:smtp.mail.ru,pop.mail.ru,10.24.70.0/26\n\
ClientBanks:192.168.9.8:bank4.ru,bank5.ru,bank6.ru\n\
ClientBanks:192.168.9.6:bank6.ru,bank4.ru\n\
"|\
awk -v itls=$itls -F: '{
if($0~/^BankPorts/) BankPorts[$2]=$3 #создаем ассоциативный массив - индекс:банк, значение:порты через запятую
if($0~/^ClientBanks/) ClientBanks[$2]=$3 #аналогично клиент -> банки
}END{
#Cгенерируем _необходимые_ правила для цепочки CLIENTBANK
for (client in ClientBanks){
split(ClientBanks[client],bank_arr,",") #поместили в массив bank_arr адреса банков для клиента
for(i in bank_arr){
all_ports=all_ports","BankPorts[bank_arr[i]] #создаем список всех портов для дальнейшего использования
count_ports=split(BankPorts[bank_arr[i]],tmp_arr,",")
if(count_ports > 15)
print "echo Слишком много портов для "bank_arr[i]".Допиши программу.Выход&&exit 1"
else
printf("%s -A CLIENTBANK -s %s -d %s -p tcp -m multiport --dports %s -j ACCEPT\n",itls,client,bank_arr[i],BankPorts[bank_arr[i]])
}
}
#Создадим правила перенаправляющие из FORWARD на обработку в CLIENTBANK, помня
про ограничение в 15 портов
sub(",","",all_ports) #отрезаем первую запятую у списка всех использующихся портов
split(all_ports,all_ports_arr,",")#поместили в массив all_ports_arr все порты какие есть
j=1;i=1
while(all_ports_arr[i]){
while(i<=(j*15)){
if (all_ports_arr[i])
tmp_all_ports=tmp_all_ports","all_ports_arr[i]
i++
}
sub(",","",tmp_all_ports) #отрезаем первую запятую
printf("%s -I FORWARD -p tcp -m multiport --ports %s -j CLIENTBANK\n",itls,tmp_all_ports)
tmp_all_ports=""
j++
}
print itls" -A CLIENTBANK -p tcp -m state --state ESTABLISHED -j ACCEPT"
print itls" -N CLIENTBANK"
print itls" -X CLIENTBANK"
print itls" -F CLIENTBANK"
#Удаляем из FORWARD все цепочки содержащие цель CLIENTBANK
del_rules_nums="'`$itls --line-numbers -L FORWARD -n|grep CLIENTBANK|cut -f1 -d" "|tr "\n" ","`'"
split(del_rules_nums,del_rules_arr,",")
cnt_rules=1
while(del_rules_arr[cnt_rules]){
printf("%s -D FORWARD %s\n",itls,del_rules_arr[cnt_rules])
cnt_rules++
}
}'|tac > gen.itls.sh
chmod 700 gen.itls.sh
echo "Команды сгенерированы в файл ./gen.itls.sh .Выход."
exit
./gen.itls.sh
rm ./gen.itls.sh
|