diff --git a/CHANGELOG.md b/CHANGELOG.md index ebed0675..dca1d1e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +In Development +-------------- + +* fail2ban won't start if Roundcube had not yet been used - new installations probably do not have fail2ban running. + v0.19 (August 13, 2016) ----------------------- diff --git a/setup/start.sh b/setup/start.sh index 9d19a411..790afe18 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -111,15 +111,22 @@ source setup/zpush.sh source setup/management.sh source setup/munin.sh -# Ping the management daemon to write the DNS and nginx configuration files. +# Wait for the management daemon to start... until nc -z -w 4 127.0.0.1 10222 do echo Waiting for the Mail-in-a-Box management daemon to start... sleep 2 done + +# ...and then have it write the DNS and nginx configuration files and start those +# services. tools/dns_update tools/web_update +# Give fail2ban another restart. The log files may not all have been present when +# fail2ban was first configured, but they should exist now. +restart_service fail2ban + # If DNS is already working, try to provision TLS certficates from Let's Encrypt. # Suppress extra reasons why domains aren't getting a new certificate. management/ssl_certificates.py -q diff --git a/setup/system.sh b/setup/system.sh index d9f84fda..293ac68d 100755 --- a/setup/system.sh +++ b/setup/system.sh @@ -299,4 +299,9 @@ cat conf/fail2ban/jails.conf \ > /etc/fail2ban/jail.d/mailinabox.conf cp -f conf/fail2ban/filter.d/* /etc/fail2ban/filter.d/ +# On first installation, the log files that the jails look at don't all exist. +# e.g., The roundcube error log isn't normally created until someone logs into +# Roundcube for the first time. This causes fail2ban to fail to start. Later +# scripts will ensure the files exist and then fail2ban is given another +# restart at the very end of setup. restart_service fail2ban diff --git a/setup/webmail.sh b/setup/webmail.sh index 8307149b..cdbc18ae 100755 --- a/setup/webmail.sh +++ b/setup/webmail.sh @@ -133,6 +133,9 @@ EOF mkdir -p /var/log/roundcubemail /tmp/roundcubemail $STORAGE_ROOT/mail/roundcube chown -R www-data.www-data /var/log/roundcubemail /tmp/roundcubemail $STORAGE_ROOT/mail/roundcube +# Ensure the log file monitored by fail2ban exists, or else fail2ban can't start. +sudo -u www-data touch /var/log/roundcubemail/errors + # Password changing plugin settings # The config comes empty by default, so we need the settings # we're not planning to change in config.inc.dist... diff --git a/tests/fail2ban.py b/tests/fail2ban.py index 0f2f1e9f..fb74e706 100644 --- a/tests/fail2ban.py +++ b/tests/fail2ban.py @@ -1,20 +1,20 @@ # Test that a box's fail2ban setting are working # correctly by attempting a bunch of failed logins. -# Specify SSH login information the command line - -# we use that to reset fail2ban after each test, -# and we extract the hostname from that to open -# connections to. +# +# Specify a SSH login command (which we use to reset +# fail2ban after each test) and the hostname to +# try to log in to. ###################################################################### import sys, os, time, functools # parse command line -if len(sys.argv) < 2: - print("Usage: tests/fail2ban.py user@hostname") +if len(sys.argv) != 3: + print("Usage: tests/fail2ban.py \"ssh user@hostname\" hostname") sys.exit(1) -ssh_user, hostname = sys.argv[1].split("@", 1) +ssh_command, hostname = sys.argv[1:3] # define some test types @@ -85,7 +85,8 @@ def http_test(url, expected_status, postdata=None, qsargs=None, auth=None): auth=HTTPBasicAuth(*auth) if auth else None, data=postdata, headers={'User-Agent': 'Mail-in-a-Box fail2ban tester'}, - timeout=8) + timeout=8, + verify=False) # don't bother with HTTPS validation, it may not be configured yet except requests.exceptions.ConnectTimeout as e: raise IsBlocked() except requests.exceptions.ConnectionError as e: @@ -106,7 +107,7 @@ def restart_fail2ban_service(final=False): if not final: # Stop recidive jails during testing. command += " && sudo fail2ban-client stop recidive" - os.system("ssh %s@%s \"%s\"" % (ssh_user, hostname, command)) + os.system("%s \"%s\"" % (ssh_command, command)) def testfunc_runner(i, testfunc, *args): print(i+1, end=" ", flush=True)