Docker VPN IPSec client without privileged access

2020-06-19 17:04发布

I have a mysql database which I can access only after establishing VPN connection (IpSec-shared-secret + username + password)

so I want to run an isolated docker container which will establish this connection and proxy/expose mysql port somehow so that other containers can just connect to it without knowing if there is an vpn connection

all the examples I can find - require privileged access to a host/network (which I want to avoid to fully isolate container logic)

all I want is expose mysql port from a container that can establish ipsec-vpn access to a remote host`s mysql port

标签: docker vpn
1条回答
爷、活的狠高调
2楼-- · 2020-06-19 17:14

You can do it without privileged access, but NET_ADMIN capabilities is required, so that the container can created and tunnel interface.

To test the config I picked up a free VPN service from

https://www.vpnbook.com/freevpn

Downloading this [file] (https://www.vpnbook.com/free-openvpn-account/VPNBook.com-OpenVPN-US1.zip)

I created below Dockerfile for the same

FROM ubuntu:16.04
RUN apt update && apt install -y openvpn curl socat wget ca-certificates openssl
WORKDIR /openvpn/config
COPY vpnbook-us1-tcp80.ovpn .
COPY start.sh /start.sh
ENV OPENVPN_USERNAME=vpnbook OPENVPN_PASSWORD=dup2atu
CMD /start.sh

In the vpnbook-us1-tcp80.ovpn, I made a small changed to auth-user-pass and made it auth-user-pass openvpn-credentials, so we can pass credentials from a file. Next was to create a start.sh

#!/bin/sh

mkdir -p /dev/net && mknod /dev/net/tun c 10 200

printf "$OPENVPN_USERNAME\n$OPENVPN_PASSWORD" > openvpn-credentials
chmod 600 openvpn-credentials

socat TCP4-LISTEN:80,reuseaddr,fork TCP4:ipinfo.io:80 2>&1 >/dev/null &
exec openvpn --inactive 3600 --ping 10 --ping-exit 60 --config vpnbook-us1-tcp80.ovpn

The mknod /dev/net/tun c 10 200 creates a tun device at run-time inside container so we don't need to map it from host.

Since you wanted other containers to access mysql by connecting to this container, you will change below

socat TCP4-LISTEN:80,reuseaddr,fork TCP4:ipinfo.io:80 2>&1 >/dev/null &

to

socat TCP4-LISTEN:3306,reuseaddr,fork TCP4:<YourMYSQLIP>:3306 2>&1 >/dev/null &

What this would do is listen to local port X on container and forward that request to port Y on IP/domain your provide. Then we can either map this ports to Host or access them directly through container.

To run the whole thing I made a simple docker-compose.yml

version: "3"

services:
  vpn:
    build: .
    cap_add:
      - NET_ADMIN
    ports:
      - 3306:3006
      - 8080:80
    dns:
      - 8.8.8.8

Now after doing docker-compose up -d and waiting for few seconds, I run below command on my host

$ curl -H "Host: ipinfo.io" localhost:8080/json
{
  "ip": "198.7.62.204",
  "hostname": "us1.vpnbook.com",
  "city": "Manassas",
  "region": "Virginia",
  "country": "US",
  "loc": "38.7701,-77.6321",
  "org": "AS30633 Leaseweb USA, Inc.",
  "postal": "20109"
}

As you can see localhost:8080 was mapped to container port 80 and socat is forwarding that port 80 to ipinfo.io:80. The forwarding is happening through the VPN

查看更多
登录 后发表回答