Subnet mask values and figure out what they mean

Here are the charts, followed by some explanations of what they mean.

CIDR SUBNET MASK WILDCARD MASK # OF IP ADDRESSES # OF USABLE IP ADDRESSES
/32 255.255.255.255 0.0.0.0 1 1
/31 255.255.255.254 0.0.0.1 2 2*
/30 255.255.255.252 0.0.0.3 4 2
/29 255.255.255.248 0.0.0.7 8 6
/28 255.255.255.240 0.0.0.15 16 14
/27 255.255.255.224 0.0.0.31 32 30
/26 255.255.255.192 0.0.0.63 64 62
/25 255.255.255.128 0.0.0.127 128 126
/24 255.255.255.0 0.0.0.255 256 254
/23 255.255.254.0 0.0.1.255 512 510
/22 255.255.252.0 0.0.3.255 1,024 1,022
/21 255.255.248.0 0.0.7.255 2,048 2,046
/20 255.255.240.0 0.0.15.255 4,096 4,094
/19 255.255.224.0 0.0.31.255 8,192 8,190
/18 255.255.192.0 0.0.63.255 16,384 16,382
/17 255.255.128.0 0.0.127.255 32,768 32,766
/16 255.255.0.0 0.0.255.255 65,536 65,534
/15 255.254.0.0 0.1.255.255 131,072 131,070
/14 255.252.0.0 0.3.255.255 262,144 262,142
/13 255.248.0.0 0.7.255.255 524,288 524,286
/12 255.240.0.0 0.15.255.255 1,048,576 1,048,574
/11 255.224.0.0 0.31.255.255 2,097,152 2,097,150
/10 255.192.0.0 0.63.255.255 4,194,304 4,194,302
/9 255.128.0.0 0.127.255.255 8,388,608 8,388,606
/8 255.0.0.0 0.255.255.255 16,777,216 16,777,214
/7 254.0.0.0 1.255.255.255 33,554,432 33,554,430
/6 252.0.0.0 3.255.255.255 67,108,864 67,108,862
/5 248.0.0.0 7.255.255.255 134,217,728 134,217,726
/4 240.0.0.0 15.255.255.255 268,435,456 268,435,454
/3 224.0.0.0 31.255.255.255 536,870,912 536,870,910
/2 192.0.0.0 63.255.255.255 1,073,741,824 1,073,741,822
/1 128.0.0.0 127.255.255.255 2,147,483,648 2,147,483,646
/0 0.0.0.0 255.255.255.255 4,294,967,296 4,294,967,294

* /31 is a special case detailed in RFC 3021 where networks with this type of subnet mask can assign two IP addresses as a point-to-point link.

And here’s a table of the decimal to binary conversions for subnet mask and wildcard octets:

SUBNET MASK WILDCARD
0 00000000 255 11111111
128 10000000 127 01111111
192 11000000 63 00111111
224 11100000 31 00011111
240 11110000 15 00001111
248 11111000 7 00000111
252 11111100 3 00000011
254 11111110 1 00000001
255 11111111 0 00000000

Note that the wildcard is just the inverse of the subnet mask.

 

here the original article

Apache command connection check

The netstat command has been deprecated and replaced by the ss command in most of the Linux distributions.

It reads various ‘/proc’ files to gather information. It would take more time when there are lots of connections to display.

1) Checking the number of concurrent Apache connections

Run following ss command to find the total number of concurrent connections to Apache:

# ss -ant | grep -E ':80|:443' | wc -l
500

Alternatively, you can get Apache concurrent connection using netstat command as shown below:

# netstat -ant | grep -E ':80|:443' | wc -l
430

2) Checking concurrent connections of Apache in detail

Run the below ss command to see detailed information of Apache connections instead of counting it.

It shows the active internet connections on the server on port 80 & 443:

# ss -ant | grep -E ':80|:443'

 LISTEN     0      128    10.10.6.160:80                       :                  
106.222.112.160:12650              
 TIME-WAIT  0      0      94.237.76.92:443                114.119.135.42:2366               
 TIME-WAIT  0      0      94.237.76.92:443                114.119.135.42:2406               
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38400              
 ESTAB      0      0      127.0.0.1:38454              94.237.76.92:443                     
 ESTAB      0      0      94.237.76.92:443                117.249.205.234:64685              
 ESTAB      0      0      94.237.76.92:443                192.99.9.25:33132              
 ESTAB      0      0      94.237.76.92:443                66.249.71.82:49611              
 ESTAB      0      0      94.237.76.92:443                106.222.112.160:12648              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38412              
 ESTAB      0      0      127.0.0.1:38402              94.237.76.92:443                
 TIME-WAIT  0      0      94.237.76.92:443                157.46.105.172:45656              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38340              
 ESTAB      0      151496 94.237.76.92:443                106.222.112.160:12656              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38332              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38396              
 ESTAB      0      0      127.0.0.1:38460              94.237.76.92:443                
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38374              
 ESTAB      0      0      94.237.76.92:80                 5.9.61.232:51082              
 ESTAB      0      0      94.237.76.92:443                60.8.123.152:64476              
 ESTAB      0      0      94.237.76.92:443                167.114.209.104:35758              
 ESTAB      0      0      94.237.76.92:80                 106.222.112.160:12643              
 ESTAB      0      0      94.237.76.92:443                167.114.158.215:53270                          
 ESTAB      0      0      94.237.76.92:443                66.249.71.147:56912              
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38454              
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38468                         
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38402              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38366

Check the same information using the netstat command as shown below:

