CBPolicyD Management
CBPolicyD
CBPolicyD is a policy server integrated with Zimbra. The policy engine and access control module will be used to create the restriction. The main goal is to implement as many spam combating and email compliance features as possible while at the same time maintaining the portability, stability and performance required for mission critical email hosting of today.
Following are the supported CBPolicyD features in Zimbra:
- Access Control : Access control refers to plain and simple access control you can perform on email, this includes holding, rejecting, discarding (dropping), filtering or redirecting.
- HELO/EHLO Checks : SMTP transaction checks based on HELO/EHLO commands.
- SPF Checks : SPF based checks to verify that incoming messages that appear to come from the domain were sent by authorized servers authorized.
- Greylisting : Anti-Spam technology that is used to detect if the sending server of a message is RFC compliant.
- Quotas : This module supports message count and message cumulative size over a user-defined period of time.
- Accounting : Supports message count and message cumulative size over a fixed period of time. Message counters can be based on (Tracked) depending on sender, recipient or sender IP.
- Amavis Integration : Support Amavis based configuration checks. (NOTE: Due to Amavis integration issues with Zimbra, this feature is currently not supported.)
Zimbra LDAP Attributes for CBPolicyD
All the features of PolicyD are controlled by an LDAP attribute in Zimbra. These attributes are bydefault disabled (i.e. set to FALSE). Following is the list of the features in CBPolicyD and its related LDAP attribute:
- Access Control --> zimbraCBPolicydAccessControlEnabled
- HELO/EHLO --> zimbraCBPolicydCheckHeloEnabled
- SPF Checks --> zimbraCBPolicydCheckSPFEnabled
- Greylisting --> zimbraCBPolicydGreylistingEnabled
- Quotas --> zimbraCBPolicydQuotasEnabled
- Accounting --> zimbraCBPolicydAccountingEnabled
- Amavis Integration --> zimbraCBPolicydAmavisEnabled (NOTE: Due to Amavis integration issues with Zimbra, this feature is currently not supported.)
Setting up CBPolicyd with Zimbra MariaDB
Execute the following steps on MTA Node to set up CBPolicyd with Zimbra MariaDB.
NOTE: These steps are for a single server install only. For a multi-MTA setup, or if more than one MTA exists in an environment, these steps must be done on each MTA. Do take note of installing a MariaDB server.
- Clone the repo (as root) :
$ git clone https://github.com/Zimbra/zm-core-utils.git
- Go to
zm-core-utils/src/bin/
directory and execute the cbpolicyd.sh script:
$ bash cbpolicyd.sh
- Obtain password for
ad-policyd_db
user using below command:
$ grep Pass /opt/zimbra/conf/cbpolicyd.conf.in |cut -d'=' -f2
- Login to MariaDB database to review your polices using mysql client as
ad-policyd_db
user.
$ su - zimbra $ /opt/zimbra/bin/mysql policyd_db -u ad-policyd_db -p
SELECT * FROM quotas_limits;
- Following will be the output:
+----+----------+-----------------------+--------------+---------+----------+ | ID | QuotasID | Type | CounterLimit | Comment | Disabled | +----+----------+-----------------------+--------------+---------+----------+ | 1 | 1 | MessageCount | 10 | NULL | 0 | | 2 | 1 | MessageCumulativeSize | 8000 | NULL | 0 | | 3 | 2 | MessageCount | 12 | NULL | 0 | | 4 | 3 | MessageCount | 100 | NULL | 0 | | 5 | 4 | MessageCount | 125 | NULL | 0 | +----+----------+-----------------------+--------------+---------+----------+
- CBPolicyd has been installed successfully.
Note:
The installed policy is a basic template to get started.
In many cases you will want to set the `Period` column in the `quotas` table to 600 or 3600 and set `CounterLimit` to around 100 for all records of type `MessageCount` in the `quotas_limits` table.
It is recommended to monitor the users e-mailing behavior prior to installing cbpolicyd. Be prepared to alter the limits after installing in case your users send more email than expected.
Setting up CBPolicyD Web
Requirements:
- Apache Webserver with PHP
- Select a domain to be used for accessing CBPolicyD Web. For this document, we will use the domain cbpolicyd.zimbra.com
- Optional - SSL certificates for the domain.
It is not recommended to use Zimbra packed version of PHP/Apache as that does not include php-mariadb extension and cannot be used with something other than SQLite. Zimbra's Mysql database will be used since it will have the required database and tables for CBPolicyD.
NOTE: Zimbra will flush the MariaDB instance on upgrades and the CBPolicyD database can get dropped. You can take a dump of the policyd_db database before the upgrade and then restore it post-upgrade.
Setting up Apache and PHP
Ubuntu
Please refer to an external guide for setting up Apache Web Server and PHP :- https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04
NOTE:
- Skip "Step 2 — Installing MySQL" section in the guide since Zimbra's MariaDB database will be used.
- Skip "Step 4 — Creating a Virtual Host for your Website" section in the guide since we will be creating our VirtualHost configuration for the domain.
RHEL/CentOS
Please refer to an external guide for setting up Apache Web Server and PHP :- https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-centos-7
NOTE:
- Skip the "Step Two — Install MySQL (MariaDB)" section in the guide since Zimbra's MariaDB database will be used.
- Skip "Install PHP Modules" in the guide since we don't need additional PHP modules.
Setting up configuration in Zimbra
Ubuntu
1. Create a Virtual Host configuration file /etc/apache2/sites-enabled/cbpolicyd.zimbra.com.conf
with following contents:
<VirtualHost *:443> ServerAdmin admin@cbpolicyd.zimbra.com DocumentRoot /var/www/html/cbpolicyd/ ServerName cbpolicyd.zimbra.com ServerAlias cbpolicyd.zimbra.com SSLEngine on SSLCipherSuite HIGH:!aNULL:!MD5 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLHonorCipherOrder on SSLCertificateFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/chain.pem <Directory /var/www/html/cbpolicyd> AuthType Basic AuthName "Restricted Content" AuthUserFile /var/www/html/cbpolicyd/.htpasswd Require valid-user </Directory> </VirtualHost>
NOTE: In case the SSL configuration is not required for the domain, delete the SSL configuration from the file and change the VirtualHost port to 80.
RHEL/CentOS
1. Create a Virtual Host configuration file /etc/httpd/conf.d/cbpolicyd.zimbra.com.conf
with following contents:
<VirtualHost *:443> ServerAdmin admin@cbpolicyd.zimbra.com DocumentRoot /var/www/html/cbpolicyd/ ServerName cbpolicyd.zimbra.com ServerAlias cbpolicyd.zimbra.com SSLEngine on SSLCipherSuite HIGH:!aNULL:!MD5 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLHonorCipherOrder on SSLCertificateFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/cbpolicyd.zimbra.com/chain.pem <Directory /var/www/html/cbpolicyd> AuthType Basic AuthName "Restricted Content" AuthUserFile /var/www/html/cbpolicyd/.htpasswd Require valid-user </Directory> </VirtualHost>
NOTE: In case the SSL configuration is not required for the domain, delete the SSL configuration from the file and change the VirtualHost port to 80.
2. Create htpasswd file to protect the document directory by executing the command and set the password for user1
when prompted. This user will be used for accessing CBPolicyD web URL.
$ htpasswd -c /var/www/html/cbpolicyd/.htpasswd user1
3. Clone the PolicyD public repository:
$ git clone https://gitlab.devlabs.linuxassist.net/policyd/policyd.git
4. Go to policyd/webui
directory and copy the contents of folder to the website's DocumentRoot:
$ cp -ra * includes/ tooltips/ /var/www/html/cbpolicyd
5. Get the ad-policyd_db
user password required for Mysql configuration:
$ grep Pass /opt/zimbra/conf/cbpolicyd.conf.in |cut -d'=' -f2
6. Update database configuration in /var/www/html/cbpolicyd/includes/config.php
.
<?php $DB_DSN="mysql:host=<server_hostname>;dbname=policyd_db;port=7306"; $DB_USER="ad-policyd_db"; $DB_PASS="PASSWORD FROM STEP #5 HERE"; $DB_TABLE_PREFIX=""; ?>
7. Change the MariaDB bind-address to 0.0.0.0
so that connection from other hosts can be made. As root, edit /opt/zimbra/conf/my.cnf
and replace bind-address = 127.0.0.1 with bind-address = 0.0.0.0.
8. As zimbra
user, enable cbpolicyd service for the Zimbra server, MTA configuration and AccessControl module to be tested with CBPolicyD Web:
$ su - zimbra $ zmprov ms `zmhostname` +zimbraServiceInstalled cbpolicyd $ zmprov ms `zmhostname` +zimbraServiceEnabled cbpolicyd $ zmprov ms `zmhostname` zimbraCBPolicydAccessControlEnabled TRUE $ zmprov mcf +zimbraMtaRestriction 'check_policy_service inet:127.0.0.1:10031' $ zmprov ms `zmhostname` zimbraCBPolicydLogLevel 4
NOTE: Service must be enabled for zmconfigd to create all the necessary configuration files.
9. Grant ad-policyd_db
user access in database:
$ su - zimbra $ mysql $ CREATE USER 'ad-policyd_db'@'%' IDENTIFIED BY 'PASSWORD FROM STEP #5 HERE'; $ GRANT ALL PRIVILEGES ON policyd_db . * TO 'ad-policyd_db'@'%' WITH GRANT OPTION; $ FLUSH PRIVILEGES ;
10. Restart zimbra services:
$ su - zimbra $ zmcontrol restart
11. The log information will be update in /opt/zimbra/log/cbpolicyd.log
and /var/log/zimbra.log
to debug.
Accessing CBPolicyD Web and Testing
Once the above steps are successful, the CBPolicyD Web should be accessible through the configured domain web URL http://http://cbpolicyd.zimbra.com/.
1. In the browser enter URL http://cbpolicyd.zimbra.com. Since we are accessing it for the first time, it will prompt for username and password. Enter the username/password set in the above section using htpasswd.
2. After successful authentication, the PolicyD Web Administration page should be displayed. In case any errors are encountered, please refer to /opt/zimbra/log/cbpolicyd.log
for more information.
3. Click on Policies -> Main. Default policies should get listed.
Message Throttling
In this, we will be setting the outgoing mail restriction across the Zimbra server. User will not be able to send a defined number of mails (2 in this example) within 60 seconds. If he tries to do that, an error will be displayed.
- Details of the policy:
- 2 emails every 60 seconds. Messages beyond this limit are deferred.
- 2 emails in a 60 second period. Messages beyond this rate are rejected.
- As
ad-policyd_db
user, login to the MariaDB database and execute the following commands for updating quotas_limits table to set the above mentioned policies:
$ /opt/zimbra/bin/mysql policyd_db UPDATE quotas_limits SET CounterLimit = 2 WHERE ID = 4; UPDATE quotas_limits SET CounterLimit = 2 WHERE ID = 5;
- To make the configuration effective, execute these commands as
zimbra
user:
$ su - zimbra $ zmprov ms `zmhostname` +zimbraServiceEnabled cbpolicyd $ zmprov ms `zmhostname` zimbraCBPolicydQuotasEnabled TRUE
NOTE: As mentioned in the Zimbra LDAP Attributes for CBPolicyD, the attribute must be true for the policy to be enabled. Set loglevel to 4 to help debug such information in the logs.
- Restart services:
$ zmmtactl restart $ zmcbpolicydctl start
- Login to Zimbra Modern Web App.
- Send 2 emails within 60 seconds.
- You will see an error message in UI:
You are sending too many emails, contact helpdesk.
- Similar message will also get logged in
/var/log/zimbra.log
and/opt/zimbra/log/cbpolicyd.log
User based delivery controls for specific domains
A user al_cb@alpha.local in the alpha.local domain is allowed to send emails to all domain users except users in the mail.local domain.
We will be creating an Access Control List to discard the messages sent from user al_cb@alpha.local to a mail.local domain user.
Pre-requisites:
- Create 2 domains -- mail.local, alpha.local.
- Create a user each for the domains -- ml_cb@mail.local, al_cb@alpha.local
- Enable the Access Control attribute in Zimbra:
$ su - zimbra $ zmprov ms `zmhostname` zimbraCBPolicydAccessControlEnabled TRUE
- Disable Quotas based restriction if the above test was executed:
$ zmprov ms `zmhostname` zimbraCBPolicydQuotasEnabled FALSE
- Restart services:
$ zmmtactl restart $ zmcbpolicydctl start
Creating Groups
Create 2 groups -- local_users, allow_domains.
For creating local_users group, follow these steps:
- In PolicyD Web, Go to Policies -> Groups.
- Click on Action dropdown -> Add.
- Specidy Name local_users. Click Submit. local_users group should be created successfully.
- Go to Policies -> Groups and select local_users and from Action dropdown select Members.
- On the page, from Action dropdown select Add
- In Member textbox, specify user al_cb@alpha.local and click Submit.
- At the top of the page, click on Back to members. Select the above created member al_cb@alpha.local. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit.
- Go to Policies -> Groups and select local_users. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit
- The local_users group is now enabled.
For creating allow_domains group, follow these steps:
- In PolicyD Web, Go to Policies -> Groups.
- Click on Action dropdown -> Add.
- Specidy Name allow_domains. Click Submit. allow_domains group should be created successfully.
- Go to Policies -> Groups and select allow_domains. From Action dropdown select Members.
- On the page, from Action dropdown select Add.
- In Member textbox, specify user @mail.local and click Submit.
- At the top of the page, click on Back to members. Select the above created member @mail.local. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit.
- Go to Policies -> Groups and select allow_domains. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit.
- The allow_domains group is now enabled.
Creating Main Policy
- Go to Policies -> Main.
- Click on Action dropdown -> Add.
- Specify Name CBPolicyTest and Description Test CBPolicyD. Click Submit. The policy should be created successfully.
- Go to Policies -> Main and select CBPolicyTest. From Action dropdown select Members.
- On the page, from Action dropdown select Add.
- In Source textbox, specify %local_users and in Destination textbox, specify %allow_domains. Click Submit.
- At the top of the page, click on Back to members. Select the above created member. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit.
- Go to Policies -> Main and select CBPolicyTest. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit.
- The CBPolicyTest policy is now enabled.
Creating Access Control
- Go to Access Control -> Configure.
- Click on Action dropdown -> Add.
- In Name textbox, specify CB_AccessControl.
- In Link to policy dropdown, select policy CBPolicyTest.
- In Verdict dropdown, select Reject.
- Click Submit. The Access Control list should be created successfully.
- Go to Access Control -> Configure and select CBPolicyTest. From Action dropdown select Change.
- For Disabled, select No from the dropdown. Click Submit
Test the Policies created to restrict email delivery
Test #1 - Domain Blocked from sending email
- Login to Zimbra Modern Web App through
al_cb@alpha.local
user. - Compose an email to
ml_cb@mail.local
and click Send. - The mail will not be sent and will be rejected based on our policy. Error message on the screen will be displayed.
- Check
/var/log/zimbra.log
to verify the mail is rejected. Similar log should be present:
Jun 25 11:20:34 zimbra-server postfix/smtpd[8594]: NOQUEUE: reject: RCPT from zimbra-server[X.X.X.X]: 554 5.7.1 <al_cb@alpha.local>: Sender address rejected: Access denied; from=<al_cb@alpha.local> to=<ml_cb@mail.local> proto=ESMTP helo=<zimbra-server>
Test #2 - Domain allowed for sending email
We will change the above created main policy to allow the local users for sending emails.
- Go to CBPolicyD Web -> Policies -> Main and select CBPolicyTest. From Action dropdown select Members.
- Select the member and from Action dropdown, select Change.
- In Destination textbox, change %allow_domains to !%allow_domains. Click Submit.
Send Mail
- Login to Zimbra Modern Web App through
al_cb@alpha.local
user. - Compose an email to
ml_cb@mail.local
and click Send. - The mail should be sent successfully.