port forwarding ke aplikasi di namespace jaringan dengan vpn

13

Saya dapat mengatur namespace jaringan, membuat terowongan dengan openvpn dan memulai aplikasi yang menggunakan terowongan ini di dalam namespace. Sejauh ini bagus, tetapi aplikasi ini dapat diakses melalui antarmuka web dan saya tidak tahu cara merutekan permintaan ke antarmuka web di dalam LAN saya.

Saya mengikuti panduan dari @schnouki yang menjelaskan cara mengatur namespace jaringan dan menjalankan OpenVPN di dalamnya

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

Setelah itu, saya dapat memeriksa ip eksternal saya dan mendapatkan hasil yang berbeda di dalam dan di luar namespace, seperti yang dimaksudkan:

curl -s ipv4.icanhazip.com
<my-isp-ip>
ip netns exec myvpn curl -s ipv4.icanhazip.com
<my-vpn-ip>

Aplikasi dimulai, saya menggunakan banjir untuk contoh ini. Saya mencoba beberapa aplikasi dengan antarmuka web untuk memastikan itu bukan masalah khusus banjir.

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

Saya dapat mengakses antarmuka web pada port 8112 dari dalam namespace dan dari luar jika saya menentukan 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

Tapi saya ingin mengarahkan port 8112 dari server saya ke aplikasi di namespace. Tujuannya adalah untuk membuka browser pada komputer di dalam LAN saya dan mendapatkan antarmuka web dengan http: // my-server-ip: 8112 (my-server-ip menjadi ip statis dari server yang membuat antarmuka jaringan)

EDIT: Saya menghapus upaya saya untuk membuat aturan iptables. Apa yang saya coba lakukan dijelaskan di atas dan perintah berikut harus menghasilkan 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

Saya mencoba aturan DNAT dan SNAT dan melemparkan MASQUERADE untuk ukuran yang baik, tetapi karena saya tidak tahu apa yang saya lakukan, usaha saya sia-sia. Mungkin seseorang dapat membantu saya menyusun konstruksi ini.

EDIT: Output tcpdump dari tcpdump -nn -q tcp port 8112. Tidak mengherankan, perintah pertama mengembalikan HTTP 200 dan perintah kedua berakhir dengan koneksi yang ditolak.

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

EDIT: @schnouki sendiri menunjuk saya ke artikel Administrasi Debian yang menjelaskan proksi TCP iptables generik . Diterapkan pada masalah yang dihadapi, skrip mereka akan terlihat seperti ini:

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

Sayangnya, lalu lintas antara antarmuka veth disita dan tidak ada lagi yang terjadi. Namun, @schnouki juga menyarankan penggunaan socatsebagai proksi TCP dan ini berfungsi dengan baik.

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

Saya belum mengerti port aneh yang bergerak sambil lalu lintas melintasi antarmuka veth, tetapi masalah saya terpecahkan sekarang.

pskiebe
sumber
Penafian: Saya sama sekali tidak memiliki pengalaman dengan vethperangkat (menemukan ini sangat menarik, ... ;-)). Sudahkah Anda terbiasa tcpdumpmemeriksa sejauh mana paket yang masuk? Jika tcpdump -i veth0tidak menunjukkan apa-apa maka tcpdumo -i lomungkin diperlukan.
Hauke ​​Laging
Saya menambahkan output non-verbose dari tcpdump
pskiebe

Jawaban:

8

Saya selalu memiliki masalah dengan pengalihan iptables (mungkin kesalahan saya, saya cukup yakin itu bisa dilakukan). Tetapi untuk kasus seperti milik Anda, IMO lebih mudah melakukannya di tanah pengguna tanpa iptables.

Pada dasarnya, Anda perlu memiliki daemon di ruang kerja "default" Anda mendengarkan pada port TCP 8112 dan mengarahkan semua lalu lintas ke port 10.200.200.2 port 8112. Jadi ini adalah proksi TCP sederhana.