# netstat -ant | grep -E ':80|:443'

3) Listing Apache connections sort by IP

To count the number of connections currently active in Apache from each IP address and to sort them, use the following command:

# ss -ant |grep -E ':80|:443'|grep ESTAB| awk '{print $5}' | cut -d":" -f1 | sort | uniq -c | sort -nr

       8 94.237.76.92
       8 127.0.0.1
       2 5.9.61.232
       2 106.222.112.160
       1 98.236.14.66
       1 66.249.72.22
       1 66.249.71.48
       1 192.99.9.25
       1 167.114.209.104
       1 167.114.158.215

Similarly, you can find the same information using netstat command as shown below:

# netstat -ant |grep -E ':80|:443'|grep ESTAB | awk '{print $5}' | cut -d":" -f1 | sort | uniq -c | sort -nr

      6 162.158.155.70
      5 127.0.0.1
      2 172.68.51.180
      2 172.68.215.98
      2 172.68.215.86
      2 172.68.215.77
      2 172.68.215.75
      2 172.68.215.113
      2 172.68.215.111
      2 172.68.215.109
      2 172.68.215.101
      2 172.68.215.100
      2 162.158.150.128
      2 162.158.150.120
      2 162.158.118.154
      2 141.101.96.253
      2 141.101.96.243
      2 141.101.76.234
      2 141.101.105.254
	  .
	  .

Bonus Tips: 1) Counting running Apache processes in Linux

ps command is used to display all running processes in Linux system. Use the following format, if you would like to count the running Apache processes in Linux:

# ps -auxw | grep httpd | grep -v grep | wc -l
12

1.a) Listing Apache processes with ps

Use the following command to see the running httpd processes in Linux:

# ps auxw | grep httpd | grep -v grep
nobody    7988  0.0  0.5 253280 23252 ?        S    14:32   0:00 /usr/sbin/httpd -k start
nobody    8050  0.0  0.6 253412 24276 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8054  0.0  0.6 253280 23288 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8158  0.0  0.6 253280 23296 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8159  0.0  0.5 253280 23176 ?        S    14:33   0:00 /usr/sbin/httpd -k start
daygeek   8202  0.0  0.6 253416 23304 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8203  0.0  0.5 253280 23052 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8207  0.0  0.5 253280 23044 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8213  0.0  0.6 253280 23300 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8216  0.0  0.5 253280 23052 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8218  0.0  0.6 253416 23304 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8266  0.0  0.5 253148 23052 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8267  0.0  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8391  0.3  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8393  0.5  0.5 253012 21776 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8394  1.0  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
root     30500  0.0  0.0 227356  3584 ?        Ss   Jul25   2:33 /usr/sbin/httpd -k start

Let’s quickly look at the parameters

  • Serverlimit – Maximum number of Apache processes
  • StartServers – Number of processes to start when you start running Apache
  • MinSpareThreads/MaxSpareThreads – Number of threads to keep idle without being killed
  • ThreadsPerChild – Number of threads per process
  • MaxRequestWorkers – Number of concurrent connections to be supported. This is the main directive that you need to change to increase max connections in Apache
  • MaxConnectionsPerChild – Number of connections to be handled by each child before it is killed

Set Up SpamAssassin on CentOS/RHEL to Block Email Spam

Good post from here thanks!

 

Previously we discussed 7 effective methods for blocking email spam with Postfix on CentOS/RHEL. In this tutorial, we are going to learn how to use SpamAssassin (SA) to detect spam on CentOS/RHEL mail server. SpamAssassin is a free, open-source, flexible and powerful spam-fighting tool.

SpamAssassin is a score-based system. It will check email message against a large set of rules. Each rule adds or removes points in the message’s score. If the score is high enough (by default 5.0), the message is considered spam.

Set Up SpamAssassin on CentOS RHEL to Block Email Spam

Install SpamAssassin on CentOS/RHEL

Run the following command to install SpamAssassin from the default CentOS/RHEL software repository.

sudo dnf install spamassassin

The server binary installed by the spamassassin package is called spamd, which will be listening on TCP port 783 on localhost. Spamc is the client for SpamAssassin spam filtering daemon. By default, the spamassassin systemd service is disabled, you can enable auto start at boot time with:

sudo systemctl enable spamassassin

Then start SpamAssassin.

sudo systemctl start spamassassin

Integrate SpamAssassin with Postfix SMTP Server as a Milter

There are several ways you can use to integrate SpamAssassin with Postfix. I prefer to use SpamAssassin via the sendmail milter interface, because it allows me to reject an email when it gets a very high score such as 8, so it will never be seen by the recipient.

Install the spamass-filter packages on CentOS/RHEL from the EPEL software repository.

sudo dnf install epel-release
sudo dnf install spamass-milter

Start the service.

sudo systemctl start spamass-milter

Enable auto-start at boot time.

sudo systemctl enable spamass-milter

Next, edit /etc/postfix/main.cf file and add the following lines at the end of the file.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:/run/spamass-milter/spamass-milter.sock
non_smtpd_milters = $smtpd_milters

If you have configured OpenDKIM and OpenDMARC on CentOS/RHEL, then these lines should look like below. The milter order matters.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:127.0.0.1:8891,inet:127.0.0.1:8893,unix:/run/spamass-milter/spamass-milter.sock
non_smtpd_milters = $smtpd_milters

If you haven’t configured OpenDMARC, then you should remove local:opendmarc/opendmarc.sock, from smtpd_milters.

