Dwa interfejsy sieciowe i dwa adresy IP w tej samej podsieci w systemie Linux

22

Niedawno spotkałem się z sytuacją, w której potrzebowałem dwóch adresów IP w tej samej podsieci przypisanych do jednego hosta Linux, abyśmy mogli uruchomić dwie witryny SSL / TLS. Moje pierwsze podejście polegało na użyciu aliasingu IP, np. Eth0: 0, eth0: 1 itd., Ale nasi administratorzy sieci mają pewne dość surowe ustawienia bezpieczeństwa, które zniweczyły ten pomysł:

  1. Używają szpiegowania DHCP i zwykle nie zezwalają na statyczne adresy IP. Adresowanie statyczne odbywa się za pomocą statycznych wpisów DHCP, więc ten sam adres MAC zawsze otrzymuje to samo przypisanie IP. Tę funkcję można wyłączyć dla poszczególnych portów przełączania, jeśli o to poprosisz i masz ku temu powód (na szczęście mam dobre relacje z ludźmi z sieci i nie jest to trudne).
  2. Przy wyłączonym szpiegowaniu DHCP w portach przełączania musieli oni wprowadzić w regule regułę, że wspomniany adres MAC X może mieć adres IP Y. Niestety, to miało efekt uboczny, mówiąc, że adres MAC X może mieć TYLKO Adres IP Y. Aliasowanie IP wymagało, aby adresowi MAC X przypisano dwa adresy IP, więc to nie działało.

Być może istniało rozwiązanie tych problemów w konfiguracji przełącznika, ale próbując zachować dobre relacje z administratorami sieci, próbowałem znaleźć inny sposób. Posiadanie dwóch interfejsów sieciowych wydawało się kolejnym logicznym krokiem. Na szczęście ten system Linux jest maszyną wirtualną, więc mogłem łatwo dodać drugi interfejs sieciowy (bez ponownego uruchamiania, dodam - całkiem fajnie). Kilka naciśnięć klawiszy później miałem dwa uruchomione interfejsy sieciowe i oba pobierałem adresy IP z DHCP.

Ale potem pojawił się problem: administratorzy sieci mogli zobaczyć (na przełączniku) pozycję ARP dla obu interfejsów, ale tylko pierwszy interfejs sieciowy, który podniosłem, zareagowałby na pingi lub jakikolwiek ruch TCP lub UDP.

Po wielu kopaniach i szturchaniu, oto co wymyśliłem. Wygląda na to, że działa, ale wydaje się również, że jest to dużo pracy dla czegoś, co wydaje się proste. Jakieś alternatywne pomysły?


Krok 1: Włącz filtrowanie ARP na wszystkich interfejsach:

# sysctl -w net.ipv4.conf.all.arp_filter=1
# echo "net.ipv4.conf.all.arp_filter = 1" >> /etc/sysctl.conf

Z pliku networking / ip-sysctl.txt w dokumentacji jądra Linux:

arp_filter - BOOLEAN
    1 - Allows you to have multiple network interfaces on the same
    subnet, and have the ARPs for each interface be answered
    based on whether or not the kernel would route a packet from
    the ARP'd IP out that interface (therefore you must use source
    based routing for this to work). In other words it allows control
    of which cards (usually 1) will respond to an arp request.

    0 - (default) The kernel can respond to arp requests with addresses
    from other interfaces. This may seem wrong but it usually makes
    sense, because it increases the chance of successful communication.
    IP addresses are owned by the complete host on Linux, not by
    particular interfaces. Only for more complex setups like load-
    balancing, does this behaviour cause problems.

    arp_filter for the interface will be enabled if at least one of
    conf/{all,interface}/arp_filter is set to TRUE,
    it will be disabled otherwise

Krok 2: Zaimplementuj routing oparty na źródłach

Zasadniczo po prostu postępowałem zgodnie ze wskazówkami z http://lartc.org/howto/lartc.rpdb.multiple-links.html , chociaż ta strona została napisana z myślą o innym celu (obsługa dwóch dostawców usług internetowych).

Załóżmy, że podsieć to 10.0.0.0/24, brama to 10.0.0.1, adres IP dla eth0 to 10.0.0.100, a adres IP dla eth1 to 10.0.0.101.

Zdefiniuj dwie nowe tabele routingu o nazwach eth0 i eth1 w / etc / iproute2 / rt_tables:

