chuyển tiếp cổng tới ứng dụng trong không gian tên mạng với vpn


13

Tôi đã có thể thiết lập một không gian tên mạng, thiết lập một đường hầm với openvpn và bắt đầu một ứng dụng sử dụng đường hầm này bên trong không gian tên. Cho đến nay rất tốt, nhưng ứng dụng này có thể được truy cập thông qua giao diện web và tôi không thể tìm ra cách định tuyến các yêu cầu đến giao diện web trong mạng LAN của mình.

Tôi đã làm theo hướng dẫn từ @schnouki giải thích cách thiết lập không gian tên mạng và chạy OpenVPN bên trong nó

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

Sau đó, tôi có thể kiểm tra ip bên ngoài của mình và nhận các kết quả khác nhau bên trong và bên ngoài không gian tên, đúng như dự định:

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

Ứng dụng được bắt đầu, tôi đang sử dụng deluge cho ví dụ này. Tôi đã thử một vài ứng dụng với giao diện web để đảm bảo đó không phải là vấn đề cụ thể.

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

Tôi có thể truy cập giao diện web trên cổng 8112 từ trong không gian tên và từ bên ngoài nếu tôi chỉ định ip của 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

Nhưng tôi muốn chuyển hướng cổng 8112 từ máy chủ của mình sang ứng dụng trong không gian tên. Mục tiêu là mở trình duyệt trên máy tính trong mạng LAN của tôi và nhận giao diện web với http: // my-server-ip: 8112 (my-server-ip là ip tĩnh của máy chủ khởi tạo giao diện mạng)

EDIT: Tôi đã loại bỏ các nỗ lực của mình để tạo quy tắc iptables. Những gì tôi đang cố gắng làm được giải thích ở trên và các lệnh sau sẽ tạo ra 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

Tôi đã thử các quy tắc DNAT và SNAT và ném vào một MẶT BẠC để có biện pháp tốt, nhưng vì tôi không biết mình đang làm gì, nên những nỗ lực của tôi là vô ích. Có lẽ ai đó có thể giúp tôi kết hợp công trình này.

EDIT: Sản lượng tcpdump của tcpdump -nn -q tcp port 8112. Không có gì đáng ngạc nhiên, lệnh đầu tiên trả về HTTP 200 và lệnh thứ hai chấm dứt với kết nối bị từ chối.

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: Chính @schnouki đã chỉ cho tôi một bài viết về Quản trị Debian giải thích một proxy TCP iptables chung . Áp dụng cho vấn đề hiện tại, kịch bản của họ sẽ như thế này:

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

Thật không may, lưu lượng giữa các giao diện veth bị thu giữ và không có gì khác xảy ra. Tuy nhiên, @schnouki cũng đề xuất sử dụng socatnhư một proxy TCP và điều này đang hoạt động hoàn hảo.

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

Tôi vẫn chưa hiểu được sự xáo trộn của cổng lạ trong khi lưu lượng truy cập đang đi qua các giao diện veth, nhưng vấn đề của tôi đã được giải quyết.


Tuyên bố miễn trừ trách nhiệm: Tôi hoàn toàn không có kinh nghiệm với vethcác thiết bị (mặc dù điều này rất thú vị, mặc dù ... ;-)). Bạn đã sử dụng tcpdumpđể kiểm tra các gói đến được bao xa? Nếu tcpdump -i veth0không hiển thị bất cứ điều gì thì tcpdumo -i locó thể cần thiết.
Hauke ​​Laging

Tôi đã thêm đầu ra không dài dòng của tcpdump
pskiebe

Câu trả lời:


8

Tôi luôn gặp vấn đề với các chuyển hướng iptables (có thể là lỗi của tôi, tôi khá chắc chắn rằng nó có thể thực hiện được). Nhưng đối với trường hợp như của bạn, IMO dễ dàng thực hiện điều đó hơn ở vùng đất người dùng mà không cần iptables.

