Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Harden Nextcloud 17+ with Fail2Ban, GUI and WebDAV - Ubuntu 20.04

Fail2ban and Nextcloud

Prerequsits

  • Ubuntu 20.04
  • nextcloud, fail2ban and e.g. iptables are installed

Note

Finally since 29 Juli 2020 this procedure is a part of an official Nextcloud Documentation. Please follow the link: https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#setup-fail2ban

Short how-to harden your Nextcloud Server with Fail2Ban

Install fail2ban:

sudo apt update && sudo apt install fail2ban -y

Create the Nextcloud-filter:

sudo nano /etc/fail2ban/filter.d/nextcloud.conf

Paste the following lines, this will cover GUI Failed login and WebDAV:

[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

If you want to protect also from direct IP access or wrong Domain name access configure it as below (as per https://github.com/nextcloud/vm/blob/master/apps/fail2ban.sh)

[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
            ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

Create a new jail:

sudo nano /etc/fail2ban/jail.d/nextcloud.local

Paste the following rows:

[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
#Number of retrys before to ban
maxretry = 3
#time in seconds
bantime = 36000
findtime = 36000
#Log path, on Ubuntu usually is following
logpath = /var/www/nextcloud/data/nextcloud.log
#For Univention Appliances the logfile is in /var/lib/univention-appcenter/apps/nextcloud/data/nextcloud-data/nextcloud.log
#logpath = /var/lib/univention-appcenter/apps/nextcloud/data/nextcloud-data/nextcloud.log

Re-start the fail2ban-service:

sudo service fail2ban restart

and enjoy your Nextcloud-Server!


P.S.

Pattern For GUI:

#Nextcloud 17+
{"reqId":"BRHKHyh1lVFon5D33u4K","level":2,"time":"2020-01-13T12:34:00+00:00","remoteAddr":"10.11.12.13","user":"--","app":"no app in context","method":"POST","url":"\/index.php\/login","message":"Login failed: Tralololjlkl (Remote IP: 10.11.12.13)","userAgent":"Mozilla\/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko\/20100101 Firefox\/72.0","version":"17.0.2.1"}
{"reqId":"y6OUpenieOevULRMaAFi","level":1,"time":"2020-06-10T13:19:06+00:00","remoteAddr":"10.11.12.13","user":"--","app":"core","method":"GET","url":"/","message":"Trusted domain error. \"10.11.12.13\" tried to access using \"Trololo.com\" as host.","userAgent":"curl/7.58.0","version":"18.0.6.0"}

#Nextcloud <= 16
{"reqId":"bFnTdevf7ZdCMQ5ddmNl","level":2,"time":"2019-04-03T21:49:30+00:00","remoteAddr":"10.11.12.13","user":"--","app":"core","method":"POST","url":"\/index.php\/login","message":"Login failed: 'Tralololjlkl' (Remote IP: '10.11.12.13')","userAgent":"Mozilla\/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko\/20100101 Firefox\/66.0","version":"15.0.5.3"}

For WebDav:

#Nextcloud 17+
{"reqId":"lqdbtb7y3pZSv8sGM0mD","level":2,"time":"2020-01-26T22:20:32+00:00","remoteAddr":"10.11.12.13","user":"--","app":"core","method":"PUT","url":"\/remote.php\/webdav\/files","message":"Login failed: 'webdavlogin' (Remote IP: '10.11.12.13')","userAgent":"curl\/7.58.0","version":"17.0.2.1"}

#Nextcloud <= 16
{"reqId":"Q4wX3I4LOUeuMV4wRK91","level":2,"time":"2019-04-03T22:14:11+00:00","remoteAddr":"10.11.12.13","user":"--","app":"core","method":"GET","url":"\/remote.php\/dav\/files","message":"Login failed: 'test' (Remote IP: '10.11.12.13')","userAgent":"Mozilla\/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko\/20100101 Firefox\/66.0","version":"15.0.5.3"}

Test WebUI and Webdav and Trusted domain error.

# fail2ban-regex /var/nextcloud/data/nextcloud.log /etc/fail2ban/filter.d/nextcloud.local -v --print-all-matched

Running tests
=============

Use   failregex filter file : nextcloud, basedir: /etc/fail2ban
Use      datepattern : ,?\s*"time"\s*:\s*"Year-Month-Day[T ]24hour:Minute:Second(Zone offset)?"
Use         log file : /var/nextcloud/data/nextcloud.log
Use         encoding : UTF-8


Results
=======

Failregex: 3 total
|-  #) [# of hits] regular expression
|   1) [2] ^\{(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*),?\s*"remoteAddr":"<HOST>"(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*),?\s*"message":"Login failed:
|      10.11.12.13  Wed Jun 10 13:07:43 2020
|      10.11.12.13  Wed Jun 10 13:07:50 2020
|   2) [1] ^\{(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*),?\s*"remoteAddr":"<HOST>"(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*),?\s*"message":"Trusted domain error.
|      10.11.12.13  Wed Jun 10 15:19:06 2020
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [1654] ,?\s*"time"\s*:\s*"Year-Month-Day[T ]24hour:Minute:Second(Zone offset)?"
`-

Lines: 1654 lines, 0 ignored, 3 matched, 1651 missed
[processed in 0.61 sec]

|- Matched line(s):
|  {"reqId":"2uzhhzlkkzXEp9yICWXE","level":2,"time":"2020-06-10T11:07:43+00:00","remoteAddr":"10.11.12.13","user":"--","app":"no app in context","method":"POST","url":"/index.php/login","message":"Login failed: Gggggg (Remote IP: 10.11.12.13)","userAgent":"Mozilla/5.0 (Android 9; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0","version":"18.0.6.0"}
|  {"reqId":"2QPK9SkSVBj6r2d9ojnk","level":2,"time":"2020-06-10T11:07:50+00:00","remoteAddr":"10.11.12.13","user":"--","app":"no app in context","method":"POST","url":"/index.php/login","message":"Login failed: Gggggvvvvg (Remote IP: 10.11.12.13)","userAgent":"Mozilla/5.0 (Android 9; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0","version":"18.0.6.0"}
|  {"reqId":"y6OUpenieOevULRMaAFi","level":1,"time":"2020-06-10T13:19:06+00:00","remoteAddr":"10.11.12.13","user":"--","app":"core","method":"GET","url":"/","message":"Trusted domain error. \"10.11.12.13\" tried to access using \"Trololo.com\" as host.","userAgent":"curl/7.58.0","version":"18.0.6.0"}
`-
Missed line(s): too many to print.  Use --print-all-missed to print all 1651 lines
@GAS85
Copy link
Author

GAS85 commented Nov 24, 2020

@Hydranet, thanks, finally it is there, it took only 2 years 😄. I add a note at the beginning .

@stucksubstitute
Copy link

stucksubstitute commented Nov 24, 2020

Just tested it on my Nextcloud version 19.0.4.2 - works fine! Thanks.

@sanfx
Copy link

sanfx commented Oct 11, 2021

Has anyone set this up for nextcloud 21 ?

@GAS85
Copy link
Author

GAS85 commented Oct 12, 2021

Works for me fine on 21. It is even part of the official documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment