cluebringer

最後更新: 2024-10-28

介紹

cluebringer = Policyd v2

Program: Perl

常用 Modules

  • Access Control
  • CheckSPF
  • Greylisting
  • Accounting
  • Quotas

目錄

  •  
  • SPF Checks
  • Policy 的 Priority
  • Policy Member 的表達
  • Pre-configured default polices
  • Policy Group Members

Installation

 

Requirements:

yum install mysql-server

yum install perl-Net-Server perl-Net-CIDR perl-Config-IniFiles perl-Cache-FastMmap perl-Mail-SPF

yum install httpd php php-pdo php-mysql

Install:

repoforge:

repos

yum install cluebringer

offical:

wget http://download.policyd.org/v2.0.14/cluebringer-2.0.14-1.noarch.rpm

rpm -Uvh cluebringer-2.0.14-1.noarch.rpm

Apache Setting:

/etc/httpd/conf.d/cluebringer.conf

Alias /cluebringer /usr/share/cluebringer/webui

<Directory /usr/share/cluebringer/webui>
    # Comment out the following 3 lines to make web ui accessible from anywhere
    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1
</Directory>

DB Setting:

rpm -ql cluebringer | grep 'policyd.mysql.sql'

mysql -p
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON cluebringer.* TO "cluebringer"@"localhost" IDENTIFIED BY 'cb_password';
mysql> FLUSH PRIVILEGES;
mysql> CREATE DATABASE cluebringer;
mysql> USE cluebringer;
mysql> SOURCE /usr/share/doc/cluebringer-2.0.14/database/policyd.mysql.sql;

User

# 事先建立 cbpolicyd 執行的 user

groupadd cluebringer

useradd -m -d /home/cluebringer -s /sbin/nologin -g cluebringer cluebringer

 

Configure:

/etc/policyd/

  • cluebringer.conf  
  • webui.conf

webui.conf

<?php
    $DB_DSN="mysql:host=localhost;dbname=cluebringer";
    $DB_USER="cluebringer";
    $DB_PASS="???????????";
?>

cluebringer.conf

protocols=<<EOT
Postfix
Bizanga
EOT

modules=<<EOT
Core
AccessControl
CheckHelo
CheckSPF
Greylisting
Quotas
EOT

# Small mailserver:
min_servers=2
min_spare_servers=2
max_spare_servers=4
max_servers=10
max_requests=1000


# Warnings and errors
log_level = 1
log_file=/var/log/cbpolicyd.log
log_detail=modules,tracking,policies,protocols

host=127.0.0.1
proto=tcp
port=10031

cidr_allow=0.0.0.0/0

[database]
DSN=DBI:mysql:database=cluebringer;host=localhost
Username=cluebringer
Password=


# 另有 "pass"
bypass_mode=tempfail
bypass_timeout=30

############ Modules Configure ###########

# HOLD, REJECT, DISCARD, FILTER, REDIRECT
[AccessControl]
enable=1

[Greylisting]
enable=1

[CheckHelo]
enable=0

[CheckSPF]
enable=1

[Quotas]
enable=1

 

Startup:

chkconfig cbpolicyd on

service cbpolicyd start

Postfix Configure:

smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:10031

# 注意這裡的次序
smtpd_recipient_restrictions =
    check_policy_service inet:127.0.0.1:10031,
    permit_mynetworks,
    permit_sasl_authenticated, ...

 

Testing:

netstat -ntlp | grep 10031

 


logrotate

 

chmod 640 cbpolicyd.log

/etc/logrotate.d/cluebringer

/var/log/cbpolicyd.log {
    create 0660 cluebringer cluebringer
    weekly
    rotate 4
    copytruncate
    compress
    missingok
}

 


cbpadmin

 

cbpadmin is responsible for deleting old entries from the database.

  • Quotas: 30 days
  • session tracking: 24 hours
  • Greylisting: GreylistAuthValidity, GreylistUnAuthValidity

設定檔:

ln -s /etc/policyd/cluebringer.conf /etc/cluebringer.conf

Usage

/usr/sbin/cbpadmin --cleanup

