I want to close my containers running in Docker to the outside world. Brute-force attacks are constantly coming to my mysql port. I don’t know how to prevent it. I add rules in ip tables, rules don’t work. I don’t know what am I doing wrong.
Commands I tried.
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
iptables -I DOCKER-USER -i ext_if ! -s 172.18.0.2 -j DROP
I didn’t get a concrete answer from any of them.
2
Answers
Here are a few ways to close Docker containers to the outside world:
Do Not Expose Ports: By default, when you run a container, its network ports are not exposed to the host system or the external network. This means that other systems won’t be able to access services running inside the container unless you specifically map the container ports to the host ports using the
-p
option withdocker run
command. To ensure the container is not exposed to the outside world, simply avoid using the-p
option when starting the container.Example:
Use a Private Network: Docker allows you to create custom bridge networks to which containers can be attached. By using a custom bridge network, you can isolate containers from the default bridge network (which allows communication between containers by default). Containers connected to a custom bridge network won’t be directly accessible from the outside world.
Example:
Firewall Rules: You can use firewall rules to control inbound and outbound network traffic on your host system. By configuring your firewall to block incoming connections to specific ports used by Docker containers, you can effectively close access to those containers from the outside world.
Docker Compose: If you use Docker Compose to manage your containers, you can specify the
expose
directive in the Compose file to indicate that the container should be accessible from other containers on the same network, but not from the external network.Example
docker-compose.yml
snippet:Remember that securing your containers is essential, especially when running them in production environments. Always follow security best practices and keep your software and Docker images up to date with the latest security patches. Additionally, consider using tools like Docker Secrets for sensitive data and restricting access to containers as needed. Hope that helps.
Typically, the best option is to not publish the port. You can access container-to-container by creating your own network and accessing the container using the container name and the port the application is listening on. With compose, this is built-in with a network alias (DNS name) for each service name. E.g. with this compose file
From
app
you can connect todb
on whichever port the DB listens on, no need to publish the port, or even expose it (exposing ports is typically done as documentation).An alternative to publishing the port on all interfaces is to only publish on the loopback interface, allowing access from the local machine, but not from any external hosts:
If you need to publish the port, then the iptables rules should use conntrack if you want to limit the rule to a specific host port. The interface may also need adjusting because I believe the rule is processed after the packet has been mangled for the container network:
It’s also important that these rules are added with an insert (
-I
) since there is a default accept all rule inDOCKER-USER
that overrides all rules added after it.