Byłem w stanie skonfigurować sieciową przestrzeń nazw, założyć tunel z openvpn i uruchomić aplikację, która korzysta z tego tunelu w przestrzeni nazw. Do tej pory było dobrze, ale do tej aplikacji można uzyskać dostęp za pośrednictwem interfejsu sieciowego i nie mam pojęcia, jak kierować żądania do interfejsu internetowego w mojej sieci LAN.
Postępowałem zgodnie z instrukcjami z @schnouki wyjaśniającymi, jak skonfigurować sieć nazw i uruchomić w niej OpenVPN
ip netns add myvpn
ip netns exec myvpn ip addr add 127.0.0.1/8 dev lo
ip netns exec myvpn ip link set lo up
ip link add vpn0 type veth peer name vpn1
ip link set vpn0 up
ip link set vpn1 netns myvpn up
ip addr add 10.200.200.1/24 dev vpn0
ip netns exec myvpn ip addr add 10.200.200.2/24 dev vpn1
ip netns exec myvpn ip route add default via 10.200.200.1 dev vpn1
iptables -A INPUT \! -i vpn0 -s 10.200.200.0/24 -j DROP
iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o en+ -j MASQUERADE
sysctl -q net.ipv4.ip_forward=1
mkdir -p /etc/netns/myvpn
echo 'nameserver 8.8.8.8' > /etc/netns/myvpn/resolv.conf
Następnie mogę sprawdzić mój zewnętrzny adres IP i uzyskać różne wyniki wewnątrz i na zewnątrz przestrzeni nazw, zgodnie z przeznaczeniem:
curl -s ipv4.icanhazip.com
<my-isp-ip>
ip netns exec myvpn curl -s ipv4.icanhazip.com
<my-vpn-ip>
Aplikacja została uruchomiona, używam potopu w tym przykładzie. Wypróbowałem kilka aplikacji z interfejsem internetowym, aby upewnić się, że nie jest to problem specyficzny dla potopu.
ip netns exec myvpn sudo -u <my-user> /usr/bin/deluged
ip netns exec myvpn sudo -u <my-user> /usr/bin/deluge-web -f
ps $(ip netns pids myvpn)
PID TTY STAT TIME COMMAND
1468 ? Ss 0:13 openvpn --config /etc/openvpn/myvpn/myvpn.conf
9302 ? Sl 10:10 /usr/bin/python /usr/bin/deluged
9707 ? S 0:37 /usr/bin/python /usr/bin/deluge-web -f
Jestem w stanie uzyskać dostęp do interfejsu sieciowego na porcie 8112 z przestrzeni nazw i z zewnątrz, jeśli podam ip veth vpn1.
ip netns exec myvpn curl -Is localhost:8112 | head -1
HTTP/1.1 200 OK
ip netns exec myvpn curl -Is 10.200.200.2:8112 | head -1
HTTP/1.1 200 OK
curl -Is 10.200.200.2:8112 | head -1
HTTP/1.1 200 OK
Ale chcę przekierować port 8112 z mojego serwera do aplikacji w przestrzeni nazw. Celem jest otwarcie przeglądarki na komputerze w mojej sieci LAN i uzyskanie interfejsu sieciowego z adresem http: // my-server-ip: 8112 (my-server-ip jest statycznym ip serwera, który utworzył instancję interfejsu sieciowego)
EDYCJA: Usunąłem moje próby tworzenia reguł iptables. To, co próbuję zrobić, zostało wyjaśnione powyżej, a następujące polecenia powinny wypisać HTTP 200:
curl -I localhost:8112
curl: (7) Failed to connect to localhost port 8112: Connection refused
curl -I <my-server-ip>:8112
curl: (7) Failed to connect to <my-server-ip> port 8112: Connection refused
Wypróbowałem reguły DNAT i SNAT i rzuciłem MASQUERADE na dobrą miarę, ale ponieważ nie wiem, co robię, moje próby są daremne. Być może ktoś może mi pomóc zmontować ten konstrukt.
EDYCJA: Wyjście tcpdump z tcpdump -nn -q tcp port 8112
. Nic dziwnego, że pierwsze polecenie zwraca HTTP 200, a drugie polecenie kończy się odrzuconym połączeniem.
curl -Is 10.200.200.2:8112 | head -1
listening on vpn0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 10.200.200.1.36208 > 10.200.200.2.8112: tcp 82
IP 10.200.200.2.8112 > 10.200.200.1.36208: tcp 145
curl -Is <my-server-ip>:8112 | head -1
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
IP <my-server-ip>.58228 > <my-server-ip>.8112: tcp 0
IP <my-server-ip>.8112 > <my-server-ip>.58228: tcp 0
EDYCJA: Sam @schnouki wskazał mi artykuł na temat administracji Debiana, wyjaśniający ogólne proxy TCP iptables . W przypadku danego problemu ich skrypt wyglądałby następująco:
YourIP=<my-server-ip>
YourPort=8112
TargetIP=10.200.200.2
TargetPort=8112
iptables -t nat -A PREROUTING --dst $YourIP -p tcp --dport $YourPort -j DNAT \
--to-destination $TargetIP:$TargetPort
iptables -t nat -A POSTROUTING -p tcp --dst $TargetIP --dport $TargetPort -j SNAT \
--to-source $YourIP
iptables -t nat -A OUTPUT --dst $YourIP -p tcp --dport $YourPort -j DNAT \
--to-destination $TargetIP:$TargetPort
Niestety ruch między interfejsami veth został przejęty i nic więcej się nie wydarzyło. Jednak @schnouki również zasugerowało użycie socat
jako proxy TCP i działa to doskonale.
curl -Is <my-server-ip>:8112 | head -1
IP 10.200.200.1.43384 > 10.200.200.2.8112: tcp 913
IP 10.200.200.2.8112 > 10.200.200.1.43384: tcp 1495
Muszę jeszcze zrozumieć dziwne tasowanie portów podczas ruchu przez interfejsy veth, ale mój problem został rozwiązany.
veth
urządzeniami (uważam to za bardzo interesujące ... ;-)). Czytcpdump
sprawdziłeś, jak daleko docierają pakiety przychodzące? Jeślitcpdump -i veth0
nic nie pokazuje,tcpdumo -i lo
może być konieczne.Odpowiedzi:
Zawsze miałem problemy z przekierowaniami iptables (prawdopodobnie moja wina, jestem prawie pewien, że jest to wykonalne). Ale w przypadku takim jak twój, IMO łatwiej zrobić to w krainie użytkowników bez iptables.
Zasadniczo musisz mieć demona w „domyślnym” obszarze roboczym nasłuchującym na porcie TCP 8112 i przekierowującym cały ruch do portu 10.200.200.2 8112. Jest to więc prosty serwer proxy TCP.
Oto jak to zrobić za pomocą socat :
(
fork
Opcja jest potrzebna, aby uniknąćsocat
zatrzymania po zamknięciu pierwszego połączenia proxy).EDYCJA : dodano
reuseaddr
zgodnie z sugestią w komentarzach.Jeśli absolutnie chcesz to zrobić za pomocą iptables, na stronie administracji Debiana znajduje się przewodnik . Ale nadal wolę
socat
bardziej zaawansowane rzeczy - takie jak proxy IPv4 do IPv6 lub usuwanie SSL, aby stare programy Java mogły łączyć się z bezpiecznymi usługami ...Uważaj jednak, że wszystkie połączenia w Potopie będą pochodzić z adresu IP twojego serwera zamiast rzeczywistego adresu IP klienta. Jeśli chcesz tego uniknąć, musisz użyć prawdziwego zwrotnego proxy HTTP, który dodaje oryginalny adres IP klienta do żądania proxy w nagłówku HTTP.
źródło
socat
i już od dłuższego czasu osiąga dokładnie to, co próbowałem zrobić z iptables. Przetestowałem kilka aplikacji i wszystkie one działają bezbłędnie, łącząc się ze światem zewnętrznym przez tun0, jednocześnie zapewniając dostęp do swojego interfejsu internetowego przez veth1.reuseaddr
flagę. Zapobiega toport already in use
błędom podczas szybkiego uruchamiania i zatrzymywania socat:socat -4 TCP-LISTEN:8112,reuseaddr,fork TCP:10.200.200.2:8112
Łączenie sieciowej przestrzeni nazw z główną przestrzenią nazw zawsze mi przeszkadza. Powodem, dla którego zwykle tworzę przestrzeń nazw, jest to, że chcę ją odizolować. W zależności od tego, co próbujesz osiągnąć dzięki przestrzeniom nazw, tworzenie połączeń może pokonać ten cel.
Ale nawet odizolowany, wciąż dla wygody chcę przeszukać sieć.
To rozwiązanie pozwala zachować izolację i przekazać niektóre połączenia z nią. Nie musisz tworzyć całej tej sieci między dwoma sieciowymi przestrzeniami nazw, aby przekierować jeden port. Uruchom to w przestrzeni nazw, w której chcesz akceptować połączenia. Aby działał, należy go uruchomić jako root
ip netns exec
.Nasłuchuje połączeń w jednej sieciowej przestrzeni nazw, w której go uruchomisz, na porcie 8112, a następnie podłączony klient
exec
uruchomi się,ip netns exec myvpn ...
aby wykonać resztę wmyvpn
sieciowej przestrzeni nazw, a następnie, gdy znajdzie się wmyvpn
sieciowej przestrzeni nazw, ponownie utworzy drugie połączenie z innymsocat
.źródło
:
znaków w cudzysłowie, bo możesz napotkać błąd... wrong number of parameters (2 instead of 1)
(2 lub 3). W przeciwnym razie: działa świetnie! Ogromne dziękuję!Dla potopu oto moje rozwiązanie. Nie ma potrzeby korzystania z iptables. Oto kroki:
Voila! Masz zabezpieczone za VPN, podczas gdy twoja sieć powodziowa jest swobodnie dostępna w sieci domowej
źródło
Odpowiedź @ AndrDevEK jest przydatna. Aby to rozwinąć, możesz nie chcieć instalować
socat
. W takim przypadku możesz osiągnąć to samo przy nieco zawiłej konfiguracji przekierowania portów SSH. W szczególności przydatna jest tutaj funkcja przekierowywania portów do / z gniazda domeny unix, ponieważ gniazda domeny unix działają niezależnie od sieciowych nazw:Sprzątać:
Pierwszy
ssh -N -L
jest uruchamiany w przestrzeni nazw myvpn. To tworzy gniazdo domeny unix/tmp/myunixsock
i nasłuchuje na nim. Połączenia przychodzące są przekazywane do localhost: 8112 (w przestrzeni nazw myvpn). Drugissh -N -L
jest uruchamiany w domyślnej przestrzeni nazw. Spowoduje to utworzenie nasłuchującego portu TCP i przekazywanie połączeń przychodzących do gniazda domeny unix.Należy zauważyć, że aby to zadziałało,
ssh
wewnątrz twojej sieciowej przestrzeni nazw będzie musiała działać, jeśli jeszcze nie jest (a operacja klucza publicznego bez hasła jest pomocna):źródło