Policyd Admin Tool (ClueBringer) v2.0.14-1 - Copyright (c) 2007-2009 AllWorldIT
  => AccessControl: enabled
  => CheckSPF: enabled
  => Greylisting: enabled
  => Quotas: enabled
Module: Core
  -> running cleanup...
[CORE] Removed 0 records from session tracking table
Module: Access Control Plugin
Module: HELO/EHLO Check Plugin
  -> running cleanup...
Module: SPF Check Plugin
Module: Greylisting Plugin
  -> running cleanup...
Module: Quotas Plugin
  -> running cleanup...
[QUOTAS] Removed 0

Troubleshoot

[1]

Can't locate cbp/logging.pm in @INC (@INC contains: /usr/local/lib/policyd-2.0 /usr/lib/policyd-2.0
/usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl 
/usr/lib/perl5 /usr/share/perl5 .)
at /usr/sbin/cbpadmin line 30.

which cbpadmin

/usr/sbin/cbpadmin

25 use lib('/usr/local/lib/policyd-2.0','/usr/lib/policyd-2.0');

改成

use lib('/usr/local/lib/policyd-2.0','/usr/lib/policyd-2.0',/usr/lib64/policyd-2.0);

 

 


Usage

 

Postfix 設定:

smtpd_recipient_restrictions =
 check_policy_service inet:127.0.0.1:10031,
 permit_mynetworks,
 permit_sasl_authenticated,
 ...

Access Control

  • Greylisting
  • Quotas
  • SASL Login

Quotas:

tables: quota, quotas_limits, quotas_tracking

當在 Period 內 Counter 超過了 CounterLimit 時,
會採取 Verdict 的 Action 並回應 Data 的 msg.

table: quotas_tracking:

TrackKey 的格式:

    SASLUsername:????
    Sender:????
    SenderIP:/28  
    Sender:????
    Recipient:????

Table id 的關係:

  `quotas_tracking`.QuotasLimitsID -->  `quotas_limits`.id
  `quotas_limits`.QuotasID --> `quotas`.ID
  `quotas`.PolicyID --> `policies`.ID

 


webui php file

 

/usr/share/cluebringer/webui

includes/config.php      # DB Settings

index.php                    # 負責載入 includes/header.php 及 includes/footer.php

header.php                  # 畫左手邊 menu

# 功能

  • policy-main.php                        # Policies
  • policy-group-main.php
  • accesscontrol-main.php             # Access Control
  • checkspf-main.php                    # SPF Checks
  • greylisting-main.php                 # Greylisting
  • greylisting-whitelist-add.php
  • quotas-main.php                       # Quotas

 


Greylisting

 

Table: greylisting

Settings

  • Track: SenderIP:/28
  • UseGreylisting: 1
  • GreylistPeriod: 120
451, '4.7.1 <x@x>: Recipient address rejected: Greylisting in effect, please come back later'

Table: greylisting_tracking

TrackKey, Sender, Recipient, FirstSeen, LastUpdate, Tries (不成功的次數), Count (成功信的次數)

 


SPF Checks

 

Table: checkspf

Settings(SQL)

  • UseSPF: 1
  • RejectFailedSPF: 1
  • AddSPFHeader: 1

# AddSPFHeader

If the mail is not rejected, add an SPF header.

log

[1]

... cbpolicyd[16668]: module=CheckSPF, action=add_header, host=x.x.x.x, 
helo=sender.helo, from=sender@sender_domain, to=test@recipient_domain, reason=no_spf_record
Received-SPF: none (sender_domain: No applicable sender policy available) receiver=recipient_domain; 
identity=mailfrom; envelope-from="sender@sender_domain"; helo=mail.sender_domain; client-ip=x.x.x.x

[2]

module=CheckSPF, action=pass host= ............ reason=spf_pass

White List

[Step 1] 建立 Group (mxserver), 將 IP (x.x.x.x, y.y.y.y) 加到 Group:

# 建立 Group (mxserver)

INSERT INTO `policy_groups`
(`Name`, `Disabled`, `Comment`)
VALUES ('mxservers', 0, '');

