summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j22
-rw-r--r--roles/common-LDAP/tasks/main.yml8
-rw-r--r--roles/common-LDAP/templates/etc/default/slapd.j22
-rw-r--r--roles/common-LDAP/templates/etc/ldap/database.ldif.j258
-rw-r--r--roles/common/tasks/main.yml2
-rwxr-xr-xroles/common/templates/etc/nftables.conf.j24
-rw-r--r--roles/nextcloud/tasks/main.yml2
-rw-r--r--roles/webmail/tasks/main.yml2
8 files changed, 40 insertions, 40 deletions
diff --git a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2
index f2ffd17..efaf06a 100644
--- a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2
+++ b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2
@@ -116,41 +116,41 @@ Job {
{% for fd in groups.all | sort %}
Job {
Name = {{ hostvars[fd].inventory_hostname_short }}
Client = {{ hostvars[fd].inventory_hostname_short }}-fd
JobDefs = DefaultJob
FileSet = FileSetRoot
Pool = {{ hostvars[fd].inventory_hostname_short }}
Priority = 15
Schedule = WeeklyCycle
}
{% endfor %}
{% for fd in groups['MDA'] | union(groups['webmail']) | union(groups['lists']) | union(groups['bacula_dir']) | union(groups['nextcloud']) | sort %}
Job {
Name = {{ hostvars[fd].inventory_hostname_short }}-mysql
Client = {{ hostvars[fd].inventory_hostname_short }}-fd
JobDefs = DefaultMySQLJob
}
{% endfor %}
-{% for fd in groups['MDA'] | union(groups['MSA']) | union(groups['LDAP-provider']) | union(groups['MX']) | sort %}
+{% for fd in groups['MDA'] | union(groups['MSA']) | union(groups['LDAP_provider']) | union(groups['MX']) | sort %}
Job {
Name = {{ hostvars[fd].inventory_hostname_short }}-slapd
Client = {{ hostvars[fd].inventory_hostname_short }}-fd
JobDefs = DefaultSlapdJob
}
{% endfor %}
#
# Standard Restore template, to be changed by Console program
# Only one such job is needed for all Jobs/Clients/Storage ...
Job {
Name = RestoreFiles
Type = Restore
Client= {{ inventory_hostname_short }}-fd
FileSet = FileSetRoot
Storage = {{ hostvars[ groups['bacula_sd'][0] ].inventory_hostname_short }}-sd
Pool = Default
Messages = Standard
# NOTE: Files are put on the client (FD) that is being restored.
diff --git a/roles/common-LDAP/tasks/main.yml b/roles/common-LDAP/tasks/main.yml
index 5255cdf..89dd1d8 100644
--- a/roles/common-LDAP/tasks/main.yml
+++ b/roles/common-LDAP/tasks/main.yml
@@ -31,76 +31,76 @@
- genkey
# XXX: It's ugly to list all roles here, and to prunes them with a
# conditional...
- name: Generate a private key and a X.509 certificate for slapd
# XXX: GnuTLS (libgnutls26 2.12.20-8+deb7u2, found in Wheezy) doesn't
# support ECDSA; and slapd doesn't seem to support DHE (!?) so
# we're stuck with "plain RSA" Key-Exchange. Also, there is a bug with
# SHA-512.
command: genkeypair.sh x509
--pubkey=/etc/ldap/ssl/{{ item.name }}.pem
--privkey=/etc/ldap/ssl/{{ item.name }}.key
--ou=LDAP {{ item.ou }} --cn={{ item.name }}
--usage=digitalSignature,keyEncipherment,keyCertSign
-t rsa -b 4096 -h sha256
--owner=root --group=openldap --mode=0640
register: r2
changed_when: r2.rc == 0
failed_when: r2.rc > 1
with_items:
- - { group: 'LDAP-provider', name: ldap.fripost.org, ou: }
+ - { group: 'LDAP_provider', name: ldap.fripost.org, ou: }
- { group: 'MX', name: mx, ou: --ou=SyncRepl }
- { group: 'lists', name: lists, ou: --ou=SyncRepl }
when: "item.group in group_names"
tags:
- genkey
- name: Fetch slapd's X.509 certificate
# Ensure we don't fetch private data
become: False
fetch_cmd: cmd="openssl x509"
stdin=/etc/ldap/ssl/{{ item.name }}.pem
dest=certs/ldap/{{ item.name }}.pem
with_items:
- - { group: 'LDAP-provider', name: ldap.fripost.org }
+ - { group: 'LDAP_provider', name: ldap.fripost.org }
- { group: 'MX', name: mx }
- { group: 'lists', name: lists }
when: "item.group in group_names"
tags:
- genkey
- name: Copy the SyncProv's server certificate
copy: src=certs/ldap/ldap.fripost.org.pem
dest=/etc/ldap/ssl/ldap.fripost.org.pem
owner=root group=root
mode=0644
- when: "'LDAP-provider' not in group_names"
+ when: "'LDAP_provider' not in group_names"
tags:
- genkey
- name: Copy the SyncRepls's client certificates
assemble: src=certs/ldap remote_src=no
dest=/etc/ldap/ssl/clients.pem
owner=root group=root
mode=0644
- when: "'LDAP-provider' in group_names"
+ when: "'LDAP_provider' in group_names"
tags:
- genkey
- name: Start slapd
service: name=slapd state=started
when: not (r1.changed or r2.changed)
- meta: flush_handlers
- name: Copy fripost & amavis' schema
copy: src=etc/ldap/schema/{{ item }}
dest=/etc/ldap/schema/{{ item }}
owner=root group=root
mode=0644
# It'd certainly be nicer if we didn't have to deploy amavis' schema
# everywhere, but we need the 'objectClass' in our replicates, hence
# they need to be aware of the 'amavisAccount' class.
with_items:
- fripost.ldif
- amavis.schema
diff --git a/roles/common-LDAP/templates/etc/default/slapd.j2 b/roles/common-LDAP/templates/etc/default/slapd.j2
index fdd7481..dd3f87e 100644
--- a/roles/common-LDAP/templates/etc/default/slapd.j2
+++ b/roles/common-LDAP/templates/etc/default/slapd.j2
@@ -6,41 +6,41 @@ SLAPD_CONF=
# System account to run the slapd server under. If empty the server
# will run as root.
SLAPD_USER="openldap"
# System group to run the slapd server under. If empty the server will
# run in the primary group of its user.
SLAPD_GROUP="openldap"
# Path to the pid file of the slapd server. If not set the init.d script
# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.conf by
# default)
SLAPD_PIDFILE=
# slapd normally serves ldap only on all TCP-ports 389. slapd can also
# service requests on TCP-port 636 (ldaps) and requests via unix
# sockets.
SLAPD_SERVICES="ldapi:///"
{% for i in group_names | intersect(['MX','lists','MSA']) | sort %}
SLAPD_SERVICES="$SLAPD_SERVICES ldapi://%2Fvar%2Fspool%2Fpostfix-{{ postfix_instance[i].name }}%2Fprivate%2Fldapi/"
{% endfor %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
SLAPD_SERVICES="$SLAPD_SERVICES ldaps:///"
{% endif %}
# If SLAPD_NO_START is set, the init script will not start or restart
# slapd (but stop will still work). Uncomment this if you are
# starting slapd via some other means or if you don't want slapd normally
# started at boot.
#SLAPD_NO_START=1
# If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,
# the init script will not start or restart slapd (but stop will still
# work). Use this for temporarily disabling startup of slapd (when doing
# maintenance, for example, or through a configuration management system)
# when you don't want to edit a configuration file.
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
# For Kerberos authentication (via SASL), slapd by default uses the system
# keytab file (/etc/krb5.keytab). To use a different keytab file,
# uncomment this line and change the path.
#export KRB5_KTNAME=/etc/krb5.keytab
diff --git a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2 b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
index b9f282f..a154e29 100644
--- a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
+++ b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
@@ -9,150 +9,150 @@
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/slapd/slapd.args
olcPidFile: /var/run/slapd/slapd.pid
olcLogLevel: none
olcToolThreads: 1
{% if ansible_processor_vcpus > 4 %}
olcThreads: {{ 2 * ansible_processor_vcpus }}
{% else %}
olcThreads: 8
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcTLSCertificateFile: /etc/ldap/ssl/ldap.fripost.org.pem
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.fripost.org.key
# If we are being offered a client cert, it has to be trusted (in which
# case we map the X.509 subject to a DN in our namespace), or we
# terminate the connection. Not providing a certificate is fine for
# TLS-protected simple binds, though.
olcTLSVerifyClient: try
olcTLSCACertificateFile: /etc/ldap/ssl/clients.pem
olcAuthzRegexp: "^(cn=[^,]+,ou=syncRepl),ou=LDAP,ou=SSLcerts,o=Fripost$"
"dn.exact:$1,dc=fripost,dc=org"
olcSaslSecProps: minssf=128,noanonymous,noplain,nodict
olcTLSCipherSuite: PFS:%LATEST_RECORD_VERSION:!CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:!VERS-SSL3.0:!VERS-TLS1.0:!VERS-TLS1.1
{% endif %}
olcLocalSSF: 128
# /!\ This is not portable! But we only use glibc's crypt(3), which
# supports (salted, streched) SHA512
olcPasswordHash: {CRYPT}
olcPasswordCryptSaltFormat: $6$%s
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMonitorConfig
olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
olcAccess: to dn.subtree="cn=monitor"
by dn.exact="username=munin,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" read
by * =0
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=fripost,dc=org
-{% if 'LDAP-provider' not in group_names and 'MX' in group_names %}
+{% if 'LDAP_provider' not in group_names and 'MX' in group_names %}
olcReadOnly: TRUE
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcLastMod: TRUE
olcDbCheckpoint: 512 15
{% else %}
olcLastMod: FALSE
{% endif %}
# The root user has all rights on the whole database (when SASL-binding
# on a UNIX socket).
olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
# Ensure that all DIT access is made according to the LDAPv3 protocol,
# and must use 1/ authentication, and 2/ SASL or TLS. (Local clients
# should use ldapi:// and SASL/EXERNAL, while remote clients should use
# TLS.)
olcRequires: none LDAPv3 authc strong
olcSecurity: simple_bind=128 ssf=128 update_ssf=128
#
#
########################################################################
# Performance considerations
#
# To reindex an existing database, you have to
# * Stop slapd sudo service slapd stop
# * Reindex sudo -u openldap slapindex -b 'dc=fripost,dc=org'
# * Restart slapd sudo service slapd start
#
olcDbIndex: objectClass eq
# Let us make Postfix's life easier.
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcDbIndex: fvd,fvl eq,sub
olcDbIndex: fripostIsStatusActive eq
{% elif 'MX' in group_names or 'MDA' in group_names %}
olcDbIndex: fripostIsStatusActive,fvd,fvl eq
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcDbIndex: fripostOptionalMaildrop,fripostMaildrop eq,sub
olcDbIndex: fripostCanAddDomain,fripostCanAddAlias,fripostCanAddList,fripostOwner,fripostPostmaster,fripostListManager eq
{% elif 'MX' in group_names %}
olcDbIndex: fripostOptionalMaildrop pres
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcDbIndex: member,cn eq
{% endif %}
-{% if ('LDAP-provider' not in group_names and 'MX' in group_names) or
- ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if ('LDAP_provider' not in group_names and 'MX' in group_names) or
+ ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
# SyncProv/SyncRepl specific indexing.
olcDbIndex: entryCSN,entryUUID eq
{% endif%}
#
#
# References
# - https://wiki.zimbra.com/wiki/OpenLDAP_Performance_Tuning_5.0
# - http://www.openldap.org/doc/admin24/tuning.html
# - http://www.openldap.org/faq/data/cache/42.html
# - http://www.openldap.org/faq/data/cache/136.html
# - http://www.zytrax.com/books/ldap/apa/indeces.html
#
#
########################################################################
# Sync Replication
#
# References:
# - http://www.openldap.org/doc/admin24/replication.html#Syncrepl
# - http://www.zytrax.com/books/ldap/ch7/#ol-syncrepl-rap
#
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
olcLimits: dn.onelevel="ou=syncRepl,dc=fripost,dc=org"
time.soft=unlimited
time.hard=unlimited
size.soft=unlimited
size.hard=unlimited
{% endif %}
-{% if 'MX' in group_names and 'LDAP-provider' not in group_names %}
+{% if 'MX' in group_names and 'LDAP_provider' not in group_names %}
# Test it:
# LDAPSASL_MECH=external LDAPTLS_CACERT=/etc/ldap/ssl/ldap.fripost.org.pem LDAPTLS_CERT=/etc/ldap/ssl/mx.pem LDAPTLS_KEY=/etc/ldap/ssl/mx.key sudo -u openldap ldapwhoami -H ldaps://ldap.fripost.org/
# LDAPSASL_MECH=external LDAPTLS_CACERT=/etc/ldap/ssl/ldap.fripost.org.pem LDAPTLS_CERT=/etc/ldap/ssl/mx.pem LDAPTLS_KEY=/etc/ldap/ssl/mx.key sudo -u openldap ldapsearch -H ldaps://ldap.fripost.org/ -b ou=virtual,dc=fripost,dc=org
olcSyncrepl: rid=000
provider=ldaps://ldap.fripost.org
type=refreshAndPersist
retry="10 30 300 +"
searchbase="ou=virtual,dc=fripost,dc=org"
attrs=objectClass,fvd,fvl,fripostIsStatusActive,fripostMaildrop,fripostOptionalMaildrop,fripostPostmaster,fripostOwner,fripostUseContentFilter,fripostListManager
scope=sub
sizelimit=unlimited
schemachecking=off
bindmethod=sasl
saslmech=external
tls_cert=/etc/ldap/ssl/mx.pem
tls_key=/etc/ldap/ssl/mx.key
tls_cacert=/etc/ldap/ssl/ldap.fripost.org.pem
tls_reqcert=hard
{% endif %}
#
@@ -198,328 +198,328 @@ olcAddContentAcl: TRUE
# authentication to the LDAP server).
# * Authenticated users are allowed to change (ie replace) their
# password through TLS-protected connections, but read access is not
# granted.
# * Domain postmasters are allowed to change (ie replace) their users'
# password through TLS-protected connections, but read access is not
# granted.
# * The same goes for general admins.
# * The same goes for local admins.
olcAccess: to dn.regex="^fvl=[^,]+,(fvd=[^,]+,ou=virtual,dc=fripost,dc=org)$"
filter=(objectClass=FripostVirtualUser)
attrs=userPassword
by realanonymous tls_ssf=128 =xd
by realanonymous sockurl.regex="^ldapi://" =xd
by realself tls_ssf=128 =w
by group/FripostVirtualDomain/fripostPostmaster.expand="$1" tls_ssf=128 =w
by dn.onelevel="ou=admins,dc=fripost,dc=org" tls_ssf=128 =w
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =w
#
# * Services can authenticate
-{% if 'LDAP-provider' in group_names -%}
+{% if 'LDAP_provider' in group_names -%}
olcAccess: to dn.onelevel="ou=services,dc=fripost,dc=org"
filter=(objectClass=simpleSecurityObject)
attrs=userPassword
by realanonymous tls_ssf=128 =xd
{% endif -%}
#
# * Catch-all: no one else may access the passwords (including for
# simple bind).
olcAccess: to dn.subtree="dc=fripost,dc=org"
attrs=userPassword
by * =0
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Base
#
# * Only SyncRepl replicates may access operational attributes in the
# subtree, when using a TLS-protected connection.
-{% if 'LDAP-provider' in group_names -%}
+{% if 'LDAP_provider' in group_names -%}
olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
attrs=entryCSN,structuralObjectClass,hasSubordinates,subschemaSubentry
by dn.onelevel="ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
by * =0
#
# * They may also read entries (ie, the attributes they have access to
# as per the ACL below) in that subtree, when using a TLS-protected
# connection. Listing entries (their DN) is required to replicate
# deletions properly.
olcAccess: to dn.subtree="ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass
by dn.onelevel="ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
olcAccess: to dn.children="ou=virtual,dc=fripost,dc=org"
by group.exact="cn=admin,ou=groups,dc=fripost,dc=org" =wrsd
by users =0 break
{% endif -%}
#
# * Postfix may use the base as a searchBase on the MX:es, when
# connecting a local ldapi:// socket from the 'private' directory in
# one of the non-default instance's chroot.
# * So may Dovecot on the MDA (needed for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * So may Nextcloud on the LDAP provider
olcAccess: to dn.exact="ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass
filter=(objectClass=FripostVirtual)
{% if 'MDA' in group_names -%}
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
{% if 'MX' in group_names or 'MSA' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =sd
{% endif -%}
- {% if 'LDAP-provider' in group_names -%}
+ {% if 'LDAP_provider' in group_names -%}
by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =sd
{% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Domain entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
# * So has Dovecot on the MDA (for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * Amavis may use the entry as searchBase (required to look for the
# per-user preferences) but doesn't have read access to the entry.
# * The 'nobody' UNIX user has read access on the MX:es, when using
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket. This is required for the 'reserved-alias.pl'
# script.
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvd
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names -%}
+ {% if 'LDAP_provider' in group_names -%}
{% if groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% endif -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% if 'MDA' in group_names -%}
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =sd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual domain is
# active, and read the destination address for catch-alls, when using
# a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostOptionalMaildrop
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# * The 'nobody' UNIX user can list the domain owners and postmasters on
# the MX:es, when SASL-binding using the EXTERNAL mechanism and
# connecting to a local ldapi:// socket. This is required for the
# 'reserved-alias.pl' script.
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostOwner,fripostPostmaster
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names %}
by dn.exact="username=nobody,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias domain entries
#
# * The SyncRepl MX replicates have read access to the entry itself and
# the destination domain it aliases to, when using a TLS-protected
# connection.
# * So has Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,fripostMaildrop
filter=(&(objectClass=FripostVirtualAliasDomain)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# User entries
#
# * The SyncRepl replicates have read access to the entry itself, when
# using a TLS-protected connection.
# * So has Postfix, when connecting a local ldapi:// socket from the
# 'private' directory in one of the non-default instance's chroot.
# * So has Dovecot on the MDA (for the iterate filter), when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# * So has Amavis on the MDA, when SASL-binding using the EXTERNAL
# mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl
filter=(objectClass=FripostVirtualUser)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% if 'MDA' in group_names -%}
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
{% endif -%}
by users =0 break
#
# * The SyncRepl MX replicates can check whether a virtual user is
# active, when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive,fripostUseContentFilter
filter=(objectClass=FripostVirtualUser)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
{% if 'MDA' in group_names %}
#
# * Amavis can look for per-user configuration options, when
# SASL-binding using the EXTERNAL mechanism and connecting to a local
# ldapi:// socket.
# TODO: only allow it to read the configuration options users are allowed
# to set and modify.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=@AmavisAccount
filter=(&(objectClass=FripostVirtualUser)(objectClass=AmavisAccount)(fripostIsStatusActive=TRUE)(fripostUseContentFilter=TRUE))
by dn.exact="username=amavis,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
#
# * Dovecot can look for user quotas, when SASL-binding using the
# EXTERNAL mechanism and connecting to a local ldapi:// socket.
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostUserQuota
filter=(objectClass=FripostVirtualUser)
by dn.exact="username=dovecot,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://" =rsd
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Alias entries
#
# * The SyncRepl MX replicates can read the entry itelf, whether it
# is active, and the address(es) it aliases to, when using a
# TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostMaildrop,fripostIsStatusActive
filter=(objectClass=FripostVirtualAlias)
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# List entries
#
# * The SyncRepl replicates can read the entry itelf and the list manager, when
# using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostListManager
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# * The SyncRepl MX replicates can check whether a virtual list is
# active when using a TLS-protected connection.
# * So can Postfix on the MX:es, when connecting a local ldapi:// socket
# from the 'private' directory in one of the non-default instance's
# chroot.
-{% if 'MX' in group_names or ('LDAP-provider' in group_names and groups.MX | difference([inventory_hostname])) %}
+{% if 'MX' in group_names or ('LDAP_provider' in group_names and groups.MX | difference([inventory_hostname])) %}
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostIsStatusActive
filter=(&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry)))
- {% if 'LDAP-provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
+ {% if 'LDAP_provider' in group_names and groups.MX | difference([inventory_hostname]) -%}
by dn.exact="cn=mX,ou=syncRepl,dc=fripost,dc=org" tls_ssf=128 =rsd
{% endif -%}
{% if 'MX' in group_names -%}
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
{% endif -%}
by users =0 break
{% endif %}
#
# * The MSA's postfix user can read entry ownership to dermine the SASL
# login name(s) owning a given sender address
{% if 'MSA' in group_names %}
olcAccess: to dn.regex="^fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=fripostOwner,fripostPostmaster
filter=(|(objectClass=FripostVirtualAliasDomain)(objectClass=FripostVirtualDomain))
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
by users =0 break
olcAccess: to dn.regex="^fvl=[^,]+,fvd=[^,]+,ou=virtual,dc=fripost,dc=org$"
attrs=entry,objectClass,fvl,fripostOwner
filter=(|(objectClass=FripostVirtualAlias)(objectClass=FripostVirtualList)(objectClass=FripostVirtualUser))
by dn.exact="username=postfix,cn=peercred,cn=external,cn=auth" sockurl.regex="^ldapi://%2Fvar%2Fspool%2Fpostfix-[-[:alnum:]]+%2Fprivate%2F" =rsd
by users =0 break
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Export Fripost members to Nextcloud
olcAccess: to dn.exact="fvd=fripost.org,ou=virtual,dc=fripost,dc=org"
attrs=entry,objectClass,fvd
filter=(&(objectClass=FripostVirtualDomain)(!(objectClass=FripostPendingEntry)))
by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
by users =0 break
olcAccess: to dn.regex="^fvl=[^,]+,fvd=fripost.org,ou=virtual,dc=fripost,dc=org$"
attrs=entry,entryDN,entryUUID,objectClass,fvl,fripostIsStatusActive
filter=(&(objectClass=FripostVirtualUser)(!(objectClass=FripostPendingEntry))(fripostIsStatusActive=TRUE))
by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
by users =0 break
olcAccess: to dn.exact="ou=groups,dc=fripost,dc=org"
attrs=entry,objectClass
by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
by users =0 break
olcAccess: to dn.exact="cn=medlemmar,ou=groups,dc=fripost,dc=org"
by dn.exact="cn=nextcloud,ou=services,dc=fripost,dc=org" tls_ssf=128 =rsd
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index 55c1489..fc692fa 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -1,39 +1,39 @@
---
- import_tasks: sysctl.yml
tags: sysctl
- import_tasks: hosts.yml
- import_tasks: apt.yml
tags: apt
- name: Install intel-microcode
apt: pkg=intel-microcode
when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'"
tags: intel
- import_tasks: firewall.yml
tags:
- firewall
- iptables
- nftables
- import_tasks: stunnel.yml
tags: stunnel
- when: "'webmail' in group_names and 'LDAP-provider' not in group_names"
+ when: "'webmail' in group_names and 'LDAP_provider' not in group_names"
- import_tasks: auditd.yml
tags: auditd
- import_tasks: unbound.yml
tags:
- unbound
- dns
when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'"
- import_tasks: rkhunter.yml
tags: rkhunter
- import_tasks: clamav.yml
tags: clamav
- import_tasks: fail2ban.yml
tags: fail2ban
- import_tasks: smart.yml
tags:
- smartmontools
- smart
when: "not ansible_virtualization_role == 'guest'"
- name: Copy genkeypair.sh and gendhparam.sh
copy: src=usr/local/bin/{{ item }}
diff --git a/roles/common/templates/etc/nftables.conf.j2 b/roles/common/templates/etc/nftables.conf.j2
index 098a66d..fc7691a 100755
--- a/roles/common/templates/etc/nftables.conf.j2
+++ b/roles/common/templates/etc/nftables.conf.j2
@@ -1,52 +1,52 @@
#!/usr/sbin/nft -f
define in-tcp-ports = {
{{ ansible_port|default(22) }}
{% if 'MX' in group_names %}
, 25 # SMTP
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
, 636 # ldaps
{% endif %}
{% if 'IMAP' in group_names %}
, 993 # imaps
, 4190 # ManageSieve
{% endif %}
{% if 'MSA' in group_names %}
, 587 # submission [RFC4409]
, 465 # submission over TLS [RFC8314]
{% endif %}
{% if 'webmail' in group_names or 'lists' in group_names or 'wiki' in group_names or 'nextcloud' in group_names %}
, 80 # HTTP
, 443 # HTTP over SSL/TLS
{% endif %}
}
define out-tcp-ports = {
22
, 80 # HTTP
, 443 # HTTP over SSL/TLS
{% if 'out' in group_names or 'MSA' in group_names %}
, 25 # SMTP
{% endif %}
-{% if 'LDAP-provider' in group_names %}
+{% if 'LDAP_provider' in group_names %}
, 11371 # OpenPGP HTTP Keyserver
, 43 # whois
{% elif 'MX' in group_names or 'lists' in group_names or 'nextcloud' in group_names %}
, 636 # ldaps
{% endif %}
{% if 'IMAP' in group_names %}
, 2703 # Razor2
{% endif %}
}
###############################################################################
flush ruleset
table inet filter {
# blackholes
set fail2ban { type ipv4_addr; timeout 10m; }
set fail2ban6 { type ipv6_addr; timeout 10m; }
diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml
index ed898f9..f1e558b 100644
--- a/roles/nextcloud/tasks/main.yml
+++ b/roles/nextcloud/tasks/main.yml
@@ -88,41 +88,41 @@
register: r3
notify:
- Restart Nginx
- name: Start Nginx
service: name=nginx state=started
when: not (r1.changed or r2.changed or r3.changed)
- meta: flush_handlers
- name: Fetch Nginx's X.509 certificate
# Ensure we don't fetch private data
become: False
fetch_cmd: cmd="openssl x509 -noout -pubkey"
stdin=/etc/nginx/ssl/cloud.fripost.org.pem
dest=certs/public/cloud.fripost.org.pub
tags:
- genkey
- import_tasks: ldap.yml
- when: "'LDAP-provider' not in group_names"
+ when: "'LDAP_provider' not in group_names"
tags:
- ldap
# Note: intentionally don't set an owner/group as we don't want to set
# ownership unless the path is a mountpoint. The service will fail
# unless the data directory is mounted and accessible, and that's what
# we want.
- name: Create directory /mnt/nextcloud-data
file: path=/mnt/nextcloud-data
state=directory
mode=0700
- name: Create directory /var/www/nextcloud
file: path=/var/www/nextcloud
state=directory
owner=root group=root
mode=0755
# Note: Nextcloud doesn't like symlinked apps
# * https://github.com/nextcloud/server/issues/10437
diff --git a/roles/webmail/tasks/main.yml b/roles/webmail/tasks/main.yml
index 210d277..146c36f 100644
--- a/roles/webmail/tasks/main.yml
+++ b/roles/webmail/tasks/main.yml
@@ -1,9 +1,9 @@
- import_tasks: ldap.yml
- when: "'LDAP-provider' not in group_names"
+ when: "'LDAP_provider' not in group_names"
tags:
- ldap
- stunnel
- import_tasks: roundcube.yml
tags:
- roundcube
- webmail