filebrowser-pub
This tutorial is for Debian Trixie users seeking to set up a secure and public-facing Filebrowser instance. This is to assist with uploading and managing music/media on Navidrome, Jellyfin, and other similar instances. Do not proceed with this tutorial until you've learned how to set up a public facing VM/VPS and harden it appropriately. If you have not done that, start with Apache Survival. So long as that's in place, you can safely begin. You can install Filebrowser manually, or use their automated bash script. I chose the latter. Make sure to verify the checksums and code before using the pipe-to-bash approach like me:
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
The system will give you an auto-generated user and password upon completion of the installer. Let's change that before we proceed:
sudo systemctl stop filebrowser sudo filebrowser users update admin --password yournewpassword sudo systemctl start filebrowser
Make sure to pick a 16+ character password; this is public facing. To be clear, this is invoking the filebrowser service to update the admin user in the sql lite database it just created. The service does, however, required a dedicated simple UNIX user, which we will now create and make sure to turn off home directory and shell access for:
sudo adduser --system --group --no-create-home filebrowser
Once the dedicated user is created, let's create the systemd unit to control starting/stopping the service. Let's create a unit file here sudo nano/etc/systemd/system/filebrowser.service and drop these contents inside:
[Unit] Description=File Browser After=network.target [Service] User=filebrowser Group=filebrowser WorkingDirectory=/var/lib/filebrowser ExecStart=/usr/local/bin/filebrowser \ --address 127.0.0.1 \ --port 8080 \ --root /opt/navidrome/music \ --database /var/lib/filebrowser/filebrowser.db Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Once that's in place, load the unit and start the service:
sudo systemctl daemon-reload sudo systemctl enable --now filebrowser
Make sure to customize the unit file for your own use-case. For example, you might have a different startup directory, different listening port, and so on. Once the unit file is created and the service has started, let's make sure that ACL is installed so we can set a custom rule for the filebrowser UNIX user, which the filebrowser's GUI / sql lite database will send commands to via your web session, which is behind a reverse proxy in apache. Let's get that done:
sudo apt install acl sudo setfacl -R -m u:filebrowser:rwx /opt/navidrome/music sudo setfacl -R -m d:u:filebrowser:rwx /opt/navidrome/music
This assumes /opt/navidrome/music is already established and running. If not, then consult the Navidrome tutorial first. The ACL above gives every current file read and write access (first stanza) and all future users read and write access (second stanza). At this time, filebrowser is already running, but behind port 8080. Now, one could simply access it with http://domain:com:8080 but that won't be TLS secured and is just kind of janky. So, for these cases, we create a reverse proxy that sits facing the public and receiving requests, and then pushes incoming requests upstream to the filebrowser service running locally on port 8080. To do that, let's first edit /etc/apache2/000-default.conf and edit the ServerName to domain.com, change the web root to /var/www/domain.com/public_html and leave everything else as is. Restart the service with systemctl restart apache2 and then let's create a Let's Encrypt cert on the thusly adjusted default virtual host:
sudo apt install certbot letsencrypt python3-certbot-apache sudo certbot --authenticator standalone --installer apache -d domain.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"
This will create another virtual host at 000-default-le.conf or something similar. It will be automatically activated along with 000-default.conf by default. But, this is serving requests from /var/www/domain.com/public_html, and so the upstream filebrowser service is entirely ignored. But/and, the dirty work of creating the TLS cert is now done, so we can simply drop in some replacement configurations into both vhosts and restart the apache2 service and everything will automagically work. Open nano /etc/apache2/sites-available/000-default.conf and drop this inside:
<VirtualHost *:80> ServerName upload.gnulinux.studio RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301] </VirtualHost>
Now, let's do the same trick with the https virtual host. Open up nano /etc/apache2/sites-available/000-default-le.conf and drop this inside:
<VirtualHost *:443> ServerName upload.gnulinux.studio SSLEngine on SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem ProxyPreserveHost On ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ RewriteEngine On RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/?(.*) ws://127.0.0.1:8080/$1 [P,L] </VirtualHost>
Once this is done, you should be good to go. Make sure that:
This tutorial is not designed to provide a full tutorial on these topics, but generally these modules are enough:
sudo a2enmod ssl sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_wstunnel sudo a2enmod headers sudo a2enmod rewrite sudo a2enmod remoteip sudo a2enmod proxy_fcgi sudo a2enmod setenvif
If you need more guidance, see the Apache Survival Tutorial already linked at the top. If you need help with mpm_event and fpm, use my WordPress tutorial. The only other thing you can optionally do is setup a rule to stop repeat brute-force attackers on Filebrowser's auth mechanism. This is optional, but here's a recipe I got off Reddit and adjusted. Open up /etc/fail2ban/jail.d/filebrowser.conf and create the jail:
[filebrowser] enabled = true backend = systemd port = 8080 filter = filebrowser logpath = /var/log/filebrowser/filebrowser.log maxretry = 3 findtime = 600 bantime = 3600 action = iptables-allports[name=filebrowser]
After the jail is established, we need to create the filter that the jail leverages to decide on whether it bans the request. To do that, open up /etc/fail2ban/filter.d/filebrowser.conf and drop the filter rules in it:
[INCLUDES] before = common.conf [Definition] datepattern = ^%%Y/%%m/%%d %%H:%%M:%%S failregex = /api/login: 403 <HOST> .* ignoreregex =
Make sure to adjust bantime, maxretry, and findtime to your preferences. Also, apache-auth's default jail is not designed for reverse proxies. So, let's create one more jail+filter to block repeat offenders against the proxy, which will trigger a 401 and/or 403 due to them trying to access something that does not exist. Let's open up the jail file /etc/fail2ban/jail.d/apache-auth.conf and drop this inside:
[apache-auth] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache2/error.log maxretry = 5 findtime = 600 bantime = 3600 action = iptables-allports[name=apache-auth]
Now, for the filter, let's open /etc/fail2ban/filter.d/apache-auth.conf and drop the following inside:
[Definition] failregex = ^<HOST> -.*"(GET|POST|HEAD).* 401 ^<HOST> -.*"(GET|POST|HEAD).* 403 ignoreregex =
This creates a separate jail for common errors brute-forcers will receive when they are trying to access your instance's directories etc. Restart the service systemctl restart fail2ban and you should be good to go. If you need help, hit me up on Matrix; I'll be happy to help!
Happy Hacking !!!
— oemb1905 2025/12/09 05:10