iptables przekierowuje zewnętrzne żądania do 127.0.0.1

41

Mam usługę działającą na 127.0.0.1 z portem 2222. Muszę przekazywać wszystkie żądania do 192.168.2.2:2222 (poza IP) tylko z podsieci 192.168.1.0/24 do 127.0.0.1:2222.

Próbuję tego użyć, ale to nie działa.

$ iptables -t nat -I PREROUTING -p tcp -d 192.168.1.0/24 --dport 2222 -j DNAT --to-destination 127.0.0.1:2222

Jak mogę to uruchomić?

UPD: Edytuj schemat adresów.

SimWhite
źródło
Potrzebujemy wyjaśnienia. Skąd pochodzi ruch? Gdzie pierwotnie zmierza ruch? Dokąd powinien zmierzać ruch? Jak czytam, chcesz, aby ruch z 192.168.1.0/24 do 127.0.0.1:2222 był przekierowywany do 12.23.34.45:2222. Ale odpowiedź Warrena zakłada, że ​​chcesz, aby ruch z 192.168.1.0/24 na 12.23.34.45:2222 został przekierowany na 127.0.0.1:222
Patrick
1
Ruch pochodzi z podsieci 192.168.1.0/24 do 192.168.2.2:2222 i powinien zostać przetłumaczony na serwis w wersji 127.0.0.1:2222. Poprawiony schemat adresów.
SimWhite
1
Chcesz regułę, która zezwala na ruch do portu 2222na interfejsie sprzężenia zwrotnego z podsieci 192.168.1.0/24? To nie jest tylko jeden typ konfiguracji reguł. Zobacz tutaj: debuntu.org/…
slm
Tak. Jak rozumiem, muszę dodać regułę maskowania? Oczywiście przekazywanie IP jest już włączone.
SimWhite
Dlaczego nie uruchomić go na „prawdziwym” adresie IP i odfiltrować ruch pochodzący z niechcianych źródeł? Do tego właśnie służą zapory ogniowe ...
vonbrand

Odpowiedzi:

60

Używana reguła iptables będzie działać, ale musisz wprowadzić jedną dodatkową zmianę:

sysctl -w net.ipv4.conf.eth0.route_localnet=1

(zamiana eth0na nic 192.168.2.2pozostaje włączona)

Domyślnie ta wartość wynosi 0, która instruuje jądro, aby nie kierowało ruchu zewnętrznego przeznaczonego do 127.0.0.0/8. Ma to na celu bezpieczeństwo, ponieważ taki ruch nie jest normalny.


Uwaga dodatkowa: twoja obecna reguła iptables jest zbyt szeroka. Reguła określa -d 192.168.1.0/24 --dport 2222jako dopasowanie docelowe, co oznacza, że ​​jeśli twój komputer spróbuje porozmawiać z innym hostem na porcie 2222 (tj. Ruch wychodzący), zostanie również przekierowany. Musisz albo zmienić -ddopasowanie -d 192.168.2.2, albo dodać -i eth0(lub cokolwiek, co jest twoje nic).

Patrick
źródło
8
Te informacje są zaskakująco trudne do znalezienia.
Wren T.
Tak, bardzo cenne, trudne do znalezienia informacje! Dziękuję Ci! Ale ja nie mam route_localnet. Czy były na to inne nazwy? (w systemie Linux 2.6.30) ls /proc/sys/net/ipv4/conf/lan/: accept_redirects arp_accept arp_filter arp_notify disable_policy force_igmp_version log_martians medium_id proxy_arp secure_redirects shared_media accept_source_route arp_announce arp_ignore bootp_relay disable_xfrm spedycja mc_forwarding promote_secondaries rp_filter send_redirects tag
IMZ - Ivan Zakharyaschev
Widzę, że łatkaroute_localnet jest nowsza (7 czerwca 2012 r.) Niż moje jądro (2.6.30-std-def-alt15 # 1 SMP Mon Dec 14 08:45:48 UTC 2009). Ok, po prostu osiągnę pożądane przekierowanie portów (z zewnątrz do wewnątrz) z procesem przekierowania, takim jak netcat( nc) xinetd, lub opcje przekierowania portów ssh(to drugie jest nieskuteczne i głupie, oczywiście, ale wspominam o tym, ponieważ, no cóż, istnieje taka możliwość).
imz - Ivan Zachharyaschev
2
Moje 2 centy: możesz włączyć ten parametr dla wszystkich interfejsów zsysctl -w net.ipv4.conf.all.route_localnet=1
Dmitriusan
Podobnie jak inni, informacje te były trudne do zdobycia. Dzięki, gdybym to wcześniej znalazł, zaoszczędziłbym mnóstwo wysiłku.
Stephen Simpson
3

Możesz przekierowywać na localhost, ale nie do pętli zwrotnej (127.0.0.0/8). Loopback to luka. Musisz przekierować do jednego ze swoich prawdziwych interfejsów. Spróbuj użyć opcji REDIRECT.

iptables -t nat -A PREROUTING ..... -j REDIRECT --to-port 222

dresende
źródło
To chyba najlepsza odpowiedź bez sysctl voodo ...
Lester Cheung
Nadal nie pomaga, jeśli port 222 jest nasłuchiwany tylko na hoście lokalnym (reguła nie zmieni adresu docelowego)
sanmai
W takim przypadku użyj-j DNAT --to-destination w.x.y.z:222
dresende
2

Co jeśli poprawna odpowiedź z route_localnetnie działa? ..

Jeśli twoje jądro nie zawiera łatkiroute_localnet , to ... zaktualizuj jądro!

Lub istnieją inne sposoby przekazywania ruchu przychodzącego do jednego interfejsu do innego portu w innym interfejsie (w szczególności do hosta lokalnego) poprzez uruchomienie procesu, który nasłuchiwałby na interfejsie zewnętrznym i przekazywał ruch.

netcat( nc) xinetdi ssh(i być może więcej) to przykłady programów, które potrafią to zrobić (chociaż wybór sshbyłby dziwny i nieskuteczny).

Napisałem xinetddla tego konfigurację . Teraz ta usługa jest automatycznie wywoływana:

# cat /etc/xinetd.d/z-from-outside 
# default: off
# description: Forward connections to the z port.
service z-from-outside
{
    disable         = no
    socket_type     = stream
    type        = UNLISTED
    wait            = no
    user            = nobody
    bind        = vaio.ob
    port        = 7070
    redirect    = localhost 7070
}
# 

( vaio.obto nazwa tego hosta w interfejsie sieci zewnętrznej).

Po a service xinetd reloadsprawdźmy, czy nasłuchuje:

# lsof -i -P | fgrep 7070
xinetd    556      root    6u  IPv4 1797906      0t0  TCP vaio.ob:7070 (LISTEN)
sshd    27438 tun_zzoom    4u  IPv4 1059100      0t0  TCP localhost.localdomain:7070 (LISTEN)
# 

I rzeczywiście, połączenia przechodzą!

imz - Ivan Zakharyaschev
źródło