Inilah cara melakukannya dengan socat :

socat tcp-listen:8112,reuseaddr,fork tcp-connect:10.200.200.2:8112

( forkOpsi diperlukan untuk menghindari socatberhenti setelah koneksi proksi pertama ditutup).

EDIT : ditambahkan reuseaddrseperti yang disarankan dalam komentar.

Jika Anda benar-benar ingin melakukannya dengan iptables, ada panduan tentang Administrasi Debian situs . Tapi saya masih lebih suka socatuntuk hal-hal yang lebih maju - seperti proksi IPv4 ke IPv6, atau menanggalkan SSL untuk memungkinkan program Java lama untuk terhubung ke layanan aman ...

Namun berhati-hatilah bahwa semua koneksi di Deluge akan berasal dari IP server Anda, bukan IP klien sebenarnya. Jika Anda ingin menghindarinya, Anda harus menggunakan proxy reverse HTTP asli yang menambahkan IP klien asli ke permintaan yang diproksi di header HTTP.

Schnouki
sumber
1
Kau mencerahkan hariku! Saya tidak pernah menemukan socatdan mencapai persis apa yang saya coba lakukan dengan iptables untuk beberapa waktu sekarang. Saya menguji beberapa aplikasi dan semuanya bekerja dengan sempurna, terhubung ke dunia luar melalui tun0, sambil tetap menyediakan akses ke antarmuka web mereka melalui veth1.
pskiebe
1
Setelah melakukan beberapa pengujian, saya menambahkan reuseaddrbenderanya. Ini mencegah port already in usekesalahan saat memulai dan menghentikan socat secara berurutan:socat -4 TCP-LISTEN:8112,reuseaddr,fork TCP:10.200.200.2:8112
pskiebe
7

Menghubungkan namespace jaringan dengan namespace utama selalu mengganggu saya. Alasan saya biasanya membuat namespace adalah karena saya ingin itu terisolasi. Tergantung pada apa yang ingin Anda capai dengan ruang nama yang menciptakan interkoneksi dapat mengalahkan tujuan itu.

Tetapi bahkan terisolasi saya masih ingin menyodoknya melalui jaringan, untuk kenyamanan.

Solusi ini memungkinkan Anda menjaga isolasi dan meneruskan beberapa koneksi ke sana. Anda tidak perlu membuat semua jaringan antara dua ruang nama jaringan hanya untuk meneruskan satu port. Jalankan ini di namespace tempat Anda ingin menerima koneksi. Harus dijalankan sebagai root untuk ip netns execbekerja.

socat tcp-listen:8112,fork,reuseaddr \
  exec:'ip netns exec myvpn socat STDIO tcp-connect\:127.0.0.1\:8112',nofork

Ia mendengarkan koneksi di satu namespace jaringan di mana Anda menjalankannya, pada port 8112, kemudian klien yang terhubung execdapat menjalankan ip netns exec myvpn ...untuk mengeksekusi sisanya di dalam myvpnnamespace jaringan, kemudian sekali di dalam myvpnnamespace jaringan itu membuat koneksi kedua lagi dengan yang lain socat.

AnyDev
sumber
bekerja seperti daya tarik
kurang lebih
Karena saya tidak terlalu berpengalaman dengan administrasi linux dan saya perlu waktu untuk mengetahuinya: pastikan untuk melepaskan kedua :karakter di dalam tanda kutip tunggal atau Anda mungkin mengalami kesalahan dalam mengatakan ... wrong number of parameters (2 instead of 1)(2 atau 3). Kalau tidak: bekerja dengan baik! Terima kasih banyak
Igor
2

Untuk banjir di sini adalah solusi saya. Tidak perlu iptables. Berikut langkah-langkahnya:

  1. Mulai terowongan openvpn Anda
  2. Buat namespace dan bawa terowongan openvpn Anda di sana:
ip netns menambahkan $ NS
# Tunggu TUN untuk muncul
while [[$ (ip route | grep $ TUN | wc -l) == 0]]; tidurlah 1; selesai
MY_IP = $ (ip addr show $ TUN | grep inet | cut -d '' -f6 | cut -d '/' -f1)
# Cara Anda mengekstrak IP gateway mungkin berbeda untuk koneksi openvpn Anda
GATEWAY_IP = $ MY_IP
# jail $ TUN saya (antarmuka VPN) ke namespace
tautan ip mengatur $ TUN menjaring $ NS
# Bawa antarmuka dengan subnet (setara dengan yang diberikan kepada saya oleh server VPN)
ip netns exec $ NS ifconfig $ TUN $ MY_IP / 24 up
# Bawa loopback ke atas
ip netns exec $ NS ifconfig lo 127.0.0.1/8 up
# Mengatur gateway jarak jauh (alamat IP VPN pointtopoint Anda)
ip netns exec $ NS route menambahkan default gw $ GATEWAY_IP
  1. Bangun koneksi dengan ruang nama default Anda dan yang Anda buat:
# Mengatur antarmuka veth untuk komunikasi antara ruang nama
ip link tambahkan veth0 ketik veth peer name veth1
# Pindahkan veth kedua ke namespace Anda
tautan ip mengatur veth1 netns $ NS
# berikan IP dari rentang IP yang tidak digunakan ke veth pertama
ifconfig veth0 10.1.1.1/24 up
# Dan yang kedua
ip netns exec $ NS ifconfig veth1 10.1.1.2/24 up
# TODO: mengatur jembatan antara antarmuka veth1 dan eth untuk membuatnya berkomunikasi dengan LAN
# Atur klien DNS. ip netns akan meniru /etc/resolv.conf menggunakan file ini:
mkdir -p / etc / netns / $ NS
echo "nameserver 8.8.4.4"> /etc/netns/$NS/resolv.conf
  1. Jalankan deluged Anda di $ NS dan web-banjir Anda di namespace default Anda. Arahkan deluge-web ke alamat IP 10.1.1.2 veth, di mana deluged akan mendengarkan koneksinya.

Voila! Anda telah diamankan di belakang VPN saat deluge-web Anda dapat diakses secara bebas di jaringan rumah Anda

Vlad
sumber
2

@ AndrDevEK jawaban berguna. Untuk memperluas itu, Anda mungkin tidak ingin menginstal socat. Dalam hal ini Anda dapat mencapai hal yang sama dengan pengaturan port-forward SSH yang sedikit berbelit-belit. Secara khusus fitur penerusan port ke / dari soket unix-domain berguna di sini, karena soket unix-domain beroperasi secara independen dari ruang nama jaringan:

sudo ip netns exec myvpn su -c "ssh -N -L /tmp/myunixsock:localhost:8112 localhost" $USER &
ssh_pid1=$!
ssh -N -L localhost:8112:/tmp/myunixsock localhost &
ssh_pid2=$!

Membersihkan:

sudo kill $ssh_pid1
kill $ssh_pid2
rm /tmp/myunixsock

Yang pertama ssh -N -Ldimulai dalam namespace myvpn. Ini menciptakan soket unix-domain /tmp/myunixsockdan mendengarkannya. Koneksi masuk diteruskan ke localhost: 8112 (di dalam namespace myvpn). Yang kedua ssh -N -Ldimulai di namespace default. Ini menciptakan port TCP yang mendengarkan dan meneruskan koneksi yang masuk ke soket unix-domain.

Perlu dicatat bahwa agar ini berfungsi, sshdi dalam namespace jaringan Anda harus berfungsi jika belum (dan operasi pubkey tanpa kata sandi sangat membantu):

sudo ip netns exec myvpn ip link set up dev lo
sudo ip netns exec myvpn /usr/sbin/sshd -o PidFile=/run/sshd-myvpn.pid
ssh-copy-id localhost
Trauma Digital
sumber