Postfix : root and system user authentication
Hello everyone,
From what I understand of the documentation, it is impossible to log in to the dovecot server as root, or as any user not in the interval between first_valid_uid and last_valid_uid.
I have been able to verify this.
However, when we have a postfix server on the same machine, that delegates authentication to dovecot SASL according to the configuration described at https://doc.dovecot.org/configuration_manual/howto/postfix_and_dovecot_sasl/, we can indeed log in as root on the postfix server.
Proof (/var/log/mail.log with auth=debug) :
Mar 13 20:16:37 ricorambo dovecot: auth: Debug: client in: AUTH#0111#011PLAIN#011service=smtp#011nologin#011lip=<redacted>#011rip=<redacted>#011secured#011resp=<hidden> Mar 13 20:16:37 ricorambo dovecot: auth: Debug: pam(root,<redacted>): Performing passdb lookup Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): Server accepted connection (fd=13) Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): Sending version handshake Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: Handling PASSV request Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: pam(root,<redacted>): Performing passdb lookup Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: pam(root,<redacted>): lookup service=dovecot Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: pam(root,<redacted>): #1/1 style=1 msg=Password: Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: pam(root,<redacted>): Finished passdb lookup Mar 13 20:16:37 ricorambo dovecot: auth-worker(136499): Debug: conn unix:auth-worker (pid=136444,uid=111): auth-worker<1>: Finished Mar 13 20:16:37 ricorambo dovecot: auth: Debug: pam(root,<redacted>): Finished passdb lookup Mar 13 20:16:37 ricorambo dovecot: auth: Debug: auth(root,<redacted>): Auth request finished Mar 13 20:16:37 ricorambo dovecot: auth: Debug: client passdb out: OK#0111#011user=root#011
At this moment, the smtps client connecting to postfix produces "Authentication successful" and we can continue.
In contrast, when we try to login to dovecot directly as root, we have the following :
Mar 13 20:28:38 ricorambo dovecot: auth: Debug: client in: AUTH#0111#011PLAIN#011service=imap#011secured=tls#011session=<redacted>#011lip=<redacted>#011rip=<redacted>#011lport=993#011rport=52004#011local_name=mail.ricorambo.su#011resp=<hidden> Mar 13 20:28:38 ricorambo dovecot: auth: Debug: pam(root,<redacted>,<redacted>): Performing passdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): Server accepted connection (fd=13) Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): Sending version handshake Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: Handling PASSV request Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: pam(root,<redacted>,<redacted>): Performing passdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: pam(root,<redacted>,<redacted>): lookup service=dovecot Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: pam(root,<redacted>,<redacted>): #1/1 style=1 msg=Password: Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: pam(root,<redacted>,<redacted>): Finished passdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<1>: Finished Mar 13 20:28:38 ricorambo dovecot: auth: Debug: pam(root,<redacted>,<eU8pHs32JMuE40wF>): Finished passdb lookup Mar 13 20:28:38 ricorambo dovecot: auth: Debug: auth(root,<redacted>,<eU8pHs32JMuE40wF>): Auth request finished Mar 13 20:28:38 ricorambo dovecot: auth: Debug: client passdb out: OK#0111#011user=root#011#011original_user=root@ricorambo.su Mar 13 20:28:38 ricorambo dovecot: auth: Debug: master in: REQUEST#<redacted> Mar 13 20:28:38 ricorambo dovecot: auth: Debug: passwd(root,<redacted>,<redacted>): Performing userdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<2>: Handling USER request Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<2>: passwd(root,<redacted>,<redacted>): Performing userdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<2>: passwd(root,<redacted>,<redacted>): lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<2>: passwd(root,<redacted>,<redacted>): Finished userdb lookup Mar 13 20:28:38 ricorambo dovecot: auth-worker(137089): Debug: conn unix:auth-worker (pid=137079,uid=111): auth-worker<2>: Finished Mar 13 20:28:38 ricorambo dovecot: auth: Debug: passwd(root,<redacted>,<redacted>): Finished userdb lookup Mar 13 20:28:38 ricorambo dovecot: auth: Debug: master userdb out: USER#<redacted> Mar 13 20:28:38 ricorambo dovecot: imap-login: Login: user=<root>, method=PLAIN, rip=<redacted>, lip=192.168.1.22, mpid=137090, TLS, session=<redacted> Mar 13 20:28:38 ricorambo dovecot: imap(root): Error: Invalid settings in userdb: userdb returned 0 as uid Mar 13 20:28:38 ricorambo dovecot: imap(root): Warning: Event 0xaaab0e9db2a0 leaked (parent=0xaaab0e9cdc80): mail-storage-service.c:1336 Mar 13 20:28:38 ricorambo dovecot: imap(root): Warning: Event 0xaaab0e9cdc80 leaked (parent=(nil)): main.c:246
At this moment, the imap client produces "Internal server error" and finishes.
Steps to reproduce :
- Delegate SASL authentication from postfix to dovecot as such :
/etc/postfix/master.cf
smtps inet n - y - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth
and of course :
/etc/dovecot/conf.d/10-master.conf
unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix }
- login to your server, port 465, with a client like openssl :
openssl s_client -connect mail.example.org:465
EHLO whateveryouwant
AUTH PLAIN \0root\0password (in base 64, ofc)
You should be able to login, and produce the first log trace I have included.
My question is, is this a feature or a bug ? The hardcoded impossibility to login as root to dovecot, and the honouring of the variables {first,last}_valid_{u,g}id, are those specific to login to dovecot directly, or should they be applicable to any other process that has delegated its authentication to dovecot ?
If this is a feature, that is if postfix cannot profit from the variables {first,last}_valid_{u,g}id (or the hardcoded forbidding of root) through dovecot sasl :
- This should maybe made more obvious somewhere in the documentation.
- What would be the good way to prevent root login to postfix, when authentication is delegated to dovecot ?
The dovecot version is 2.3.13 (89f716dc2) The system is the following : Linux 5.10.0-21-arm64 #1 SMP Debian 5.10.162-1 (2023-01-21) aarch64 GNU/Linux
Thank you in advance for your time. I have included the output of dovecot -n for reference.
Best regards,
Aymeric
However, when we have a postfix server on the same machine, that delegates authentication to dovecot SASL ... we can indeed log in as root on the postfix server.
You are not logging into Dovecot with root, you are connecting to Postfix for submission.
When you connect to dovecot using linux users (PAM) the process running takes on the UID of the login user to give file permissions to read that users home directory where email could be stored. The risk being if someone had root UID:0 they could read anything on the server, not just the home directory of a user.
But you aren't logging into Dovecot, you are connecting to Postfix. You aren't checking mail or reading directories. You are only submitting an email to Postfix for submission services. Postfix runs as its own Postfix UID no matter who you authenticate as. So even though you are authenticating yourself with root credentials, you aren't doing so as the root UID, you aren't reading email, and you aren't accessing any file systems like Dovecot would be.
Le mardi 14 mars 2023 à 22:32, dovecot@ptld.com a écrit :
However, when we have a postfix server on the same machine, that delegates authentication to dovecot SASL ... we can indeed log in as root on the postfix server.
You are not logging into Dovecot with root, you are connecting to Postfix for submission.
When you connect to dovecot using linux users (PAM) the process running takes on the UID of the login user to give file permissions to read that users home directory where email could be stored. The risk being if someone had root UID:0 they could read anything on the server, not just the home directory of a user.
But you aren't logging into Dovecot, you are connecting to Postfix. You aren't checking mail or reading directories. You are only submitting an email to Postfix for submission services. Postfix runs as its own Postfix UID no matter who you authenticate as. So even though you are authenticating yourself with root credentials, you aren't doing so as the root UID, you aren't reading email, and you aren't accessing any file systems like Dovecot would be.
I agree that this is absolutely not the same in terms of security.
The thing I'm worrying about is a lot less dangerous than what you're describing, no arguing about that. It's just, if we imagine that we have disabled root ssh access, and password ssh connection (allowing only keypair connection), this situation provides the port 465 as another way to test passwords, for instance. I would just like to be able to implement on port 465 more or less the same requirements I have implemented on port 22, and on port 993 as well through the use of {first,last}_valid_{u,g}id : a static, and well-known set of users that are allowed to try and authenticate, even though, as you say (and I agree), that the risk is absolutely not the same as with SSH or IMAPS.
So, am I to understand from your answer that the fact that login with root or with users not respecting {first,last}_valid_{u,g}id is only applicable to dovecot direcly, not to other processes that have delegated authentication to dovecot ? In other words, that this is a feature and not a bug ?
Best,
Aymeric
However, when we have a postfix server on the same machine, that delegates authentication to dovecot SASL ... we can indeed log in as root on the postfix server.
You are not logging into Dovecot with root, you are connecting to Postfix for submission.
When you connect to dovecot using linux users (PAM) the process running takes on the UID of the login user to give file permissions to read that users home directory where email could be stored. The risk being if someone had root UID:0 they could read anything on the server, not just the home directory of a user.
But you aren't logging into Dovecot, you are connecting to Postfix. You aren't checking mail or reading directories. You are only submitting an email to Postfix for submission services. Postfix runs as its own Postfix UID no matter who you authenticate as. So even though you are authenticating yourself with root credentials, you aren't doing so as the root UID, you aren't reading email, and you aren't accessing any file systems like Dovecot would be.
I agree that this is absolutely not the same in terms of security.
The thing I'm worrying about is a lot less dangerous than what you're describing, no arguing about that. It's just, if we imagine that we have disabled root ssh access, and password ssh connection (allowing only keypair connection), this situation provides the port 465 as another way to test passwords, for instance. I would just like to be able to implement on port 465 more or less the same requirements I have implemented on port 22, and on port 993 as well through the use of {first,last}_valid_{u,g}id : a static, and well-known set of users that are allowed to try and authenticate, even though, as you say (and I agree), that the risk is absolutely not the same as with SSH or IMAPS.
So, am I to understand from your answer that the fact that login with root or with users not respecting {first,last}_valid_{u,g}id is only applicable to dovecot direcly, not to other processes that have delegated authentication to dovecot ? In other words, that this is a feature and not a bug ?
Me personally, this is why i prefer to use virtual users stored in a database for email and never use linux users. I have ultimate control over what users can be authenticated or receive email. I can add flags to the DB query to fail an otherwise valid user. Why would i want a root@ email address? Why would i want my system to accept email for httpd from some stranger on the internet? Why would i want to have to create a linux user at the OS level just to add a mailbox?
"dovecot" == dovecot dovecot@ptld.com writes:
Me personally, this is why i prefer to use virtual users stored in a database for email and never use linux users. I have ultimate control over what users can be authenticated or receive email. I can add flags to the DB query to fail an otherwise valid user. Why would i want a root@ email address? Why would i want my system to accept email for httpd from some stranger on the internet? Why would i want to have to create a linux user at the OS level just to add a mailbox?
This is 110% agree. It's just so simple to use purely virtual users, even if you are pulling the login info from LDAP/AD for real users. But you don't need to allow *any* logins to the dovecot or postfix server using local logins at all. It's just better security.
John
I have a solution to my problem.
For reference, I am putting it here :
I recall that my issue is that postfix authorises login with root (or other users), even though authentication is delegated to dovecot, and the documentation about {first,last}_valid_{g,u}id seems to say that is should not be possible (and that authentication to dovecot with root is also forbidden in a hardcoded way).
I thank Mr. Ardley to have pointed out that dovecot delegates the authentication to PAM.
What actually happens (in my case at least) is that dovecot questions PAM about a specific authentication attempt, and receives PAM's answer. Then, *and only for itself*, it applies its own restrictions regarding root login and {first,last}_valid_{g,u}id. When it authenticates on behalf of postfix, it notifies postfix of success directly.
So the semantic of {first,last}_valid_{g,u}id should be understood for dovecot only, not for other processes that have delegated authentication to dovecot, which answers my first question.
Then, on how to effectively restrict postfix submission login based on uids, the simple solution not involving virtual users is to set these conditions in PAM directly.
The conditions that dovecot must match in order to succeed authentication with PAM are in the file /etc/pam.d/dovecot (at least on Debian) :
#%PAM-1.0
@include common-auth @include common-account @include common-session
A simple way to restrict login based on uids is to modify the file as such :
#%PAM-1.0
auth required pam_succeed_if.so uid > 500 quiet @include common-auth @include common-account @include common-session
Now, in order for dovecot (and *for every process it authenticates on behalf of* as well, which is what matters) to succeed authentication, the uid will have to be greater than 500. It is possible to specify other conditions as well, see https://linux.die.net/man/8/pam_succeed_if.
Best regards to everyone,
Aymeric
On 16/3/23 06:31, Aymeric Agon-Rambosson wrote:
I have a solution to my problem.
For reference, I am putting it here :
A simple way to restrict login based on uids is to modify the file as such :
#%PAM-1.0
auth required pam_succeed_if.so uid > 500 quiet @include common-auth @include common-account @include common-session
It is possible for dovecot sasl component to use different authorisation back-ends, such as LDAP, GSSAPI, MySQL etc. These do not necessarily have the ability to reject uid < 500.
However, generally, these backends can be used by pam as well. In default debian installations:
cat dovecot #%PAM-1.0
#auth required pam_faillock.so preauth silent audit #auth [default=die] pam_faillock.so authfail audit
@include common-auth @include common-account @include common-session
cat common-auth
# # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms.
A good practice would be to use postfix --> dovecot/sasl --> pam --> backend server and do the uid vetting in the dovecot pam configuration
--
Jeremy
On 16/03/2023 03:58 EET jeremy ardley jeremy@ardley.org wrote:
On 16/3/23 06:31, Aymeric Agon-Rambosson wrote:
I have a solution to my problem.
For reference, I am putting it here :
A simple way to restrict login based on uids is to modify the file as such :
#%PAM-1.0
auth required pam_succeed_if.so uid > 500 quiet @include common-auth @include common-account @include common-session
It is possible for dovecot sasl component to use different authorisation back-ends, such as LDAP, GSSAPI, MySQL etc. These do not necessarily have the ability to reject uid < 500.
However, generally, these backends can be used by pam as well. In default debian installations:
cat dovecot #%PAM-1.0
#auth required pam_faillock.so preauth silent audit #auth [default=die] pam_faillock.so authfail audit
@include common-auth @include common-account @include common-session
cat common-auth
# # /etc/pam.d/common-auth - authentication settings common to all services # # This file is included from other service-specific PAM config files, # and should contain a list of the authentication modules that define # the central authentication scheme for use on the system # (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the # traditional Unix authentication mechanisms.
A good practice would be to use postfix --> dovecot/sasl --> pam --> backend server and do the uid vetting in the dovecot pam configuration
Dovecot itself can reject uid < 500. Just set first_valid_uid = 500 and first_valid_gid = 500.
Aki
--
Jeremy
On 16/3/23 14:53, Aki Tuomi wrote:
On 16/03/2023 03:58 EET jeremy ardley jeremy@ardley.org wrote:
A good practice would be to use postfix --> dovecot/sasl --> pam --> backend server and do the uid vetting in the dovecot pam configuration
Dovecot itself can reject uid < 500. Just set first_valid_uid = 500 and first_valid_gid = 500.
Is that in the part of dovecot that 'does dovecot' or is that also in the part of dovecot that 'does SASL'
Jeremy
On Wed, Mar 15, 2023 at 1:46 AM Aymeric Agon-Rambosson < aymeric.agon@yandex.com> wrote:
Hello everyone,
From what I understand of the documentation, it is impossible to log in to the dovecot server as root, or as any user not in the interval between first_valid_uid and last_valid_uid.
https://doc.dovecot.org/configuration_manual/authentication/master_users/
-- Best regards, Odhiambo WASHINGTON, Nairobi,KE +254 7 3200 0004/+254 7 2274 3223 "Oh, the cruft.", egrep -v '^$|^.*#' ¯\_(ツ)_/¯ :-)
On 15/3/23 18:32, Odhiambo Washington wrote:
On Wed, Mar 15, 2023 at 1:46 AM Aymeric Agon-Rambosson aymeric.agon@yandex.com wrote:
Hello everyone, From what I understand of the documentation, it is impossible to log in to the dovecot server as root, or as any user not in the interval between first_valid_uid and last_valid_uid.
https://doc.dovecot.org/configuration_manual/authentication/master_users/
I understand the most common method of authentication used by dovecot is pam.
Pam has no problem with authenticating root.
Postfix uses dovecot (and hence pam) to authenticate users
If dovecot won't allow root users to access dovecot services directly then that is a dovecot configuration separate from pam or any other authentication method.
https://doc.dovecot.org/configuration_manual/authentication/pam/
Jeremy
participants (6)
-
Aki Tuomi
-
Aymeric Agon-Rambosson
-
dovecot@ptld.com
-
jeremy ardley
-
John Stoffel
-
Odhiambo Washington