Internet Access of Docker Container

I'm currently using OpenWRT to host some docker containers using the default bridged network, but the containers don't have internet access.

I've also configured the firewall that accepts forward from any zone to the Docker network, and from the Docker network to any zone. This doesn't help either.

I have also checked the community posts that are marked as solved, i.e.

and

These solutions don't grant internet access either.

I'm wondering if there are other solutions that can fix the internet access problem.

hi,
can you show in firewall config file how you did that?

and your dockerd config, along with some details about your owrt version please?

Hi there.
My Firmware version is
OpenWrt 22.03.4 r20123-38ccc47687 / LuCI openwrt-22.03 branch git-23.119.80898-65ef406
under architecture rockchip/armv8

Below is my firewall config. The general configuration is to accept all input/output/forward packages.

My Docker version is 20.10.22, with default bridge docker.network.ip.address/16. This is a virtual bridge device that bridges all the virtual LAN ports of the existing docker containers. The network segment is different from my home network home.network.ip.address/24. The default gateway is WAN. This interface is assigned to the firewall zone Docker0 shown in the above pictures. The interface has a static address docker.network.0.1. The config is similar to my LAN interface config, which works well. The interface Docker0 reports the error "Network device is not present" irrelevant to how I configure the bridged ports.



Moreover, another solution that I've tried and failed was that I have set up two NAT rules, statically rewriting docker.network.ip.address/16 addresses to my home network gateway and the other way around.

  1. can you remove all firewall rules you added and try the followings?
  • edit docker zone, at the bottom add wan zone to "Allow forward to destination zones"
  1. i cannot follow your network config, screenshots are not really helps. could you please copy the content of /etc/config/network? pls remove sensitive details (wan isp account for example) but keep ip address details of lan+docker interfaces.
    3, copy the content of /etc/config/dockerd too

Hello,
After I checked the /etc/config/dockerd, I found out that the WAN port was blocked by Docker configuration, as shown in the figure. This is the default configuration and there is no GUI option that shows this.

image

After I deleted the arrow-pointed line, the containers have access to the internet.

There is nothing to do with the firewall configuration you and I mentioned. I have tried not to do the point 1 you have mentioned, and the container also has the access.

Thank you very much for your help!

this is quick and dirty "solution", you allow anything from wan into docker network you probably don't want that. the extra option is included in the default config:

config firewall 'firewall'
        option device 'docker0'
        list blocked_interfaces 'wan'
        option extra_iptables_args '--match conntrack ! --ctstate RELATED,ESTABLISHED' # allow outbound connections

you'd need two things:

  1. with the config above any traffic which is NOT related/established would be blocked on interface wan, meaning traffic initiated from docker to wan direction and the respective reply traffic is allowed. but no traffic initiated from wan to docker for example,
  2. docker network to actually access internet - which can be controlled with the firewall zone setup, as suggested allowing docker to wan direction.

Thank you for your hint. I have edited the config and it works as well.
But I have two questions regarding the config

  1. As far as I know, Openwrt uses nftables instead of iptables, and you are giving an extra iptables arg, I didn't find the information of this config command in the document. Could you tell me where I could look it up, or could you briefly explain what this extra_iptables_args means?

  2. My firewall zone for WAN has been set to reject incoming connections and only allow outgoing connections, which means, as of my knowledge, the incoming connection (or I would say the return connection) will be accepted only if an outgoing connection was initiated. Is it still not possible to filter out the connection from outside the network, if a connection was not initiated by my docker container?

Thank you again for your kind help!

  1. yes, recent owrt releases indeed switched from fw3/iptables to fw4/nftables. but there are tools to convert from legacy iptables rules to new nftables sysntax. e.g.
$ grep RELEASE /etc/openwrt_release
DISTRIB_RELEASE='22.03.5'
$ which iptables
/usr/sbin/iptables
$ ls -al /usr/sbin/iptables
lrwxrwxrwx    1 root     root            30 May  4 22:07 /usr/sbin/iptables -> /usr/sbin/xtables-legacy-multi
$ opkg info xtables-legacy
Package: xtables-legacy
Version: 1.8.7-7
Depends: libc, kmod-ipt-core, libip4tc2, libip6tc2, libiptext0, libiptext6-0, libxtables12
Status: install ok installed
Section: net
Architecture: x86_64
Size: 26066
Filename: xtables-legacy_1.8.7-7_x86_64.ipk
Description: IP firewall administration tool
Installed-Time: 1683230823

$ opkg files xtables-legacy
Package xtables-legacy (1.8.7-7) is installed on root and has the following files:
/usr/sbin/xtables-legacy-multi
$ xtables-legacy-multi
ERROR: No valid subcommand given.
Valid subcommands:
 * iptables
 * main4
 * iptables-save
 * save4
 * iptables-restore
 * restore4
 * iptables-legacy
 * iptables-legacy-save
 * iptables-legacy-restore
 * ip6tables
 * main6
 * ip6tables-save
 * save6
 * ip6tables-restore
 * restore6
 * ip6tables-legacy
 * ip6tables-legacy-save
 * ip6tables-legacy-restore

  1. you are right, default owrt configuration prevents random incoming traffic from wan. but if you install dockerd package it comes with default config files including this comment
# Docker undermines the fw3 rules. By default all external source IPs are allowed to connect to the Docker host.
# See https://docs.docker.com/network/iptables/ for more details.

so i guess as dockerd wants to manage firewall based on its on uniformed logic knowing nothing about your environment it is better be safe than sorry.

Thank you very much for your explanation.

