Implement header authentication via external proxy

main
Florent Daigniere 2 years ago
parent 68bb8da2b7
commit e2d4e3eb2e

@ -80,6 +80,9 @@ DEFAULT_CONFIG = {
'TLS_PERMISSIVE': True,
'TZ': 'Etc/UTC',
'DEFAULT_SPAM_THRESHOLD': 80,
'PROXY_AUTH_WHITELIST': '',
'PROXY_AUTH_HEADER': 'X-Auth-Email',
'PROXY_AUTH_CREATE': False,
# Host settings
'HOST_IMAP': 'imap',
'HOST_LMTP': 'imap:2525',
@ -171,6 +174,7 @@ class ConfigManager:
self.config['HOSTNAMES'] = ','.join(hostnames)
self.config['HOSTNAME'] = hostnames[0]
self.config['DEFAULT_SPAM_THRESHOLD'] = int(self.config['DEFAULT_SPAM_THRESHOLD'])
self.config['PROXY_AUTH_WHITELIST'] = set(ipaddress.ip_network(cidr, False) for cidr in (cidr.strip() for cidr in self.config['PROXY_AUTH_WHITELIST'].split(',')) if cidr)
# update the app config
app.config.update(self.config)

@ -6,6 +6,8 @@ from mailu.ui import access
from flask import current_app as app
import flask
import flask_login
import secrets
import ipaddress
@sso.route('/login', methods=['GET', 'POST'])
def login():
@ -57,3 +59,36 @@ def logout():
flask.session.destroy()
return flask.redirect(flask.url_for('.login'))
@sso.route('/proxy', methods=['GET'])
@sso.route('/proxy/<target>', methods=['GET'])
def proxy(target='webmail'):
ip = ipaddress.ip_address(flask.request.remote_addr)
if not any(ip in cidr for cidr in app.config['PROXY_AUTH_WHITELIST']):
return flask.abort(500, '%s is not on PROXY_AUTH_WHITELIST' % flask.request.remote_addr)
email = flask.request.headers.get(app.config['PROXY_AUTH_HEADER'], None)
if not email:
return flask.abort(500, 'No %s header' % app.config['PROXY_AUTH_HEADER'])
user = models.User.get(email)
if user:
flask.session.regenerate()
flask_login.login_user(user)
return flask.redirect(app.config['WEB_ADMIN'] if target=='admin' else app.config['WEB_WEBMAIL'])
elif app.config['PROXY_AUTH_CREATE']:
localpart, desireddomain = email.split('@')
domain = models.Domain.query.get(desireddomain) or flask.abort(500, 'You don\'t exist. Go away! (domain=%s)' % desireddomain)
if not domain.max_users == -1 and len(domain.users) >= domain.max_users:
flask.current_app.logger.warning('Too many users for domain %s' % domain)
return flask.abort(500, 'Too many users in (domain=%s)' % domain)
user = models.User(localpart=localpart, domain=domain)
user.set_password(secrets.token_urlsafe())
models.db.session.add(user)
models.db.session.commit()
user.send_welcome()
client_ip = flask.request.headers.get('X-Real-IP', flask.request.remote_addr)
flask.current_app.logger.info(f'Login succeeded by proxy created user: {user} from {client_ip} through {flask.request.remote_addr}.')
return flask.redirect(app.config['WEB_ADMIN'] if target=='admin' else app.config['WEB_WEBMAIL'])
else:
return flask.abort(500, 'You don\'t exist. Go away! (%s)' % email)

@ -362,3 +362,15 @@ It can be configured with the following option:
When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the
logs every week and keep 52 logs. To override the logrotate configuration, create the file logrotate.conf
with the desired configuration in the :ref:`Postfix overrides folder<override-label>`.
Header authentication using an external proxy
---------------------------------------------
The ``PROXY_AUTH_WHITELIST`` (default: unset/disabled) option allows you to configure a comma separated list of CIDRs of proxies to trust for authentication. This list is separate from ``REAL_IP_FROM`` and any entry in ``PROXY_AUTH_WHITELIST`` should also appear in ``REAL_IP_FROM``.
Use ``PROXY_AUTH_HEADER`` (default: 'X-Auth-Email') to customize which HTTP header the email address of the user to authenticate as should be and ``PROXY_AUTH_CREATE`` (default: False) to control whether non-existing accounts should be auto-created. Please note that Mailu doesn't currently support creating new users for non-existing domains; you do need to create all the domains that may be used manually.
Once configured, any request to /sso/proxy will be redirected to the webmail and /sso/proxy/admin to the admin panel. Please check issue `1972` for more details.
.. _`1972`: https://github.com/Mailu/Mailu/issues/1972

@ -0,0 +1 @@
Implement Header authentication via external proxy
Loading…
Cancel
Save