Zidichy Posted February 21, 2021 Share Posted February 21, 2021 (edited) Hi let me first start of by saying, that i would have liked to contribute to unraid community a long time ago, but time has been getting in my way. And now that lastpass has decided to limit their free service, which force many users to change password manager and a lot of people is turning to bitwarden, i thought it would be a good idea for me to share in detail exactly how to protect your selfhosted bitwarden (bitwarden_rs) with fail2ban and connect it to cloudflare IP Access Rules. And also protect /admin 😋 So in this guide we are going to be using the following. 1. Swag from linuxserver/swag 2. Bitwardenrs from bitwardenrs/server 3. GilbN's cloudflare-apiv4 template So let's say some unknown user comes along and tries to login with unauthorized credentials / start hammering the portal 30 seconds ~ 1 min and poff banned via cloudflare. Here is how we set this up. (my bitwardenrs container is named bitwarden) First we go into the settings of bitwardenrs container and we edit the template like I have in the images below. And inside bitwarden logs you add this. The /data/ is equal to /mnt/cache/appdata/bitwarden/ Now it's important to know that the bitwarden.log I have there is not going to be generated untill you add the varaibles in the container, then restart the container. Once this is done the .log will show up in /appdata/bitwarden/ Lets now head into the fail2ban folder that is located inside /mnt/cache/appdata/swag/fail2ban And let's open jail.local (your might be different) but these are the settings i use for my fail2ban if we scroll down below to the very end, and we add our own jail for bitwarden this is what you type. (ofc you add your own IP) Save the jail and cd into, /mnt/cache/appdata/swag/fail2ban/filter.d (thank you zfa for noticing that i missed a line at action) Create a new file in here called bitwarden_rs.conf In this file you type this, Then save it. Now cd into /mnt/cache/appdata/swag/fail2ban/action.d Create a new file in here called cloudflare-apiv4.conf inside this file you copy the excellent template from GilbN which you can find on his blog here https://technicalramblings.com/blog/cloudflare-fail2ban-integration-with-automated-set_real_ip_from-in-nginx/ Not much needs to be changed in here just at the bottom, cfuser = and cftoken = and you can find those from https://dash.cloudflare.com/profile/api-tokens (Global API Key) Next let's head into Swag container, and add a path like i have done in the image below. And same thing here, the /bitwarden/ is equal to /mnt/cache/appdata/bitwarden/ Next you save and restart swag Following commands should now work. In unraid webui > webterminal type > docker exec -it swag bash > cat bitwarden/bitwarden.log A tail should work also, webterminal > docker exec swag tail -f /bitwarden/bitwarden.log Don't know if you need it but, this is how my volume mapping looks for bitwarden. Yours should look the same. I wanted to add this section. As I have CF Real IP in my nginx.conf located in /mnt/cache/appdata/swag/nginx/nginx.conf ## # CF Real IP ## include /config/nginx/cf_real-ip.conf; real_ip_header X-Forwarded-For; right under my Gzip Settings If i do a simple cat on cf_real-ip.conf it looks like this. :~# cat /mnt/cache/appdata/swag/nginx/cf_real-ip.conf ## Version 2021/02/06 set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/12; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; set_real_ip_from 2400:cb00::/32; set_real_ip_from 2606:4700::/32; set_real_ip_from 2803:f800::/32; set_real_ip_from 2405:b500::/32; set_real_ip_from 2405:8100::/32; set_real_ip_from 2c0f:f248::/32; set_real_ip_from 2a06:98c0::/29; When it comes to the reverse proxy for some reason i could not get the default template from linuxserver.io to work for me. So i decided to add my reverse proxy and my ssl.conf that i use for bitwarden. (gives A+ on securityheaders.com) It's based on Roxedus template (i think...) ## Version 2020/12/09 server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name bw.FQDN.TLD; # TLS settings include /config/nginx/bitssl.conf; # Organizr Authentication include /config/nginx/auth.conf; # Custom Error Pages include /config/nginx/errorpages.conf; # Maxmind Geographic IP Block # include /config/nginx/geoblock.conf; client_max_body_size 128M; location /{ proxy_pass http://IP:PORT; proxy_redirect off; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Protocol $scheme; proxy_set_header X-Url-Scheme $scheme; proxy_hide_header X-Frame-Options; proxy_hide_header "x-webkit-csp"; proxy_hide_header "content-security-policy"; proxy_set_header Accept-Encoding ""; sub_filter '</head>' '<link rel="stylesheet" type="text/css" href="https://gilbn.github.io/theme.park/CSS/themes/bitwarden/plex.css"> </head>'; sub_filter_once on; } location /admin { auth_request /auth-0; include /config/nginx/proxy.conf; resolver 127.0.0.11 valid=30s; set $upstream_app bitwarden; set $upstream_port 8242; set $upstream_proto http; proxy_pass http://IP:PORT; } location /notifications/hub/negotiate { proxy_pass http://IP:PORT; } location /notifications/hub { proxy_pass http://IP:PORT; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } Error pages can be found from here https://docs.organizr.app/books/setup-features/page/custom-error-pages Here is my bitssl.conf ## Version 2019/06/19 - Changelog: https://github.com/linuxserver/docker-letsencrypt/commits/master/root/defaults/ssl.conf # session settings ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE cipher suites ssl_dhparam /config/nginx/dhparams.pem; # ssl certs ssl_certificate /config/keys/letsencrypt/fullchain.pem; ssl_certificate_key /config/keys/letsencrypt/privkey.pem; # protocols ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 127.0.0.11 valid=30s; # Docker DNS Server ## Header security settings to reach A+ Grade on, htbridge.com/websec | securityheaders.io | ssllabs.com add_header Content-Security-Policy "form-action 'self' https://xy.FQDN.TLD https://FQDN.TLD; base-uri 'self'; upgrade-insecure-requests; block-all-mixed-content; frame-ancestors https://xy.FQDN.TLD https://yx.FQDN.TLD https://FQDN.TLD"; add_header "Content-Security-Policy-Report-Only" "report-uri https://xy.report-uri.com/r/d/csp/reportOnly"; add_header Expect-CT max-age=604800,enforce,report-uri="https://xy.report-uri.com/r/d/ct/reportOnly"; add_header Expect-Staple "max-age=31536000; includeSubDomains; preload"; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "ALLOW-FROM https://yx.FQDN.TLD"; add_header X-Robots-Tag none; ##/SSL SETTINGS And since i'm using organizr as my http authentication i'll include that .conf too Now if the bitwarden.conf fails just # the auth out or ask here in comments and i'll do my best to help out # Version 2020/12/09 # ###################### # Organizr Auth v2 # ###################### # auth_request /auth-0; #=Admin # auth_request /auth-1; #=Co-Admin # auth_request /auth-2; #=Super User # auth_request /auth-3; #=Power User # auth_request /auth-4; #=User # auth_request /auth-8; # logged in # auth_request /auth-9; #=Guest location ~ /auth-([0-9]+) { internal; include /config/nginx/proxy.conf; resolver 127.0.0.11 valid=30s; set $upstream_organizr organizrv2; proxy_pass http://IP:PORT/api/v2/auth?group=$1; proxy_set_header Content-Length ""; } After this restart swag. And that's it Everything should now be working as intended. This guide was written & created by me Zidichy on February 21, 2021. ~ Fin Edited March 12, 2021 by Zidichy added info to the guide. 1 6 Quote Link to comment
Selmak Posted January 26, 2022 Share Posted January 26, 2022 Thank you for this. I have been trying to get swag fail2ban working for the last day with Authelia. I had it banning the IP address but it was not actually blocking the connection. Here is the error just in case anyone knows what it is. 2022-01-26 13:06:07,664 fail2ban.utils [1756]: ERROR 150757ff7190 -- exec: ip6tables -w -N f2b-authelia ip6tables -w -A f2b-authelia -j RETURN ip6tables -w -I DOCKER-USER -p tcp -j f2b-authelia 2022-01-26 13:06:07,664 fail2ban.utils [1756]: ERROR 150757ff7190 -- stderr: 'ip6tables: Chain already exists.' 2022-01-26 13:06:07,665 fail2ban.utils [1756]: ERROR 150757ff7190 -- stderr: 'ip6tables: No chain/target/match by that name.' 2022-01-26 13:06:07,665 fail2ban.utils [1756]: ERROR 150757ff7190 -- returned 1 Anyway 10 mins after reading your post fail2ban is working with cloudflare. 1 Quote Link to comment
Zidichy Posted January 28, 2022 Author Share Posted January 28, 2022 On 1/26/2022 at 5:48 AM, Selmak said: Thank you for this. I have been trying to get swag fail2ban working for the last day with Authelia. I had it banning the IP address but it was not actually blocking the connection. Here is the error just in case anyone knows what it is. 2022-01-26 13:06:07,664 fail2ban.utils [1756]: ERROR 150757ff7190 -- exec: ip6tables -w -N f2b-authelia ip6tables -w -A f2b-authelia -j RETURN ip6tables -w -I DOCKER-USER -p tcp -j f2b-authelia 2022-01-26 13:06:07,664 fail2ban.utils [1756]: ERROR 150757ff7190 -- stderr: 'ip6tables: Chain already exists.' 2022-01-26 13:06:07,665 fail2ban.utils [1756]: ERROR 150757ff7190 -- stderr: 'ip6tables: No chain/target/match by that name.' 2022-01-26 13:06:07,665 fail2ban.utils [1756]: ERROR 150757ff7190 -- returned 1 Anyway 10 mins after reading your post fail2ban is working with cloudflare. You're very welcome Quote Link to comment
Hammy Havoc Posted September 21, 2022 Share Posted September 21, 2022 Why did you screenshot your config instead of copy-pasting the text? Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.