# 獲得 Group 的 ID - 5

SELECT `ID` FROM `policy_groups` WHERE `Name` = "mxservers";

# 將 IP (x.x.x.x, y.y.y.y ) 加到 Group:

INSERT INTO `policy_group_members`
(`PolicyGroupID`, `Member`, `Disabled`, `Comment`)
VALUES (5, 'x.x.x.x', 0, 'mx1');

INSERT INTO `policy_group_members`
(`PolicyGroupID`, `Member`, `Disabled`, `Comment`)
VALUES (5, 'y.y.y.y', 0, 'mx2');

[Step 2] 建立 Policy (WhiteList), 並將 Group (mxserver) 加進去 Policy

# 建立 Policy (WhiteList)

GUI: Policies: Main -> Action: Add

Name: WhiteList

Priority: 30            # 自選 1~99

INSERT INTO `policies` 
 (`NAME`, `Priority`, `Disabled`)
 VALUES ("WhiteList", 30, 0);

# 獲得 Policy 的 ID - 8

SELECT `ID` FROM `policies` WHERE `Name` = "WhiteList";

 

# 並將 Group (mxserver) 加進去 Policy

GUI: Policies: Main -> 選 "WhiteList" -> Action: Members -> Action: Add

Source: %mxservers

Destination: any

INSERT INTO `policy_members` 
 (`PolicyID`, `Source`, `Destination`, `Comment`, `Disabled`)
 VALUES (8, '%mxservers', 'any', 'mx server', 0);

[Step 3] 在 spf 上加入新的 policy(ID=8). 它的 Priority 係比現有 policy 的大.

GUI: SPF Checks -> Configure -> Action > Add > "Link to policy" 選 "WhiteList"
        "Use SPF": No

# 2 相當於 "No"

INSERT INTO `checkspf` (`PolicyID`, `Name`, `UseSPF`, `RejectFailedSPF`, `AddSPFHeader`)
 VALUES (8, "Bypass SPF Check", 2, 2, 2);

 


Policy 的 Priority

 

GUI: Policies > Main

0 will be processed before 1 and 10 before 20 (0~100)

 * Last Win !!

  • 0      Default
  • 10    Default Outbound
  • 10    Default Inbound
  • 20    Default Internal
  • 30    BlackList
  • 100  LastRule <- 必定生效

 


Policy Member 的表達

 

  • anything                        # any / NULL
  • @domain                       # match email domain
  • user@domain                 # match email account
  • @                                 # This will match < >
  • a.b.c.d                           # Matches a single sending server IP address.
  • a.b.c.d/e                       # Matches a CIDR formatted range of sending server IP addresses.
  • %group                         # Matches a group
  • whatever.example.com   # reverse dns of the IP where the client is connecting from.
                                         # Specifying ".example.com" will match anything.example.com and anything.anything.example.com

 


Pre-configured default polices

 

Policy: Default (Priority: 0)

Source: any
Desination: any

Policy: Default Outbound Policy (Priority: 10)

Source: %internal_ips,%internal_domains
Destination: !%internal_domains

 * "," to generate the equivalent of an AND

 * negation match by prefixing "!"

Policy: Default Inbound Policy (Priority: 10)

Source: !%internal_ips,!%internal_domains
Destination: %internal_domains

Policy: Default Internal (Priority: 20)

Source: %internal_ips,%internal_domains
Destination: %internal_domains

 


Policy Group Members

 

GUI: Policies > Groups

選 item 後在 Action 選 Members 可以自到 Values

internal_ips

10.0.0.0/8

internal_domains

example.org
example.com
example.net

 


Quotas

 

設定

  • Track: SASLUsername          # Sender(IP/E-Mail/Domain) / Recipient / Policy
  • Period: 300                         # 每 300 秒
  • Link to policy: Default          # 一般不用修改
  • Verdict: Reject                    # 一般不用修改
  • Data: Over send mail limit   # Error Msg

Limit

Type: Count / Size

Counter Limit: 100            # 在 Period 內的數量

Creative Commons license icon Creative Commons license icon