Using specific host IP (interface) for docker containers
Introduction
The following article describes how I select a specific host IP for egress traffic in a specific docker container.
It was a trick used few years ago, at that time 2 seperate sites were sharing the same VPS, each has its own designated IP. What I would like to achieve is that each site should only use its own IP for egress traffic.
- Site A IP: 10.201.0.201 interface: eth0
- Site B IP: 10.201.0.202 interface: eth0:1
Here you can see I have 2 IPs on eth0:
[root@vps ~]# ip add
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP grup default qlen 1000
link/ether AA:BB:CC:0e:ce:28 brd ff:ff:ff:ff:ff:ff
inet 10.201.0.201/24 brd 10.201.0.255 scope global dynamic eth0
valid_lft 80555sec preferred_lft 80555sec
inet 10.201.0.202/24 brd 10.201.0.255 scope global eth0:1
valid_lft forever preferred_lft forever
...
Here is the routing table on my VPS:
[root@vps ~]# ip route
default via 10.201.0.254 dev eth0
10.201.0.0/24 dev eth0 proto kernel scope link src 10.201.0.201
...
So that’s all for my network setup! Let’s look at the Docker-compose YAML file.
Docker-Compose
In my docker-compose.yaml file, you can see I have deployed softEtherVPN.
Everything is as usual except I have created a network net_iptwo and have NET_ADMIN enabled.
The network net_uptwo, applies a default route to the container, and also assigns an IP with subnet 192.168.200.0/24 to the container
Fire up the service with docker-compose up -d
then we are good to prepare for firewalld rules
# docker-compose.yaml
version: '3'
services:
softether1:
container_name: nic-softether1
image: siomiz/softethervpn
networks:
- net_iptwo
volumes:
- ./softether/vpn_server.config:/usr/vpnserver/vpn_server.config
cap_add:
- NET_ADMIN
ports:
- 192.168.100.100:500:500/udp
- 192.168.100.100:4500:4500/udp
- 192.168.100.100:1701:1701/tcp
- 192.168.100.100:1194:1194/udp
- 192.168.100.100:5555:5555/tcp
networks:
net_iptwo:
driver: bridge
driver_opts:
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "false"
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
com.docker.network.bridge.name: "br_ip2"
com.docker.network.driver.mtu: "1500"
ipam:
driver: default
config:
- subnet: 192.168.200.0/24
Firewalld
This Firewall rule is a self-explainatory one-liner: whenever the source is from 192.168.200.0/24 subnet, do SNAT to 10.201.0.202
firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 192.168.200.0/24 -j SNAT --to-source 10.201.0.202