Security
Please, note that this documentation :
- Is not exhaustive.
- Gives you the basics for securing your installation.
- Is based on a Docker installation of BorgWarehouse (it’s simple to adapt to a baremetal installation).
- I’ve chosen to use fail2ban for the examples in this documentation, but you’re free to use the IDS of your choice.
Log location
There are two main logs:
- The BorgWarehouse application log
- SSH service log
Logs are formatted by rsyslog to provide a clear timestamp. They are located in your volume, inside the logs
folder. You’re encouraged to use some form of logrotate, as SSH logs in particular can quickly become very large, depending on the exposure of your server.
Log format
Since BorgWarehouse v2.2.0, the log format has been improved to enable you to detect and respond to a case of login/password brutforce.
Here is the list of cases that trigger a specific log, and an example of the associated log :
Login log example | |
---|---|
❌ | Login failed from <IP> : Wrong password for alovelace [<Timestamp UTC ISO-8601>] |
❌ | Login failed from <IP> : Bad username ghopper [<Timestamp UTC ISO-8601>] |
✅ | Login success from <IP> with user yoda [<Timestamp UTC ISO-8601>] |
API log exemple | |
---|---|
❌ | API auth failed from : <IP> [<Timestamp UTC ISO-8601>] |
✅ | API auth success with the token '<token-name>' of user '<username>' from : <IP> [<Timestamp UTC ISO-8601>] |
Fail2ban
The SSH part is relatively simple, as we’ll be using the SSH filter provided by fail2ban. For the active response to login attempts on the web interface, I’ve created an adaptive filter that I’ll share with you.
Create a new jail for BorgWarehouse
Inside the jail.d
directory of fail2ban, create a new borgwarehouse.conf
with :
[borgwarehouse-ssh]
filter = sshd[mode=aggressive]
enabled = true
logpath = <path-to-docker-volume>/logs/sshd.log
maxretry = 3
findtime = 600
bantime = 360000
#Delete the next line for non-docker env.
chain = DOCKER-USER
[borgwarehouse-login]
filter = borgwarehouse
enabled = true
logpath = <path-to-docker-volume>/logs/borgwarehouse.log
maxretry = 3
bantime = 360000
Create a new borgwarehouse filter
Inside the filter.d
directory of fail2ban, create a new borgwarehouse.conf
with :
[Definition]
failregex = ^.* Login failed from <HOST> .*
^.* API auth failed from : <HOST> .*
Check your configuration
Restart your fail2ban service and check the status of jails :
fail2ban-client status borgwarehouse-ssh
fail2ban-client status borgwarehouse-login
SSHD default configuration
SSH daemon configuration is required to enable BorgBackup backups. BorgWarehouse in its “docker” version provides a default configuration which is placed in <your-volume>/ssh_host/sshd_config
. You can read this default configuration here.
By default, I’ve provided a restrictive configuration adapted to BorgBackup use and compliant with ANSSI recommendations. However, this configuration can be modified and adapted to suit your needs.
Using BorgWarehouse behind HTTP Basic Authentication (.htpasswd)
It is of course possible to use BorgWarehouse behind HTTP Basic Authentication.
However, this authentication requires you to pass an ‘Authorization’ header, which means you won’t be able to use the integration API requests. To be able to combine HTTP Basic authentication with REST API management of your repositories, you need to adapt the configuration of your web server.
In this documentation, the example chosen is an Apache 2 vhost, but it can be adapted to any type of web server.
Inside your vhost, this is an example of good configuration :
<VirtualHost *:443>
...
# Check if Authorization header has a Bearer Token
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^Bearer\s(.*)
RewriteRule .* - [E=NO_AUTH_REQUIRED:true]
</IfModule>
<Location />
# Allow access if the Authorization header contains a Bearer token
SetEnvIf Authorization "Bearer" NO_AUTH_REQUIRED
Require env NO_AUTH_REQUIRED
# HTTP Basic Auth
AuthType Basic
AuthName "BorgWarehouse Basic Auth"
AuthUserFile .htpasswd
Require valid-user
</Location>
...
</VirtualHost>
With a configuration like this, you can have a HTTP Basic Authentication and your REST API is still functional.