And I would like to ask a follow-up question. How can I edit the config if I want to expose a container to WAN network under this configuration file:

config firewall 'firewall'
        option device 'docker0'
        list blocked_interfaces 'wan'
        option extra_iptables_args '--match conntrack ! --ctstate RELATED,ESTABLISHED' # allow outbound connections

I'd like to allow the connection from WAN to my container with IP 172.17.0.4. I only want this container to be exposed to WAN network.

well, containers usually receive dynamic ip address, so you have to fix that first (custom network, fixed subnet). then comment out extra option and create a respective rule in DOCKER-USER chain something similar -s 172.17.0.4 -o $wan -j ACCEPT where $wan is your actual wan interface. but i have not tested it.

Thanks, I'll try to do it. But if I comment out the extra option, my container will not be able to connect to the internet, right? I'll try to append a custom rule in DOCKER-USER without commenting out the extra option to see if this ACCEPT can be treated as an exception rule.

as i see combination of blocked interface wan and the extra options creates the rule:

-A DOCKER-USER -i $wan -o docker0 -m conntrack ! --ctstate RELATED,ESTABLISHED -j REJECT --reject-with icmp-port-unreachable

which rejects all traffic from $wan to docker0 unless it is related traffic. but it does not control from docker to $wan direction at all. so no, your container will still able to connect to internet - in theory, but you can test it easily :wink:

when you say expose your docker to wan do you mean allowing uncontrolled traffic initiated from wan accepted by your docker, or allowing reply traffic for the data flow initiated by your docker container?

for example if you are using adguard home or pi hole as filtering DNS service, it needs obviously connection to upstream DNS server (i.e. access to internet). but that's a traffic initiated by your docker container and you want to allow reply traffic from wan only. which is already covered with this rule above (plus the zone setting).

but if you want to expose your e.g. containerized nginx web server, i.e. any random internet client access your web server that's a different story as i see: you need to punch a hole on your firewall anyhow (see luci / firewall / port forward).

so not sure about your use case but a) you may want to re-think your use case if it really needs to expose anything, b) if so maybe it is better to use the standard owrt approach (port forwarding instead of playing with dockerd) and enhance docker security (privileged container vs unprivelged etc).

though, i think is not really recommended to expose docker containers directly on wan.

But... If in the end there is a random web application exposed via a Proxy then where is the difference? Sure databases and such which are not needed to be accessible should not be reachable. Just ensure that you just allow ports you really need. (I just hate all this unnecessary port forwarding and NAT shizzle. We have reached a point where most of "young" people do not even know that we have routing! And do not need NAT in many situations..../rant)

not sure what is your point which would be different to mine as i feel we agree on the allow ports only you need if you need part :wink:

"random web application exposed via a Proxy then where is the difference": application gateways exist for a reason, to expose web application securely: protocol analysis, DOS protection, TLS policy, WAF etc. but web (application) security is a totally different topic imho.

My intention is to deploy a Snapdrop and NextCloud in Docker and enable secure file sharing between home network and WAN.

The device R (abbrev. for Remote) is the device I want to share file with my home device H (abbrev. for Home)

My first attempt was to use VPN to connect the R to my home network, but it was not successful due to some restrictions.

Then I tried the following solution with my DDNS ready:

  1. Deploy a stand-alone Snapdrop container with internal IP 172.17.0.4
  2. Forward external port 50080 to 172.17.0.4:80, and forward external port 50443 to 172.17.0.4:443
  3. Set up a customized NAT rule to translate all the IP addresses of the connections incoming to 172.17.0.4 with external port 50080 and 50443 to 192.168.1.1 (home network address)

In this case, I'm expecting to expose this Snapdrop service to the public network and share the files with my own Cert.

I'm not quite sure if this NAT will make Snapdrop think that device R is in the same home network as H since I've been stuck in setting up the extra arguments for iptables. I've received an error message "bad argument ACCEPT" when setting up the iptables. In the worst case I'm gonna switch the solution to NextCloud, create an account with storage quota 2GB (which is on my NAS, different from my OpenWRT router) and also inject my own Cert. However, I still want Snapdrop since this is a real-time file transmission and the shared file doesn't land in my storage, while NextCloud is a net-disk-based solution which I'm trying to avoid even if the service is deployed by myself.

Well, I know it will never be too careful when it comes to the security issue. But using one Docker container for real-time file sharing and only exposing the needed ports to the internet is the most secure solution I could figure out based on my poor knowledge XD. If there are other secure file sharing solutions over the internet, I'd also like to give it a shot.

ok. don't do this if your files have any value for you.

setup wireguard vpn, there are plenty of guides how to set on owrt. then you can access your nextcloud securely without expose it to internet.

for what purpose? how would it stop hackers to crack your nextcloud?

keep in mind once you expose NC to internet it is really exposed: anybody can try to connect it not just you. CVEs related to NC link these are the possible attack vectors, so it is your call if you open the opportunity to hackers break in to your system by exposing your server.

if you are referring to a (self-signed) server cert that will be not enough to close these vulnerabilities. with a (self-signed) server cert still any client can connect (that's the whole purpose of server cert, i.e. make sure for clients that the server they are connecting to is the one they suppose to connect to, it works for any client). if you mean client cert to identify the client the vulnerabilities are still there.

traditional firewall is for network protection not an application protection. if a port is open and there is stupid application which has known default user/password, weak password policy, sensitive to brute force login, does not do input validation etc etc etc then it is like an invitation for hackers to break in, stole your data, install virus and so on.

use vpn.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.