Save and close the file. Now open the /etc/sysconfig/spamass-milter file and find the following line.

#EXTRA_FLAGS="-m -r 15"

Uncomment this line and change 15 to your preferred reject score such as 8.

EXTRA_FLAGS="-m -r 8"

If the score of a particular email is over 8, Spamassassin would reject it and you would find a message like below in the /var/log/maillog file, indicating it’s rejected.

milter-reject: END-OF-MESSAGE  5.7.1 Blocked by SpamAssassin

If you want the sender to see a different reject text, then add the -R (reject text) option like below.

EXTRA_FLAGS="-m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE"

It’s a good practice to ignore emails originating from localhost by adding the -i 127.0.0.1 option.

EXTRA_FLAGS="-m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE -i 127.0.0.1"

We also need to add the -g sa-milt option to make the spamass-milter socket writable by the sa-milt group.

EXTRA_FLAGS="-m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE -i 127.0.0.1 -g sa-milt"

Save and close the file. Then add postfix user to the sa-milt group, so that Postfix will be able to communicate with spamass-milter.

sudo gpasswd -a postfix sa-milt

Restart Postfix and Spamass Milter for the changes to take effect.

sudo systemctl restart postfix spamass-milter

Check the status and make sure they are running.

sudo systemctl status postfix spamass-milter

Checking Email Header and Body with SpamAssassin

SpamAssassin ships with many spam detection rules in /usr/share/spamassassin/ directory. Allow me to explain some of the rules.

In the /usr/share/spamassassin/20_head_tests.cf file, you can find the following two lines.

header MISSING_HEADERS       eval:check_for_missing_to_header()
describe MISSING_HEADERS     Missing To: header

The first line tests if the To: header exists in an email message. The second line, which is optional, explains what the first line does. The uppercase letters is the name of this test.

The following 3 lines are for testing if there’s a Date: header in the email message.

header __HAS_DATE            exists:Date
meta MISSING_DATE            !__HAS_DATE
describe MISSING_DATE        Missing Date: header

And these 3 lines are for testing if there’s a From: header in the email message.

header __HAS_FROM            exists:From
meta MISSING_FROM            !__HAS_FROM
describe MISSING_FROM        Missing From: header

Set Custom Score for Existing Rules

In the 50_scores.cf and 72_scores.cf file, you can see the default scores for various tests. If you think the default score is too low or too high for a certain test, you can set custom score in /etc/mail/spamassassin/local.cf file.

sudo nano /etc/mail/spamassassin/local.cf

For example, RFC 5322 requires that every email message must have From: and Date: header fields, so I can set a very high score if either of them is missing in an email message by appending the following two lines in local.cf file.

score MISSING_FROM   5.0
score MISSING_DATE   5.0

Although the To: header field is not mandatory in RFC 5322, I prefer to set a high score if it’s missing in an email message because I have never seen a legitimate email missing this header field.

score MISSING_HEADERS 3.0

Some spammers uses two email addresses in the From: header field like below.

From: "tonywei_darefly_mold@aliyun.com" <sales10@darefly-mould.com>

I think the default score for this kind of email is low, I prefer to set it to 3.0.

score PDS_FROM_2_EMAILS 3.0

There are spammers who send empty message with no subject and no textual parts in the body. I set the score for this kind of email to 5.0, so it will be placed to spam folder. Why read it if it’s empty?

score EMPTY_MESSAGE 5.0

And other spammers often ask you to send a read receipt, I set the score to 2.0 for this kind of email.

score FREEMAIL_DISPTO 2.0

There are some spammers use different domain names in the From: and Reply-To: header, I give them a 3.5 score.

score FREEMAIL_FORGED_REPLYTO 3.5

I also have seen some spammers using non-existent domain name in the From: header field. I set a 5.0 score for this type of email.

score DKIM_ADSP_NXDOMAIN 5.0

Last but not least, many spammers spoof the gmail.com domain in the From: header field. I set a 2.5 score this kind of email.

score FORGED_GMAIL_RCVD 2.5

Adding Your Own Rules

You can add custom SpamAssassin rules in /etc/mail/spamassassin/local.cf file.

sudo nano /etc/mail/spamassassin/local.cf

Header Rules

For example, some spammers use the same email address in the From: and To: header. you can add the following lines at the end of the file to add scores to such emails.

header   FROM_SAME_AS_TO   ALL=~/\nFrom: ([^\n]+)\nTo: \1/sm
describe FROM_SAME_AS_TO   From address is the same as To address.
score    FROM_SAME_AS_TO   2.0

Some spammers use an empty address for the Envelope From address (aka the Return Path header). Although this is legitimate for sending bounce messages, I prefer to give this kind of email a score.

header    EMPTY_RETURN_PATH    ALL =~ /<>/i
describe  EMPTY_RETURN_PATH    empty address in the Return Path header.
score     EMPTY_RETURN_PATH    3.0

If you have configured OpenDMARC on your mail server, you can now add the following lines to add scores to emails that fail DMARC check.

header    CUSTOM_DMARC_FAIL   Authentication-Results =~ /dmarc=fail/
describe  CUSTOM_DMARC_FAIL   This email failed DMARC check
score     CUSTOM_DMARC_FAIL   3.0

The above code tells SpamAssassin to check if the Authentication-Results header contains the string “dmarc=fail”. If found, increase the score by 3.0.

Body Rules

You can tell SpamAssassin to increase the score of an email if a certain phrase is found in the body. For example, many spammers use the recipient’s email address in the first body line like below.