Về cơ bản, bạn cần có một daemon trong không gian làm việc "mặc định" của mình trên cổng TCP 8112 và chuyển hướng tất cả lưu lượng truy cập đến 10.200.200.2 cổng 8112. Vì vậy, đó là proxy TCP đơn giản.

Đây là cách thực hiện với socat :

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

( forkTùy chọn là cần thiết để tránh socatdừng lại sau khi đóng kết nối proxy đầu tiên).

EDIT : thêm reuseaddrnhư đề xuất trong các ý kiến.

Nếu bạn thực sự muốn làm điều đó với iptables, có một hướng dẫn về Quản trị Debian trang . Nhưng tôi vẫn thích socatnhững thứ cao cấp hơn - như ủy quyền IPv4 sang IPv6 hoặc tước SSL để cho phép các chương trình Java cũ kết nối với các dịch vụ bảo mật ...

Tuy nhiên, hãy cẩn thận rằng tất cả các kết nối trong Deluge sẽ từ IP máy chủ của bạn thay vì IP máy khách thực sự. Nếu bạn muốn tránh điều đó, bạn sẽ cần sử dụng proxy ngược HTTP thực có thêm IP máy khách gốc vào yêu cầu được ủy quyền trong tiêu đề HTTP.


1
Bạn đã làm ngày hôm nay của tôi trở nên thú vị! Tôi chưa bao giờ đi qua socatvà nó hoàn thành chính xác những gì tôi đã cố gắng làm với iptables trong một thời gian khá lâu. Tôi đã thử nghiệm một số ứng dụng và tất cả chúng đều hoạt động hoàn hảo, kết nối với thế giới bên ngoài thông qua tun0, trong khi vẫn cung cấp quyền truy cập vào giao diện web của chúng thông qua veth1.
pskiebe

1
Sau khi thực hiện một số thử nghiệm, tôi đã thêm reuseaddrcờ. Điều này ngăn ngừa port already in uselỗi khi bắt đầu và dừng socat liên tiếp:socat -4 TCP-LISTEN:8112,reuseaddr,fork TCP:10.200.200.2:8112
pskiebe

7

Không gian tên mạng kết nối với không gian tên chính luôn làm phiền tôi. Lý do tôi thường tạo một không gian tên là vì tôi muốn nó bị cô lập. Tùy thuộc vào những gì bạn đang cố gắng đạt được với các không gian tên tạo ra các kết nối có thể đánh bại mục đích đó.

Nhưng ngay cả khi bị cô lập, tôi vẫn muốn chọc nó qua mạng, để thuận tiện.

Giải pháp này cho phép bạn giữ sự cô lập và chuyển tiếp một số kết nối đến nó. Bạn không cần tạo tất cả mạng đó giữa hai không gian tên mạng chỉ để chuyển tiếp một cổng. Chạy cái này trong không gian tên nơi bạn muốn chấp nhận kết nối. Phải được chạy như root ip netns execđể làm việc.

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

Nó lắng nghe các kết nối trong một không gian tên mạng nơi bạn chạy nó, trên cổng 8112, sau đó máy khách được kết nối sẽ execchạy ip netns exec myvpn ...để thực thi phần còn lại bên trong myvpnkhông gian tên mạng, sau đó một lần trong myvpnkhông gian tên mạng, nó tạo lại kết nối thứ hai với một kết nối khác socat.


làm việc như một bùa mê
xấp xỉ

Vì tôi không quá có kinh nghiệm với quản trị linux và tôi đã mất một thời gian để tìm hiểu: đảm bảo thoát cả hai :ký tự bên trong dấu ngoặc đơn nếu không bạn có thể gặp phải lỗi ... wrong number of parameters (2 instead of 1)(2 hoặc 3). Nếu không: hoạt động tuyệt vời! Rất cảm ơn bạn!
Igor

2

Đối với deluge ở đây là giải pháp của tôi. Không cần iptables. Dưới đây là các bước:

  1. Bắt đầu đường hầm openvpn của bạn
  2. Tạo không gian tên và mang đường hầm openvpn của bạn đến đó:
