8 ms·
I would add one more general security tip. Always restrict your mapped ports to localhost (as in 127.0.0.1:3306:3306) unless you really want to expose it to the
by blago 6y ago
I would add one more general security tip. Always restrict your mapped ports to localhost (as in 127.0.0.1:3306:3306) unless you really want to expose it to the world.
I think it's counterintuitive, but I learned the hard way that 3306:3306 will automatically add a rule to open the firewall on linux and make MySQL publicly accessible.
- BossingAround 6y ago> I learned the hard way that 3306:3306 will automatically add a rule to open the firewall on linux and make MySQL publicly accessible. Is that true? 3306:3306 would bind the port on all interfaces, but I was under the assumption you'd have to explicitly enable firewall port 3306 for the machine to accept traffic to port 3306 from outside of your machine. I'll have to test that.
- blago 6y agohttps://github.com/docker/for-linux/issues/690 https://github.com/docker/for-linux/issues/690
- isbvhodnvemrwvn 6y agoFrom memory and a quick glance at one of my servers: When an IP packet related to your container arrives (<host ip>:<host port>): - docker rewrites it to target <your container's ip address>:<your container's port> (NAT table, chain PREROUTING delegates to DOCKER chain with the relevant DNAT entry) - since the IP does not match your host, the packet is forwarded (there's a relevant routing entry pointing to docker's virtual interface) - the first thing you encounter in the FORWARD chain of the FILTER table is a few jumps to the docker-related chains, DOCKER chain in particular accepts all packets destined to <your container's ip address>:<your container's port> So a few takeaways: - your standard firewall might not be involved because its chains are plugged in after the docker chains in the FORWARD chain (e.g. ufw under Ubuntu) - if the above is true and you want your firewall to matter, you have to add stuff to DOCKER-USER chain in the FILTER table - at that point the host port and IP doesn't matter since it's already been mapped in the NAT table's PREROUTE chain at the beginning of processing - write your firewall rules to address specific containers
- junon 6y ago> automatically add a rule to open the firewall on linux There's no way this is true. This completely defeats the purpose of a firewall. If it is happening, then it's Docker doing this - not the linux firewall that comes stock with most distribution (iptables and the like). They would never simply add rules to the chains just because something was listening on that port. Really, the best security advice for using Docker is to not use Docker. Unfortunately, there aren't very many "hold your hand" alternatives available. Aside from LXD and that family of technologies, which are criminally underused.
- Nullabillity 6y agoDocker uses iptables for port forwarding, and those rules typically end up ahead of the rules inserted by your firewall (firewalld/ufw/manual scripts/whatever). It's not so much that they explicitly open a firewall rule, as that they take a networking path that isn't really covered by traditional firewalls. Another way of viewing it is that Docker "is" your firewall for your container workloads, and that adding a port-forward is equivalent to adding a firewall rule. Of course, that doesn't change that public-by-default is a bad default.
- junon 6y agoThis is right, I remember now - docker does mangle your iptables chains. I remember fighting with this a while back. Terrible practice, in my opinion. Docker shouldn't be touching firewall stuff.
- krab 6y agoIptables magic is essential to how a lot of container networking stuff is implemented, though.
- peterwwillis 6y agoThis is (imho) a huge flaw in the concept of a "container". I don't think most people comprehend how much crap is going on in the background. For most container purposes, host networking and the default process namespace is absolutely fine, and reduces a lot of problems with interacting with containerized apps. 95% of the use case of containers is effectively just a chroot wrapper. If you need more features, this should be optional. This would also make rootless federated containerized apps just work. But nobody wants to go back to incremental features if Docker gives them everything at once.
- gchamonlive 6y agoI like creating a security choke point, like a firewall in a vm serving as a nat gateway or actual cloud security groups and network acl. This way you can make all your servers private and manage the firewall in a single access point to the outside world. Making your servers public to the net by default and without a separate firewall solution is not so advisable in the first place.
- chousuke 6y agoPeople who know enough to consider architectures like this aren't the ones most likely to accidentally expose databases to the internet. It happens, but most often these mistakes are made by people who just don't have the experience to be wary. I think software like docker have a responsibility to encourage secure-by-default configurations, but unfortunately "easy" is often the default that wins mindshare.
- gchamonlive 6y agoI am not sure why you were downvoted. I agree with that. I prefer technologies that are restrictive by default and more flexible and potentially harmful configurations hidden behind explicit and well structured options. Either an exception should be raised or a default safe behaviour should be adopted when the example is encountered. I prefere breaking as soon as possible because the alternative is harder to debug.
- carlmr 6y agoI agree with you, but since Docker is kind of a given, how can one learn the necessary stuff about networking as to not make these mistakes? I always see best practices like this, but they don't really help in grokking what's happening and why. I'd like to know more about the networking stuff, but whenever i look something up it's very specific, so you don't really learn why it's bad. How can a regular user understand how the network stack works? At least enough to get an instinct why something would be bad.
- gchamonlive 6y ago
- nickjj 6y agoYep, this was especially deadly a few years back with Redis because it bound to 0.0.0.0 by default and by default Redis allows connections without a password. So if you had 6379:6379 published anyone from the internet could connect to your Redis container. Oops. > Always restrict your mapped ports to localhost (as in 127.0.0.1:3306:3306) unless you really want to expose it to the world It's also worth pointing out that typically you don't even need to publish your database port. If you omit it, containers on the same network can still communicate with each other. Very rarely do I end up publishing ports in production. If you wanted to connect to postgres you could still docker exec into the container on the box it's running on and interact with your db using psql that's already installed in that container. A while back I wrote a blog post on the difference vs exposing and publishing ports at https://nickjanetakis.com/blog/docker-tip-59-difference-between-exposing-and-publishing-ports https://nickjanetakis.com/blog/docker-tip-59-difference-betw....
- amanzi 6y agoThis is why I like to use both a host-based firewall __as well as__ a network-based firewall. For the VPS's that I have running on the internet, I always use the hosting provider's firewall offering in addition to iptables (or ufw).
- MaxBarraclough 6y agoThis is something AWS gets right, and Digital Ocean and Linode both get wrong (they offer no cloud firewall of any sort, to my knowledge). It should be trivial for me to lock down the ports of my instance, from the VPS web UI. AWS lets me create a new instance which is entirely closed to incoming connections except for port 22, which is closed except for whitelisting my IP address. This gives me good assurances even if my instance is running a vulnerable SSH server. It's also trivial to block outgoing connections, where that's appropriate. It also means my instance is spared from constant probing, which keeps the logs clear.
- nickjj 6y ago> Digital Ocean and Linode both get wrong (they offer no cloud firewall of any sort, to my knowledge) DO has had a cloud firewall for a while now (a year or 2?) https://www.digitalocean.com/docs/networking/firewalls/ https://www.digitalocean.com/docs/networking/firewalls/. It's free too. Looks like Linode has one coming soon https://www.linode.com/products/firewall/ https://www.linode.com/products/firewall/.
- optimuspaul 6y agoWhy would you have a database running on a machine with a public ip?
- CGamesPlay 6y agoFor UFW users, installing this will make docker compatible with the firewall. https://github.com/chaifeng/ufw-docker https://github.com/chaifeng/ufw-docker
- pabs3 6y agoI'd map them to sockets instead, since you can't restrict a TCP/UDP port to a specific user.