Hi xiao@linuxbabe.com
Hello xiao@linuxbabe.com
Dear xiao@linuxbabe.com

I don’t want to talk with people who doesn’t bother writing my name in the first line of email. So I created a rule in SpamAssassin to filter this kind of email.

body      BE_POLITE       /(hi|hello|dear) xiao\@linuxbabe\.com/i
describe  BE_POLITE       This email doesn't use a proper name for the recipient
score     BE_POLITE       5.0

Regular expression in SpamAssassin is case-sensitive by default, you can add the i option at the end to make it case-insensitive.

Add Negative Scores

You can also add negative score to good emails, so there will be less false positives. For example, many of my blog readers ask me Linux questions and I don’t think spammers would include words like DebianUbuntuLinux Mint in the email body, so I created the following rule.

body      GOOD_EMAIL    /(debian|ubuntu|linux mint|centos|red hat|RHEL|OpenSUSE|Fedora|Arch Linux|Raspberry Pi|Kali Linux)/i
describe  GOOD_EMAIL    I don't think spammer would include these words in the email body.
score     GOOD_EMAIL    -4.0

If the email body contains a Linux distro’s name, then add a negative score (-4.0).

There are some common phrases that is included in legitimate bounce messages, so I can add negatives scores to these email messages.

body      BOUNCE_MSG    /(Undelivered Mail Returned to Sender|Undeliverable|Auto-Reply|Automatic reply)/i
describe  BOUNCE_MSG    Undelivered mail notifications or auto-reply messages
score     BOUNCE_MSG    -1.5

Note that body rules also include the Subject as the first line of the body content.

Meta Rules

In addition to header and body rules, there’s also meta rules. Meta rules are combinations of other rules. You can create a meta rule that fires off when two or more other rules are true. For example, I occasionally receive emails saying that the sender wants to apply for a job and a resume is attached. I have never said on my website that I need to hire people. The attachment is used to spread virus. I created the following meta rule to filter this kind of email.

body      __RESUME        /(C.V|Resume)/i
meta      RESUME_VIRUS    (__RESUME && __MIME_BASE64)
describe  RESUME_VIRUS    The attachment contains virus.
score     RESUME_VIRUS    5.5

The first sub rule __RESUME tests if the email body contains the word C.V. or resume. The second sub rule __MIME_BASE64 is already defined in /usr/share/spamassassin/20_body_tests.cf file, as follows, so I don’t need to define it again in local.cf file. This rule tests if the email message includes a base64 attachment.

rawbody   __MIME_BASE64  eval:check_for_mime('mime_base64_count')
describe  __MIME_BASE64  Includes a base64 attachment

My meta rule RESUME_VIRUS will fire off when both of the sub rules are true, adding a 5.5 score to the email message. Note that sub rule often starts with double underscore, so it has no score in its own right.

Now you learned how to add score if a string is found. What if you want to add score when a string doesn’t exist in the email headers? Well, you can use the ! operator. For example, I have seen spammers using a single word in the From: address.  I added the following lines to score this kind of email.

header __AT_IN_FROM   From =~ /\@/
meta  NO_AT_IN_FROM   !__AT_IN_FROM
score NO_AT_IN_FROM   4.0

The first line checks if the @ sign exists in the From: header. The second line defines a meta rule, which fires off when !__AT_IN_FROM is true. !__AT_IN_FROM rule is the opposite of the first header rule, which means when there’s no @ sign in the From: address, the meta rule fires off.

You can also add the following lines to check if a dot exists in the From: address.

header __DOT_IN_FROM   From =~ /\./
meta   NO_DOT_IN_FROM  !__DOT_IN_FROM
score  NO_DOT_IN_FROM  4.0

Whitelist

You can use the whitelist_from parameter to add a particular email address or domain to your Spamassassin whitelist. For example, add the following two lines at the end of local.cf file.

whitelist_from xiao@linuxbabe.com
whitelist_from *@canonical.com

A whitelisted sender has a -100 default score. They will still be tested by SpamAssassin rules, but it’s super hard for them to reach a 5.0 score.

Blacklist

To blacklist a sender, use the blacklist_from parameter, which has the same format as whitelist_from.

blacklist_from spam@example.com
blacklist_from *@example.org

Checking Syntax and Restart

After saving the local.cf file. You should run the spamassassin command in lint mode to check if there’s any syntax errors.

sudo spamassassin --lint

Then restart SpamAssassin for the changes to take effect.

sudo systemctl restart spamassassin amavisd

SpamAssassin’s Builtin Whitelist

It’s worth mentioning that SpamAssassin ships with its own whitelist. There are several files under /usr/share/spamassassin/ directory that includes 60_whitelist in the filename. These files contain SpamAssassin’s builtin whitelist. For example, the 60_whitelist_spf.cf file contains a list of addresses which send mail that is often tagged (incorrectly) as spam.

Move Spam into the Junk Folder

I’m going to show you how to move spam to Junk folder with the Dovecot IMAP server and the sieve plugin. This method requires that inbound emails are delivered to the message store via the Dovecot “deliver” LDA (local delivery agent). If you can find the following text in /var/log/maillog file, then this requirement is satisfied.

postfix/lmtp

or

delivered via dovecot service

Run the following command install dovecot-pigeonhole package from CentOS/RHEL software repository.

sudo dnf install dovecot-pigeonhole

This package installs two configuration files under /etc/dovecot/conf.d/ directory: 90-sieve.conf and 90-sieve-extprograms.conf. Open the 15-lda.conf file.

sudo nano /etc/dovecot/conf.d/15-lda.conf

