Skip to content

Simple sidecar to connect a container to an external network with another container as the gateway

License

Notifications You must be signed in to change notification settings

wolffshots/connectorr

Repository files navigation

connectorr

Simple sidecar to connect a container to an external network with another container as the gateway. The goal is to be able to connect to a Gluetun container from multiple stacks without using network_mode: container:<gluetun> since the container network mode introduces some problems like it not being a direct dependency which can cause stacks to fail to start and if the Gluetun container updates and restarts then the attached container won't regain network access until it is taken down and started again.

I tried to keep the container itself as lightweight (I got it to like 4.1MB!) and simple as possible with enough functionality and configurability that it solves lots of problems.

Network

You'll need an external network with a known subnet which you can create like this:

docker network create -subnet=172.21.0.0/24 --ip-range=172.21.0.128/25 --gateway=172.21.0.1 vpn_net

You'll use IPs in this subnet and this network name for the containers you want to hook up. If you don't specify an IP it will assing one from 172.21.0.128-172.21.0.255 but if you do specify then you can use 172.21.0.0-172.21.0.255 but it's better to keep manual and auto assigned IPs separate so if you want a manual IP it would be better to select from 172.21.0.3-172.21.0.127.

Gateway container

Here's a simple setup for a gluetun stack which you could have at /opt/stacks/glutun/docker-compose.yml. You'll just need to set up your credentials for your provider as you can see in the gluetun-wiki repo

services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    environment:
      - VPN_SERVICE_PROVIDER=${VPN_PROVIDER}
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
      - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
      - SERVER_CITIES=${SERVER_CITIES}
    volumes:
      - /opt/stacks/gluetun/iptables:/iptables
      - /etc/localtime:/etc/localtime:ro
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
    networks:
      vpn_net:
        ipv4_address: 172.21.0.2
    restart: always
    logging:
      driver: json-file
      options:
        max-size: 100m
        max-file: "5"
networks:
  vpn_net:
    external: true

And then create a file at /opt/stacks/gluetun/iptables/post-rules.txt with the following content (edit the subnets if your network uses a different one):

iptables -A FORWARD -s 172.21.0.0/24 -o tun0 -j ACCEPT
iptables -A FORWARD -d 172.21.0.0/24 -i tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 172.21.0.0/24 -o tun0 -j MASQUERADE

Make sure the gluetun stack is up and running correctly before moving on. If you have trouble please check the gluetun-wiki repo for help

Environment

Once you have the gateway container set up and configured correctly you have these options for the environment of this connector:

Variable Description Status Default Example
GATEWAY_IP IP of the gateway container (on the Docker network) that traffic will be routed through Required N/A 172.21.0.2
BYPASS_IP IP of the Docker host in the Docker network, normally 172.x.0.1 Optional unless BYPASS_SUBNETS is defined then required N/A 172.21.0.1
BYPASS_SUBNETS Comma separated list of subnets that should be routed through the bypass IP Optional Empty 192.168.88.0/24,100.64.0.0/10
HEALTH_REMOTE_IP External IP to ping for health check Optional unless HEALTH_REMOTE_CHECK is on N/A 1.1.1.1
HEALTH_REMOTE_CHECK Whether to ping the HEALTH_REMOTE_IP from inside the container to log health Optional with default off off on
HEALTH_LOCAL_IP Local IP to ping for health check Optional unless HEALTH_LOCAL_CHECK is on then required N/A 192.168.88.1
HEALTH_LOCAL_CHECK Whether to ping the HEALTH_LOCAL_IP from inside the container to log health Optional with default off off on
IP_API_URL Endpoint to wget from to print IP Optional with default ifconfig.me/ip ifconfig.me/ip ifconfig.me/ip
IP_API_CHECK Whether to check the public IP on boot using IP_API_URL Optional with default on on on
TRACE_ON_START Run traceroutes when starting using HEALTH_REMOTE_IP and HEALTH_LOCAL_IP to confirm routing table Optional with default off off off

Create a new stack for the things you want to include in what this connector routes and then add it as you see in the example docker-compose.yml.

Here is a simplified version:

services:
  # this apline container represents your apps
  app_one:
    image: alpine:latest
    network_mode: service:connectorr # connect it to the connectorr container
    command: sh -c "apk add curl && curl ifconfig.me/ip"
  app_two:
    image: alpine:latest
    network_mode: service:connectorr # connect it to the connectorr container
    command: sh -c "apk add curl && curl ifconfig.me/ip"
  connectorr:
    image: ghcr.io/wolffshots/connectorr:latest
    container_name: app_connectorr
    ## specific port for the app/s you have connected (in this case the ports you access alpine on)
    ## note that they must be unique ports on the actual app side
    ports:
      - 8085:8085 # an example port for app one. to access app one in the docker network it would be 172.21.0.50:8085 or app_connectorr:8085
      - 8086:8086 # an example port for app two. vice versa for app two
    cap_add:
      - NET_ADMIN
    environment:
      - GATEWAY_IP=172.21.0.2 # gluetun
      - BYPASS_IP=172.21.0.1 # docker host
      - BYPASS_SUBNETS=192.168.88.0/24 # local network
    restart: always
    networks:
      - vpn_net # the network you created which will assign an ip in 172.21.0.128-172.21.0.255 based on the ip pool of the network
networks:
  vpn_net: # the network you created
    external: true

Once this stack is up your apps should be using connectorr as their network and it should be routing all traffic through gluetun except for traffic between the bypassed subnets

About

Simple sidecar to connect a container to an external network with another container as the gateway

Topics

Resources

License

Stars

Watchers

Forks

Packages