
我已經在 Docker 容器內成功設定了 VPN 隧道strongswan
,並希望使用該隧道連接將特定連接埠(例如 SMTP)轉送到隧道另一側的主機(在我的例子中)host 10.0.0.10
。
目標是能夠透過strongswan-container
像這樣連接到中間的服務來直接在我的應用程式中使用 SMTP
(smtp-host)-[IPSec-tunnel]-(strongswan-container [exposes port 25 and forwards everything to tunneled smtp-host])-[some-docker-network]-(my-mail-sending-app-container [calls strongswan-container:25 for smtp])
在閱讀了一些有關此內容的文檔後,我嘗試了這些iptables
命令strongswan-container
但沒有成功:
iptables -t nat -A PREROUTING -p tcp --dport 25 -j DNAT --to-destination 10.0.0.10:25
iptables -t nat -A POSTROUTING -p tcp -d 10.0.0.10 --dport 25 -j MASQUERADE
我my-mail-sending-app-container
嘗試跑步
telnet strongswan-container 25
但它只會等待響應直到超時。
我的命令有什麼問題iptables
?
iptables-save
Strongswan 連接到隧道後的輸出:
root@14d43f1e2f55:/# iptables-save
# Generated by iptables-save v1.8.4 on Thu Jul 22 16:25:04 2021
*filter
:INPUT ACCEPT [1:112]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:112]
-A INPUT -s 10.0.0.0/16 -d 192.168.112.2/32 -i eth0 -m policy --dir in --pol ipsec --reqid 1 --proto esp -j ACCEPT
-A OUTPUT -s 192.168.112.2/32 -d 10.0.0.0/16 -o eth0 -m policy --dir out --pol ipsec --reqid 1 --proto esp -j ACCEPT
COMMIT
# Completed on Thu Jul 22 16:25:04 2021
# Generated by iptables-save v1.8.4 on Thu Jul 22 16:25:04 2021
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [2:1600]
:POSTROUTING ACCEPT [2:1600]
:DOCKER_OUTPUT - [0:0]
:DOCKER_POSTROUTING - [0:0]
-A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT
-A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.11:46701
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.11:58024
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -m tcp --sport 46701 -j SNAT --to-source :53
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -m udp --sport 58024 -j SNAT --to-source :53
COMMIT
# Completed on Thu Jul 22 16:25:04 2021
我的ipsec.conf
:
config setup
strictcrlpolicy=no
uniqueids=no
# left is local by default, left and right otherwise dynamically detected
conn %default
conn "ezvpn"
keyexchange=ikev2
aggressive=yes
ike=(some-ciphers) # Phase1 parameters
esp=(some-ciphers) # Phase2 parameters
left=192.168.112.2 # local IP used to connect to IOS
leftid=12.123.123.1 # IKEID (group name) used for IOS
leftfirewall=yes
leftauth=psk
rightauth=psk
fragmentation=yes
right=12.123.123.2 #gateway (IOS) IP
rightsubnet=10.0.0.0/16
rightfirewall=yes
auto=route
type=tunnel
ikelifetime=180m
keylife=60m
答案1
我透過安裝traefik
到strongswan
容器中然後使用在內部公開隧道連接埠TCP routing
的功能來解決這個問題。traefik
Dockerfile
(我完全知道這alpine
也可以透過使用來實現):
FROM ubuntu
RUN apt update && apt-get install -yf wget iputils-ping telnet strongswan iptables \
&& ln -sf /conf/ipsec.conf /etc/ipsec.conf \
&& ln -sf /conf/ipsec.secrets /etc/ipsec.secrets \
&& echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf \
&& wget -O /traefik.tar.gz https://github.com/traefik/traefik/releases/download/v2.4.12/traefik_v2.4.12_linux_amd64.tar.gz \
&& tar -zxvf /traefik.tar.gz \
&& ln -s /traefik /usr/bin/traefik
COPY docker-entrypoint.sh /entrypoint.sh
COPY /strongswan /conf
COPY /traefik-conf /traefik-conf
CMD ["/entrypoint.sh"]
我的entrypoint.sh
:
#!/bin/sh -e
{
# wait to make sure ipsec is started when upping the tunnel
sleep 2
ipsec up ezvpn
traefik --configfile /traefik-conf/traefik.yml
} &
exec ipsec start --nofork "$@"
traefik-conf/traefik.yml
:
# https://doc.traefik.io/traefik/routing/entrypoints/
entryPoints:
smtp:
address: ":1025" # the port that listens within the docker network
accessLog: {}
providers:
file:
directory: /traefik-conf/dynamic/
# I use dynamic configurations for local development
watch: true
api:
dashboard: true
insecure: true
/traefik-conf/dynamic/dynamic.yml
:
tcp:
# https://doc.traefik.io/traefik/routing/routers/#rule_1
routers:
smtp-router:
rule: "HostSNI(`*`)"
entryPoints:
- smtp
service: smtp-service
# https://doc.traefik.io/traefik/routing/routers/#services
services:
smtp-service:
loadBalancer:
servers:
- address: 10.0.0.1:25 # replace with your target IP & service port
看這裡完整的例子。