From: Ralf Jung Date: Sun, 14 Jan 2024 09:13:21 +0000 (+0100) Subject: ignore more SSH errors X-Git-Url: https://git.ralfj.de/ansible.git/commitdiff_plain/HEAD?hp=d6c2eb5f79917a2df728e6b9f86ceb5022f25d90 ignore more SSH errors --- diff --git a/.gitignore b/.gitignore index 2bf7c68..545a838 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ *.retry hosts host_vars -hosts diff --git a/ansible.cfg b/ansible.cfg index d6bbf37..dfba7c4 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,7 +1,7 @@ [defaults] inventory = hosts stdout_callback = debug -hash_behaviour = merge +interpreter_python = auto_silent [diff] always = True diff --git a/do-update b/do-update deleted file mode 100755 index e9edd48..0000000 --- a/do-update +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -cd "$(dirname "$(readlink -e "$0")")" -for HOST in "$@"; do - echo "Playing on $HOST" - ansible-playbook upgrade.yml -l "$HOST" - read -p "Do you want me to reboot $HOST? (y/N) " ANSWER - if [[ "$ANSWER" == y* ]]; then - ansible "$HOST" -a "shutdown -r +1" - fi - echo -done diff --git a/host_vars/template.yml b/host_vars/template.yml index 142e408..941796b 100644 --- a/host_vars/template.yml +++ b/host_vars/template.yml @@ -51,6 +51,7 @@ postfix: # optional: install and configure mailman mailman: default_host: lists.example.org + smtp_outgoing: smtp2 default_lang: en # if you change this, also run "dpkg-reconfigure mailman" to enable more languages domains: # the file /etc/postfix/virtual_alias_map can be used to configure aliases - lists.example.org @@ -91,5 +92,6 @@ bind: etherpad: domain: pad.example.org default_text: "Welcome to Etherpad!\\n\\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\\n\\nGet involved with Etherpad at http:\/\/etherpad.org\\n" + # Also see for some database configuration advice! mysql_password: $RANDOM admin_password: $RANDOM diff --git a/roles/apache/files/log-anon b/roles/apache/files/log-anon index 32b6c1e..0b84668 100644 --- a/roles/apache/files/log-anon +++ b/roles/apache/files/log-anon @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/python3 import sys, re from netaddr import IPAddress, AddrFormatError if len(sys.argv) != 2: - print >>sys.stderr, "Usage: %s filename" % sys.argv[0] + print("Usage: %s filename" % sys.argv[0], file=sys.stderr) sys.exit(1) log = open(sys.argv[1], "a") diff --git a/roles/apache/tasks/main.yml b/roles/apache/tasks/main.yml index fee26ef..8d1382c 100644 --- a/roles/apache/tasks/main.yml +++ b/roles/apache/tasks/main.yml @@ -1,5 +1,5 @@ - name: install apache - apt: name=apache2,python-netaddr state=latest + apt: name=apache2,python3-netaddr state=latest - name: enable apache service: name=apache2 enabled=yes # apache config @@ -35,6 +35,7 @@ - php5.conf - security.conf - defaults.conf + - caching.conf notify: apache - name: enable config files command: a2enconf {{ item }} @@ -44,6 +45,7 @@ - ssl - security - defaults + - caching notify: apache - name: disable config files command: a2disconf {{ item }} diff --git a/roles/apache/templates/000-default.conf b/roles/apache/templates/000-default.conf index 0d68ad6..5e02d0b 100644 --- a/roles/apache/templates/000-default.conf +++ b/roles/apache/templates/000-default.conf @@ -1,14 +1,8 @@ -# redirect all undefined virtual hosts to {{ apache.default_host }} +# Default host: serve nothing. -{% if 'letsencrypt' in group_names %} - Redirect temp / https://{{ apache.default_host }}/ -{% else %} - Redirect temp / http://{{ apache.default_host }}/ -{% endif %} {% if 'letsencrypt' in group_names %} Use SSL letsencrypt/live - Redirect temp / https://{{ apache.default_host }}/ {% endif %} diff --git a/roles/apache/templates/caching.conf b/roles/apache/templates/caching.conf new file mode 100644 index 0000000..7880aec --- /dev/null +++ b/roles/apache/templates/caching.conf @@ -0,0 +1,7 @@ + + Header set Cache-Control "max-age=86400, public" + + + + Header set Cache-Control "no-cache" + diff --git a/roles/apache/templates/security.conf b/roles/apache/templates/security.conf index adefdd8..9334c36 100644 --- a/roles/apache/templates/security.conf +++ b/roles/apache/templates/security.conf @@ -59,7 +59,7 @@ Header set X-Content-Type-Options: "nosniff" # site as frames. This defends against clickjacking attacks. # Requires mod_headers to be enabled. # -Header set X-Frame-Options: "sameorigin" +Header add Content-Security-Policy "frame-ancestors 'self'" # vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/roles/apache/templates/ssl.conf b/roles/apache/templates/ssl.conf index bb80746..5fa87c3 100644 --- a/roles/apache/templates/ssl.conf +++ b/roles/apache/templates/ssl.conf @@ -17,7 +17,7 @@ Header unset Strict-Transport-Security Header set Strict-Transport-Security "max-age=864000" # Make sure we load everything via HTTPS - Header set Content-Security-Policy "upgrade-insecure-requests" + Header add Content-Security-Policy "upgrade-insecure-requests" ######################################################### # SSL configuration below ############################### @@ -33,8 +33,11 @@ SSLCipherSuite 'kEECDH+AESGCM:kEDH+AESGCM:kEECDH:kEDH:AESGCM:ALL:!3DES:!EXPORT:!LOW:!MEDIUM:!aNULL:!eNULL' SSLHonorCipherOrder on - # Certificate, DH parameters and key - SSLCertificateFile /etc/ssl/mycerts/$cert.crt+dh + # DH parameters + SSLOpenSSLConfCmd DHParameters "/etc/ssl/dh2048.pem" + + # Certificate and key + SSLCertificateFile /etc/ssl/mycerts/$cert.crt SSLCertificateKeyFile /etc/ssl/private/$cert.key # Server Certificate Chain: @@ -44,7 +47,7 @@ # the referenced file can be the same as SSLCertificateFile # when the CA certificates are directly appended to the server # certificate for convinience. - SSLCertificateChainFile /etc/ssl/mycerts/$cert.chain + SSLCertificateChainFile /etc/ssl/mycerts/$cert.crt # Certificate Authority (CA): # Set the CA certificate verification path where to find CA diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index 9112430..4b4e4cd 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -13,7 +13,7 @@ - name: get rid of packages we do not want apt: name=exim4-base,rpcbind,procmail,fetchmail state=absent autoremove=yes - name: install some basic tools - apt: name=nano,aptitude,rsync,git,mercurial,curl,apt-transport-https,psmisc,dnsutils,tree,htop,acl,libpam-systemd,needrestart state=latest + apt: name=nano,aptitude,rsync,git,mercurial,curl,apt-transport-https,psmisc,dnsutils,tree,htop,acl,libpam-systemd,needrestart,reboot-notifier,debian-security-support state=latest # configuration - name: configure root shell copy: diff --git a/roles/email/files/mailman-check b/roles/email/files/mailman-check index 0a5d9de..09d2d00 100755 --- a/roles/email/files/mailman-check +++ b/roles/email/files/mailman-check @@ -10,5 +10,11 @@ if not ((mlist.dmarc_moderation_action in (1, 2) and mlist.dmarc_quarantine_mode print "List",mlist.real_name,"by",(', '.join(mlist.owner)),"is not configured to deal with DMARC." if mlist.reply_goes_to_list != 0 and not mlist.first_strip_reply_to: print "List",mlist.real_name,"by",(', '.join(mlist.owner)),"provides an inconsistent Reply-To treatment." +if mlist.generic_nonmember_action == 2: + print "List",mlist.real_name,"by",(', '.join(mlist.owner)),"is prone to backscatter spam due to reject notifications" +if mlist.generic_nonmember_action == 1 and mlist.respond_to_post_requests: + print "List",mlist.real_name,"by",(', '.join(mlist.owner)),"is prone to backscatter spam due to hold notifications" +if mlist.bounce_unrecognized_goes_to_list_owner: + print "List",mlist.real_name,"by",(', '.join(mlist.owner)),"may spam the owner with unrecognized bounce notifications" EOF done diff --git a/roles/email/files/mailman-patched/Cgi/listinfo.py b/roles/email/files/mailman-patched/Cgi/listinfo.py index b46bab1..0e38d03 100644 --- a/roles/email/files/mailman-patched/Cgi/listinfo.py +++ b/roles/email/files/mailman-patched/Cgi/listinfo.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2016 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2018 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -38,8 +38,7 @@ _ = i18n._ i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) - - + def main(): parts = Utils.GetPathPieces() if not parts: @@ -61,7 +60,7 @@ def main(): # See if the user want to see this page in other language cgidata = cgi.FieldStorage() try: - language = cgidata.getvalue('language') + language = cgidata.getfirst('language') except TypeError: # Someone crafted a POST with a bad Content-Type:. doc = Document() @@ -79,8 +78,7 @@ def main(): list_listinfo(mlist, language) - - + def listinfo_overview(msg=''): # Present the general listinfo overview hostname = Utils.get_domain() @@ -117,7 +115,7 @@ def listinfo_overview(msg=''): else: advertised.append((mlist.GetScriptURL('listinfo'), mlist.real_name, - Utils.websafe(mlist.description))) + Utils.websafe(mlist.GetDescription()))) if msg: greeting = FontAttr(msg, color="ff5060", size="+1") else: @@ -175,8 +173,7 @@ def listinfo_overview(msg=''): print doc.Format() - - + def list_listinfo(mlist, lang): # Generate list specific listinfo doc = HeadlessDocument() @@ -227,10 +224,10 @@ def list_listinfo(mlist, lang): # fill form replacements[''] += ( '\n' - % (now, captcha_idx, Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + - now + - captcha_idx + - mlist.internal_name() + + % (now, captcha_idx, Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + ":" + + now + ":" + + captcha_idx + ":" + + mlist.internal_name() + ":" + remote ).hexdigest() ) @@ -253,13 +250,25 @@ def list_listinfo(mlist, lang): replacements[''] = displang replacements[''] = mlist.FormatFormStart('listinfo') replacements[''] = mlist.FormatBox('fullname', size=30) + # If reCAPTCHA is enabled, display its user interface + if mm_cfg.RECAPTCHA_SITE_KEY: + noscript = _('This form requires JavaScript.') + replacements[''] = ( + """  + + +
+ """ + % (noscript, lang, mm_cfg.RECAPTCHA_SITE_KEY)) + else: + replacements[''] = '' # Do the expansion. doc.AddItem(mlist.ParseTags('listinfo.html', replacements, lang)) print doc.Format() - - + if __name__ == "__main__": main() diff --git a/roles/email/files/mailman-patched/Cgi/subscribe.py b/roles/email/files/mailman-patched/Cgi/subscribe.py index 153286d..ea4ef94 100644 --- a/roles/email/files/mailman-patched/Cgi/subscribe.py +++ b/roles/email/files/mailman-patched/Cgi/subscribe.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2016 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2018 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -22,6 +22,9 @@ import os import cgi import time import signal +import urllib +import urllib2 +import json from Mailman import mm_cfg from Mailman import Utils @@ -36,14 +39,14 @@ from Mailman.Logging.Syslog import syslog SLASH = '/' ERRORSEP = '\n\n

' +COMMASPACE = ', ' # Set up i18n _ = i18n._ i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) - - + def main(): doc = Document() doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) @@ -73,7 +76,7 @@ def main(): # for the results. If not, use the list's preferred language. cgidata = cgi.FieldStorage() try: - language = cgidata.getvalue('language', '') + language = cgidata.getfirst('language', '') except TypeError: # Someone crafted a POST with a bad Content-Type:. doc.AddItem(Header(2, _("Error"))) @@ -114,19 +117,18 @@ def main(): mlist.Unlock() - - + def process_form(mlist, doc, cgidata, lang): listowner = mlist.GetOwnerEmail() realname = mlist.real_name results = [] # The email address being subscribed, required - email = cgidata.getvalue('email', '').strip() + email = cgidata.getfirst('email', '').strip() if not email: results.append(_('You must supply a valid email address.')) - fullname = cgidata.getvalue('fullname', '') + fullname = cgidata.getfirst('fullname', '') # Canonicalize the full name fullname = Utils.canonstr(fullname, lang) # Who was doing the subscribing? @@ -134,6 +136,26 @@ def process_form(mlist, doc, cgidata, lang): os.environ.get('HTTP_X_FORWARDED_FOR', os.environ.get('REMOTE_ADDR', 'unidentified origin'))) + + # Check reCAPTCHA submission, if enabled + if mm_cfg.RECAPTCHA_SECRET_KEY: + request = urllib2.Request( + url = 'https://www.google.com/recaptcha/api/siteverify', + data = urllib.urlencode({ + 'secret': mm_cfg.RECAPTCHA_SECRET_KEY, + 'response': cgidata.getvalue('g-recaptcha-response', ''), + 'remoteip': remote})) + try: + httpresp = urllib2.urlopen(request) + captcha_response = json.load(httpresp) + httpresp.close() + if not captcha_response['success']: + e_codes = COMMASPACE.join(captcha_response['error-codes']) + results.append(_('reCAPTCHA validation failed: %(e_codes)s')) + except urllib2.URLError, e: + e_reason = e.reason + results.append(_('reCAPTCHA could not be validated: %(e_reason)s')) + # Are we checking the hidden data? if mm_cfg.SUBSCRIBE_FORM_SECRET: now = int(time.time()) @@ -147,15 +169,15 @@ def process_form(mlist, doc, cgidata, lang): # for our hash so it doesn't matter. remote1 = remote.rsplit(':', 1)[0] try: - ftime, fcaptcha_idx, fhash = cgidata.getvalue('sub_form_token', '').split(':') + ftime, fcaptcha_idx, fhash = cgidata.getfirst('sub_form_token', '').split(':') then = int(ftime) except ValueError: ftime = fcaptcha_idx = fhash = '' then = 0 - token = Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + - ftime + - fcaptcha_idx + - mlist.internal_name() + + token = Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + ":" + + ftime + ":" + + fcaptcha_idx + ":" + + mlist.internal_name() + ":" + remote1).hexdigest() if ftime and now - then > mm_cfg.FORM_LIFETIME: results.append(_('The form is too old. Please GET it again.')) @@ -169,17 +191,17 @@ def process_form(mlist, doc, cgidata, lang): results.append( _('There was no hidden token in your submission or it was corrupted.')) results.append(_('You must GET the form before submitting it.')) - # Check captcha - captcha_answer = cgidata.getvalue('captcha_answer', '') - if not Captcha.verify(fcaptcha_idx, captcha_answer, mm_cfg.CAPTCHAS): - results.append(_('This was not the right answer to the CAPTCHA question.')) + # Check captcha + captcha_answer = cgidata.getvalue('captcha_answer', '') + if not Captcha.verify(fcaptcha_idx, captcha_answer, mm_cfg.CAPTCHAS): + results.append(_('This was not the right answer to the CAPTCHA question.')) # Was an attempt made to subscribe the list to itself? if email == mlist.GetListEmail(): syslog('mischief', 'Attempt to self subscribe %s: %s', email, remote) results.append(_('You may not subscribe a list to itself!')) # If the user did not supply a password, generate one for him - password = cgidata.getvalue('pw', '').strip() - confirmed = cgidata.getvalue('pw-conf', '').strip() + password = cgidata.getfirst('pw', '').strip() + confirmed = cgidata.getfirst('pw-conf', '').strip() if not password and not confirmed: password = Utils.MakeRandomPassword() @@ -189,11 +211,11 @@ def process_form(mlist, doc, cgidata, lang): results.append(_('Your passwords did not match.')) # Get the digest option for the subscription. - digestflag = cgidata.getvalue('digest') + digestflag = cgidata.getfirst('digest') if digestflag: try: digest = int(digestflag) - except ValueError: + except (TypeError, ValueError): digest = 0 else: digest = mlist.digest_is_default @@ -318,8 +340,7 @@ You have been successfully subscribed to the %(realname)s mailing list.""") print_results(mlist, results, doc, lang) - - + def print_results(mlist, results, doc, lang): # The bulk of the document will come from the options.html template, which # includes its own html armor (head tags, etc.). Suppress the head that diff --git a/roles/email/tasks/dovecot.yml b/roles/email/tasks/dovecot.yml index 6e1b12a..1766ede 100644 --- a/roles/email/tasks/dovecot.yml +++ b/roles/email/tasks/dovecot.yml @@ -1,5 +1,5 @@ - name: install dovecot - apt: name=dovecot-imapd,dovecot-lmtpd,dovecot-mysql,dovecot-pop3d,dovecot-sieve,dovecot-managesieved state=latest + apt: name=dovecot-imapd,dovecot-lmtpd,dovecot-mysql,dovecot-pop3d,dovecot-sieve,dovecot-managesieved,python3-mysqldb state=latest - name: enable dovecot service: name=dovecot enabled=yes # configuration @@ -22,7 +22,7 @@ template: dest: /etc/dovecot/{{ item }} src: templates/dovecot/{{ item }} - mode: u=rw,g=r,o= + mode: u=rw,g=r,o=r # changepw needs read access group: dovecot loop: - conf.d/10-auth.conf @@ -34,6 +34,14 @@ - conf.d/20-lmtp.conf - conf.d/90-quota.conf - conf.d/auth-sql.conf.ext +- name: configure dovecot secrets + notify: dovecot + template: + dest: /etc/dovecot/{{ item }} + src: templates/dovecot/{{ item }} + mode: u=rw,g=r,o= + group: dovecot + loop: - dovecot-sql.conf.ext - name: install quota notification script template: diff --git a/roles/email/tasks/mailman.yml b/roles/email/tasks/mailman.yml index 5d1288f..cba4519 100644 --- a/roles/email/tasks/mailman.yml +++ b/roles/email/tasks/mailman.yml @@ -21,8 +21,8 @@ - name: check if all the files have the right checksums to be patched shell: 'echo "{{item}}" | sha256sum -c' loop: - - "26b4cbb7c5bde8badf741e31975235e74abb932037d77d862cf00b412726c2c2 /usr/lib/mailman/Mailman/Cgi/listinfo.py" - - "cbef3d8cb6b65e4c9b2462f8627966d55dd52caa2e626c87241c4f8d47477dc7 /usr/lib/mailman/Mailman/Cgi/subscribe.py" + - "621368ef38d991be46e4537b1d5444276579cd60cc721a749d500dd0b98efe27 /usr/lib/mailman/Mailman/Cgi/listinfo.py" + - "c6e46afe1c016d6853c8397916a6f6fd88c6cea71ae890ef3680617f1f8f7c9a /usr/lib/mailman/Mailman/Cgi/subscribe.py" changed_when: False when: mailman_patched.rc != 0 - name: install patched python files @@ -33,6 +33,7 @@ - Cgi/listinfo.py - Cgi/subscribe.py - Captcha.py + when: mailman_patched.rc != 0 - name: install patched templates copy: dest: /etc/mailman/{{item}} diff --git a/roles/email/tasks/opendkim.yml b/roles/email/tasks/opendkim.yml index 8da35b3..5b76b02 100644 --- a/roles/email/tasks/opendkim.yml +++ b/roles/email/tasks/opendkim.yml @@ -20,7 +20,6 @@ become_user: opendkim args: creates: /etc/opendkim/{{ item }}/mail.private - warn: False loop: "{{ postfix.opendkim.private_keys }}" - name: generate opendkim tables template: diff --git a/roles/email/tasks/postfix.yml b/roles/email/tasks/postfix.yml index adb054c..d59144d 100644 --- a/roles/email/tasks/postfix.yml +++ b/roles/email/tasks/postfix.yml @@ -13,6 +13,7 @@ loop: - main.cf - master.cf + - postscreen_access.cidr notify: postfix - name: install postfix mysql config when: postfix.dovecot is defined @@ -45,13 +46,12 @@ when: virtual_alias_map.changed command: postmap /etc/postfix/virtual_alias_map notify: postfix -- name: create empty sender_transport_map +- name: create sender_transport_map when: postfix.smtp_outgoing is defined register: sender_transport_map - copy: + template: dest: /etc/postfix/sender_transport_map - content: "" - force: no + src: templates/sender_transport_map - name: postmap sender_transport_map when: sender_transport_map.changed command: postmap /etc/postfix/sender_transport_map @@ -76,8 +76,6 @@ command: postmap /etc/postfix/transport_map notify: postfix # cronjobs -- name: delete old local-mail cronjob - file: path=/etc/cron.daily/local-mail state=absent - name: install check-for-local-mail cronjob copy: dest: /etc/cron.daily/check-for-local-mail diff --git a/roles/email/templates/changepw b/roles/email/templates/changepw index 96eef60..7a1b600 100644 --- a/roles/email/templates/changepw +++ b/roles/email/templates/changepw @@ -1,5 +1,5 @@ -#!/usr/bin/env python2 -from __future__ import print_function +#!/usr/bin/env python3 + import os, cgi, MySQLdb, subprocess, time # settings diff --git a/roles/email/templates/dovecot/conf.d/10-auth.conf b/roles/email/templates/dovecot/conf.d/10-auth.conf index 7c814e0..a6634cf 100644 --- a/roles/email/templates/dovecot/conf.d/10-auth.conf +++ b/roles/email/templates/dovecot/conf.d/10-auth.conf @@ -124,5 +124,4 @@ auth_mechanisms = plain login #!include auth-ldap.conf.ext #!include auth-passwdfile.conf.ext #!include auth-checkpassword.conf.ext -#!include auth-vpopmail.conf.ext #!include auth-static.conf.ext diff --git a/roles/email/templates/dovecot/conf.d/10-ssl.conf b/roles/email/templates/dovecot/conf.d/10-ssl.conf index 70df7c5..ae6d354 100644 --- a/roles/email/templates/dovecot/conf.d/10-ssl.conf +++ b/roles/email/templates/dovecot/conf.d/10-ssl.conf @@ -9,7 +9,7 @@ ssl = required # dropping root privileges, so keep the key file unreadable by anyone but # root. Included doc/mkcert.sh can be used to easily generate self-signed # certificate, just make sure to update the domains in dovecot-openssl.cnf -ssl_cert = +smtpd_data_restrictions = reject_unauth_pipelining +smtpd_discard_ehlo_keywords = chunking + {% if postfix.relay_host is defined %} # Relay everything default_transport = smtp:{{ postfix.relay_host }} @@ -139,4 +147,4 @@ smtpd_delay_reject = yes disable_vrfy_command = yes recipient_delimiter = {{ postfix.recipient_delimiter | default("+") }} delay_warning_time = 4h -message_size_limit = 21384000 +message_size_limit = 30100100 diff --git a/roles/email/templates/mm_cfg.py b/roles/email/templates/mm_cfg.py index 89dd0d8..2b9c451 100644 --- a/roles/email/templates/mm_cfg.py +++ b/roles/email/templates/mm_cfg.py @@ -121,6 +121,7 @@ DEB_LISTMASTER = '{{postfix.postmaster}}' DEFAULT_ARCHIVE = Off DEFAULT_MAX_MESSAGE_SIZE = 1024 # KB DEFAULT_ADMIN_MEMBER_CHUNKSIZE = 100 +DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER = No # footer DEFAULT_MSG_FOOTER = """{{postfix.mailman.default_footer}}""" diff --git a/roles/email/templates/newmail/newmail b/roles/email/templates/newmail/newmail index 86a1d99..4f37859 100755 --- a/roles/email/templates/newmail/newmail +++ b/roles/email/templates/newmail/newmail @@ -1,8 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # -*- coding: utf-8 -*- -from __future__ import print_function + import sys, os, random, MySQLdb, subprocess, time, string, argparse -import urllib, smtplib, email.mime.text, email.utils +import smtplib, email.mime.text, email.utils from settings import * from templates import * diff --git a/roles/email/templates/opendkim.conf b/roles/email/templates/opendkim.conf index 6fccfc2..b603f87 100644 --- a/roles/email/templates/opendkim.conf +++ b/roles/email/templates/opendkim.conf @@ -36,3 +36,8 @@ OversignHeaders From ## at http://unbound.net for the expected format of this file. TrustAnchorFile /usr/share/dns/root.key + + +# Path must match postfix main.cf +Socket local:/var/spool/postfix/opendkim/sock +PidFile /var/spool/postfix/opendkim/opendkim.pid diff --git a/roles/email/templates/opendkim.env b/roles/email/templates/opendkim.env index 02fadef..f56a2b9 100644 --- a/roles/email/templates/opendkim.env +++ b/roles/email/templates/opendkim.env @@ -1,5 +1,8 @@ # Command-line options specified here will override the contents of # /etc/opendkim.conf. See opendkim(8) for a complete list of options. +# RJ: This might seem redundant with the opendkim.conf settings, +# but the script in /lib/opendkim/opendkim.service.generate also helps by +# generating tmpfiles.d/opendkim.conf so replacing it seems like a hassle. #DAEMON_OPTS="" RUNDIR=/var/spool/postfix/opendkim diff --git a/roles/email/templates/postscreen_access.cidr b/roles/email/templates/postscreen_access.cidr new file mode 100644 index 0000000..91acb4c --- /dev/null +++ b/roles/email/templates/postscreen_access.cidr @@ -0,0 +1,23 @@ +# Google thinks they are better than everyone else, and don't need to be compatible with greylisting. +209.85.128.0/17 permit +# Same for Microsoft. +40.96.0.0/13 permit +40.104.0.0/15 permit +52.96.0.0/14 permit +2603:1000::/24 permit +# And Sparkpost. +156.70.4.0/23 permit +156.70.2.0/23 permit +147.253.208.0/20 permit + +# Some hosts that send bounces to the wrong guy (i.e., me) +192.241.146.138 reject please check mail server config, your server is sending bounce spam +209.97.143.86 reject please check mail server config, your server is sending bounce spam +209.97.132.56 reject please check mail server config, your server is sending bounce spam +188.166.20.128 reject please check mail server config, your server is sending bounce spam +159.203.188.91 reject please check mail server config, your server is sending bounce spam +159.203.190.197 reject please check mail server config, your server is sending bounce spam +159.65.138.221 reject please check mail server config, your server is sending bounce spam +128.199.206.172 reject please check mail server config, your server is sending bounce spam +142.93.223.22 reject please check mail server config, your server is sending bounce spam +59.106.209.178 reject please check mail server config, your server is sending bounce spam diff --git a/roles/email/templates/sender_transport_map b/roles/email/templates/sender_transport_map new file mode 100644 index 0000000..e59fb7c --- /dev/null +++ b/roles/email/templates/sender_transport_map @@ -0,0 +1,6 @@ +# default is {{ postfix.default_smtp_outgoing }} +{% if postfix.mailman is defined and postfix.mailman.smtp_outgoing is defined %} +{% for item in postfix.mailman.domains %} +@{{item}} {{ postfix.mailman.smtp_outgoing }} +{% endfor %} +{% endif %} diff --git a/roles/etherpad/tasks/main.yml b/roles/etherpad/tasks/main.yml index 790e8cd..6cc9c3e 100644 --- a/roles/etherpad/tasks/main.yml +++ b/roles/etherpad/tasks/main.yml @@ -16,7 +16,7 @@ git: dest: /srv/{{etherpad.domain}}/etherpad-lite repo: 'https://github.com/ether/etherpad-lite.git' - version: '1.7.5' + version: '1.8.18' force: yes - name: create etherpad service file register: etherpad_service diff --git a/roles/etherpad/templates/settings.json b/roles/etherpad/templates/settings.json index 74bb3c6..61a324e 100644 --- a/roles/etherpad/templates/settings.json +++ b/roles/etherpad/templates/settings.json @@ -4,6 +4,8 @@ Please edit settings.json, not settings.json.template */ { + "skinName": "colibris", + //IP and port which etherpad should bind at "ip": "127.0.0.1", "port" : 9001, @@ -15,7 +17,8 @@ "user" : "etherpad", "host" : "localhost", "password": "{{etherpad.mysql_password}}", - "database": "etherpad" + "database": "etherpad", + "charset" : "utf8mb4" }, //the default text of a pad diff --git a/roles/journalwatch/templates/patterns b/roles/journalwatch/templates/patterns index c08b64e..db20d2d 100644 --- a/roles/journalwatch/templates/patterns +++ b/roles/journalwatch/templates/patterns @@ -51,36 +51,56 @@ Failed to allocate manager object: Permission denied _SYSTEMD_UNIT = init.scope user@\d+\.service: Killing process \d+ \(kill\) with signal SIGKILL\. +[^: ]+: Consumed [\d.]+s CPU time\. {% if journalwatch is defined and journalwatch.strato_broken | default(False) %} Failed to set devices.allow on /system.slice/[a-z-]+.service: Operation not permitted {% endif %} SYSLOG_IDENTIFIER = sudo -\s*[_\w.-]+ : TTY=(unknown|console|(pts/|ttyp?|vc/)\d+) ; PWD=[^;]+ ; USER=[._\w-]+ ; COMMAND=.* +\s*[._\w-]+ : (TTY=(unknown|console|(pts/|ttyp?|vc/)\d+) ; )?PWD=[^;]+ ; USER=[._\w-]+ ; COMMAND=.* + +SYSLOG_IDENTIFIER = su +\(to [._\w-]+\) [._\w-]+ on none _SYSTEMD_UNIT = postfix@-.service -warning: hostname [^\s]+ does not resolve to address [\da-fA-F.:]+(: Name or service not known)? +warning: hostname [\w._-]+ does not resolve to address [\da-fA-F.:]+(: .*)? warning: [._\w-]+\[[\da-fA-F.:]+\]: SASL (LOGIN|PLAIN) authentication failed:.* -warning: non-SMTP command from \w+\[[\da-fA-F.:]+\]: .* +warning: non-SMTP command from [._\w-]+\[[\da-fA-F.:]+\]: .* warning: TLS library problem: error:[0-9A-F]+:SSL routines:\w+:(no shared cipher|decryption failed or bad record mac|unknown protocol|version too low):[\w./]+:\d+: +warning: dnsblog reply timeout \d+s for .* +warning: dnsblog_query: lookup error for DNS query .*: Host or domain name not found. Name service error .* +warning: ciphertext read/write timeout for \[[\da-fA-F.:]+\]:\d+ +warning: getpeername: Transport endpoint is not connected -- dropping this connection {% if journalwatch is defined and journalwatch.postfix_slow | default(False) %} warning: psc_cache_update: btree:/var/lib/postfix/[a-z_]+ (update|lookup) average delay is \d\d\d ms {% endif %} {% if journalwatch is defined and journalwatch.strato_broken | default(False) %} warning: dnsblog reply timeout [0-9]+s for [\w._-]+ +warning: dnsblog_query: lookup error for DNS query .* {% endif %} _SYSTEMD_UNIT = dovecot.service auth: Warning: auth client \d+ disconnected with \d+ pending requests: (EOF|Connection reset by peer) +auth: Warning: Event 0x[\da-fA-F]+ leaked \(parent=\(nil\)\): auth-client-connection.c:\d+ SYSLOG_IDENTIFIER = sshd error: Received disconnect from [\da-fA-F.:]+ port \d+:\d+: .* -error: maximum authentication attempts exceeded for (invalid user \w*|\w+) from [\da-fA-F.:]+ port \d+ ssh2 \[preauth\] +error: maximum authentication attempts exceeded for (invalid user [\w_-]*|[\w_-]+) from [\da-fA-F.:]+ port \d+ ssh2 \[preauth\] +error: (kex_exchange_identification|send_error|kex_protocol_error|kex protocol error|Bad remote protocol version identification|Protocol major versions differ|beginning MaxStartups throttling).* fatal: ssh_packet_get_string: string is too large \[preauth\] +(error|fatal): userauth_pubkey: (parse request failed:|could not parse key:|cannot decode key:) .* +fatal: monitor_read: unpermitted request .* +error: key_from_blob: invalid format \[preauth\] -_SYSTEMD_UNIT = bind9.service -client [\da-fA-F.:]+#\d+( \([\w.-]+\))?: (zone transfer '[\w.-]+/AXFR/IN' denied|message parsing failed: (bad compression pointer|bad label type|unexpected end of input)) +_SYSTEMD_UNIT = named.service +client (@0x[a-f0-9]+ )?[\da-fA-F.:]+#\d+( \([\w.-]+\))?: (zone transfer '[\w.-]+/AXFR/IN' denied|message parsing failed: (bad compression pointer|bad label type|unexpected end of input)) _SYSTEMD_UNIT = opendkim.service [A-Z0-9]+: (bad signature data|failed to parse [Aa]uthentication-[Rr]esults: header field) -[A-Z0-9]+: key retrieval failed \(s=[\w._-]+, d=[\w._-]+\)(: '[\w._-]+' record not found)? +[A-Z0-9]+: key retrieval failed \(s=[\w._-]+, d=[\w._-]+\)(: '[\w._-]+' (record not found|query timed out))? + +_SYSTEMD_SLICE=system-openvpn.slice +(client/)?[0-9a-f.:]+ (peer info: .*|VERIFY OK: .*|Outgoing Data Channel: .*|Incoming Data Channel: .*|Control Channel: .*|TLS: .*|\[client\] .*|MULTI(_sva)?: .*|SIGUSR1.*|PUSH: .*|SENT CONTROL \[client\]: .*|WARNING: '(tun|link)-mtu' is used inconsistently, local='(tun|link)-mtu \d+', remote='(tun|link)-mtu \d+') + +SYSLOG_IDENTIFIER = kernel +xfs filesystem being remounted at /run/schroot/mount/schsh-[^ ]* supports timestamps until 2038 \(0x7fffffff\) diff --git a/roles/prosody/handlers/main.yml b/roles/prosody/handlers/main.yml index 9a9db71..e89cf99 100644 --- a/roles/prosody/handlers/main.yml +++ b/roles/prosody/handlers/main.yml @@ -2,3 +2,5 @@ service: name=prosody state=restarted enabled=yes - name: apache service: name=apache2 state=restarted enabled=yes +- name: coturn + service: name=coturn state=restarted enabled=yes diff --git a/roles/prosody/tasks/main.yml b/roles/prosody/tasks/main.yml index 9b6f5dd..662647f 100644 --- a/roles/prosody/tasks/main.yml +++ b/roles/prosody/tasks/main.yml @@ -1,6 +1,6 @@ # install - name: install prosody - apt: name=prosody,lua-zlib,lua-dbi-sqlite3 state=latest default_release={{ansible_distribution_release}}-backports + apt: name=prosody,lua-zlib,lua-dbi-sqlite3,coturn state=latest default_release={{ansible_distribution_release}}-backports - name: fetch prosody modules hg: dest: "{{ prosody.paths.modules }}" @@ -13,6 +13,11 @@ dest: /etc/prosody/prosody.cfg.lua src: templates/prosody.cfg.lua notify: prosody +- name: configure coturn + template: + dest: /etc/turnserver.conf + src: templates/turnserver.conf + notify: coturn - name: configure apache when: inventory_hostname in groups['apache'] template: diff --git a/roles/prosody/templates/prosody.cfg.lua b/roles/prosody/templates/prosody.cfg.lua index d92d82e..0fc27e2 100644 --- a/roles/prosody/templates/prosody.cfg.lua +++ b/roles/prosody/templates/prosody.cfg.lua @@ -72,7 +72,7 @@ modules_enabled = { --"websocket"; -- XMPP over WebSockets --"http_files"; -- Serve static files from a directory over HTTP - -- Other specific functionality + -- Other specific functionality --"limits"; -- Enable bandwidth limiting for XMPP connections --"groups"; -- Shared roster support --"server_contact_info"; -- Publish contact information for this service @@ -82,6 +82,7 @@ modules_enabled = { --"motd"; -- Send a message to users when they log in --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use + "external_services"; -- XEP-0215: External Service Discovery -- Community modules "smacks"; -- XEP-0198: Stream Management @@ -117,7 +118,7 @@ pidfile = "/var/run/prosody/prosody.pid" -- to use SSL/TLS, you may comment or remove this ssl = { key = "/etc/ssl/private/letsencrypt/live.key"; - certificate = "/etc/ssl/mycerts/letsencrypt/live.crt+chain"; + certificate = "/etc/ssl/mycerts/letsencrypt/live.crt"; ciphers = "ALL:!EXPORT:!LOW:!MEDIUM:!aNULL:!3DES"; dhparam = "/etc/ssl/dh2048.pem"; } @@ -216,6 +217,22 @@ http_upload_file_size_limit = 5 * 1024 * 1024 http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds http_upload_quota = 50 * 1024 * 1024 +-- Set up external services +external_services = { + { + type = "stun", + transport = "udp", + host = "{{ prosody.host }}", + port = 3478 + }, { + type = "turn", + transport = "udp", + host = "{{ prosody.host }}", + port = 3478, + secret = "{{ prosody.turn.secret }}" + } +} + ----------- Virtual hosts ----------- -- You need to add a VirtualHost entry for each domain you wish Prosody to serve. -- Settings under each VirtualHost entry apply *only* to that host. diff --git a/roles/prosody/templates/turnserver.conf b/roles/prosody/templates/turnserver.conf new file mode 100644 index 0000000..dfd17da --- /dev/null +++ b/roles/prosody/templates/turnserver.conf @@ -0,0 +1,643 @@ +# Coturn TURN SERVER configuration file +# +# Boolean values note: where boolean value is supposed to be used, +# you can use '0', 'off', 'no', 'false', 'f' as 'false, +# and you can use '1', 'on', 'yes', 'true', 't' as 'true' +# If the value is missed, then it means 'true'. +# + +# Listener interface device (optional, Linux only). +# NOT RECOMMENDED. +# +#listening-device=eth0 + +# TURN listener port for UDP and TCP (Default: 3478). +# Note: actually, TLS & DTLS sessions can connect to the +# "plain" TCP & UDP port(s), too - if allowed by configuration. +# +#listening-port=3478 + +# TURN listener port for TLS (Default: 5349). +# Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS +# port(s), too - if allowed by configuration. The TURN server +# "automatically" recognizes the type of traffic. Actually, two listening +# endpoints (the "plain" one and the "tls" one) are equivalent in terms of +# functionality; but we keep both endpoints to satisfy the RFC 5766 specs. +# For secure TCP connections, we currently support SSL version 3 and +# TLS version 1.0, 1.1 and 1.2. +# For secure UDP connections, we support DTLS version 1. +# +#tls-listening-port=5349 + +# Alternative listening port for UDP and TCP listeners; +# default (or zero) value means "listening port plus one". +# This is needed for RFC 5780 support +# (STUN extension specs, NAT behavior discovery). The TURN Server +# supports RFC 5780 only if it is started with more than one +# listening IP address of the same family (IPv4 or IPv6). +# RFC 5780 is supported only by UDP protocol, other protocols +# are listening to that endpoint only for "symmetry". +# +#alt-listening-port=0 + +# Alternative listening port for TLS and DTLS protocols. +# Default (or zero) value means "TLS listening port plus one". +# +#alt-tls-listening-port=0 + +# Listener IP address of relay server. Multiple listeners can be specified. +# If no IP(s) specified in the config file or in the command line options, +# then all IPv4 and IPv6 system IPs will be used for listening. +# +#listening-ip=172.17.19.101 +#listening-ip=10.207.21.238 +#listening-ip=2607:f0d0:1002:51::4 + +# Auxiliary STUN/TURN server listening endpoint. +# Aux servers have almost full TURN and STUN functionality. +# The (minor) limitations are: +# +# 1) Auxiliary servers do not have alternative ports and +# they do not support STUN RFC 5780 functionality (CHANGE REQUEST). +# +# 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply. +# +# Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6. +# +# There may be multiple aux-server options, each will be used for listening +# to client requests. +# +#aux-server=172.17.19.110:33478 +#aux-server=[2607:f0d0:1002:51::4]:33478 + +# (recommended for older Linuxes only) +# Automatically balance UDP traffic over auxiliary servers (if configured). +# The load balancing is using the ALTERNATE-SERVER mechanism. +# The TURN client must support 300 ALTERNATE-SERVER response for this +# functionality. +# +#udp-self-balance + +# Relay interface device for relay sockets (optional, Linux only). +# NOT RECOMMENDED. +# +#relay-device=eth1 + +# Relay address (the local IP address that will be used to relay the +# packets to the peer). +# Multiple relay addresses may be used. +# The same IP(s) can be used as both listening IP(s) and relay IP(s). +# +# If no relay IP(s) specified, then the turnserver will apply the default +# policy: it will decide itself which relay addresses to be used, and it +# will always be using the client socket IP address as the relay IP address +# of the TURN session (if the requested relay address family is the same +# as the family of the client socket). +# +#relay-ip=172.17.19.105 +#relay-ip=2607:f0d0:1002:51::5 + +# For Amazon EC2 users: +# +# TURN Server public/private address mapping, if the server is behind NAT. +# In that situation, if a -X is used in form "-X " then that ip will be reported +# as relay IP address of all allocations. This scenario works only in a simple case +# when one single relay address is be used, and no RFC5780 functionality is required. +# That single relay address must be mapped by NAT to the 'external' IP. +# The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field. +# For that 'external' IP, NAT must forward ports directly (relayed port 12345 +# must be always mapped to the same 'external' port 12345). +# +# In more complex case when more than one IP address is involved, +# that option must be used several times, each entry must +# have form "-X ", to map all involved addresses. +# RFC5780 NAT discovery STUN functionality will work correctly, +# if the addresses are mapped properly, even when the TURN server itself +# is behind A NAT. +# +# By default, this value is empty, and no address mapping is used. +# +#external-ip=60.70.80.91 +# +#OR: +# +#external-ip=60.70.80.91/172.17.19.101 +#external-ip=60.70.80.92/172.17.19.102 + + +# Number of the relay threads to handle the established connections +# (in addition to authentication thread and the listener thread). +# If explicitly set to 0 then application runs relay process in a +# single thread, in the same thread with the listener process +# (the authentication thread will still be a separate thread). +# +# If this parameter is not set, then the default OS-dependent +# thread pattern algorithm will be employed. Usually the default +# algorithm is the most optimal, so you have to change this option +# only if you want to make some fine tweaks. +# +# In the older systems (Linux kernel before 3.9), +# the number of UDP threads is always one thread per network listening +# endpoint - including the auxiliary endpoints - unless 0 (zero) or +# 1 (one) value is set. +# +#relay-threads=0 + +# Lower and upper bounds of the UDP relay endpoints: +# (default values are 49152 and 65535) +# +min-port=50000 +max-port=51000 + +# Uncomment to run TURN server in 'normal' 'moderate' verbose mode. +# By default the verbose mode is off. +#verbose + +# Uncomment to run TURN server in 'extra' verbose mode. +# This mode is very annoying and produces lots of output. +# Not recommended under any normal circumstances. +# +#Verbose + +# Uncomment to use fingerprints in the TURN messages. +# By default the fingerprints are off. +# +#fingerprint + +# Uncomment to use long-term credential mechanism. +# By default no credentials mechanism is used (any user allowed). +# +#lt-cred-mech + +# This option is opposite to lt-cred-mech. +# (TURN Server with no-auth option allows anonymous access). +# If neither option is defined, and no users are defined, +# then no-auth is default. If at least one user is defined, +# in this file or in command line or in usersdb file, then +# lt-cred-mech is default. +# +#no-auth + +# TURN REST API flag. +# Flag that sets a special authorization option that is based upon authentication secret. +# This feature can be used with the long-term authentication mechanism, only. +# This feature purpose is to support "TURN Server REST API", see +# "TURN REST API" link in the project's page +# https://github.com/coturn/coturn/ +# +# This option is used with timestamp: +# +# usercombo -> "timestamp:userid" +# turn user -> usercombo +# turn password -> base64(hmac(secret key, usercombo)) +# +# This allows TURN credentials to be accounted for a specific user id. +# If you don't have a suitable id, the timestamp alone can be used. +# This option is just turning on secret-based authentication. +# The actual value of the secret is defined either by option static-auth-secret, +# or can be found in the turn_secret table in the database (see below). +# +use-auth-secret + +# 'Static' authentication secret value (a string) for TURN REST API only. +# If not set, then the turn server +# will try to use the 'dynamic' value in turn_secret table +# in user database (if present). The database-stored value can be changed on-the-fly +# by a separate program, so this is why that other mode is 'dynamic'. +# +static-auth-secret={{ prosody.turn.secret }} + +# Server name used for +# the oAuth authentication purposes. +# The default value is the realm name. +# +#server-name=blackdow.carleon.gov + +# Flag that allows oAuth authentication. +# +#oauth + +# 'Static' user accounts for long term credentials mechanism, only. +# This option cannot be used with TURN REST API. +# 'Static' user accounts are NOT dynamically checked by the turnserver process, +# so that they can NOT be changed while the turnserver is running. +# +#user=username1:key1 +#user=username2:key2 +# OR: +#user=username1:password1 +#user=username2:password2 +# +# Keys must be generated by turnadmin utility. The key value depends +# on user name, realm, and password: +# +# Example: +# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic +# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee +# ('0x' in the beginning of the key is what differentiates the key from +# password. If it has 0x then it is a key, otherwise it is a password). +# +# The corresponding user account entry in the config file will be: +# +#user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee +# Or, equivalently, with open clear password (less secure): +#user=ninefingers:youhavetoberealistic +# + +# SQLite database file name. +# +# Default file name is /var/db/turndb or /usr/local/var/db/turndb or +# /var/lib/turn/turndb. +# +#userdb=/var/db/turndb + +# PostgreSQL database connection string in the case that we are using PostgreSQL +# as the user database. +# This database can be used for long-term credential mechanism +# and it can store the secret value for secret-based timed authentication in TURN RESP API. +# See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL +# versions connection string format, see +# http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING +# for 9.x and newer connection string formats. +# +#psql-userdb="host= dbname= user= password= connect_timeout=30" + +# MySQL database connection string in the case that we are using MySQL +# as the user database. +# This database can be used for long-term credential mechanism +# and it can store the secret value for secret-based timed authentication in TURN RESP API. +# +# Optional connection string parameters for the secure communications (SSL): +# ca, capath, cert, key, cipher +# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the +# command options description). +# +# Use string format as below (space separated parameters, all optional): +# +#mysql-userdb="host= dbname= user= password= port= connect_timeout= read_timeout=" + +# MongoDB database connection string in the case that we are using MongoDB +# as the user database. +# This database can be used for long-term credential mechanism +# and it can store the secret value for secret-based timed authentication in TURN RESP API. +# Use string format is described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html +# +#mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]" + +# Redis database connection string in the case that we are using Redis +# as the user database. +# This database can be used for long-term credential mechanism +# and it can store the secret value for secret-based timed authentication in TURN RESP API. +# Use string format as below (space separated parameters, all optional): +# +#redis-userdb="ip= dbname= password= port= connect_timeout=" + +# Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used). +# This database keeps allocations status information, and it can be also used for publishing +# and delivering traffic and allocation event notifications. +# The connection string has the same parameters as redis-userdb connection string. +# Use string format as below (space separated parameters, all optional): +# +#redis-statsdb="ip= dbname= password= port= connect_timeout=" + +# The default realm to be used for the users when no explicit +# origin/realm relationship was found in the database, or if the TURN +# server is not using any database (just the commands-line settings +# and the userdb file). Must be used with long-term credentials +# mechanism or with TURN REST API. +# +realm= {{ prosody.host }} + +# The flag that sets the origin consistency +# check: across the session, all requests must have the same +# main ORIGIN attribute value (if the ORIGIN was +# initially used by the session). +# +#check-origin-consistency + +# Per-user allocation quota. +# default value is 0 (no quota, unlimited number of sessions per user). +# This option can also be set through the database, for a particular realm. +# +#user-quota=0 + +# Total allocation quota. +# default value is 0 (no quota). +# This option can also be set through the database, for a particular realm. +# +#total-quota=0 + +# Max bytes-per-second bandwidth a TURN session is allowed to handle +# (input and output network streams are treated separately). Anything above +# that limit will be dropped or temporary suppressed (within +# the available buffer limits). +# This option can also be set through the database, for a particular realm. +# +#max-bps=0 + +# +# Maximum server capacity. +# Total bytes-per-second bandwidth the TURN server is allowed to allocate +# for the sessions, combined (input and output network streams are treated separately). +# +# bps-capacity=0 + +# Uncomment if no UDP client listener is desired. +# By default UDP client listener is always started. +# +#no-udp + +# Uncomment if no TCP client listener is desired. +# By default TCP client listener is always started. +# +#no-tcp + +# Uncomment if no TLS client listener is desired. +# By default TLS client listener is always started. +# +#no-tls + +# Uncomment if no DTLS client listener is desired. +# By default DTLS client listener is always started. +# +#no-dtls + +# Uncomment if no UDP relay endpoints are allowed. +# By default UDP relay endpoints are enabled (like in RFC 5766). +# +#no-udp-relay + +# Uncomment if no TCP relay endpoints are allowed. +# By default TCP relay endpoints are enabled (like in RFC 6062). +# +#no-tcp-relay + +# Uncomment if extra security is desired, +# with nonce value having limited lifetime. +# By default, the nonce value is unique for a session, +# and has unlimited lifetime. +# Set this option to limit the nonce lifetime. +# It defaults to 600 secs (10 min) if no value is provided. After that delay, +# the client will get 438 error and will have to re-authenticate itself. +# +#stale-nonce=600 + +# Uncomment if you want to set the maximum allocation +# time before it has to be refreshed. +# Default is 3600s. +# +#max-allocate-lifetime=3600 + + +# Uncomment to set the lifetime for the channel. +# Default value is 600 secs (10 minutes). +# This value MUST not be changed for production purposes. +# +#channel-lifetime=600 + +# Uncomment to set the permission lifetime. +# Default to 300 secs (5 minutes). +# In production this value MUST not be changed, +# however it can be useful for test purposes. +# +#permission-lifetime=300 + +# Certificate file. +# Use an absolute path or path relative to the +# configuration file. +# +#cert=/usr/local/etc/turn_server_cert.pem + +# Private key file. +# Use an absolute path or path relative to the +# configuration file. +# Use PEM file format. +# +#pkey=/usr/local/etc/turn_server_pkey.pem + +# Private key file password, if it is in encoded format. +# This option has no default value. +# +#pkey-pwd=... + +# Allowed OpenSSL cipher list for TLS/DTLS connections. +# Default value is "DEFAULT". +# +#cipher-list="DEFAULT" + +# CA file in OpenSSL format. +# Forces TURN server to verify the client SSL certificates. +# By default it is not set: there is no default value and the client +# certificate is not checked. +# +# Example: +#CA-file=/etc/ssh/id_rsa.cert + +# Curve name for EC ciphers, if supported by OpenSSL +# library (TLS and DTLS). The default value is prime256v1, +# if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+, +# an optimal curve will be automatically calculated, if not defined +# by this option. +# +#ec-curve-name=prime256v1 + +# Use 566 bits predefined DH TLS key. Default size of the key is 1066. +# +#dh566 + +# Use 2066 bits predefined DH TLS key. Default size of the key is 1066. +# +#dh2066 + +# Use custom DH TLS key, stored in PEM format in the file. +# Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file. +# +#dh-file= + +# Flag to prevent stdout log messages. +# By default, all log messages are going to both stdout and to +# the configured log file. With this option everything will be +# going to the configured log only (unless the log file itself is stdout). +# +#no-stdout-log + +# Option to set the log file name. +# By default, the turnserver tries to open a log file in +# /var/log, /var/tmp, /tmp and current directories directories +# (which open operation succeeds first that file will be used). +# With this option you can set the definite log file name. +# The special names are "stdout" and "-" - they will force everything +# to the stdout. Also, the "syslog" name will force everything to +# the system log (syslog). +# In the runtime, the logfile can be reset with the SIGHUP signal +# to the turnserver process. +# +#log-file=/var/tmp/turn.log + +# Option to redirect all log output into system log (syslog). +# +#syslog + +# This flag means that no log file rollover will be used, and the log file +# name will be constructed as-is, without PID and date appendage. +# This option can be used, for example, together with the logrotate tool. +# +#simple-log + +# Option to set the "redirection" mode. The value of this option +# will be the address of the alternate server for UDP & TCP service in form of +# [:]. The server will send this value in the attribute +# ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client. +# Client will receive only values with the same address family +# as the client network endpoint address family. +# See RFC 5389 and RFC 5766 for ALTERNATE-SERVER functionality description. +# The client must use the obtained value for subsequent TURN communications. +# If more than one --alternate-server options are provided, then the functionality +# can be more accurately described as "load-balancing" than a mere "redirection". +# If the port number is omitted, then the default port +# number 3478 for the UDP/TCP protocols will be used. +# Colon (:) characters in IPv6 addresses may conflict with the syntax of +# the option. To alleviate this conflict, literal IPv6 addresses are enclosed +# in square brackets in such resource identifiers, for example: +# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . +# Multiple alternate servers can be set. They will be used in the +# round-robin manner. All servers in the pool are considered of equal weight and +# the load will be distributed equally. For example, if we have 4 alternate servers, +# then each server will receive 25% of ALLOCATE requests. A alternate TURN server +# address can be used more than one time with the alternate-server option, so this +# can emulate "weighting" of the servers. +# +# Examples: +#alternate-server=1.2.3.4:5678 +#alternate-server=11.22.33.44:56789 +#alternate-server=5.6.7.8 +#alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 + +# Option to set alternative server for TLS & DTLS services in form of +# :. If the port number is omitted, then the default port +# number 5349 for the TLS/DTLS protocols will be used. See the previous +# option for the functionality description. +# +# Examples: +#tls-alternate-server=1.2.3.4:5678 +#tls-alternate-server=11.22.33.44:56789 +#tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 + +# Option to suppress TURN functionality, only STUN requests will be processed. +# Run as STUN server only, all TURN requests will be ignored. +# By default, this option is NOT set. +# +#stun-only + +# Option to suppress STUN functionality, only TURN requests will be processed. +# Run as TURN server only, all STUN requests will be ignored. +# By default, this option is NOT set. +# +#no-stun + +# This is the timestamp/username separator symbol (character) in TURN REST API. +# The default value is ':'. +# rest-api-separator=: + +# Flag that can be used to disallow peers on the loopback addresses (127.x.x.x and ::1). +# This is an extra security measure. +# +#no-loopback-peers + +# Flag that can be used to disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*). +# This is an extra security measure. +# +#no-multicast-peers + +# Option to set the max time, in seconds, allowed for full allocation establishment. +# Default is 60 seconds. +# +#max-allocate-timeout=60 + +# Option to allow or ban specific ip addresses or ranges of ip addresses. +# If an ip address is specified as both allowed and denied, then the ip address is +# considered to be allowed. This is useful when you wish to ban a range of ip +# addresses, except for a few specific ips within that range. +# +# This can be used when you do not want users of the turn server to be able to access +# machines reachable by the turn server, but would otherwise be unreachable from the +# internet (e.g. when the turn server is sitting behind a NAT) +# +# Examples: +# denied-peer-ip=83.166.64.0-83.166.95.255 +# allowed-peer-ip=83.166.68.45 + +# File name to store the pid of the process. +# Default is /var/run/turnserver.pid (if superuser account is used) or +# /var/tmp/turnserver.pid . +# +#pidfile="/var/run/turnserver.pid" + +# Require authentication of the STUN Binding request. +# By default, the clients are allowed anonymous access to the STUN Binding functionality. +# +#secure-stun + +# Mobility with ICE (MICE) specs support. +# +#mobility + +# User name to run the process. After the initialization, the turnserver process +# will make an attempt to change the current user ID to that user. +# +#proc-user= + +# Group name to run the process. After the initialization, the turnserver process +# will make an attempt to change the current group ID to that group. +# +#proc-group= + +# Turn OFF the CLI support. +# By default it is always ON. +# See also options cli-ip and cli-port. +# +#no-cli + +#Local system IP address to be used for CLI server endpoint. Default value +# is 127.0.0.1. +# +#cli-ip=127.0.0.1 + +# CLI server port. Default is 5766. +# +#cli-port=5766 + +# CLI access password. Default is empty (no password). +# For the security reasons, it is recommended to use the encrypted +# for of the password (see the -P command in the turnadmin utility). +# +# Secure form for password 'qwerty': +# +#cli-password=$5$79a316b350311570$81df9cfb9af7f5e5a76eada31e7097b663a0670f99a3c07ded3f1c8e59c5658a +# +# Or unsecure form for the same paassword: +# +#cli-password=qwerty + +# Server relay. NON-STANDARD AND DANGEROUS OPTION. +# Only for those applications when we want to run +# server applications on the relay endpoints. +# This option eliminates the IP permissions check on +# the packets incoming to the relay endpoints. +# +#server-relay + +# Maximum number of output sessions in ps CLI command. +# This value can be changed on-the-fly in CLI. The default value is 256. +# +#cli-max-output-sessions + +# Set network engine type for the process (for internal purposes). +# +#ne=[1|2|3] + +# Do not allow an TLS/DTLS version of protocol +# +#no-tlsv1 +#no-tlsv1_1 +#no-tlsv1_2 diff --git a/roles/unbound/tasks/main.yml b/roles/unbound/tasks/main.yml index d8d03e3..f3aacac 100644 --- a/roles/unbound/tasks/main.yml +++ b/roles/unbound/tasks/main.yml @@ -32,8 +32,11 @@ src: files/dhclient.conf - name: configure system DNS copy: - dest: /etc/resolv.conf - content: "nameserver 127.0.0.2\n" + dest: "{{ item }}" + content: "nameserver 127.0.0.2\noptions trust-ad\noptions edns0\n" + loop: + - /etc/resolv.conf.unbound + - /etc/resolv.conf # some providers need extra hacks to make our DNS persistent - name: install DNS-fix cronjob template: diff --git a/roles/unbound/templates/fix-dns b/roles/unbound/templates/fix-dns index ca7f860..f7b4bf2 100644 --- a/roles/unbound/templates/fix-dns +++ b/roles/unbound/templates/fix-dns @@ -2,9 +2,9 @@ set -e # Fix for some providers messing with DNS settings -if ! diff /etc/resolv.conf <(echo "nameserver 127.0.0.2") > /dev/null; then +if ! diff /etc/resolv.conf /etc/resolv.conf.unbound > /dev/null; then echo "Someone messed up our DNS! Fixing it..." - echo "nameserver 127.0.0.2" > /etc/resolv.conf + cp /etc/resolv.conf.unbound /etc/resolv.conf {% if 'email' in group_names %} # Just to make sure postfix uses the new settings systemctl restart postfix