Open BirgerK opened 7 years ago
Would this be a smooth solution? :
192.168.253.0/24
push 192.168.253.0 255.255.255.0
to ovpn.conf
I guess this would be ok.
Well, it sounds like a great idea, but I don't get it working.
My setup:
I got this Image running as a container named my-ovpn
. my-ovpn
is connected to a docker-network named great-private-stuff
. great-private-stuff
is f.e. the subnet 172.19.0.0/16
, so it's a "normal" docker-network.
There's also another container connected to the docker-network great-private-stuff
which is running f.e. an nginx and has the ip f.e. 172.19.0.3
.
My ovpn-container is started with --privileged --cap=NET_ADMIN
.
I created the openvpn-config by ovpn-genconfig -u udp://example.com -p "route 172.19.0.0 255.255.0.0"
If I connect my client to this ovpn-server, I can see in my routes that the subnet 172.19.0.0/16
will now be routed through the ovpn-tunnel. I can see with traceroute 172.19.0.3
(which is the nginx) that the package halts at 192.168.255.1
, which is the tun0
-device on serverside. Same thing if I try to traceroute 172.19.0.1
(which is the docker-network-gateway).
But:
If my ovpn-container is not connected to the docker-network great-private-stuff
, then I can ping 172.19.0.1
but not the nginx connected to it.
What's running wrong?
Thank you, BirgerK
TL;DR: How do you route to a container which is connected with your vpn-container by a docker-network?
Are you using docker-compose? As far as I understood [1] you could set up a different docker network for the services that should be using your vpn and others that don't. That way you maybe could use the options in Issues 110 or 109 to get the vpn container and the others you want to restrict to work together in one network (option -c and all)
I prepared a docker-compose-example for you:
version: '2'
services:
openvpn:
cap_add:
- NET_ADMIN
image: kylemanna/openvpn
ports:
- "1194:1194/udp"
volumes:
- /tmp/openvpn/conf:/etc/openvpn
networks:
public:
ipv4_address: 172.100.0.10
private:
ipv4_address: 172.200.0.10
webserver:
image: httpd
networks:
public:
ipv4_address: 172.100.0.20
private:
ipv4_address: 172.200.0.20
networks:
public:
ipam:
config:
- subnet: 172.100.0.0/16
private:
ipam:
config:
- subnet: 172.200.0.0/16
I create my ovpn-config by:
mkdir -p /tmp/openvpn/conf && docker-compose run --rm openvpn ovpn_genconfig -u udp://<your-local-ip> -p "route 172.200.0.0 255.255.0.0" -p "route 172.100.0.0 255.255.0.0" -c
And run it (locally) by: docker-compose up -d
Now you can ping from your ovpn-container the webserver on his both ips 172.100.0.20
and 172.200.0.20
. -> The docker-network works internally.
If I do d exec openvpn_1 ifconfig
I get:
eth0 Link encap:Ethernet HWaddr 02:42:AC:C8:00:0A
inet addr:172.200.0.10 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fec8:a%32738/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:64:00:0A
inet addr:172.100.0.10 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe64:a%32738/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1%32738/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.255.1 P-t-P:192.168.255.2 Mask:255.255.255.255
inet6 addr: fe80::6b94:1b2b:e735:1eaa%32738/64 Scope:Link
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 B) TX bytes:144 (144.0 B)
There you see that eth0
is connected to subnet 172.200.0.0/16
.
This was docker-side.
Now I connect by my openvpn-client to the created and configured ovpn-docker-server. From there I can ping the webserver on IP 172.200.0.20
but NOT on the IP 172.100.0.20
.
We can see that the subnet, which is connected to eth0, is reachable but no other docker-networks. At ovpn_run you can see that eth0
is configured for NAT'ing. ofc you can change the interface for NAT'ing but I want to use NAT on all eth*
-interfaces.
You know what I mean?
@BirgerK Did you activate the client_to_client option in your config ?
I did some research and I think you might have some hints on how to proceed here : http://blog.bobbyallen.me/2016/02/07/enabling-openvpn-clients-to-access-to-the-lan/
I didn't try any of it and I don't now much about openvpn but I am quite interested if you could tell me if you succeeded.
To access the other eth* interfaces you might need to create a bridge and add them to the bridge.
This might be the solution according to my research.
@farfeduc and then configure the NAT'ing on the created bridge? Would this work? (Never added a bridge before)
EDIT: and yes, I'm already using the client-to-client-option. :) For now I got no solution for this problem.
@BirgerK I tried to apply this : http://powtos.fr/255-openvpn-bridge/ but I didn't succeed. May be you might have an idea.
I made a docker image based on this one with bridge-utils : https://github.com/farfeduc/docker-openvpn-bridge in order to create the bridge.
In my image, I work on the 192.168.111.0/24 subnet and my goal is to make my other docker containers on the same network as my openvpn container to be accessed.
But by changing the openvpn.conf I wasn't able to connect to the vpn anymore. I'm trying again today to recreate all of that and maybe do some debug.
As I understood, creating a bridge and switching to a TAP device should make the openvpn server's lan available. So in theory, adding :
server-bridge 192.168.111.254 255.255.255.0 192.168.111.100 192.168.111.200
to the openvpn.conf should help gain access to the docker network as if it were the "lan"
@BirgerK thanks for hinting. The dirty but working solution is to override function setupIptablesAndRouting
in ovpn_env.sh
:
setupIptablesAndRouting {
iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE || {
iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE
}
# olegstepura: add eth1 NAT rules as hinted by https://github.com/kylemanna/docker-openvpn/issues/182#issuecomment-269363050
# this allows to connect to docker internal network which is eth1
iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o eth1 -j MASQUERADE || {
iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o eth1 -j MASQUERADE
}
for i in "${OVPN_ROUTES[@]}"; do
iptables -t nat -C POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE || {
iptables -t nat -A POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE
}
done
}
@BirgerK thanks for hinting. The dirty but working solution is to override function
setupIptablesAndRouting
inovpn_env.sh
:setupIptablesAndRouting { iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE || { iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE } # olegstepura: add eth1 NAT rules as hinted by https://github.com/kylemanna/docker-openvpn/issues/182#issuecomment-269363050 # this allows to connect to docker internal network which is eth1 iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o eth1 -j MASQUERADE || { iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o eth1 -j MASQUERADE } for i in "${OVPN_ROUTES[@]}"; do iptables -t nat -C POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE || { iptables -t nat -A POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE } done }
thanks for the solution!
I think this solution should be extended for per interface
and get merged with source code by maintainers.
@farfeduc I have a similar issue.
I want the clients to get an IP of the defined subnet in the docker-compose , but access it without doing any NATing on the OpenVPN container, just like a 'bridge' to that network.
Is there a way to accomplish that without switching to a TAP device?
@iedmrc and @olegstepura: according to man iptables there is a better way put eth+ in OVPN_NATDEVICE that way, all ethx devices get configured by the already existring function. no changes in a bash script required.
@iedmrc and @olegstepura: according to man iptables there is a better way put eth+ in OVPN_NATDEVICE that way, all ethx devices get configured by the already existring function. no changes in a bash script required.
This works beautifully, thank you! I have searched 10hrs+ for a working and simple solution... and was about to create my own Dockerfile with custom scripts... because I'll probably want to reach more than only "eth0" and "eth1" in the future...
In my case, I have dev-systems on an internal docker-network I want to reach via VPN only (for debugging purposes).
10.10.0.4 is where a pihole lies, for forwarding dns queries to docker (127.0.0.11) and resolving internal dns names.
The pihole is also member of all other networks I want to reach.
Note: to resolve the hostname of containers you actually have to use <container>.<network>
.
10.10.10.0/24 is a docker-network which containers I want to access. This was previously not possible. I could ping the Gateway (10.10.10.2) and resolve the IP of my container (via 10.10.0.4) but not ping.
Now with OVPN_NATDEVICE=eth+
it works:
docker-compose run --rm openvpn -e OVPN_NATDEVICE=eth+ openvpn ovpn_genconfig \
-N -c \
-n 10.10.0.4 \
-u udp://vpn.domain.com \
-p "route 10.10.0.0 255.255.255.0" \
-p "route 10.10.10.0 255.255.255.0"
An alternative method without manually touching iptables is to use the same network as the openvpn container in your service:
version: '2'
services:
openvpn:
cap_add:
- NET_ADMIN
image: kylemanna/openvpn
ports:
- "1194:1194/udp"
- "80:8080/tcp" # for service webserver
volumes:
- /tmp/openvpn/conf:/etc/openvpn
webserver:
image: httpd
network_mode: "service:openvpn"
The downside is that webserver and openvpn will share the same network interfaces (same ip). The good thing is there is no other configuration to do.
Hi there,
I'm using this Image for a long time and I like it! And now I want to add some services which are only accessible inside of the VPN.
Those services shall run as docker-container on the same host like the VPN-container does. The problem: I don't want to route the Docker-IP from every VPN-client inside of the VPN-network. This is not practicable because I got on my VPN-client also a docker-service running which shall not be restricted.
My question: How do I get a docker-container inside of the VPN-network, so it get's (like my VPN-client) a IP from the VPN-network 192.168.254.0?
ofc I have to use the param
-c
ongenconfig
but first the container must be reachable in this IP-network.Thank you for your help!
Birger