1

Topic: How to internally disable client pop3/imap/smtp for webmail only?

With a fully working (can send and receive) iRedmail setup (on the latest stable Red Hat w/MySQL and iRedMail 0.8.5), how can one disable (internally, without external firewall etc) clients from connecting to mail (pop3/imap/smtp), and use the server for webmail login (sending/receiving from Roundcube) only?

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: How to internally disable client pop3/imap/smtp for webmail only?

You can disable POP3/IMAP/SMTP services by setting value of SQL column in 'vmail.mailbox' to 0:

- mailbox.enablepop3 (and mailbox.enablepop3secured)
- mailbox.enableimap (and mailbox.enableimapsecured)
- mailbox.enablesmtp (and mailbox.enablesmtpsecured)

But since Roundcube perform user authentication via IMAP protocol directly, if you disable IMAP service for this user, he/she cannot login to Roundcube webmail anymore.

Possible solution is, update Dovecot SQL query in /etc/dovecot/dovecot-mysql.conf, reject all IMAP requests if remote IP address is not the server which hosts Roundcube webmail (e.g. 127.0.0.1): Sample SQL query:

# Original SQL query in dovecot-mysql.conf:
#user_query = SELECT ... FROM mailbox,domain WHERE ...

# Modified one:
user_query = SELECT ... FROM mailbox,domain WHERE ... AND '%r' = '127.0.0.1'

Reference: http://wiki2.dovecot.org/Variables (Search "remote ip")

3

Re: How to internally disable client pop3/imap/smtp for webmail only?

ZhangHuangbin wrote:

You can disable POP3/IMAP/SMTP services by setting value of SQL column in 'vmail.mailbox' to 0:

- mailbox.enablepop3 (and mailbox.enablepop3secured)
- mailbox.enableimap (and mailbox.enableimapsecured)
- mailbox.enablesmtp (and mailbox.enablesmtpsecured)

But since Roundcube perform user authentication via IMAP protocol directly, if you disable IMAP service for this user, he/she cannot login to Roundcube webmail anymore.

Possible solution is, update Dovecot SQL query in /etc/dovecot/dovecot-mysql.conf, reject all IMAP requests if remote IP address is not the server which hosts Roundcube webmail (e.g. 127.0.0.1): Sample SQL query:

# Original SQL query in dovecot-mysql.conf:
#user_query = SELECT ... FROM mailbox,domain WHERE ...

# Modified one:
user_query = SELECT ... FROM mailbox,domain WHERE ... AND '%r' = '127.0.0.1'

Reference: http://wiki2.dovecot.org/Variables (Search "remote ip")

Excellent advice, thank you.

Unfortunately, I tried adding the AND '%r' = '127.0.0.1', but this locked out all Roundcube logins.  I guess %r, in the webmail setting, looks at the actual remote IP rather than Roundcube's internal IP.  I tried actual server IP as well, but same result (received "connection to mail storage" error.  Removing the line allowed Roundcube login. 

Are there any other alternatives that might work for disabling external imap/smtp/pop3 connections, while allowing Roundcube to communicate with these services properly?

4

Re: How to internally disable client pop3/imap/smtp for webmail only?

arondsmithy wrote:

Unfortunately, I tried adding the AND '%r' = '127.0.0.1', but this locked out all Roundcube logins.  I guess %r, in the webmail setting, looks at the actual remote IP rather than Roundcube's internal IP.

Could you please show me which file(s) you actually modified? Paste whole file (without sensitive info like password) is better.

arondsmithy wrote:

Are there any other alternatives that might work for disabling external imap/smtp/pop3 connections, while allowing Roundcube to communicate with these services properly?

How about disable imap/smtp/pop3 in firewall directly?

5

Re: How to internally disable client pop3/imap/smtp for webmail only?

Zhang

Thanks to this thread I could solve my (other) problem... and I wanted to share my solution.

I wanted to be able to select what accounts can use IMAP while keeping the webmail functioning at all times... so in /etc/dovecot/dovecot-mysql.conf I changed

   AND mailbox.`enable%Ls%Lc`=1 \
to
   AND (mailbox.`enable%Ls%Lc`=1 OR '%r'='127.0.0.1') \

so it will check if the protocol is allowed for that user OR if the request is coming from the server itself.

Maybe it would be a good idea to make this a default config, as I don't see why you would want to disable webmail... unless this is dovecot configuration and you prefer to keep it standard... it seems like a must-have for anyone!

6 (edited by camel1cz 2014-02-25 22:22:51)

Re: How to internally disable client pop3/imap/smtp for webmail only?

I would better suggest to create new "service" webmail and corresponding attribute enablewebmail. The implementation could be similar as Dominique suggested.
It should enable IMAP and SMTP from localhost only.

