By using basic auth on you apps there is nothing stopping people from trying to brute force their way in. But by implementing Fail2ban, you can give the user or intruder x amount of retries before getting banned.

Creating the .htpasswd file

SSH into your server and create the .htpasswd file

Use this command to create a .htpasswd file. Just drop the docker part if you don’t use that.

docker exec -it letsencrypt htpasswd -c /config/nginx/.htpasswd USER-NAME

New password:
Re-type new password:
Adding password for user yourusername

The outcome would be like this:

login:password
exampleuser:$apr1$adiBYUBX$61udeQ5OGHJXev1l.Mr5X/

If you choose to put the .htaccess in your root folder you can block access to it with this:

location ~ /\. { 
return 404; 
}

Nginx

Use the include syntax and create a basicauth.conf file that you include in the block.

include /config/nginx/basicauth.conf;

Here is an example:

# SABNZBD redirect
location /sabnzbd {
return 301 /sabnzbd/;
}
# SABNZBD
location /sabnzbd/ {
include /config/nginx/basicauth.conf;
include /config/nginx/proxy.conf;
proxy_pass http://192.168.1.34:8383/sabnzbd/;
}

Note: This will not work if you use server based authentication with Organizr. Read more here

basicauth.conf contents

auth_basic "Restricted";
auth_basic_user_file /config/nginx/.htpasswd;

Fail2ban

If you use linuxservers letsencrypt container, Fail2ban should already be pre configured to ban failed http auths.

If not you can add this in your jail.local file.

[nginx-http-auth]

enabled = true
filter = nginx-http-auth
port = http,https
logpath = /config/log/nginx/error.log
ignoreip = 192.168.1.0/24

Note: The ignore IP is so that fail2ban won’t ban your local IP. Check out http://jodies.de/ipcalc if you are wondering what your netmask is.

  • The logpath is the path to your nginx error log

You also need to create a file called nginx-http-auth.conf in the filter.d folder in the fail2ban directory.

# fail2ban filter configuration for nginx
[Definition]

failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$

ignoreregex = 

# DEV NOTES:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# 
# Author: Daniel Black
Fail2ban.log output
2017-11-04 15:14:58,867 fail2ban.filter [308]: INFO [nginx-http-auth] Ignore 192.168.1.1 by ip
2017-11-04 15:14:58,868 fail2ban.filter [308]: INFO [nginx-http-auth] Ignore 192.168.1.1 by ip
2017-11-04 15:52:04,055 fail2ban.filter [308]: INFO [nginx-http-auth] Found 77.16.40.104 - 2017-11-04 15:52:04
2017-11-04 15:52:06,530 fail2ban.filter [308]: INFO [nginx-http-auth] Found 77.16.40.104 - 2017-11-04 15:52:06
2017-11-04 15:52:16,989 fail2ban.filter [308]: INFO [nginx-http-auth] Found 77.16.40.104 - 2017-11-04 15:52:16
2017-11-04 15:52:18,817 fail2ban.filter [308]: INFO [nginx-http-auth] Found 77.16.40.104 - 2017-11-04 15:52:18
2017-11-04 15:52:29,309 fail2ban.filter [308]: INFO [nginx-http-auth] Found 77.16.40.104 - 2017-11-04 15:52:29
2017-11-04 15:52:29,340 fail2ban.actions [308]: NOTICE [nginx-http-auth] Ban 77.16.40.104

Unbanning

If you managed to ban yourself or a friend banned themself you can do this to unban.

SSH into the container with:

docker exec -it letsencrypt bash

Enter fail2ban interactive mode:

fail2ban-client -i

Check the status of the jail:

status nginx-http-auth

Output

Status for the jail: nginx-http-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 5
| `- File list: /config/log/nginx/error.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 77.16.40.104

unban with:

set nginx-http-auth unbanip 77.16.40.104

If you already know the IP you want to unban you can just type this:

docker exec -it letsencrypt fail2ban-client set nginx-http-auth unbanip 77.16.40.104

For Fail2Ban integration with Organizr, check out my post here