The above output is an interesting discovery I found with the relationship between Podman and Firewalld (aka firewall-cmd).
So I was tinkering with a semi-production environment that is a web server with Apache and PHP on it, and a MySQL database running as a container. This was originally just done quickly, but is becoming more and more important. Honestly, long term, I may want to just move the database to an actual VM that has all the bells and whistles - like Cron for scheduled backups, etc. I digress.
The point is I was reading an article that a lot of sites have MySQL databases without SSL. If you run your database in a container, there is a good chance it also doesn't have SSL since most Docker images do not include that out-of-the-box. I personally don't think it is a problem if the service is on a truly internal network, but I ran a Telnet check from a remote system and it responded. Holy ^$%%@#$!
Now the port shouldn't be exposed, the firewall-cmd rules for the external interface don't allow that port type. However, with further testing I was able to connect a phpmyadmin to that host from a completely remote system. Holy#$%^&*&^%$!
What happens is on RedHat / CentOS / Fedora, podman essentially knows about firewall-cmd and spins itself into the zone trusted. You get that source and everything is available from that source. This also allows the outside world to come to that port - which is NOT what we want.
Turns out though, that it is relatively straightforward to lock this down.
Backup all the databases using a mysqldump - or in this case just by using a PHPMyAdmin to export.
Then destroy the current container. Run the following:
podman stop <DB container name>
podman rm <DB container name>
Assuming the container has its /var/lib/mysql directory mounted to the host using the -v or --volume at creation likely the backups won't need to be restored. Just re-run the container creation command (example below).
podman run -d --name mySQLdb -v <host directory>:/var/lib/mysql -p 127.0.0.1:3306:3306 --restart=unless-stopped -e MYSQL_ROOT_PASSWORD=<password> -e lower_case_table_names=1 mysql:5.7
The difference in the above command is that the localhost IP - 127.0.0.1 - is specified along with the port value. As such, the container is now only reachable by services or other containers running on the local system.
Now testing with a telnet command to that host with port 3306 shows unreachable, but the local web server can still interact with the database.
telnet: Unable to connect to remote host: No route to host
Most tutorials and explanations about Docker or Podman or containers in general usually cover the "-p" call as a network port. However, it can also be used to bind a specific IP:portnum which is very important to helping protect a system that is running on the Internet.
I hope this can help others keep themselves safer when using containers in production.
No comments:
Post a Comment