mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 15:45:55 +08:00
Merge pull request #1400 from PhilippMundhenk/master
Automatic login for ProxyAuth plugin, improved security documentation
This commit is contained in:
commit
dac5b105ce
|
@ -12,7 +12,7 @@ The following example is for Traefik with Authelia and Dovecot as mailserver.
|
|||
|
||||
The following steps are require in SnappyMail:
|
||||
|
||||
- To open SnappyMail through a reverse proxy server, make sure to enable the correct secfetch policies: ```mode=navigate,dest=document,site=cross-site,user=true``` in the admin panel -> Config -> Security -> secfetch_allow.
|
||||
- To open SnappyMail through a reverse proxy server (with redirect of authentication system), make sure to enable the correct secfetch policies: ```mode=navigate,dest=document,site=cross-site,user=true;mode=navigate,dest=document,site=same-site,user=true``` in the admin panel -> Config -> Security -> secfetch_allow.
|
||||
- Activate plugin in admin panel -> Extensions
|
||||
- Configure the plugin with the required data:
|
||||
- Master User Separator is dependent on Dovecot config (see below)
|
||||
|
@ -21,6 +21,7 @@ The following steps are require in SnappyMail:
|
|||
- Header Name is dependent on authentication solution. This is the header containing the name of currently logged in user. In case of Authelia, this is "Remote-User".
|
||||
- Check Proxy: Since this plugin partially bypasses authentication, it is important to only allow this access from well-defined hosts. It is highly recommended to activate this option!
|
||||
- When checking for reverse proxy, it is required to set the IP filter to either an IP address or a subnet.
|
||||
- Automatic Login: Automatically logs in the user of user header is present (see below)
|
||||
|
||||
This concludes the setup of SnappyMail.
|
||||
|
||||
|
@ -50,12 +51,16 @@ passdb {
|
|||
|
||||
You then need to create a master user in /etc/dovecot/master-users:
|
||||
```
|
||||
admin:PASSWORD
|
||||
admin:PASSWORD::::::allow_nets=local,172.17.0.0/16
|
||||
```
|
||||
where the encrypted password ```PASSWORD``` can be created from a cleartext password with ```doveadm pw -s CRYPT```.
|
||||
It should start with ```{CRYPT}```.
|
||||
Username and password need to configured in the SnappyMail ProxyAuth plugin (see above).
|
||||
|
||||
You likely also want to limit the access by an IP address filter, e.g., to ```local,172.17.0.0/16```, if you are running Postfix (```local```) and within a default Docker environment (```172.17.0.0/16```).
|
||||
Otherwise, master user login (assuming password is known) is possible from every connectable system.
|
||||
This is an unnecessary security risk.
|
||||
|
||||
Additionally, you need to set the master user separator in /etc/dovecot/conf.d/10-auth.conf, e.g., ```auth_master_user_separator = *```.
|
||||
The separator needs to be configured in the SnappyMail ProxyAuth plugin (see above).
|
||||
|
||||
|
@ -64,3 +69,14 @@ The separator needs to be configured in the SnappyMail ProxyAuth plugin (see abo
|
|||
Once configured correctly, you should be able to access SnappyMail through your reverse proxy at ```https://snappymail.tld/?ProxyAuth```.
|
||||
If your reverse proxy provides the username in the configured header (e.g., Remote-User), you will automatically be logged in to your account.
|
||||
If not, you will be redirected to the login page.
|
||||
|
||||
## Automatic Login
|
||||
|
||||
By default, automatic login is activated.
|
||||
Behind the scenes, this checks for the existence of the configured user header (through ```/?UserHeaderSet```) and automatically redirects to ```https://snappymail.tld/?ProxyAuth```, trying to log in the user.
|
||||
Note that due to this implementation, logout is impossible, as once logged out, the user will automatically be logged in again.
|
||||
The user is always considered logged in, as authentication is handled through reverse proxy and authentication system.
|
||||
|
||||
Auto login can be disabled in the plugin settings.
|
||||
You can also change the logout link in admin panel -> Config -> custom_logout_link to the one of your authentication system, e.g., ```https://auth.yourdomain.com/logout```.
|
||||
In this case, you can log out from your overall system via SnappyMail.
|
||||
|
|
|
@ -15,7 +15,9 @@ class ProxyAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
|
||||
public function Init() : void
|
||||
{
|
||||
$this->addJs('js/auto-login.js');
|
||||
$this->addPartHook('ProxyAuth', 'ServiceProxyAuth');
|
||||
$this->addPartHook('UserHeaderSet', 'ServiceUserHeaderSet');
|
||||
$this->addHook('login.credentials', 'MapEmailAddress');
|
||||
}
|
||||
|
||||
|
@ -140,6 +142,28 @@ class ProxyAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
return true;
|
||||
}
|
||||
|
||||
public function ServiceUserHeaderSet() : bool
|
||||
{
|
||||
$oActions = \RainLoop\Api::Actions();
|
||||
|
||||
$oLogger = $oActions->Logger();
|
||||
$sLevel = LOG_DEBUG;
|
||||
$sPrefix = "ProxyAuth";
|
||||
|
||||
$sHeaderName = \trim($this->Config()->getDecrypted('plugin', 'header_name', ''));
|
||||
|
||||
$sRemoteUser = $this->Manager()->Actions()->Http()->GetHeader($sHeaderName);
|
||||
$sMsg = "Remote User: " . $sRemoteUser;
|
||||
$oLogger->Write($sMsg, $sLevel, $sPrefix);
|
||||
|
||||
if (strlen($sRemoteUser) > 0) {
|
||||
\MailSo\Base\Http::StatusHeader('200');
|
||||
} else {
|
||||
\MailSo\Base\Http::StatusHeader('401');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function configMapping() : array
|
||||
{
|
||||
return array(
|
||||
|
@ -178,7 +202,13 @@ class ProxyAuthPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('IP or Subnet of proxy, auth header will only be accepted from this address')
|
||||
->SetDefaultValue('10.1.0.0/24')
|
||||
->SetEncrypted()
|
||||
->SetEncrypted(),
|
||||
\RainLoop\Plugins\Property::NewInstance('auto_login')
|
||||
->SetAllowedInJs(true)
|
||||
->SetLabel('Activate automatic login')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetDescription('Activates automatic login, if User Header is set (note: Use custom_logout_link to enable logout, see plugin README)')
|
||||
->SetDefaultValue(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
32
plugins/proxy-auth/js/auto-login.js
Normal file
32
plugins/proxy-auth/js/auto-login.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
(rl => {
|
||||
|
||||
rl && addEventListener('rl-view-model', e => {
|
||||
const id = e.detail.viewModelTemplateID;
|
||||
if (e.detail && ('Login' === id)) {
|
||||
let
|
||||
auto_login = window.rl.pluginSettingsGet('proxy-auth', 'auto_login');
|
||||
;
|
||||
|
||||
const
|
||||
ForwardProxyAuth = () => {
|
||||
if (auto_login) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/?UserHeaderSet", true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
window.location.href = "/?ProxyAuth";
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
}
|
||||
};
|
||||
|
||||
window.ForwardProxyAuth = ForwardProxyAuth;
|
||||
|
||||
ForwardProxyAuth();
|
||||
}
|
||||
});
|
||||
})(window.rl);
|
||||
|
Loading…
Reference in a new issue