---
# System prepended metadata

title: NA HW3
tags: [NA]

---

# NA HW3
###### tags: `NA`

This note is based on CentOS 7.8.

## About CentOS 7
### Setup
Update packages and install useful tools.
```shell
sudo yum update -y
sudo yum upgrade -y
sudo yum install -y epel-release vim bind-utils telnet wget curl mailx
```

### Basic
You need to know how to maintain services.
```shell
sudo systemctl start <service-name>
sudo systemctl restart <service-name>
sudo systemctl status <service-name>
sudo systemctl stop <service-name>
# You can manipulate more than one service in one line
sudo systemctl restart <service-name1> <service-name2>
```

Power management.
```shell
sudo shutdown [timeout-in-seconds-default-to-60]
sudo reboot
```

Send an email. You don't need to be root.
```
echo '<mail content>' | mail -s '<mail subject>' <receiver>
```

### Preinstallation
Make sure you have an A record pointing to mail.0716xxx.nasa. Your mail server should have static IP.

## Setup Postfix and Dovecot
### Installation
- See [here](https://computingforgeeks.com/installing-postfix3-on-centos-7/).

Add following to /etc/yum.repos.d/gf.repo. If this file does not exist, create new one.
```
[gf]
name=Ghettoforge packages that won't overwrite core distro packages.
mirrorlist=http://mirrorlist.ghettoforge.org/el/7/gf/$basearch/mirrorlist
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-gf.el7
failovermethod=priority

[gf-plus]
name=Ghettoforge packages that will overwrite core distro packages.
mirrorlist=http://mirrorlist.ghettoforge.org/el/7/plus/$basearch/mirrorlist
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-gf.el7
failovermethod=priority
```

Install postfix and dovecot. BTW we disable firewall and sendmail (CentOS builtin MTA).
```shell
# Disable firewall, we don't need it
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# Remove sendmail
sudo yum remove -y sendmail*
# Enable ghettoforge auth
sudo wget -P /etc/pki/rpm-gpg/ https://mirror.ghettoforge.org/distributions/gf/RPM-GPG-KEY-gf.el7
# Install postfix and dovecot
sudo yum install -y postfix3 cyrus-sasl cyrus-sasl-md5 dovecot
# Enable postfix and dovecot so that they run on boot.
sudo systemctl enable postfix dovecot
```

Make sure you have postfix version >= 3.5.
```shell
postconf mail_version
```

### Configuration
Edit /etc/postfix/main.cf. Of course you need root permission.
```
myhostname = mail.0716xxx.nasa
mydomain = 0716xxx.nasa
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, $mydomain, localhost
```

Edit /etc/dovecot/conf.d/10-mail.conf.
```
mail_location = mbox:~/mail:INBOX=/var/mail/%u
mail_privileged_group = mail
```

### Before going to next step
Use one of following to refresh postfix rules.
```shell
sudo postfix reload
sudo systemctl restart postfix
```

You may need something to troubleshoot.
- /var/log/messages
- /var/log/maillog
- [IMAP with telnet error](https://wiki2.dovecot.org/MailLocation/mbox)

## STARTTLS
- [x] STARTTLS on IMAP/SMTP

Create RSA keys and certificates
```shell
sudo ln -sf /etc/pki/tls/certs /etc/ssl/certs
sudo ln -sf /etc/pki/tls/private /etc/ssl/private
sudo openssl req -newkey rsa:2048 -nodes -sha512 -x509 -days 365 -nodes -out /etc/ssl/certs/mail.0716xxx.nasa.pem -keyout /etc/ssl/private/mail.0716xxx.nasa.pem
```

Edit /etc/postfix/main.cf.
```
smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_security_level = may
smtpd_tls_key_file =  /etc/ssl/private/mail.0716xxx.nasa.pem
smtpd_tls_cert_file = /etc/ssl/certs/mail.0716xxx.nasa.pem
smtpd_tls_loglevel = 1
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
```

Edit /etc/dovecot/conf.d/10-ssl.conf.
```
ssl = yes
ssl_cert = </etc/ssl/certs/mail.0716xxx.nasa.pem
ssl_key =  </etc/ssl/private/mail.0716xxx.nasa.pem
```

Edit /etc/dovecot/conf.d/10-auth.conf.
```
auth_mechanisms = plain login
```

Edit /etc/dovecot/conf.d/10-master.conf
```
unix_listener auth-userdb {
    mode = 0666
    user = postfix
    group = postfix
}
  
# Postfix smtp-auth
    unix_listener /var/spool/postfix/private/auth {
    mode = 0666
}  
```

Change mailbox permission.
```shell
sudo chmod 600 /var/mail/*
```

You need to restart postfix and dovecot after updating rules.
```shell
sudo systemctl enable postfix dovecot
sudo systemctl restart postfix dovecot
```

### Test imap login
- [Reference](https://busylog.net/telnet-imap-commands-note/)

```shell
openssl s_client -connect mail.0716xxx.nasa:143 -starttls imap
> # ...
> a login <username> <password>
> # ...
> quit
```

If fails to setup STARTTLS, see logs to debug.

### Test smtp login
- [Reference](http://woshub.com/sending-email-via-telnet-using-smtp-authentication/)
```shell
openssl s_client -connect mail.0716xxx.nasa:25 -starttls smtp
> EHLO 0716xxx.nasa
> # ...
> AUTH LOGIN
> # 334 VXNlcm5hbWU6
> <base64 username>
> # 334 UGFzc3dvcmQ6.
> <base64 password>
> # 235 2.7.0 Authentication successful
> mail from: <mail address>
> # 250 2.1.0 Sender OK
> rcpt to: <mail address>
> # 250 2.1.5 Recipient OK
> data
> [from: <mail address>]
> [to: <mail address>]
> [Subject: <mail subject>]
> <mail content>
> .
> # ...
> quit
```

If fails to setup STARTTLS, see logs to debug.

## DNS
### MX
- [x] Set MX record on your domain. Sending mail to @{student_ID}.nasa will go to mail.{student_ID}.nasa

```
@    IN  MX  10  mail.0716xxx.nasa.
```

### SPF record
- [x] Allow your server to send mail using your domain. Deny other servers from pretending your domain, and drop these invalid mail.

```
@    IN    TXT    "v=spf1 mx -all"
```

### DKIM record
- [x] Signing your outgoing email with your private key.

1. Generate your records using [this tool](https://dkimcore.org/tools/). Your domain should be **0716xxx.nasa**, not ~~mail.0716xxx.nasa~~.
2. Publish your DKIM record.
3. Keep your DKIM selector and private key. They will be used later.

This is your DKIM selector.
```
Generated at Sat May 30 00:50:37 2020 for selector xxxxx.0716xxx
                                                   ^^^^^^^^^^^^^
```

### DKIM signing
Reference
- [https://snippetinfo.net/mobile/media/1449](https://snippetinfo.net/mobile/media/1449)
- [https://www.linuxtechi.com/configure-domainkeys-with-postfix-on-centos-7/](https://www.linuxtechi.com/configure-domainkeys-with-postfix-on-centos-7/)

Install opendkim.
```
sudo yum install -y opendkim
sudo systemctl enable opendkim
sudo systemctl start opendkim
```

Edit /etc/opendkim.conf.
```
Mode     sv
Domain   0716xxx.nasa
Selector <your-selector>
```

Put private key at /etc/opendkim/keys/default.private. Then:
```
sudo chown opendkim:opendkim /etc/opendkim/keys/default.private
sudo chmod 400 /etc/opendkim/keys/default.private
```

Edit /etc/postfix/main.cf
```
milter_default_action = accept
milter_protocol = 6
smtpd_milters = 
        ...
        inet:127.0.0.1:8891
```

Restart opendkim. Send an email, your mail should be signed.

### DMARC record
- [x] Let others drop mails that does not pass DMARC policy check.

This is DMARC record. Choose one.
```
_dmarc    IN    TXT    "v=DMARC1; p=reject"            ; mine
_dmarc    IN    TXT    "v=DMARC1; p=rehect; sp=none"   ; TA's
```

### Incoming check
- [x] Do DMARC policy check to the incoming email.
- [x] Do SPF policy check on incoming email.

```shell
sudo yum -y install opendmarc
sudo systemctl enable opendmarc
sudo systemctl start opendmarc
```

Edit /etc/postfix/main.cf.
```
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = 
        ...
        inet:127.0.0.1:8893
```

Edit /etc/opendmarc.conf
```
AuthservID OpenDMARC
TrustedAuthservIDs mail.0716xxx.nasa
# Peform DMARC and SPF checking
RejectFailures true
# TA's judge sends malformed headers hence ignore them
RequiredHeaders false
# Allow self-signed certificate
IgnoreAuthenticatedClients true
```

Restart services.
```shell
sudo systemctl restart postfix opendmarc
```

## Virtual
### Create users
- [x] Specific user `TA` and `TU`. Set password to your VPN private key (WG_KEY).

```shell
# Create users
sudo useradd ta # lowercase
sudo useradd tu # lowercase
# Set passwords
echo '<password>' | sudo passwd --stdin ta
echo '<password>' | sudo passwd --stdin tu
# Add to group mail
sudo usermod -a -G mail ta
sudo usermod -a -G mail tu
```

### Setup alias and rewriting
- [x] Receipt: for any mail to `TO@` alias to `TA@`.
- [x] Receipt: for any mail to `<blablabla>|<user>@` alias to `<user>@`.
- [x] Rewrite `@mail.{student_ID}.nasa` to `@{student_ID}.nasa`.
- [x] Rewrite `TU@` to `TUTU@`.

Reference:
- [Virtual aliases](http://www.postfix.org/ADDRESS_REWRITING_README.html#virtual)
- [Address rewriting]()

Edit /etc/postfix/main.cf
```
# `TO@` alias to `TA@`
# `TUTU@` alias to `TU@`
# `<blablabla>|<user>@` alias to `<user>@`
# `@mail.{student_ID}.nasa` to `@{student_ID}.nasa`
virtual_alias_maps = regexp:/etc/postfix/aliases

# `TU@` to `TUTU@`.
# `@mail.{student_ID}.nasa` to `@{student_ID}.nasa`
canonical_maps = hash:/etc/postfix/canonical
```

Edit (or create) /etc/postfix/aliases.
```
/@mail.0716xxx.nasa$/           @0716xxx.nasa
/^.*\|(.*)@0716xxx.nasa$/       $1@0716xxx.nasa
/^TO@0716xxx.nasa$/             TA@0716xxx.nasa
/^TUTU@0716xxx.nasa/            TU@0716xxx.nasa
```

Edit (or create) /etc/postfix/canonical
```
@mail.0716xxx.nasa      @0716xxx.nasa
TU@0716xxx.nasa         TUTU@0716xxx.nasa
```

Restart postfix. 
```shell
sudo postmap /etc/postfix/canonical
sudo postfix reload
```

You should send some mails to check affects.

## Security
### Auth
- [x] Only send emails with authenticated `username@`.
- [x] Avoid to fake other users on envelop `from`.

Edit /etc/postfix/main.cf.
```
check_sender_access hash:/etc/postfix/reject_null_sender
smtpd_sender_login_maps = regexp:/etc/postfix/login_map
smtpd_sender_restrictions = 
        ...
        reject_sender_login_mismatch
        ...
        permit
```

Edit (or create) /etc/postfix/login_map.
```
/^(.*)@(mail\.)?0716xxx.nasa$/  $1
/^TUTU@(mail\.)?0716xxx.nasa$/  TU
/^TO@(mail\.)?0716xxx.nasa$/    TA
```

Edit /etc/postfix/reject_null_sender.
```
<>    REJECT
```

Restart postfix with:
```
sudo postmap /etc/postfix/reject_null_sender
sudo postfix reload
```

### No relay
- [x] No open relay.

```
smtpd_sender_restrictions =
        ...
        reject_non_fqdn_sender
        reject_unknown_sender_domain
        ...
        permit
```

## Spam defense
### Greylist
- [x] Greylist for 30 seconds

Install postgrey.
```shell
sudo yum install -y postgrey
```

Edit /etc/sysconfig/postgrey.
```
POSTGREY_OPTS="--delay=30"
```

Add this line to /etc/postfix/postgrey_whitelist_clients.local.
```
0716xxx.nasa
mail.0716xxx.nasa
```


Edit /etc/postfix/main.cf.
```
smtpd_recipient_restrictions =
        ...
        check_policy_service unix:postgrey/socket
        permit
```

Reload postfix and postgrey.
```shell
sudo systemctl enable postgrey
sudo systemctl restart postfix postgrey
```

### Spam filtering
- [x] Add `*** SPAM ***` in front of the subject if the mail contains virus or spam message.
    - You can use amavisd-new / rspamd.

Resources:
- [clamav](https://www.server-world.info/en/note?os=CentOS_7&p=clamav)
- [amavis](https://www.server-world.info/en/note?os=CentOS_7&p=mail&f=6)

Install tools.
```shell
sudo yum install -y install clamav clamav-update amavisd-new clamav-scanner-systemd
sudo sed -i -e "s/^Example/#Example/" /etc/freshclam.conf
```

:::danger
Then you have to reboot.
:::

Update virus and spam database.
```shell
sudo sed -i -e "s/^Example/#Example/" /etc/freshclam.conf
sudo freshclam
```

Edit /etc/amavisd/amavisd.conf.
```
$mydomain = '0716xxx.nasa';
$myhostname = 'mail.0716xxx.nasa';
$sa_spam_subject_tag = '*** SPAM *** ';
$sa_spam_modifies_subj = 1;
$final_virus_destiny = D_PASS;
$final_banned_destiny = D_PASS;
$final_spam_destiny = D_PASS;
$final_bad_header_destiny = D_PASS;
$subject_tag_maps_by_ccat{+CC_VIRUS} = [ '*** SPAM *** ' ];
```

Test if your config is good.
```shell
sudo amavisd -u amavis -c /etc/amavisd/amavisd.conf debug
```

Edit /etc/postfix/main.cf.
```
content_filter=amavis:127.0.0.1:10024
```

Edit /etc/postfix/master.cf. Add following to the end.
```
amavis unix - - - - 2 smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
127.0.0.1:10025 inet n - - - - smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
```

Restart services. 
```
sudo systemctl restart clamd@amavisd amavisd spamassassin postfix
```

Send am email to check affects.

### Custom filtering
- [x] Reject mails whose subject contains keyword `肺炎` or `wuhan`.

Edit /etc/postfix/main.cf. 
```
header_checks = regexp:/etc/postfix/header_checks
```

Edit (or create) /etc/postfix/header_checks. Note that base64 encoding of `肺炎` is `6IK654KO`.
```
/^Subject:.*6IK654KO.*/  REJECT
/^Subject:.*wuhan.*/     REJECT
```

Restart.
```
sudo systemctl restart postfix
```