¿Está intentando reenviar el puerto SMTP en el contenedor acoplable tunelizado IPsec de Strongswan?

¿Está intentando reenviar el puerto SMTP en el contenedor acoplable tunelizado IPsec de Strongswan?

He configurado con éxito un túnel VPN dentro strongswande un contenedor acoplable y quiero usar esa conexión tunelizada para reenviar puertos específicos como SMTP a un host al otro lado del túnel, en mi caso host 10.0.0.10.

El objetivo sería poder usar SMTP en mi aplicación directamente conectándome a strongswan-containerun servicio en el medio como este

(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])

Después de leer algunos documentos sobre esto, probé estos iptablescomandos strongswan-containerpero sin éxito:

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

en el my-mail-sending-app-containerintenté correr

telnet strongswan-container 25

pero simplemente esperaría una respuesta hasta que se agote el tiempo.

¿Cuál es el problema con mi iptablescomando?

iptables-saveSalida después de que Strongswan se haya conectado al túnel:

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

mi 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

Respuesta1

Lo resolví instalándolo traefiken mi strongswancontenedor y luego usando las TCP routingcapacidades de traefikexponer el puerto tunelizado internamente.

Dockerfile(Soy plenamente consciente de que esto alpinetambién se puede lograr usando):

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"]

Mi 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

Veraquípara el ejemplo completo.

información relacionada