Add the sieve plugin to local delivery agent (LDA).

protocol lda {
    # Space separated list of plugins to load (default is global mail_plugins).
    mail_plugins = $mail_plugins sieve
}

Save and close the file. If you can find the 20-lmtp.conf file under /etc/dovecot/conf.d/ directory, then you should also enable the sieve plugin in that file like below.

protocol lmtp {
      mail_plugins = quota sieve
}

Then open the 90-sieve.conf file.

sudo nano /etc/dovecot/conf.d/90-sieve.conf

Go to line 79 and add the following line, which tells Sieve to always execute the SpamToJunk.sieve script before any user specific scripts.

sieve_before = /var/mail/SpamToJunk.sieve

Save and close the file. Then create the sieve script.

sudo nano /var/mail/SpamToJunk.sieve

Add the following lines, which tells Dovecot to move any email messages with the X-Spam-Flag: YES header into Junk folder.

require "fileinto";

if header :contains "X-Spam-Flag" "YES"
{
   fileinto "Junk";
   stop;
}

Save and close the file. We can compile this script, so it will run faster.

sudo sievec /var/mail/SpamToJunk.sieve

Now there is a binary file saved as /var/mail/SpamToJunk.svbin. Edit the 10-mail.conf file.

/etc/dovecot/conf.d/10-mail.conf

Add the following line in the file, so that individual user’s sieve scripts can be stored in his/her home directory.

mail_home = /var/vmail/%d/%n

Finally, restart dovecot for the changes to take effect.

sudo systemctl restart dovecot

Set Message Maximum Size

By default, SpamAssassin does not check messages with attachments larger than 500KB, as indicated by the following line in the /var/log/mail.log file.

spamc[18922]: skipped message, greater than max message size (512000 bytes)

The default max-size is set to 512000 (bytes). A high value could increase server load, but I think the default size is a little bit small. To increase the max-size, edit /etc/sysconfig/spamass-milter file and find the following line.

EXTRA_FLAGS="-m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE -i 127.0.0.1 -g sa-milt"

Add the -- --max-size=5120000 option at the end.

EXTRA_FLAGS="-m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE -i 127.0.0.1 -g sa-milt -- --max-size=5120000"

The empty -- option tells spamass-milter to pass all remaining options to spamc, which understands the --max-size option. I increased the size to 5000KB. Save and close the file. Then restart spamass-milter.

sudo systemctl restart spamass-milter

How to Configure Individual User Preferences

You may want to set custom rules for emails sent to a specific address on the mail server. I like this feature very much. I have a contact email address for this blog, which is only used for keeping contact with readers. I don’t use the contact email address elsewhere, so I can create special spam-filtering rules that apply only to this contact email address.

First, edit the SpamAssassin main configuration file.

sudo nano /etc/mail/spamassassin/local.cf

Add the following line to allow user rules.

allow_user_rules 1

Save and close the file. Next, edit the SpamAssassin environment file.

sudo nano /etc/sysconfig/spamassassin

Find the following line.

SPAMDOPTIONS="-c -m5 -H --razor-home-dir='/var/lib/razor/' --razor-log-file='sys-syslog'"

We need to add several extra options.

SPAMDOPTIONS="-c -m5 -H --razor-home-dir='/var/lib/razor/' --razor-log-file='sys-syslog' --nouser-config --virtual-config-dir=/var/vmail/%d/%l/spamassassin --username=vmail"

Where:

  • --nouser-config: disable per-user configuration file for local Unix users.
  • --virtual-config-dir: specify the per-user configuration directory for virtual users. The %d placeholder represents the domain part of email address and %l represents the local part of email address.
  • --username: run spamd as the vmail user.

Save and close the file. Then restart SpamAssassin.

sudo systemctl restart spamassassin

By default, spamass-milter doesn’t pass the recipient address to SpamAssassin. We need to make it send the full email address to SpamAssassin. Edit the spamass-milter configuration file.

sudo nano /etc/sysconfig/spamass-milter

Add the following option.

-e yourdomain.com -u sa-milt

Like this:

EXTRA_FLAGS="-e yourdomain.com -u sa-milt -m -r 8 -R SPAM_ARE_NOT_ALLOWED_HERE -i 127.0.0.1 -g sa-milt -- --max-size=5120000"

The -e option will make spamass-milter pass the full email address to SpamAssassin. Replace yourdomain.com with your real domain name. Save and close the file. Then restart spamass-milter.

sudo systemctl restart spamass-milter

Now send an email from Gmail, Hotmail, etc. to your domain email address. You will find the spamassassin directory is automatically created under /var/vmail/yourdomain.com/username/ directory.

cd /var/vmail/yourdomain.com/username/spamassassin/

You can use a command-line text editor to create the per-user preference file here. This file must be named as user_prefs.

sudo nano user_prefs

You can add custom rules in this file just as you would do in the /etc/spamassassin/local.cf file.

For instance, I found many spammers end their email body with an unsubscribe link to let you remove future contact. I didn’t subscribe to their spam and I don’t think the unsubscribe link will remove my email address from their contact database. So I use SpamAssassin to score this kind of email.  The following rule adds 3.0 score to emails containing the word “unsubscribe” or its variations in the body. (I don’t use the contact email address of this blog to subscribe to anything online.)

body      SUBSCRIPTION_SPAM   /(unsubscribe|u n s u b s c r i b e|Un-subscribe)/i
describe  SUBSCRIPTION_SPAM   I didn't subscribe to your spam.
score     SUBSCRIPTION_SPAM   3.0