7 (edited by Dominique 2014-02-25 23:13:01)

Re: How to internally disable client pop3/imap/smtp for webmail only?

camel1cz wrote:

I would better suggest to create new "service" webmail and corresponding attribute enablewebmail. The implementation could be similar as Dominique suggested.
It should enable IMAP and SMTP from localhost only.

so something like this:

AND (mailbox.`enable%Ls%Lc`=1 OR ('%r'='127.0.0.1' AND mailbox.`enablewebmail`=1)) \

Adding another field to the database is easy; adding another checkbox for enabling/disabling the webmail service if for the developers of course...

but I second that idea... as we can't be the only ones who want IMAP disabled due to lack of disk space but still need webmail active.

8

Re: How to internally disable client pop3/imap/smtp for webmail only?

Do you guys think it's better to check whether it's imap protocol and secure connection? For webmail running on localhost, it's always considered as secure connection by Dovecot. If webmail running on another server (not same as IMAP server), it's always good idea to use IMAPS or IMAP over TLS.

For example, in dovecot-mysql.conf, it looks like this:

AND (mailbox.enable%Ls%Lc=1 OR (mailbox.enablewebmail=1 AND '%r'='127.0.0.1' AND '%Ls%Lc'='imapsecured'))

*) For MySQL/PostgreSQL backends, what we need to do is adding new column (mailbox.enablewebmail) and index. If you have another webmail application running on other servers, just replace '%r'='127.0.0.1' by '%r' IN ('127.0.0.1', '192.168.1.1').
*) For OpenLDAP (or OpenBSD ldapd) backend, we have to add below LDAP attribute/value pair for all existing mail users.

enabledService=webmail-127.0.0.1-imapsecured

LDAP filter is not flexible like SQL query, so we have to hard-code remote IP address, protocol, secure connection in LDAP value. If you have multiple webmail servers, you have to add multiple values for ldap attribute 'enabledService' like below:

enabledService=webmail-192.168.1.1-imapsecured

Good or bad?

9

Re: How to internally disable client pop3/imap/smtp for webmail only?

That does sound good... if Roundcube connects over IMAP secured then adding that extra check in dovecot-mysql.conf is a good idea; it can never be too secure.

Giving the option of using webmail from another server is a step further in making it more versatile, it would require an extra input field in iRedAdmin-Pro though.  If nothing is filled out, that part of the query would be  '%r' IN ('127.0.0.1', '') which I think is ok, unless there's a chance that the %r variable would fail, also giving an empty string.  But then again, the rest of the query is still in place to keep it all secure.

The extra row in the SQL database for the IP address of an external webmail server should probably go in another table, as I think it's a global variable applicable to all domains and users on the server.

I can't comment on the LDAP versions, as I don't have any experience with it... but it looks good to me.

All in all it seems like you have it covered.

10

Re: How to internally disable client pop3/imap/smtp for webmail only?

Dominique wrote:

unless there's a chance that the %r variable would fail

I believe Dovecot will always get the remote IP address.

Dominique wrote:

The extra row in the SQL database for the IP address of an external webmail server should probably go in another table, as I think it's a global variable applicable to all domains and users on the server.

IMO, your IMAP servers won't be changed too often, so i think it's acceptable to modify dovecot-xxsql.conf to add it. For ISP who has many mail servers, that will be a problem. But let's make it simpler right now.

P.S. Already committed into iRedMail source code, and upgrade steps were added in upgrade tutorial for upcoming iRedMail release.
https://bitbucket.org/zhb/iredmail/comm … ebe84e0c00

11

Re: How to internally disable client pop3/imap/smtp for webmail only?

If roundcube uses imaps, I don't see any problem adding the additional check - it's good to corner the webmail usage as much as possible.

To the additional argument for remote webmail server/servers allowing more remote webmail servers: it can be done in SQL

remote_webmail_ips_attribute like '%' || '%r' || '%'

with remote_webmail_ips_attribute holding all allowed IPs. But it would be complicated/impossible with LDAP backend.
Sticking with "keep it simple" the "localhost" implementation by Zhang is probably OK. Special setting will be needed by more experienced users and they are able to adjust the config manually.

There is only one thing, I don't like on this solution: if I'm not wrong, disabling enablewebmail doesn't prevent the user accessing webmail in case, he has enableimapsecure active. It's not a big deal, but the new argument should work exactly the same as all others, so I would adjust the implementation to:

AND (mailbox.enable%Ls%Lc=1 AND '%Ls%Lc' <> 'imapsecured' )
AND ('%Ls%Lc' = 'imapsecured'  AND ((mailbox.enablewebmail=1 AND '%r'='127.0.0.1') || (mailbox.enableimapsecured=1 AND '%r' <> '127.0.0.1')))

12

Re: How to internally disable client pop3/imap/smtp for webmail only?

