This gist contains example of how you can configure nginx reverse-proxy with autmatic container discovery, SSL certificates generation (using Let's Encrypt) and auto updates.
Features:
- Automatically detect new containers and reconfigure nginx reverse-proxy
- Automatically generate/update SSL certificates for all specified containers.
- Watch for new docker images and update them.
- Ban bots and hackers who are trying to bruteforce your website or do anything suspicious.
Techonolgy stack:
- Docker, docker-compose
- jwilder/nginx-proxy - nginx reverse proxy
- jrcs/letsencrypt-nginx-proxy-companion - Let's encrypt SSL
- containrrr/watchtower - auto updater for containers
- crazymax/fail2ban - dynamic firewall
- nginx - sample service based on the nginx image
With watchtower you can update the running version of your containerized app simply by pushing a new image to the Docker Hub or your own image registry. Watchtower will pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
In this example we run watchtower with the following command: "--interval 60 --cleanup", so basically we ask watchtower to check for new images every minute and remove old images when udpate is performed.
Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs -- too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured.
In this example I created two configuration rules - "wplogin" and "phpmyadmin".
- "wplogin" rule: if someone will make 3 POST call to "wp-login.php" within 10 minutes - consider it as a brute force attack and block such IP for 10 minutes.
- "phpmyadmin" rule: I don't host any "phpmyadmin" implementation on the website, so if someone (or some vulnerability scanner to be preciese) will try reach such URL - block his IP for an hour.
How to use fail2ban client?
# check status
$ sudo docker exec -t fail2ban fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: phpmyadmin, wplogin
# Check status of specific jail
$ sudo docker exec -t fail2ban fail2ban-client status phpmyadmin
Status for the jail: phpmyadmin
|- Filter
| |- Currently failed: 0
| |- Total failed: 2
| `- File list: /container-logs/[....]-json.log
`- Actions
|- Currently banned: 0
|- Total banned: 2
`- Banned IP list:
# ban specific IP
$ sudo docker exec -t fail2ban fail2ban-client set <JAIL> banip <IP>
# unban specific IP
$ sudo docker exec -t fail2ban fail2ban-client set <JAIL> banip <IP>
I had the problem that fail2ban banned IPs and added a correct iptables rule, though the rule was not processed correctly - banned IPs came through anyway. It seemed like the rule was not in the correct order. The solution for me was to specifically configuring the chain DOCKER-USER to be used in the fail2ban jail like this:
Source: fail2ban/fail2ban#2292
PS: thanks for this awesome guide which really helped me for my project!