Sometimes the email body doesn’t contain the word “unsubscribe”, but the there’s a List-Unsubscribe header, which means the spammer added my contact email address to their mailing list without my consent. I can score this type of email too, with the following rule.

header    LIST_UNSUBSCRIBE   ALL =~ /List-Unsubscribe/i
describe  LIST_UNSUBSCRIBE   I didn't join your mailing list.
score     LIST_UNSUBSCRIBE   2.0

I created a Mailjet account with a different email address. Some spammers assume that I used my contact email address to create Mailjet account, so they try to impersonate Mailjet customer service to lure me into typing my password at a fake Mailjet login page. I can score this kind of email like below.

header    MAILJET_IMPOSTER   From =~ /mailjet/i
describe  MAILJET_IMPOSTER   I don't have a mailjet account for this email address.
score     MAILJET_IMPOSTER   2.5

The above lines check if the From: header contains the word mailjet. If found, give it a 2.5 score.

I occasionally receive emails from Chinese spammers whose From: domain name has no vowel letters (a, e, i, o, u). The spammer used the cdjcbzclyxgs.xyz domain name. It is nearly impossible for a normal person/entity to use domain names without vowel letters, considering that many top level domains have already included vowel letters (.com, .net, .org, .co, .io, .shop, .dev, etc), so I give this kind of email a very high score like below. The default score is 0.5.

score FROM_DOMAIN_NOVOWEL 4.0

Some spam emails use many images in the body but contains very little text. The default score for this kind of email is 1.9, but I prefer to set a high score for my contact email address.

score HTML_IMAGE_RATIO_02 4.0

I also received a spam email with my email address in the subject, so I can add a high score to it.

header    SUBJECT_SPAM   Subject =~ /xiao\@linuxbabe.com/i
describe  SUBJECT_SPAM   Subject contains my email address.
score     SUBJECT_SPAM   4.0

Some spammers use BCC (Blind Carbon Copy) to hide other recipients. I don’t want to receive such email. So I made the following rule. If my domain name is not in the To: header, add 3.0 to the email.

header __DOMAIN_IN_TO     To =~ /linuxbabe.com/
meta   DOMAIN_NOT_IN_TO   !__DOMAIN_IN_TO
score  DOMAIN_NOT_IN_TO   3.0

After adding custom rules, close the file and run the following command to check syntax. Silent output means there’s no syntax error.

sudo spamassassin --lint

Finally, restart SpamAssassin for the changes to take effect.

sudo systemctl restart spamassassin

Now you can test the user preferences by sending test emails from other email services to your own domain email address.

Reject or Bounce

If a receiving SMTP server determines during the SMTP conversation that it will not accept the message, it rejects the message. Sometimes the SMTP server accepts a message and later discovers that it cannot be delivered, perhaps the intended recipient doesn’t exist or there is a problem in the final delivery. In this case, the SMTP server that has accepted the message bounces it back to the original sender by sending an error report, usually including the reason the original message could not be delivered.

You should not bounce spam, because the email address in the Return-path: header or From: header probably doesn’t exist or is an innocent person’s email address, so the bounce message will probably go to an innocent person’s email address, creating the backscatter problem. Instead of bouncing the spam, you should reject spam during the SMTP dialog, before the email is accepted. This article didn’t show you bouncing a spam message. You should remember this rule in case you are going to create spam-filter rules by yourself. If in doubt, test your spam-filtering rules to see if it’s going to create bounce messages.

URIBL_BLOCKED

By default, SpamAssassin enables URIBL rule, which checks if an email message contains links that are identified as spam by URIBL. This is a very effective anti-spam measurement. However, you might be blocked from querying URIBL. Check the raw email headers of an inbound email message, find the X-Spam-Status header.

X-Spam-Status: No, score=-92.2 required=5.0 tests=DATING_SPAM,DKIM_SIGNED,
	DKIM_VALID,HTML_FONT_LOW_CONTRAST,HTML_MESSAGE,SPF_PASS,
	SUBSCRIPTION_SPAM,UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_IN_WHITELIST
	autolearn=no autolearn_force=no version=3.4.2

If you can find URIBL_BLOCKED in this header, that means you are blocked from querying URIBL. Most of the time it’s because you are not using your own local DNS resolver. You can run the following command on your mail server to test which DNS server you are using to query URIBL.

host -tTXT 2.0.0.127.multi.uribl.com

Sample output:

2.0.0.127.multi.uribl.com descriptive text "127.0.0.1 -> Query Refused. See http://uribl.com/refused.shtml for more information [Your DNS IP: xx.xx.xx.xx]"

To fix this error, you need to run your own local DNS resolver on your mail server.

Once your local DNS resolver is up and running, test URIBL again.

host -tTXT 2.0.0.127.multi.uribl.com

If you see the following output, it means you are now allowed to query URIBL.

2.0.0.127.multi.uribl.com descriptive text "permanent testpoint"

From here on out, inbound email messages won’t have the URIBL_BLOCKED tag in the X-Spam-Status header.

Other Tidbits

SpamAssassin 4.0 includes a HashBL plugin, which can check if a Bitcoin address in the email body has been used by scammers. And there’s also a new plugin called “Ole Macro” that can check if an email contains an Office attachment with a macro. This plugin would try to detect if the attched macro is malicious or not.

Wrapping Up

I hope this tutorial helped you use Postifix and SpamAssassin to filter spam. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

how to test spamassasin

vim /usr/share/doc/spamassassin/sample-spam-01.txt 

