Несколько алиасов из одной подсети

При настраивании разного рода сервисов приходится сталкиваться с тем, что на одном интерфейсе, находится несколько алиасов. Всё бы ничего, но возникают вопросы: с каким src address будет уходить пакет?

Если алиасы из разных подсетей, то ответ сразу ясен. А если нет?

Linux

По дефолту берётся «первичный» адрес интерфейса, то есть тот, который не алиас. В нашем примере берётся адрес 10.5.6.114:

eth0      Link encap:Ethernet  HWaddr 08:00:27:e5:73:35  
          inet addr:10.5.6.114  Bcast:10.5.7.255  Mask:255.255.252.0
          inet6 addr: fe80::a00:27ff:fee5:7335/64 Scope:Link
eth0:1    Link encap:Ethernet  HWaddr 08:00:27:e5:73:35  
          inet addr:10.5.5.78  Bcast:10.5.7.255  Mask:255.255.252.0

Но это поведение можно изменить:

# ip route add <HOST|NET> dev <ALIAS_DEV> src <ALIAS_SRC_IP>

Пример:

# ip route add 10.5.5.6/32 dev eth0:1 src 10.5.5.78

Посмотрим, с каким src address будут уходить наши пакеты, в зависимости от dst address:

# ip route get 10.5.5.6
10.5.5.6 dev eth0 src 10.5.5.78
cache
# ip route get 10.5.5.55
10.5.5.55 dev eth0 src 10.5.6.114
cache ipid 0xd02c
# ip route get 10.5.5.56
10.5.5.56 dev eth0 src 10.5.6.114
cache

Solaris

Здесь существует параметр -setsrc в команде route:

# ipadm show-addr | grep 10.5.5.
net0/v4           static   ok           10.5.5.219/22
net0/new          static   ok           10.5.5.31/22
# route add -host 10.5.5.6 10.5.5.88 -setsrc 10.5.5.31
# route get 10.5.5.6
   route to: 10.5.5.6
destination: 10.5.5.6
       mask: 255.255.255.255
    gateway: 10.5.5.88
     setsrc: 10.5.5.31
  interface: net0
      flags: <UP,GATEWAY,HOST,DONE,STATIC,SETSRC>
 recvpipe  sendpipe  ssthresh    rtt,ms rttvar,ms  hopcount      mtu     expire
       0         0         0         0         0         0      1500         0 

При этом, вместо 10.5.5.88 может стоять любой доступный хост (но он должен быть обязательно), но не сам 10.5.5.31. Иначе команда будет ругаться

# route add -host 10.5.5.6 10.5.5.31 -setsrc 10.5.5.31
add host 10.5.5.6: gateway 10.5.5.31: Network is unreachable

FreeBSD

В старых версиях тоже был параметр -setsrc к команде route, но потом его убрали. Единственное решение — это использовать setfib. То есть обязательная пересборка ядра. О том, как это сделать, написано здесь. При этом, это справедливо для любого созданного интерфейса, а не только carp (то есть по сути, вы можете создать tun, gif, … интерфейс и проделать с ним всё то, что описано в статье). Зато для IPv6 можно заюзать недокументированный параметр deprecated (пример не мой, взят из сети):

# ifconfig gif0 inet6 2001:470:1f08:84f::2 2001:470:1f08:84f::1 prefixlen 128 deprecated
# ifconfig gif0
gif0: flags=8151<UP,POINTOPOINT,RUNNING,PROMISC,MULTICAST> metric 0 mtu 1280
        tunnel inet 31.193.132.199 --> 216.66.80.26
        inet6 fe80::be30:5bff:feda:b396%gif0 prefixlen 64 scopeid 0x7
        inet6 2001:470:1f09:84f::1 prefixlen 64
        inet6 2001:470:1f09:84f::2 prefixlen 64
        inet6 2001:470:1f09:84f:: prefixlen 64
        inet6 2001:470:1f09:84f::3 prefixlen 64
        inet6 2001:470:1f09:84f::5e4c:dad4 prefixlen 64
        inet6 2001:470:1f09:84f::5e4c:dad5 prefixlen 64
        inet6 2001:470:1f09:84f::1fc1:84c7 prefixlen 64
        inet6 2001:470:1f08:84f::2 --> 2001:470:1f08:84f::1 prefixlen 128 deprecated
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        options=1<ACCEPT_REV_ETHIP_VER>
# ping6 home.b0rken.org
PING6(56=40+8+8 bytes) 2001:470:1f09:84f::1 --> 2001:470:1f08:84e::2

OpenBSD

Для Openbsd решения мне не удалось найти.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *