Маршрутизация по доменным именам — ipset + mangle + route rule
Данная реализация может помочь роутить не весь трафик, а только определенные сайты
Суть схемы в следующем:
- Создается отдельная routing table;
- Задается необходимый домен;
- Производится резолв dns имени средствами dig (должен быть установлен в системе);
- Полученный ip или список ip заносится в ipset соответствующий домену;
- Добавляется default маршрут в отдельную таблицу маршрутизации через требуемый шлюз;
- Добавляется правило для маршрутизации маркированного трафика.
На принимающей машине (если linux) нужно активировать forwarding, настроить маскарад приходящий пакетов с клиента и уходящих на внешний интерфейс. Также нужны маршруты в подсеть, с которой приходят пакеты
Пример.
Forwarding:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
Masquerade (можно использовать в скрипте /etc/ppp/ip-up):
iptables -t nat -I POSTROUTING -s 10.0.0.0/8 -o enp41s0 -j MASQUERADE
Route (можно использовать в скрипте /etc/ppp/ip-up):
ip route add 10.0.0.0/8 dev ppp0
Добавляем в cron задание (при необходимости меняем пути и названия файлов):
crontab -e
*/1 * * * * /bin/bash /root/./update-ipset.sh
Создаем файл и делаем его исполняемым:
touch update-ipset.sh && chmod +x update-ipset.sh
Содержимое (скрипт автоматического резолва, добавления в ipset, создания правил mangle, маршрутов и правил маршрутизации):
Скрипт
#!/bin/bash
# здесь перечислить домены, без запятой
domain_list="domain.ru domain2.ru domain3.ru"
mark="2435"
table="vpnrouting"
gate="10.4.175.253"
# создание таблицы маршрутизации
if [ $( cat /etc/iproute2/rt_tables | grep "252 '"$table"'" | wc -l ) -eq 0 ]; then
echo "252 '"$table"'" >> /etc/iproute2/rt_tables
fi
# перебор доменов и занесение ip в ipset + mangle
for domain in $domain_list
do
ip=$( dig +short $domain )
# проверка и при необходимости создание ipset
if ipset list $domain; then
echo "ipset '"$domain"' exist"
else
ipset create $domain hash:ip
fi
# занесение ip в ipset
for i in $ip
do
ipset add $domain $i
done
# лобавления правила mangle в iptables
if iptables -C PREROUTING -t mangle -m set --match-set $domain dst -j MARK --set-mark $mark; then
echo "rule '"$domain"' exist"
else
iptables -I PREROUTING -t mangle -m set --match-set $domain dst -j MARK --set-mark $mark
fi
done
# проверка стандартного маршрута в таблицу маршрутизации
if [ $( ip route show table $table default via $gate | wc -l ) -eq 0 ]; then
ip route add table $table default via $gate
fi
# проверка правила маршрутизации
if [ $( ip rule show prio 100 fwmark $mark lookup $table | wc -l ) -eq 0 ]; then
ip rule add prio 100 fwmark $mark lookup $table
fi