... top of file omitted ...
1    eth0
2    eth1

Zdefiniuj trasy dla tych dwóch tabel:

# ip route add default via 10.0.0.1 table eth0
# ip route add default via 10.0.0.1 table eth1
# ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
# ip route add 10.0.0.0/24 dev eth1 src 10.0.0.101 table eth1

Zdefiniuj reguły, kiedy należy używać nowych tabel routingu:

# ip rule add from 10.0.0.100 table eth0
# ip rule add from 10.0.0.101 table eth1

Główna tabela routingu była już obsługiwana przez DHCP (i nie jest nawet jasne, że jest to absolutnie konieczne w tym przypadku), ale w zasadzie to odpowiada:

# ip route add default via 10.0.0.1 dev eth0
# ip route add 130.127.48.0/23 dev eth0 src 10.0.0.100
# ip route add 130.127.48.0/23 dev eth1 src 10.0.0.101

I voila! Wszystko wydaje się działać dobrze. Wysyłanie pingów na oba adresy IP działa dobrze. Wysyłanie pingów z tego systemu do innych systemów i wymuszanie pingowania przy użyciu określonego interfejsu działa poprawnie ( ping -I eth0 10.0.0.1, ping -I eth1 10.0.0.1). Co najważniejsze, cały ruch TCP i UDP do / z dowolnego adresu IP działa zgodnie z oczekiwaniami.


Ponownie moje pytanie brzmi: czy jest na to lepszy sposób? Wydaje się, że to dużo pracy dla pozornie prostego problemu.


Aktualizacja: powyższe rozwiązanie okazało się niekompletne. Wszystko działało dobrze, jeśli ruch utrzymywał się w tej samej podsieci, ale komunikacja z innymi podsieciami przy użyciu drugiego interfejsu nie działałaby poprawnie. Zamiast kopać większą dziurę, skończyłem rozmawiać z administratorami sieci i poprosiłem ich, aby zezwalali na wiele adresów IP dla jednego interfejsu i użyli aliasingu IP (np. Eth0 i eth0: 0).

Scott Duckworth
źródło
Kluczową różnicą do zapamiętania jest to, że adres IP nie należy do interfejsu, należy do komputera. Prawidłowe jest więc wysyłanie dowolnego interfejsu dla dowolnego adresu IP w tej konfiguracji, dlatego też nie jest to konieczne.
MikeyB
Uważam, że routing źródła nie jest w tym przypadku konieczny, ponieważ filtrowanie arp powinno być stosowane tylko wtedy, gdy przełącznik wysyła do interfejsu / musi znaleźć go wśród swoich portów. Mogę się mylić, ale kiedy maszyna wysyła dane w kierunku przełącznika, adres IP w polu źródłowym (nagłówek IP) nie jest sprawdzany, tylko arp wysyła pakiet.
AndreasM
MikeyB ma rację, jedynym sposobem jest routing źródła. Urządzenie może wybrać dowolny interfejs wychodzący, który chce wysyłać ruch, o ile znajduje się w tej samej podsieci. Nie ma znaczenia, czy adres IP naprawdę nie znajduje się w tym interfejsie, czy nie.
Patrick
2
AndreasM: Przychodzące pakiety nie stanowią problemu, problem stanowią wychodzące pakiety. Bez routingu źródłowego wszystkie wychodzące pakiety będą korzystać z domyślnej trasy, która jest powiązana z jednym lub drugim interfejsem. Mimo że wychodzące pakiety będą miały poprawny źródłowy adres IP, filtry na przełączniku nie pozwolą im wyjść, ponieważ ten adres IP nie należy do adresu MAC tego interfejsu. Dla przełącznika wygląda to tak, jakby klient próbuje sfałszować adres IP innego klienta. (Są to inteligentne przełączniki warstwy 3).
Scott Duckworth,
Aliasy IP są przestarzałe i hack, nie odzwierciedlają rzeczywistości, nie wspominając już o tym, że usunięcie podstawowego spowoduje usunięcie wszystkich aliasów. Użyj ipod, iproute2aby dodać więcej niż jeden adres do tego samego interfejsu.
pilona

Odpowiedzi:

8

Tak, lepszym sposobem jest zbudowanie odpowiedniego uzasadnienia biznesowego i rozluźnienie reguł na przełącznikach, aby można było mieć wiele adresów IP na jednej karcie sieciowej.

Zypher
źródło