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=6ed68e5d856a1d75a488551c036523670d2245e6 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 32215cf..dfba7c4 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,7 +1,6 @@ [defaults] inventory = hosts stdout_callback = debug -hash_behaviour = merge interpreter_python = auto_silent [diff] 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/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 528f662..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,debian-security-support 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 5d8ef0c..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 diff --git a/roles/email/tasks/mailman.yml b/roles/email/tasks/mailman.yml index 0988edb..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 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 a76cc25..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 @@ -75,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/etherpad/tasks/main.yml b/roles/etherpad/tasks/main.yml index d2c5a0c..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.8.4' + version: '1.8.18' force: yes - name: create etherpad service file register: etherpad_service diff --git a/roles/journalwatch/templates/patterns b/roles/journalwatch/templates/patterns index a05fdd1..db20d2d 100644 --- a/roles/journalwatch/templates/patterns +++ b/roles/journalwatch/templates/patterns @@ -51,21 +51,26 @@ 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 %} @@ -76,15 +81,26 @@ warning: dnsblog_query: lookup error for DNS query .* _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