and copi the source of the email

spamassassin -t -D razor2 < /usr/share/doc/spamassassin/sample-spam-01.txt

 

 

How to Set up SPF and DKIM with Postfix on Linux Server?

Article from here…good job and thanks

Introduction

In the earlier tutorials, you learned how to install and configure Postfix. But, despite doing the correct setup of Postfix and having correct MX, A and PTR record your emails might be getting flagged as spam by few of the major ISPs like Gmail, Outlook. So, in this tutorial, you will learn how to further improve email delivery to the recipient’s inbox by setting up SPF and DKIM on your server.

What are these SPF and DKIM records all about?

SPF (Sender Policy Framework) is a simple email validation system designed to detect email spoofing. It is an authentication protocol which, when used allows senders to specify which IP addresses are authorized to send emails on behalf of a particular domain. To ensure that your customers and brand are protected from phishing and spoofing attacks, you need to authenticate your email with an SPF record.

DKIM is the acronym for DomainKeys Identified Mail. It is an authentication protocol used to validate sending domain names with email messages. DKIM uses cryptographic authentication by inserting a digital signature into the email message header which is later verified by the receiving host to validate the authenticity of the sender’s domain. The DKIM digital signature is created using a unique string of characters encrypted as the public key and stored in your DNS. When a recipient gets your email signed by DKIM, the public key is retrieved from the DNS Records of the sender and is decrypted to authenticate the sender’s domain.

Setup SPF Record

Step 1: Create An SPF Record In DNS Of Your Sender Domain

If you are using example.com as the From/Sender domain in all your emails going through Postfix, then this is the domain for which you have to actually set up the SPF record. And, SPF record can be easily set up by login into your DNS provider, e.g. Godaddy, Namecheap.

Mechanisms can be used to describe the set of hosts which are designated outbound mailers for the domain and can be prefixed with one of four qualifiers:

+    (Pass)
–     (Fail)
~    (SoftFail)
?     (Neutral)

If a mechanism results in a hit, its qualifier value is used.  The default qualifier is “+“, i.e. “Pass”. Mechanisms are evaluated in order. If no mechanism or modifier matches, the default result is “Neutral”.

More in-depth information on the differences between “~” and “–” can be found here

Examples:

“v=spf1 -all”

“v=spf1 a -all”

“v=spf1 a mx -all”

“v=spf1 +a +mx -all”

Evaluation of an SPF record can return any of these results:

Result Explanation Intended action
Pass The SPF record designates the host to be allowed to send accept
Fail The SPF record has designated the host as NOT being allowed to send reject
SoftFail The SPF record has designated the host as NOT being allowed to send but is in transition accept but mark
Neutral The SPF record specifies explicitly that nothing can be said about validity accept
None The domain does not have an SPF record or the SPF record does not evaluate to a result accept
PermError A permanent error has occurred (eg. badly formatted SPF record) unspecified
TempError A transient error has occurred accept or reject

 

Once you are logged in, just create a new TXT record like the one below:

TXT  @  v=spf1 mx ~all

 

Note, there might be a few DNS providers, who will require you to enclose the SPF record with quotes, like the one below:

TXT  @  "v=spf1 mx ~all"

 

Once you have added the SPF records, it might take up to 24-48 hrs to propagate globally over the internet. You can use the dig command to see the current SPF record which is updated globally:

dig example.com TXT

Or you can also use online SPF validators like mxtoolbox.comKitterman.com or spf.myisp.ch

Out of the above online SPF validators, spf.myisp.ch is quite useful because it gives a very detailed view of what all servers/IP addresses are allowed to send emails for your domain.

Step 2: Configuring SPF Policy Agent On Server

By setting up the SPF record for your domain, you have completed a very important step to improve the delivery of outgoing emails to recipient’s inbox. Like the way you did the SPF configuration for outgoing emails, the very same way you should also do the SPF validation for the incoming emails. This will help you to detect the forged incoming emails coming in your network.

First, install the required package for SPF policy agent

sudo apt install postfix-policyd-spf-python

 

The next step is to edit the postfix’s master file master.cf. You can use any of your favourite editor vim or nano to edit the file:

sudo nano /etc/postfix/master.cf

Append the following lines at the EOF. This will tell the postfix to start the SPF policy daemon whenever postfix starts itself.

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf

Save and close the file. Next step is to edit the postfix’s main configuration file main.cf.

sudo nano /etc/postfix/main.cf

Add the following lines at the end of the file main.cf. Adding these lines means, you are giving the instructions to postfix to check SPF on incoming emails and reject the emails which are unauthorized.

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   check_policy_service unix:private/policyd-spf

Save and close the file. You are now done with the SPF setup, just restart the postfix to reflect the changes.

sudo service postfix restart

or

sudo systemctl restart postfix

 

How to see whether the emails which you sent to Gmail are SPF passed?

Open any of the email sent via your postfix to Gmail and click on Show original link as shown below:

Next, you will see a window like the one below, where you will see the status of SPF (whether Pass or Fail) in Gmail.

If you see the below line, then this means SPF is pass:

Received-SPF: Pass (sender SPF authorized)

Setting up DKIM

DKIM can be set up by installing OpenDKIM- an open-source package for setting up DKIM.

sudo apt install opendkim opendkim-tools

Once the installation is successful, you need to add postfix user to opendkim group. By doing this, you are actually linking DKIM with your Postfix installation:

sudo gpasswd -a postfix opendkim

Next step is to edit the main configuration file of the OpenDKIM:

