Linux – Routing Bridge Docker Network to IPSEC on docker host

dockeripseclinuxrouting

I'm in trouble with a specific situation with a stand-alone docker host, ipsec and docker containers network.

I have a stand-alone docker host, within it is installed a libreswan 3 ipsec service and my Docker environment.

INFOS:

My docker network is a bridge with the IP range of 172.81.238.0/24.

I have a IPSec libreswan outside my docker environment, yet in the same host, that uses a virtual interface (eth0:3 -> 10.120.0.38) and close connection site-to-site with the other ipsec side (10.120.0.36/30).

The CIDR that I communicate on the other side of the ipsec vpn is 172.36.0.0/22.

THE PROBLEM

The point is, when I connect via SSH (or ssh tunnel) in my host directly, I can easily communicate with the other server on the 172.36.0.0/22 network (client's network).

But when I connect on a docker container (on network 172.81.238.0/24) I simply can't communicate to the CIDR 172.36.0.0/22.
On a docker container I can "ping" the eth0:3 (10.120.0.38) interface on my docker host, but can't communicate with the other side of the ipsec vpn.

My routes are working for the stand-alone host, but not for my containers (that are being dockerized by this same host), it's like I'm missing something, some bypas or like.

Could anyone help me please ?

EDIT

Output for Anton:

# ip x s ls

# ip x p ls
src 10.120.0.36/30 dst 172.36.0.0/22 
    dir out priority 1040873 ptype main 
    tmpl src 0.0.0.0 dst 0.0.0.0
        proto esp reqid 0 mode transport
src ::/0 dst ::/0 
    socket out priority 0 ptype main 
src ::/0 dst ::/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket out priority 0 ptype main 
src 0.0.0.0/0 dst 0.0.0.0/0 
    socket in priority 0 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 135 
    dir out priority 1 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 135 
    dir fwd priority 1 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 135 
    dir in priority 1 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 136 
    dir out priority 1 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 136 
    dir fwd priority 1 ptype main 
src ::/0 dst ::/0 proto ipv6-icmp type 136 
    dir in priority 1 ptype main

Libreswan config:

# basic configuration

config setup
        strictcrlpolicy=no
        uniqueids= yes

# Add connections here.

conn %default
        type= tunnel
        authby= secret
        keyexchange=ike
        ikelifetime= 86400s
        aggressive= no

        # Outras configurações
        compress= no
        forceencaps= yes

        # IPSEC Fase 1
        ike= aes256-sha1-modp1536,aes256gcm16-sha256-ecp521,aes256-sha256-ecp384,aes256gcm16-sha256-ecp256!

        # IPSEC Fase 2
        esp= aes256-sha1-modp1024,aes256gcm16-sha256,aes256-sha256!

conn vpnipsec-myclient

        keyexchange=ike
        leftprotoport= %any
        ikev2=insist
        # IPSEC Fase 1
        ike= aes256-sha256-modp2048

        # IPSEC Fase 2
        esp= aes256-sha256-modp2048

        # Left security
        left= 173.X.X.X
        leftid= 173.X.X.X
        leftsubnet= 10.120.0.36/30
        leftauth= secret

# Right security
        right= 177.X.X.X
        rightid= 177.X.X.X
        rightauth= secret
        rightsubnet= 172.36.0.0/22
        auto= start

Best Answer

This is pretty old, but I'll leave some info here for others who might run into it.

Deploying a docker container with default bridge network configuration assumes your application will need to access the same resources as the host, therefor it masquerades traffic from the container.

There are two ways to go about it:

  1. Prevent masquerading, by setting the com.docker.network.bridge.enable_ip_masquerade variable to false or alternatively deleting the NAT rules from your firewall (see iptables -n -t nat -L --line-numbers).

Deleting iptables rules is risky as a new deployment will write them right back.

Preventing NAT will also prevent access to the internet, something most guest applications will require.

  1. Add the host's default eth IP address to the encryption domain of your IPSec connection, thus allowing NATed packets to traverse the tunnel. Your IPSec partner will need to authorize your NAT address on its end.

Hope it helps.

Related Topic