mạng ip thêm $ NS
# Đợi TUN xuất hiện
trong khi [[$ (ip tuyến | grep $ TUN | wc -l) == 0]]; ngủ 1 giấc; làm xong
MY_IP = $ (ip addr hiển thị $ TUN | grep inet | cut -d '' -f6 | cut -d '/' -f1)
# Cách bạn trích xuất IP gateway có thể khác với kết nối openvpn của bạn
GATEWAY_IP = $ MY_IP
# bỏ $ TUN (giao diện VPN) của tôi vào không gian tên
liên kết ip đặt $ TUN net $ NS
# Đưa giao diện lên với một mạng con (tương đương với giao diện được cung cấp cho tôi bởi máy chủ VPN)
ip thực hiện $ NS ifconfig $ TUN $ MY_IP / 24 trở lên
# Đưa loopback lên
ip netns thực hiện $ NS ifconfig lo 127.0.0.1/8 trở lên
# Thiết lập cổng từ xa (địa chỉ IP VPN điểm cuối của bạn)
ip netns exec $ NS tuyến thêm gw mặc định $ GATEWAY_IP
  1. Thiết lập kết nối veth giữa không gian tên mặc định của bạn và không gian tên bạn đã tạo:
# Thiết lập giao diện veth để liên lạc giữa các không gian tên
liên kết ip thêm veth0 gõ veth tên ngang hàng veth1
# Di chuyển veth thứ hai vào không gian tên của bạn
liên kết ip đặt veth1 netns $ NS
# cung cấp IP từ dải IP không sử dụng cho veth đầu tiên
ifconfig veth0 10.1.1.1/24 trở lên
# Và cái thứ hai
ip netns thực hiện $ NS ifconfig veth1 10.1.1.2/24 trở lên
# TODO: thiết lập cầu nối giữa giao diện veth1 và eth để cho phép nó giao tiếp với mạng LAN
# Thiết lập máy khách DNS. ip netns sẽ mô phỏng /etc/resolv.conf bằng tệp này:
mkdir -p / etc / netns / $ NS
echo "máy chủ tên 8.8.4.4"> /etc/netns/$NS/resolv.conf
  1. Chạy deluged của bạn trong $ NS và deluge-web của bạn trong không gian tên mặc định của bạn. Điểm deluge-web đến địa chỉ IP 10.1.1.2 veth, nơi đã xóa sẽ lắng nghe kết nối của nó.

Voila! Bạn đã được bảo mật an toàn đằng sau VPN trong khi web deluge của bạn có thể truy cập tự do trên mạng gia đình của bạn


2

Câu trả lời của @ AndrDevEK là hữu ích. Để mở rộng theo đó, bạn có thể không muốn cài đặt socat. Trong trường hợp đó, bạn có thể đạt được điều tương tự với thiết lập chuyển tiếp cổng SSH hơi phức tạp. Cụ thể, tính năng chuyển tiếp cổng đến / từ một ổ cắm tên miền unix rất hữu ích ở đây, bởi vì các ổ cắm tên miền unix hoạt động độc lập với không gian tên mạng:

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=$!

Dọn dẹp:

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

Đầu tiên ssh -N -Lđược bắt đầu trong không gian tên myvpn. Điều này tạo ra một ổ cắm tên miền unix /tmp/myunixsockvà lắng nghe nó. Các kết nối đến được chuyển tiếp đến localhost: 8112 (bên trong không gian tên myvpn). Thứ hai ssh -N -Lđược bắt đầu trong không gian tên mặc định. Điều này tạo ra một cổng TCP lắng nghe và chuyển tiếp các kết nối đến ổ cắm tên miền unix.

Cần lưu ý rằng để điều này hoạt động, sshbên trong không gian tên mạng của bạn sẽ cần phải hoạt động nếu nó chưa hoạt động (và thao tác pubkey không mật khẩu là hữu ích):

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.