kylemanna / docker-openvpn

🔒 OpenVPN server in a Docker container complete with an EasyRSA PKI CA
https://hub.docker.com/r/kylemanna/openvpn/
MIT License
8.71k stars 2.39k forks source link

OpenVpn container not starting and giving Iptables errors in Centos 8 host #564

Open yadaom opened 4 years ago

yadaom commented 4 years ago

Hello Guys,

I have using "docker-openvpn" to VPN to my home from outside. Whenever I try to start the docker container it gives the following error:

+ iptables -t nat -C POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
modprobe: can't change directory to '/lib/modules': No such file or directory
modprobe: can't change directory to '/lib/modules': No such file or directory
iptables v1.8.3 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
+ iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
modprobe: can't change directory to '/lib/modules': No such file or directory
modprobe: can't change directory to '/lib/modules': No such file or directory
iptables v1.8.3 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

Here is the command I am using: docker run --privileged -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN --cap-add=NET_RAW --name openvpn kylemanna/openvpn I have tried lots of solution from the internet but nothing is working. My docker is installed on centos 8.

Can someone help? Thanks Om

hafniumdk commented 4 years ago

I am seeing (roughly) the same (Arch Linux, all updated)

+ setupIptablesAndRouting
+ iptables -t nat -C POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
iptables: No chain/target/match by that name.
+ iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
+ for i in "${OVPN_ROUTES[@]}"
+ iptables -t nat -C POSTROUTING -s 192.168.254.0/24 -o eth0 -j MASQUERADE
iptables: No chain/target/match by that name.
+ iptables -t nat -A POSTROUTING -s 192.168.254.0/24 -o eth0 -j MASQUERADE

Seems to coincide with the recent rebuild of the image (to get on newest alpine).

Quite a major issue (for me, but likely also for others).

hafniumdk commented 4 years ago

I just figured that this seems related to the Alpine Linux version. Did a local build of the image but with FROM alpine:3.10 (as in the previous official build of the image) instead of FROM alpine:latest in the current official image.

This fixed any issues, which I also tracked down to the container not getting a IP address assigned (bridged network with cap_add=NET_ADMIN).

yadaom commented 4 years ago

I tried the above suggestion and build the image using using FROM alpine:3.10, but it didn't help. It seems like the problem with Centos-8, and it is not loading the kernel modules for ip-filter. After lots digging, I found that running following commands helped:

Running the above commands first and then starting the container worked. May be someone knows more about this and can shed more light on this.

Thanks

rdebath commented 4 years ago

There are two versions of iptables labeled "iptables-nft" and "iptables-legacy". There are two independent sets of kernel modules. They can both be loaded at the same time and operate side-by-side.

AFAICS alpine only uses "iptables-legacy" ie: the real iptables not the one faked ontop of the new "netfilter" kernel modules.

If the host is Debian/Ubuntu you can change the default by using: sudo update-alternatives --config iptables. You can also call iptables-legacy directly, on the host, and it'll load and configure the real iptables modules.

Obviously using modprobe as @yadaom suggests works too.

scidar commented 2 years ago

I'm on centos 8 and I use this openvpn image 2 years ago. I didn't have this "No such file or directory" problem till now. Does anybody know what happened?

Modprobe commands don't load modules after reboot so I made a conf file in the modules-load.d directory that contains the iptable_filter and iptable_nat text so these modules load on next boot. It solves the problem but I'm not sure if it is the proper way.

rdebath commented 2 years ago

@scidar These config files are a normal way of running modprobe at boot.

BTW: It changed because the host was upgraded. However, as it sounds like you're still using a two year old image, I should mention that it's best if you make sure to upgrade the guest image on a regular basis.

scidar commented 2 years ago

@rdebath Thank you for the information!

I set up the systemd init script when I installed the system. It is true that I didn't changed anything to the vpn service since then, but I thought the script is upgrading to the latest image on reboot so I hope I'm using a decent version.

stanimirivanovde commented 2 years ago

I had the same issues and fixed it by modifying the file bin/ovpn_run by changing all iptables calls to iptables-nft:

-    iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE 2>/dev/null || {
-      iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE
+    iptables-nft -t nat -C POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE 2>/dev/null || {
+      iptables-nft -t nat -A POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE
     }
     for i in "${OVPN_ROUTES[@]}"; do
-        iptables -t nat -C POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE 2>/dev/null || {
-          iptables -t nat -A POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE
+        iptables-nft -t nat -C POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE 2>/dev/null || {
+          iptables-nft -t nat -A POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE
         }
     done
 }

Then rebuild the docker image and run it. It might be a good idea to symlink directly to iptables-nft.

I can submit a pull request if needed.

belqit commented 1 year ago

permanent fix:

sudo bash -c 'cat <<EOF > /etc/systemd/system/load-iptables-modules.service
[Unit]
Description=Load iptables modules at startup

[Service]
Type=oneshot
ExecStart=/sbin/modprobe iptable_filter
ExecStart=/sbin/modprobe iptable_nat

[Install]
WantedBy=multi-user.target
EOF'

sudo chmod 644 /etc/systemd/system/load-iptables-modules.service
sudo systemctl daemon-reload
sudo systemctl enable load-iptables-modules.service