mirror of
https://github.com/Mailu/Mailu.git
synced 2024-12-12 10:45:38 +02:00
Implement header authentication via external proxy
This commit is contained in:
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
|
||||
|
1
towncrier/newsfragments/1972.feature
Normal file
1
towncrier/newsfragments/1972.feature
Normal file
@ -0,0 +1 @@
|
||||
Implement Header authentication via external proxy
|
Loading…
Reference in New Issue
Block a user