camel1cz wrote:
AND (mailbox.enable%Ls%Lc=1 AND '%Ls%Lc' <> 'imapsecured' )
AND ('%Ls%Lc' = 'imapsecured'  AND ((mailbox.enablewebmail=1 AND '%r'='127.0.0.1') || (mailbox.enableimapsecured=1 AND '%r' <> '127.0.0.1')))

This wouldn't work as you turned it into 2 conditions that need to be met. 
The first condition will just disable every imapsecured connection, which is achieving the opposite of what we want here. 

I'll show you what would happen when trying to connect over imapsecured: 

AND (mailbox.enableimapsecured=1 AND 'imapsecured' <> 'imapsecured')

This would of course fail and refuse connection.

The right solution was already provided in this thread.

13 (edited by Dominique 2014-02-27 17:06:32)

Re: How to internally disable client pop3/imap/smtp for webmail only?

And furthermore, the second condition would break anything else because it requires the connection to be imapsecured. Together those 2 lines would just disable all connections.

camel1cz wrote:
AND ('%Ls%Lc' = 'imapsecured'  AND ((mailbox.enablewebmail=1 AND '%r'='127.0.0.1') || (mailbox.enableimapsecured=1 AND '%r' <> '127.0.0.1')))

and this condition would always be met, regardless of any situation:

camel1cz wrote:
remote_webmail_ips_attribute like '%' || '%r' || '%'

14

Re: How to internally disable client pop3/imap/smtp for webmail only?

I don't think, it's wrong.
The first line is for all protocols but imapsecured.
The second is only for imapsecured and enables is correctly (enablewebmail required for localhost OR emableimapsecured for remote access)

I just did error - I used || instead of OR in SQL...

Correct is:

AND (mailbox.enable%Ls%Lc=1 AND '%Ls%Lc' <> 'imapsecured' )
AND ('%Ls%Lc' = 'imapsecured'  AND ((mailbox.enablewebmail=1 AND '%r'='127.0.0.1') OR (mailbox.enableimapsecured=1 AND '%r' <> '127.0.0.1')))

15

Re: How to internally disable client pop3/imap/smtp for webmail only?

Ah, I see what you mean now. Right, the lines should be ORed! Good catch, thanks!

AND (
 (mailbox.enable%Ls%Lc=1 AND '%Ls%Lc' <> 'imapsecured' )
 OR
 ('%Ls%Lc' = 'imapsecured'  AND ((mailbox.enablewebmail=1 AND '%r'='127.0.0.1') OR (mailbox.enableimapsecured=1 AND '%r' <> '127.0.0.1')))
)

16

Re: How to internally disable client pop3/imap/smtp for webmail only?

Dominique wrote:

and this condition would always be met, regardless of any situation:

camel1cz wrote:
remote_webmail_ips_attribute like '%' || '%r' || '%'

What do you mean by this?

Example 1:
connection from IP 192.168.0.11
remote_webmail_ips_attribute is "" (not set)

It evaluates to "" like '%192.168.0.11%' => FALSE

Example 2:
connection from IP 192.168.0.11
remote_webmail_ips_attribute is "192.168.0.11, 192.168.0.12"

It evaluates to "192.168.0.11, 192.168.0.12" like '%192.168.0.11%' => TRUE

It wouldn't work only in case %r will be empty - it shouldn't happen.

17

Re: How to internally disable client pop3/imap/smtp for webmail only?

You were right, disabling webmail would actually not disable it when imapsecured is allowed.  The condition I wrote was to make webmail work without IMAP enabled, which it did, disregarding the opposite requirement.

Your solution seems a bit lengthy in my opinion, this would do the same job:

AND ((mailbox.enable%Ls%Lc=1 AND '%r'<>'127.0.0.1') OR (mailbox.enablewebmail=1 AND '%r'='127.0.0.1' AND '%Ls%Lc'='imapsecured'))

- the first part requires the used protocol to be enabled for all connections from a remote IP
- the second part requires webmail to be enabled and connecting over imapsecured for all connections from the server itself (roundcube)

Let me know if I missed something.  I do like to make SQL queries as simple and straightforward as possible.

@Zhang:  camel1cz had a valid point, have a look yourself but I think you'll need to update the query again... sorry for that wink

18

Re: How to internally disable client pop3/imap/smtp for webmail only?

camel1cz wrote:
remote_webmail_ips_attribute like '%' || '%r' || '%'

if you do whateverfield LIKE '%' which is the first of your 3 optional conditions it would always be met... try it wink

and for example, the last part of your query says

OR  '%'

what would this accomplish?

I just tried this on MySQL and it always fails the condition

while

OR '%r'

always is met again, as it will return TRUE

19 (edited by camel1cz 2014-02-27 17:58:05)

