a67a57913d
Software updates: * Upgraded Nextcloud from 17.0.6 to 20.0.1 (with Contacts from 3.3.0 to 3.4.1 and Calendar from 2.0.3 to 2.1.2) * Upgraded Roundcube to version 1.4.9. Mail: * The MTA-STA max_age value was increased to the normal one week. Control Panel: * Two-factor authentication can now be enabled for logins to the control panel. However, keep in mind that many online services (including domain name registrars, cloud server providers, and TLS certificate providers) may allow an attacker to take over your account or issue a fraudulent TLS certificate with only access to your email address, and this new two-factor authentication does not protect access to your inbox. It therefore remains very important that user accounts with administrative email addresses have strong passwords. * TLS certificate expiry dates are now shown in ISO8601 format for clarity. -----BEGIN PGP SIGNATURE----- iQFDBAABCgAtFiEEX0wOcxPM10RpOyrquSBB9MEL3YEFAl+v8k4PHGp0QG9jY2Ft cy5pbmZvAAoJELkgQfTBC92BMYUIAJTD1iKzY1SoDNSp8JMPn2sWusOnJNrnvYEV vsrBM4AzwJv3DIZKSkYCitbTQW2FsTcjF6Jl5PCavEmAGe55AIKAPM/52Uq6jqDE aR8EZvI9ca1i7yR7DOHEI043QSPmp/iCFD48vvmKgN/LZy67TaHaOlGJbc3nfpk0 y7ejMpF/6RP6ik4snnRQoWTFShaOpB9WcEVnUO7CHZdWcpSCZ55c9yi6A6ExGk7e 97R5+JN1MgOdZ6rzWZuMWiz7EZ/Ew4jYLZpOwg8qJm0HNbYJ6+/xxsQBwaQzyBw3 TsTl4GmunNPfoNrmKdJeLy0sBwiVBv/rysjWjim5v8jAYBoKoUQ= =2oRU -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEAKK/toPAcMkE+dinLzJ3OKPArjoFAl+xc7sACgkQLzJ3OKPA rjo6Zw//eYyTBlfQfFHIsLYKxJbwh6fDrIG6/Za6898cPhkJ/ugBeJlNEyT/EjpU MvtIgEU9xbG/tjsnQXsgAXJ6s7ZWm1QB5D+wqUIEeAFUn5IkCnXo0wPZJhSTNZhD 4InnWsicYZj/ByuSH179xHyTAx2uYDBbPT4HjUlzIsaopvWOKLvAfzY3r42AiNvZ e79MhKbtOs9kDkrB2LULRzz6WzJDKb11fJccf7UaBerwFvOarMr8hSpOysK0ocHk H0wbrGxjb8iBjczVP4OFh36satQ5l4B1W+QVIxZG9ufVAOe3dhv8HngaHqAVyUgF gWjDYTnL/anoMMew+kbn2sjeKH6m2ZA+u9g+mDyMGSECVVYhkpOpcbPjZlmlNAQN C5BHmHltIg90uicrhzEEPFDBR1JF7JrYO42EwnOWMwjhzRkH2cepVw86lDr+pbrH s3hvoWiFFt7cs5ShCpgZDL20ey1e+9wL6b72Qlo7ls7MK3vfZvLPxJLpTi+bnymD CNt82Mjpu3BrhjCIGp+px9E2JU/7wUwqyUbgWFtyqxCdJOZXA4ZXVtDs5pQFzhug G+Z1HxFmhxck17SD0uHhXJKRD8IRttnO5sBESJaLNB4Ws/KspHVPePNskB/1XSfr pFOqikZsoKOICZnpd/eTnUlciqFygqvB0WuFsJNttQN2dBpJViA= =ZMFZ -----END PGP SIGNATURE----- Merge upstream v0.51
157 lines
6.8 KiB
Bash
Executable file
157 lines
6.8 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# User Authentication and Destination Validation
|
|
# ----------------------------------------------
|
|
#
|
|
# This script configures user authentication for Dovecot
|
|
# and Postfix (which relies on Dovecot) and destination
|
|
# validation by quering an Sqlite3 database of mail users.
|
|
|
|
source setup/functions.sh # load our functions
|
|
source /etc/mailinabox.conf # load global vars
|
|
|
|
# ### User and Alias Database
|
|
|
|
# The database of mail users (i.e. authenticated users, who have mailboxes)
|
|
# and aliases (forwarders).
|
|
|
|
db_path=$STORAGE_ROOT/mail/users.sqlite
|
|
|
|
# Create an empty database if it doesn't yet exist.
|
|
if [ ! -f $db_path ]; then
|
|
echo Creating new user database: $db_path;
|
|
echo "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, password TEXT NOT NULL, extra, privileges TEXT NOT NULL DEFAULT '');" | sqlite3 $db_path;
|
|
echo "CREATE TABLE aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT NOT NULL UNIQUE, destination TEXT NOT NULL, permitted_senders TEXT);" | sqlite3 $db_path;
|
|
echo "CREATE TABLE mfa (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, type TEXT NOT NULL, secret TEXT NOT NULL, mru_token TEXT, label TEXT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE);" | sqlite3 $db_path;
|
|
fi
|
|
|
|
# ### User Authentication
|
|
|
|
# Have Dovecot query our database, and not system users, for authentication.
|
|
sed -i "s/#*\(\!include auth-system.conf.ext\)/#\1/" /etc/dovecot/conf.d/10-auth.conf
|
|
sed -i "s/#\(\!include auth-sql.conf.ext\)/\1/" /etc/dovecot/conf.d/10-auth.conf
|
|
|
|
# Specify how the database is to be queried for user authentication (passdb)
|
|
# and where user mailboxes are stored (userdb).
|
|
cat > /etc/dovecot/conf.d/auth-sql.conf.ext << EOF;
|
|
passdb {
|
|
driver = sql
|
|
args = /etc/dovecot/dovecot-sql.conf.ext
|
|
}
|
|
userdb {
|
|
driver = sql
|
|
args = /etc/dovecot/dovecot-sql.conf.ext
|
|
}
|
|
EOF
|
|
|
|
# Configure the SQL to query for a user's metadata and password.
|
|
cat > /etc/dovecot/dovecot-sql.conf.ext << EOF;
|
|
driver = sqlite
|
|
connect = $db_path
|
|
default_pass_scheme = SHA512-CRYPT
|
|
password_query = SELECT email as user, password FROM users WHERE email='%u';
|
|
user_query = SELECT email AS user, "mail" as uid, "mail" as gid, "$STORAGE_ROOT/mail/mailboxes/%d/%n" as home FROM users WHERE email='%u';
|
|
iterate_query = SELECT email AS user FROM users;
|
|
EOF
|
|
chmod 0600 /etc/dovecot/dovecot-sql.conf.ext # per Dovecot instructions
|
|
|
|
# Have Dovecot provide an authorization service that Postfix can access & use.
|
|
cat > /etc/dovecot/conf.d/99-local-auth.conf << EOF;
|
|
service auth {
|
|
unix_listener /var/spool/postfix/private/auth {
|
|
mode = 0666
|
|
user = postfix
|
|
group = postfix
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# And have Postfix use that service. We *disable* it here
|
|
# so that authentication is not permitted on port 25 (which
|
|
# does not run DKIM on relayed mail, so outbound mail isn't
|
|
# correct, see #830), but we enable it specifically for the
|
|
# submission port.
|
|
management/editconf.py /etc/postfix/main.cf \
|
|
smtpd_sasl_type=dovecot \
|
|
smtpd_sasl_path=private/auth \
|
|
smtpd_sasl_auth_enable=no
|
|
|
|
# ### Sender Validation
|
|
|
|
# We use Postfix's reject_authenticated_sender_login_mismatch filter to
|
|
# prevent intra-domain spoofing by logged in but untrusted users in outbound
|
|
# email. In all outbound mail (the sender has authenticated), the MAIL FROM
|
|
# address (aka envelope or return path address) must be "owned" by the user
|
|
# who authenticated. An SQL query will find who are the owners of any given
|
|
# address.
|
|
management/editconf.py /etc/postfix/main.cf \
|
|
smtpd_sender_login_maps=sqlite:/etc/postfix/sender-login-maps.cf
|
|
|
|
# Postfix will query the exact address first, where the priority will be alias
|
|
# records first, then user records. If there are no matches for the exact
|
|
# address, then Postfix will query just the domain part, which we call
|
|
# catch-alls and domain aliases. A NULL permitted_senders column means to
|
|
# take the value from the destination column.
|
|
cat > /etc/postfix/sender-login-maps.cf << EOF;
|
|
dbpath=$db_path
|
|
query = SELECT permitted_senders FROM (SELECT permitted_senders, 0 AS priority FROM aliases WHERE source='%s' AND permitted_senders IS NOT NULL UNION SELECT destination AS permitted_senders, 1 AS priority FROM aliases WHERE source='%s' AND permitted_senders IS NULL UNION SELECT email as permitted_senders, 2 AS priority FROM users WHERE email='%s') ORDER BY priority LIMIT 1;
|
|
EOF
|
|
|
|
# ### Destination Validation
|
|
|
|
# Use a Sqlite3 database to check whether a destination email address exists,
|
|
# and to perform any email alias rewrites in Postfix.
|
|
management/editconf.py /etc/postfix/main.cf \
|
|
virtual_mailbox_domains=sqlite:/etc/postfix/virtual-mailbox-domains.cf \
|
|
virtual_mailbox_maps=sqlite:/etc/postfix/virtual-mailbox-maps.cf \
|
|
virtual_alias_maps=sqlite:/etc/postfix/virtual-alias-maps.cf \
|
|
local_recipient_maps=\$virtual_mailbox_maps
|
|
|
|
# SQL statement to check if we handle incoming mail for a domain, either for users or aliases.
|
|
cat > /etc/postfix/virtual-mailbox-domains.cf << EOF;
|
|
dbpath=$db_path
|
|
query = SELECT 1 FROM users WHERE email LIKE '%%@%s' UNION SELECT 1 FROM aliases WHERE source LIKE '%%@%s'
|
|
EOF
|
|
|
|
# SQL statement to check if we handle incoming mail for a user.
|
|
cat > /etc/postfix/virtual-mailbox-maps.cf << EOF;
|
|
dbpath=$db_path
|
|
query = SELECT 1 FROM users WHERE email='%s'
|
|
EOF
|
|
|
|
# SQL statement to rewrite an email address if an alias is present.
|
|
#
|
|
# Postfix makes multiple queries for each incoming mail. It first
|
|
# queries the whole email address, then just the user part in certain
|
|
# locally-directed cases (but we don't use this), then just `@`+the
|
|
# domain part. The first query that returns something wins. See
|
|
# http://www.postfix.org/virtual.5.html.
|
|
#
|
|
# virtual-alias-maps has precedence over virtual-mailbox-maps, but
|
|
# we don't want catch-alls and domain aliases to catch mail for users
|
|
# that have been defined on those domains. To fix this, we not only
|
|
# query the aliases table but also the users table when resolving
|
|
# aliases, i.e. we turn users into aliases from themselves to
|
|
# themselves. That means users will match in postfix's first query
|
|
# before postfix gets to the third query for catch-alls/domain alises.
|
|
#
|
|
# If there is both an alias and a user for the same address either
|
|
# might be returned by the UNION, so the whole query is wrapped in
|
|
# another select that prioritizes the alias definition to preserve
|
|
# postfix's preference for aliases for whole email addresses.
|
|
#
|
|
# Since we might have alias records with an empty destination because
|
|
# it might have just permitted_senders, skip any records with an
|
|
# empty destination here so that other lower priority rules might match.
|
|
cat > /etc/postfix/virtual-alias-maps.cf << EOF;
|
|
dbpath=$db_path
|
|
query = SELECT destination from (SELECT destination, 0 as priority FROM aliases WHERE source='%s' AND destination<>'' UNION SELECT email as destination, 1 as priority FROM users WHERE email='%s') ORDER BY priority LIMIT 1;
|
|
EOF
|
|
|
|
# Restart Services
|
|
##################
|
|
|
|
restart_service postfix
|
|
restart_service dovecot
|
|
|
|
|