Маршрут по умолчанию
Материал из Xgu.ru
- Автор: Игорь Чубин
- Короткий URL: default_gateway
Содержание |
[править] Маршрут по умолчанию в Linux
[править] Просмотр маршрута
Просмотреть таблицу маршрутизации в Linux можно множеством способов. Наиболее распространённые это: использовать программы netstat, route или ip.
%$ netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 192.168.80.0 192.168.1.196 255.255.255.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.1.198 0.0.0.0 UG 0 0 0 eth0
%$ /sbin/route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.80.0 192.168.1.196 255.255.255.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.1.198 0.0.0.0 UG 0 0 0 eth0
%$ ip r 192.168.80.0/24 via 192.168.1.196 dev eth0 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.197 default via 192.168.1.198 dev eth0
Во втором случае (/sbin/route)
использовался полный путь, поскольку программа вызывалась от имени пользователя,
у которого по умолчанию каталог /sbin/ не просматривается в поисках
исполняемых программ (переменная PATH).
Ключ -n в программах netstat и route говорит о том, что не нужно выполнять обратное преобразование IP-адресов и показывать вместо них DNS-имена.
Если нужна только запись о маршруте по умолчанию, вывод можно отфильтровать:
%# ip r | grep default
или
%# ip r l s global default via 192.168.1.198 dev eth0
или
%# ip ro sh 0.0.0.0/0 default via 192.168.1.198 dev eth0
и если нужен только IP-адрес:
%# ip r | awk '/default/{print $3}' 192.168.1.198
[править] Смена маршрута
[править] Маршрут по умолчанию в FreeBSD
route add default 192.168.37.2
[править] Маршрут по умолчанию в старых версиях FreeBSD
route add 0.0.0.0/0 192.168.37.2
[править] Просмотр маршрута
netstat -rn
[править] Смена маршрута
Процесс установки маршрута по умолчанию может выполнятся двумя способами:
1. Удалением записи о существующем маршруте(фиктивном), а далее добавлением записи о новом:
# route delete default # delete net default # route add default 192.168.137.2 # add net default: gateway 192.168.137.2 # defaultrouter="192.168.137.2"
2. Изменением маршрута:
# route change default 192.168.137.2
[править] Установка маршрута по умолчанию при запуске системы
В файле /etc/network/interfaces |
Пример:
allow-hotplug eth0 iface eth0 inet static address 192.168.137.11 netmask 255.255.255.0 network 192.168.137.0 broadcast 192.168.107.255 # Указывам шлюз по умолчанию для интерфейса eth0 gateway 192.168.137.2
В файле /etc/network/interfaces |
В файле /etc/conf.d/net |
В файле /etc/sysconfig/network |
В файле /etc/sysconfig/network/routes |
В переменной GATEWAY файла /etc/rc.d/rc.inet1.conf вручную или с помощью программы netconfig [1] |
В файле /etc/sysconfig/network |
ОС FreeBSD | |||||
---|---|---|---|---|---|
Печать | CUPS • IPP • LPR • LPD | ||||
Сеть | ipfw • NAT • mpd5 • squid • netgraph | ||||
| |||||
|
В файле /etc/net/ifaces/NAME/iproute |
[править] Автоматическая смена маршрута по умолчанию
[править] Задача
Есть два канала связи с Интернетом, через двух независимых провайдеров. Нужно сделать так, что бы как только Интернет становится недоступным через одно из соединений (не имеет значения из-за того что пропала связь с провайдером, или потому что проблемы у провайдера), автоматически менять маршрут по умолчанию и использовать другой канал.
[править] Решение
Использовать скрипт:
СКРИПТ
Имя скрипта: change_default_route
Путь: /usr/local/sbin/change_default_route
Назначение скрипта: Скрипт контролирует доступность удалённой точки ${REMOTE_SITE} через известные внешние каналы. Если связь через основной канал теряется, осуществляется переход на резервный канал. Как только удалённая точка становится видна через основной канал, скрипт возвращает шлюз по умолчанию на него.
#!/bin/sh GW_CONF=gateways GW_RUN=current-gateway REMOTE_SITE=10.0.3.3 OPENVPN_UPLINK_CONFIG=/etc/openvpn/server.conf read_gateways_from_files() { [ -f ${GW_CONF} ] && source ${GW_CONF} [ -f ${GW_CONF} ] || echo file ${GW_CONF} missing | logger -t $0 -p daemon.error GW=`cat ${GW_RUN} 2> /dev/null` } change_default_route() { if ip route show | grep -q default then if ip route show | grep default | grep -q tun then [ ${GW} == ${DEFAULTGW} ] && return route delete default gw "$GW" route add default gw "$NEWGW" && echo $NEWGW > ${GW_RUN} kill -1 `openvpn_uplink_pid` else [ -z "$GW" ] && GW=${DEFAULTGW} [ "$GW1" = "$GW" ] && NEWGW=$GW2 || NEWGW=$GW1 route delete default gw "$GW" route add default gw "$NEWGW" && echo $NEWGW > ${GW_RUN} fi else route add default gw "$DEFAULTGW" echo $DEFAULTGW > ${GW_RUN} fi echo "$1" | logger -t $0 -p daemon.info } while true do read_gateways_from_files ip route show | grep default | grep -q tun \ || ping -q -c 1 ${REMOTE_SITE} >& /dev/null \ || change_default_route "Connection via ${GW} lost. Changing to another gateway (GW1=$GW1; GW2=$GW2; GW was ${GW})" [ "${GW}" != "${DEFAULTGW}" -a "${GW}" == "${GW1}" ] \ && ping -q -c 1 -I "${IP2}" "${REMOTE_SITE}" >& /dev/null \ && change_default_route "Link via ${GW2} has restored. Changhing default gateway back (GW1=$GW1; GW2=$GW2; GW was ${GW}; now GW is ${GW2} )" [ "${GW}" != "${DEFAULTGW}" -a "${GW}" == "${GW2}" ] \ && ping -q -c 1 -I "${IP1}" "${REMOTE_SITE}" >& /dev/null \ && change_default_route "Link via ${GW1} has restored. Changhing default gateway back (GW1=$GW1; GW2=$GW2; GW was ${GW}; now GW is ${GW1} )" sleep 5 done
Скрипт может быть размещён /usr/local/bin/change_default_route
Скрипт должен вызываться автоматически при старте системы. Например, в /etc/rc.local:
nohup /usr/local/sbin/change_default_route &
или в /etc/network/interfaces
iface ... .... up nohup /usr/local/sbin/change_default_route &
Файл /etc/network/gateways должен содержать адреса шлюзов, а также указание какой из них должен использоваться по умолчанию:
#### ISP 1 IP1=10.0.1.1 GW1=10.0.1.2 #### ISP2 IP2=10.0.4.1 GW2=10.0.4.4 ### Let ISP1 be default DEFAULTGW=${GW1}
Если используется OpenVPN, при изменении маршрута скрипт находит и перестартовывает процесс (процессы) openvpn, который держит на один из адресов, указанных в конфигурационном файле OpenVPN OPENVPN_UPLINK_CONFIG в директиве remote.
Если нужна однократная проверка, например, при установке маршрута, для выбора того из них, который работает, используйте такой скрипт:
/usr/local/bin/change_default_route
#!/bin/sh change_default_route() { [ -f /etc/network/gateways ] && source /etc/network/gateways GW=`cat /var/run/current-gateway 2> /dev/null` [ -z "$GW" ] && GW=${DEFAULTGW} [ "$GW1" = "$GW" ] && NEWGW=$GW2 || NEWGW=$GW1 route delete default gw "$GW" && route add default gw "$NEWGW" && echo $NEWGW > /var/run/current-gateway } for i in 1 2; do ping -q -c 1 ya.ru || ping -q -c 1 google.com || change_default_route ; sleep 1; done
(ещё один вариант:)
IP1=192.168.201.2 IP2=192.168.211.2 GW1=192.168.201.1 GW2=192.168.211.1 while true do if ping -I $IP1 -c 1 10.0.35.1 >& /dev/null then ip route change default via $GW1 else ping -I $IP2 -c 1 10.0.35.1 >& /dev/null && ip route change deflt fi sleep 1 done
Автоматическая правка файла /etc/default/gateways выполняется при поднятии интерфейса с помощью скрипта:
# cat /etc/ppp/ip-up.d/eb_up #!/bin/sh case $1 in ppp200) /bin/ip rule add from $4 lookup 3 /bin/ip route add default via $5 table 3 /usr/bin/perl -i -p -e 's/GW1=.*/GW1='"$5"/ /etc/network/gateways /usr/bin/perl -i -p -e 's/IP1=.*/IP1='"$4"/ /etc/network/gateways ;; esac exit 0
[править] Одновременное использование нескольких внешних каналов
[править] Задача
Есть два канала связи с Интернетом, через двух независимых провайдеров. Нужно сделать так, чтобы если происходит обращение через интерфейс 1, ответы должны уходить тоже через интерфейс 1 и с обратным адресом интерфейса 1.
[править] Решение
Настроить и использовать policy routing.
Например для шлюзов GW1 и GW2, которые описываются в /etc/network/gateways:
. /etc/network/gateways ip rule add from $IP1 lookup 2 ip rule add from $IP2 lookup 3 ip route add default via $GW1 table 2 ip route add default via $GW2 table 3 ip route add default via $DEFAULTGW
|
При использовании дополнительных таблиц маршрутизации необходимо либо отключить reverse path filter echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter либо перевести его в менее строгий режим echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter mamahtehok |
|
Такая схема маршрутизации не будет правильно работать с iptables DNAT. Другими словами, если с помощью iptables/netfilter пробрасывать обращения на какие-то порты внутрь сети, принцип «ответы уходят по тому каналу, по которому приходят запросы» работать не будет. |
Как ни странно, проблема с iproute2 и DNAT в некоторых случаях может быть решена (SOLVED) простой парой команд:
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -p tcp --sport 80 -j MARK --set-mark 1
Таким образом мы можем вручную (через ip rule fwmark 1) указать необходимую таблицу. (N, 21:34, 27 августа 2009 (UTC))
Для решения проблем с трансляцией соединений внутрь сети,
необходимо использовать схему с промежуточным шлюзом:
GW1 GW2 * * | | IP1 | | IP2 [eth1] | | [eth2] +-------+ | | | gw | | | +-------+ 10.0.3.250 | 10.0.3.254 [eth0] | [eth0:1] | | 10.0.3.249 | 10.0.3.253 [eth1] | [eth1:1] +-------+ | | | pgw | | | +-------+ | 10.0.3.6 | [eth0] |
В этом случае:
- на шлюзе gw выполняется проброска на один из внутренних адресов, в зависимости от того, куда пришёл запрос;
- на шлюзе pgw выполняется дальнейшая проброска внутрь сети.
Подобное решение описывается здесь [2].
[править] Дополнительная информация
- Policy Routing With Linux (англ.)
- Маршрутизация через несколько каналов/провайдеров (рус.) - Информация, раскладывающая всё "по полочкам" в кратком виде. Весьма полезно.
- Blackhole - маршрутизация "в никуда" в UNIX
|
---|