Re: How to internally disable client pop3/imap/smtp for webmail only?

Dominique, the || is string concatenation, not logical OR... it will evaluate to the pattern '%ip.address%' - at least in postgresql

EDIT: OK, it's postgresql specific code, it would be better to use universal CONCAT function:

remote_webmail_ips_attribute like CONCAT('%', '%r', '%')

this does work in both mysql and pgsql as it was ment

20

Re: How to internally disable client pop3/imap/smtp for webmail only?

camel1cz wrote:

Dominique, the || is string concatenation, not logical OR... it will evaluate to the pattern '%ip.address%' - at least in postgresql

OK, it's postgresql specific code, it would be better to use universal CONCAT function:

remote_webmail_ips_attribute like CONCAT('%', '%r', '%')

I see, I didnt' know that as I'm not familiar with postgresql... it seems to be different than all SQLs I used in the past.  As I do understand that every language can choose its own syntax, it's weird to use double pipes for anything else than what the world considers it to mean, which is an logical OR... IMHO wink

21 (edited by camel1cz 2014-02-27 18:34:25)

Re: How to internally disable client pop3/imap/smtp for webmail only?

I'm used to it, so I didn't think about it like that. You're right...

But on the other hand... postgresql strictly follows SQL standards with logical operators AND, OR, NOT. Duplicating it if for me confusing and unnecessary. I personally would never use || in place of logical OR in SQL - simple because it's "less visible"... I like to write all SQL key words in capitals and attributes and everything else in small letters - so it's for me easier to read and understand the semantics.

Cheers!

Btw. the expression OR 'string_constant' doesn't evaluate to TRUE either. It triggers type error in pgsql - "invalid input syntax for type boolean"

22

Re: How to internally disable client pop3/imap/smtp for webmail only?

Yes, it's good to understand each other... I'll have to keep an open mind in the future when it comes to SQL syntax.

It's good that postgresql follows SQL standards... but I noticed they also support CONCAT (which is an SQL standard while || isn't) so I suppose it's also a nice idea to use these standards in your queries, whatever SQL you're using.... that way it's easier to maintain when one has to translate a query to a different SQL platform.  For that reason I would never use || in an statement instead of AND because I know that not every SQL supports it.  It seems like postgresql is also guilty when it comes to duplicating functions... wouldn't things be a lot easier is there was only 1 standard for everything?  (VHS/Betamax, DVD+R/DVD-R...)

And I do the same, SQL keywords in capitals and the rest in small letters... and never use capitals in table of field names, as some SQL platforms are case sensitive... even MySQL changed this a while ago, from not case sensitive, to case sensitive with the upgrade to a new version... cause quite the headache to people using CamelCaps.

Cheers to you!

23

Re: How to internally disable client pop3/imap/smtp for webmail only?

camel1cz wrote:

There is only one thing, I don't like on this solution: if I'm not wrong, disabling enablewebmail doesn't prevent the user accessing webmail in case, he has enableimapsecure active. It's not a big deal, but the new argument should work exactly the same as all others, so I would adjust the implementation to:

If you allow this user to access IMAP (enableimapsecured=1), why don't allow him/her to use webmail? Does it make sense?

24

Re: How to internally disable client pop3/imap/smtp for webmail only?

It doen's have any reason from practice. It's just because I try to strictly follow the enable/disable logic of the attributes.

It should be the same logic like for example smtp:
If you enablesmtp=1, you expect it to be enabled, also if you enablesmtp=0, you expect the server to reject incoming mails via this SMTP AUTH account.
It doesn't depend on any other enableXXX.

In the same logic:
If you set enablewebmail=1, webmail should work w/o any additional requirements and if you set enablewebmail=0, it shouldn't work.

We both know, webmail works thru imap secure, but many users don't and they could wonder (and will by IMO right), why user can access webmail if he/she has enablewebmail=0.



If, we created new explicit rule to access webmail - so if the enablewebmail = 1, webmail should be accessible (no additional requirements) and also the opposite / if enablewebmail = 0, it shouldn't be accessible.

25 (edited by Dominique 2014-02-27 21:39:46)

Re: How to internally disable client pop3/imap/smtp for webmail only?

ZhangHuangbin wrote:

If you allow this user to access IMAP (enableimapsecured=1), why don't allow him/her to use webmail? Does it make sense?

well... it doesn't sound very likely but technically speaking it could be possible... so it's up to you of course to decide what options you want to make available and what not

on the other hand, since it would be possible (in iRedAdmin-Pro) to check imapsecured and uncheck webmail you would expect it to respect that selection, logic or not... so I personally think it should be done... unless you want to limit the option of allowing webmail only after someone disabled imapsecured... but that would be even less logic in my opinion

p.s. this is almost the same as what camel1cz said

my 2ct