sudo nano /etc/opendkim.conf

Change the below-highlighted content in the main configuration:

# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendkim/examples/opendkim.conf.sample.

# Log to syslog
Syslog          yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask           002

# Sign for example.com with key in /etc/mail/dkim.key using
# selector '2007' (e.g. 2007._domainkey.example.com)
#Domain         example.com
#KeyFile        /etc/mail/dkim.key
#Selector       2007

# Commonly-used options; the commented-out versions show the defaults.
Canonicalization  relaxed/simple
Mode            sv
SubDomains      no
#ADSPAction             continue
AutoRestart       yes
AutoRestartRate         10/1M
Background          yes
DNSTimeout          5
SignatureAlgorithm      rsa-sha256

# Always oversign From (sign using actual From and a null From to prevent
# malicious signatures header fields (From and/or others) between the signer
# and the verifier.  From is oversigned by default in the Debian pacakge
# because it is often the identity key used by reputation systems and thus
# somewhat security sensitive.
OversignHeaders     From

# List domains to use for RFC 6541 DKIM Authorized Third-Party Signatures
# (ATPS) (experimental)

#ATPSDomains        example.com

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID                 opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable            refile:/etc/opendkim/key.table
SigningTable        refile:/etc/opendkim/signing.table

# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts

# A set of internal hosts whose mail should be signed
InternalHosts /etc/opendkim/trusted.hosts

Once changes are done, save and close the file.

Create Signing Table

In order to create the signing table, you need to first create a directory structure for OpenDKIM. Execute the following commands to configure the same:

sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys

Change the permission and role:

sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rw /etc/opendkim/keys

Execute the following command to create the signing table:

sudo nano /etc/opendkim/signing.table

then add the following lines in the above file:

*@your-domain.com    default._domainkey.your-domain.com

Save and close the file.

Create Key Table

Execute the following command to create the key table:

sudo nano /etc/opendkim/key.table

Once created, add the following lines in the file:

default._domainkey.your-domain.com     your-domain.com:default:/etc/opendkim/keys/your-domain.com/default.private

Save and close the file.

Create The Trusted Hosts File

Execute the following command to create the trusted table:

sudo nano /etc/opendkim/trusted.hosts

Once created, add the following lines in the file:

127.0.0.1
localhost

*.your-domain.com

Adding the above line means that emails coming from the mentioned IP addresses and domains will be trusted and signed.

 

Generation of the Private and Public Key for DKIM

DKIM is going to be used for signing outgoing emails. So, you need to generate both private and the public key for DKIM. The private key will be used to signing and the public key which will be published in the DNS will be used for remote verification.

Create a folder for your domain for which DKIM to be signed

sudo mkdir /etc/opendkim/keys/your-domain.com

 

You can use the opendkim-genkey tool to generate the keys

sudo opendkim-genkey -b 2048 -d your-domain.com -D /etc/opendkim/keys/your-domain.com -s default -v

Once you will execute the above command, two files will get generated:

1. This file will contain your private key.

/etc/opendkim/keys/your-domain.com/default.private

2. This file will contain your public key which you need to add in the DNS record of your domain.

/etc/opendkim/keys/your-domain.com/default.txt

 

Change the ownership of the private key file:

sudo chown opendkim:opendkim /etc/opendkim/keys/your-domain.com/default.private

 

Configure Public Key in DNS Record of Domain

Get the public key by doing cat:

sudo cat /etc/opendkim/keys/your-domain.com/default.txt

Copy the record, and log in to your DNS manager e.g. if your DNS is with GoDaddy or Namecheap, then login to their dashboard and add the following DNS record:

 

 

Testing Your DKIM Configuration

Execute the following command on your Ubuntu machine to test your keys:

sudo opendkim-testkey -d your-domain.com -s default -vvv
in my server i need to use mail instead of default because it's a prefix I used in the configuratioon

If the setup is correct, you will get the following message:

key OK

 

Integrate Postfix to OpenDKIM

Postfix can connect with OpenDKIM via Unix socket i.e. /var/run/opendkim/opendkim.sock. But, we need to change the file path because the SMTP daemon which comes with Ubuntu resolves all filenames relative to the Postfix queue directory (/var/spool/postfix).

Create a new directory to keep the OpenDKIM socket file

sudo mkdir /var/spool/postfix/opendkim

sudo chown opendkim:postfix /var/spool/postfix/opendkim

The next step is to edit the socket conf file.

sudo nano /etc/default/opendkim

Search for the following line:

SOCKET="local:/var/run/opendkim/opendkim.sock"

And, replace it with the following:

SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

Save and close the file.

Note: You need to do similar changes in the opendkim.conf file too:

sudo nano /etc/opendkim.conf

Search for the following line:

Socket                  local:/var/run/opendkim/opendkim.sock

And, replace it with the following:

Socket                  local:/var/spool/postfix/opendkim/opendkim.sock

 

Next step is to edit the Postfix main configuration file:

sudo nano /etc/postfix/main.cf

Append the following lines after smtpd_recipient_restriction section in the main.cf file.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Save and close the file.

You are now all done. Just restart opendkim and postfix service to reflect all the changes.

sudo service opendkim restart
sudo service postfix restart

Now, your Postfix setup is ready with the SPF and DKIM. You can also visit the official Ubuntu community page for additional detailed documentation on SPF and DKIM set up.

Quick Question: Do you know about DMARC policy? It’s another crucial component of email authentication.

Keep reading the tutorials and blogs to get deeper into email delivery. Rate us if you loved the article.