---
# System prepended metadata

title: NA_計算機網路管理互助筆記

---

# NA_計算機網路管理互助筆記
[SA互助筆記](https://hackmd.io/0dIy9vLuSqydRT-dwSjQdA?both)

## 簡單板規、格式

 * 本筆記原則上完全開放，不管有沒有修過NA都歡迎
 * 寫的東西具名、不具名都可以(具名請多利用`[name=YourName]`)
 * 禁止人身攻擊、謾罵，然後宗教戰爭盡量不要。拜託QQ
 * 不要刪除別人寫的東西，這樣大家會很困擾，對內容有意見可以用`>`發表Quote或在意見區寫下寶貴的意見
 * 大區塊(ex.基本操作整理)請使用h2，小區塊(ex.一些你應該要先安裝的東西)請使用h3，然後沒事不要使用Heading，請多利用Quote和List
 * 基本上沒有誰說了算，希望能採用共識決
 * 顏文字有時會造成HackMD格式上的混亂，不禁止但使用時要注意一下
 * [HackMD操作指引](https://hackmd.io/s/E1UakUq8)

>基本板規撰寫(2019/04/22)[name=pleezaD(明亮)]

## Lab1 Wireguard, DHCP
**架構:**
![](https://i.imgur.com/gNR7vo8.png)

VirtualBox->YourVM setting->Network 可以選擇使用幾張網卡
設定好後在VM中`ifconfig -a`可以看到所有可用的網卡(包括未啟用)

[How to emulate a network using VirtualBox](http://www.brianlinkletter.com/how-to-use-virtualbox-to-emulate-a-network/)


**VPN:**
本次作業只需要在`Router`上設置VPN Client。

`/etc/wireguard/wg0.conf`:
```
[Interface]
PrivateKey = <Output of privatekey file that contains your private key>
Address = <Your interface address>/<netmask>

[Peer]
PublicKey = <Server Public key>
Endpoint = <Server Public IP or hostname>:51820
AllowedIPs = <network which your packet allowed to send to>
```
注意幾點：
1. `[Interface]:Address`只需要給IP address，不用加CIDR。
2. 在設定VPN時不需要管`wg0`的部分。Wireguard會自己維護這張網卡，加了rule反而容易會衝突。
3. 出現`RTNETLINK answers: File exists`錯誤時表示你的 routing table 有衝突。用`route -n`查看 routing table，`route del <routing entry>`手動刪除衝突的部分(通常是你設錯netmask造成)。
4. 記住 Private(接 Client)與 VPN (接 VPN 網路)的子網路遮罩(netmask)是不一樣的。 

助教會給你的資訊：

`Subnet`: DHCP的部分會用到
`Wireguard Private Key`: 你的VPN Client private key
`Wireguard Peer IP`: 你`wg0`interface的IP(在`[Interface]:Address`設定)，VPN網路中你就是這個IP
`Wireguard Server`: Wireguard Server Hostname:Port
`Wireguard Server Public Key`: Wireguard Server的public key，你會在`[Peer]:Endpoint:`中設定
`Wireguard Interal IP`: 不知道有什麼用

[Set Up WireGuard VPN on Ubuntu](https://www.linode.com/docs/networking/vpn/set-up-wireguard-vpn-on-ubuntu)

**DHCP:**
1. 架好Network環境。
   Router's Private interface 與 Client's interface 要在 VirtualBox 中設為內網(網路名稱要一樣)。注意進階→混合模式不要設成`拒絕`。

2. 進`/etc/default/isc-dhcp-server`設定 DHCP Server 要聽在哪幾張網卡上(可多選，用空白隔開)。

3. 進`etc/dhcp/dhcpd.conf`設定 DHCP Server 本身的參數。

4. `systemctl restart isc-dhcp-server`

6. 在 client 用`sudo dhclient <interface>`來手動 DHCP。或在`/etc/network/interfaces`設定，開機自動使用 DHCP。

* 可以在`/var/lib/dhcp/dhcpd.leases`中查詢存在的租約

[How to build Ubuntu Server in VirtualBox on host-only network adapter with internet access from host](https://medium.com/@exesse/how-to-build-ubuntu-server-in-virtualbox-on-host-only-network-adapter-with-internet-access-from-81cd7253e3b1)

[How to Install and Configure DHCP on Ubuntu 18.04](https://linoxide.com/linux-how-to/install-configure-dhcp-ubuntu/)

[Ubuntu 網路卡(`/etc/network/interfaces`)設定 | Calos's Blog](https://caloskao.org/ubuntu-nic-configure/)


**VPN**
基本上都在用`iptables`這個工具。不熟的可以參考鳥哥的文章，非常清晰易懂。注意不要去替 `wireguard` 做 Forwarding ，很可能導致衝突讓你跑不出東西來。

話說`route`與`iptables`的設定上有什麼不同啊?
> `route` 是 routing table；`iptables`是防火牆，沒辦法做routing，只能對某個路由做阻擋(不幫忙轉發)

[Linux 的封包過濾軟體: iptables](http://linux.vbird.org/linux_server/0250simple_firewall.php#netfilter)

[[Ubuntu 14.04 LTS] NAT Router](http://eric.logdown.com/posts/2014/12/29/ubuntu-1404-lts-nat-router?fbclid=IwAR1UOnowN-sK3V9be-vnWlzdQGrwNsqdyBxKRcZJryUWcWIvZ1_TN91yndw)

## Lab2 LDAP

### DHCP
這次要給LDAP Master一個固定位址，需要用到static dhcp。
在`/etc/dhcp/dhcpd.conf`中找到這段
> 這是我改完的畫面，預設是被註解掉

![](https://i.imgur.com/VtWvcPu.png)
* `Master`改為Client的hostname
* `hardware ethernet`改為Client的MAC
* `fixed-address`改為你要給他的固定IP

再restart server後應該就可以了
[ISC DHCP Server Static Lease](https://oitibs.com/isc-dhcp-server-static-lease/)

### LDAP
:::info
:mega:什麼都是假的，只有man page是真的。
:::
搜尋時最好加上時間限制，看近幾年的文章。不然會因為一直找到舊版教學浪費時間。

看完這篇文章你就應該能成功架好LDAP Server
[使用Ubuntu Server架設LDAP伺服器](https://magiclen.org/ubuntu-server-ldap/)
[LDAP教學](http://dic.vbird.tw/linux_server/unit07.php)
要修改`/etc/hosts`加入`<server ip> ldap://ldap.<Base DN>`
ex.`10.113.37.11    ldap://ldap.0516224.nasa`

或著直接用LDAP server IP也行，但兩種方式統一選一種用
ex. `10.113.37.11    ldap://10.113.37.11`


### 新增objectClass與Attribute：
需要新增`example.schema`檔案
請依照下面這份Specification寫好`.schema`
[Schema Specification](http://www.openldap.org/doc/admin24/schema.html)
* `numericoid`就我目前所知亂設沒關係
* 因為每個node只能有一個`STRUCTURAL objectClass`，所以建議自訂義的objectClass型態用`AUXILIARY`就好

範例：
```schema
attributetype ( 2.2.3.1 NAME 'address'
    DESC 'IP address'
    EQUALITY caseIgnoreMatch
    SUBSTR caseIgnoreSubstringsMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )

objectclass ( 1.2.3.1 NAME 'clusterInfo'
    DESC 'cluster information'
    AUXILIARY
    MUST address )

attributetype ( 2.2.3.1 NAME 'sshPublicKey'
    DESC 'ssh public key'
    EQUALITY caseIgnoreMatch
    SUBSTR caseIgnoreSubstringsMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )

objectclass ( 1.2.3.1 NAME 'publicKeyLogin'
    DESC 'object for ssh login by publickey'
    AUXILIARY
    MUST sshPublicKey )
```

然後依照這篇把`*.schema`轉成`*.ldif`
1. 建立一個`example.conf`。
    裡面只有一行`include /path/to/file/example.schema`
2. 創建一個資料夾`exampleDir`
3. 執行`slaptest -f example.conf -F exampleDir`
4. `exampleDir//cn=config/cn=schema`裡會出現一個`example.ldif`
    把`.ldif`裡的`dn`改成`cn=example,cn=schema,cn=config`；檔名改成`cn`欄位的內容
    改好大概長這樣：
![](https://i.imgur.com/uZrbh1l.png)
5. 將`slapd`關掉
6. `slapadd -l exmaple.ldif -n 0`將檔案加入資料庫(**要確認沒有Error!**)
7. 確認`example.ldif`有在`/etc/ldap/slapd.d/cn=config/cn=schema`底下就表示加入成功
:::warning
:zap: **重要:** 要記得把`example.ldif`的owner與group改成`openldap`，否則slapd會開不起來
:::

參考：
[Creating a new ObjectClass and Attribute in openLDAP](https://stackoverflow.com/questions/45511696/creating-a-new-objectclass-and-attribute-in-openldap)

### 在BaseDN底下新增node
1. 請依教學[LDAP教學](http://dic.vbird.tw/linux_server/unit07.php)寫好`.ldif`檔案。
**每個node都要恰好有一個STRUCTURE的objectClass**
    範例：
    ```ldap
    dn: cn=TA,dc=0516224,dc=nasa
    objectClass: organizationalRole
    objectClass: posixAccount
    objectClass: publicKeyLogin
    cn: TA
    uid: TAaccount
    gidNumber: 10000
    homeDirectory: /home/ldapuser
    uidNumber: 3000
    sshPublicKey: <public key>
    ```

2. 加入node：`ldapadd -x -W -D "cn=admin,<your Base DN>" -f sample.ldif`
    ex.` ldapadd -x -W -D "cn=admin,dc=0516224,dc=nasa" -f add.ldif`

成功的畫面大概長這樣：
![](https://i.imgur.com/IGkQgDu.png)

### 讓機器以Ldap登入
1. 在你的BaseDN下新增一個ou(organization unit)叫People
2. 然後在下面新增使用者(group也要建)
詳細步驟請參考下列文章的`User and Group Management`章節：
[Ubuntu Openldap指南](https://help.ubuntu.com/lts/serverguide/openldap-server.html.en#ldap-usergroup-management)
3. 在別台機器上設定ldap client使之可以用ldap登入
    照著這篇文章做就行了
    [How to Configure LDAP Client to Connect External Authentication](https://www.tecmint.com/configure-ldap-client-to-connect-external-authentication/)
    要注意的是**有時**會因為顯示問題會讓你打的字錯位，所以如果沒有要用預設值記得`backspace`按到底再整個重打
![](https://i.imgur.com/b67yLPA.png)
![](https://i.imgur.com/VBTQ2cy.png)

**讓client可以使用`passwd`更改密碼**
依照這篇去修改`/etc/pam.d/common-password`
[How to allow LDAP user to change password?](https://askubuntu.com/questions/340340/how-to-allow-ldap-user-to-change-password)

### slave server
[How to configure OpenLDAP Master-Slave Replication](https://www.itzgeek.com/how-tos/linux/configure-openldap-master-slave-replication.html)
[Centralized authentication using OpenLDAP](https://wiki.gentoo.org/wiki/Centralized_authentication_using_OpenLDAP#Replication)
[askUbuntu: How to configure Master-Slave LDAP replication](https://askubuntu.com/questions/360190/how-to-configure-master-slave-ldap-replication)

1. 在master server創建一個指定的帳號
    ```ldap
    dn: cn=Syncer,dc=your,dc=baseDN
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: Syncer
    description: Replication User
    userPassword: {SSHA}C1Vj2CKdKERgFNpEL9lTf0UgObRXZuG8
    ```
    > userPassword使用`slappasswd -h {SSHA} -s "your password"`產生
    > >不hash，直接用明碼似乎也行
    > 
    > 加入ldap：
    > ```bash
    > ldapmodify -H ldapi:/// -x -W -D "cn=admin,dc=your,dc=baseDN" -f filename.ldif
    > ```
    
2. 在master server
   * 設定允許`cn=Syncer`讀取`userPassword`
   * `olcDbIndex`創建目錄，加速ldap server存取資料的速度
   * 載入`syncprov`模組，讓slave可以同步
    ```ldap
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess:  {0}to attrs=userPassword by self write by anonymous auth by * none
    -
    olcAccess: {0}to attrs=userPassword,shadowLastChange
      by self write
      by dn="cn=admin,dc=0516224,dc=nasa" write
      by dn="cn=Syncer,dc=0516224,dc=nasa" read
      by anonymous auth
      by * none
    -
    add: olcDbIndex
    olcDbIndex: entryUUID eq
    -
    add: olcDbIndex
    olcDbIndex: entryCSN eq
    -
    dn: cn=module{0},cn=config
    changetype: modify
    add: olcModuleLoad
    olcModuleLoad: {1}syncprov
    -
    dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
    changetype: add
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: {0}syncprov
    olcSpCheckpoint: 100 10
    olcSpSessionlog: 100
    ```
    :::warning
    :zap: 這邊要動到`config`，所以必須要以 `-D cn=config`身分來做`ldapmodify`
    後面會講如何更新`cn=config`的密碼
    :::
    > 加入ldap：
    > ```sh
    > sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f filename.ldif
    > ```

3. 在slave server
    * **你在master server加入的objectType、attributeType也都要加在slave server裡，上一部新增的`olcIndex`也要有。簡單來說就是兩者的設定盡量一致**
    * `olcSyncrepl`的參數定義可以參考[man slapd-config](https://manpages.courier-mta.org/htmlman5/slapd-config.5.html)。
    比較重要的有：
    `binddn`：要用什麼身分去同步(作業要求用`cn=Syncer`)
    `credentials`：`binddn`的密碼
    `interval`：slave去同步資料的間隔
    * `olcSuffix`：指定query的後綴(可以有多個，通常是baseDN)
    * `olcRootDN`：定義有superuser權限的root的Distingush Name
    * `olcRootPW`：`RootDN`的密碼
    ```ldap
    dn: cn=config
    changetype: modify
    replace: olcServerID
    olcServerID: 1
    
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    replace: olcSuffix
    olcSuffix: dc=0516224,dc=nasa
    -
    replace: olcRootDN
    olcRootDN: cn=admin,dc=0516224,dc=nasa
    -
    replace: olcRootPW
    olcRootPW: {SSHA}pQv7lj/3blpuf9QKhGiSvHoru8Y8kX8+
    -
    add: olcSyncrepl
    olcSyncrepl:
      rid=001
      provider=ldap://<master server ip>
      binddn="cn=admin,dc=0516224,dc=nasa"
      bindmethod=simple
      credentials="adminPasswd"
      searchbase="dc=0516224,dc=nasa"
      type=refreshOnly
      interval=00:00:01:00
      timeout=10
      network-timeout=10
      retry="60 +"
      schemachecking=on
      
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    add: olcMirrorMode
    olcMirrorMode: TRUE
    -
    add: olcDbIndex
    olcDbIndex: entryUUID eq
    -
    add: olcDbIndex
    olcDbIndex: entryCSN eq
    ```
    > 加入ldap：
    > ```sh
    > sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f filename.ldif
    > ```

**修改`cn=config`密碼**
```ldap
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: newPassword
```
```sh
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f <filename>.ldif
```
參考：[Unknown LDAP cn=config admin password](https://serverfault.com/questions/556629/unknown-ldap-cn-config-admin-password)

### Access Control
1. * 需要在到`/etc/ldap/slapd.d/cn=config/<a olcDataBase>`設定`olcAccess`
   * 這次作業要求`cn=Syncer,dc=base,dc=DN`只能被slave server讀到
   * 因為是設定在BaseDN下node，所以我們要調整
    `olcDatabase={1}mdb.ldif`

2. 寫好`modiAcl.ldif`
    範例：
    ```ldif
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {2}to dn.exact="cn=Syncer,dc=0516224,dc=nasa"
      by peername.ip=10.113.37.12 read
      by * none
    ```
    * `{2}`用於指定新加入的`olcAccess`是第幾順位
    * 詳細的格式請參考：[Openldap: Access Control](http://www.openldap.org/doc/admin24/access-control.html)


## Lab3 DNS
[Ubuntu Domain Name Service (DNS)](https://help.ubuntu.com/lts/serverguide/dns.html.en)

[簡介 DNSSEC (Introduction to DNS Security Extensions)](https://www.lijyyh.com/2012/07/dnssec-introduction-to-dnssec.html)
[SSHFP: Authenticate SSH Fingerprints via DNSSEC](https://blog.webernetz.net/sshfp-authenticate-ssh-fingerprints-via-dnssec/)

**設定檔**:
`/etc/bind/name.conf.local`：設定domain, zone, view etc.
`/etc/bind/name.conf.options`：設定global參數(ex.`recursion`, `allow-query`, `forward`)
[DNS BIND9 Query Statements(可用參數)](http://www.zytrax.com/books/dns/ch7/queries.html#allow-recursion)

**ACL(Access Control List)**
通常寫在設定檔最頂端，一定要在使用前宣告。
格式：
```
acl <acl name> {
    domain1;
    domain2;
    ...
    ...
};
```

### DNSSEC
[NSEC/NSEC3 Resource Records Format](https://docs.infoblox.com/pages/viewpage.action?pageId=3246079)
1. 請先看上面的連結熟悉一下DNSSEC
2. 利用`dnssec-keygen`產生KSK, ZSK

    ```shell=on
    format: dnssec-keygen -r <random device> -f KSK -a <alogorithm> -b <byte> -n <nametype> <zone name>
    KSK: dnssec-keygen -r /dev/urandom -f KSK -a RSASHA256 -b 2048 -n ZONE <stu-id>.nasa
    ZSK: dnssec-keygen -r /dev/urandom -a RSASHA256 -b 1024 -n ZONE <stu-id>.nasa
    ```
3. 將key引入你的zone file中。如果你的key有階層，請在最下面一層(引入其他zone file的zone file)操作。
    ```scirpt
    $INCLUDE /etc/bind/keys/K<stuid>.nasa.+008+<key id>.key    
    $INCLUDE /etc/bind/keys/K<stuid>.nasa.+008+<key id>.key
    ```
4. 利用`dnssec-signzone`將zone file加入DNSSEC資訊
    ```shell=on
    format: dnssec-signzone -o <zone name> -k <KSK_file> -d <dir storing dsset-> -g -3 <salt> <zone_file> <ZSK_file>
    dnssec-signzone -o 0516224.nasa. -k deskey/K0516224.nasa.+008+59749.key -d . -g -3 - db.0516224.nasa.any deskey/K0516224.nasa.+008+47943.key
    ```
    `-3 -`表示不加salt。

5. 限制`cn=Syncer,dc=0516224,dc=nasa`只能給slave server存取
    * `dn.exact`之類的意義請參考[man Access Control](http://www.openldap.org/doc/admin24/access-control.html)
    * 要注意olcAccess的優先序
    * `{index}`只是用來表示順序，也可以當alias使用
    ```ldap
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: to dn.exact="cn=Syncer,dc=0516224,dc=nasa"
      by peername.ip=<slave ip> read
      by * none
    ```

## Lab4 Postfix

:::danger
:warning: 中文教學雷包一堆，少看為妙。
:::

:::danger
:warning: 請注意此部分是晚一年的修課生寫的，spec內容不完全相同，照抄者風險自負
:warning: 另請注意本人做死使用的OS是mint，雖然是基於ubuntu開發的，但是還是有區別
:warning: 本廢物只有寫80分，關於dmarc dkim check policy跟spam detector完全沒動
:::

[ubuntu document: PreviousNext
Postfix](https://help.ubuntu.com/lts/serverguide/postfix.html.en)
[How to Set up SPF and DKIM with Postfix on Ubuntu Server](https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf)

本文下方使用的xed等同於ubuntu的gedit

1. 安裝postfix與其他必要套件
    
    ```shell=on
    sudo apt install postfix postgrey opendmarc opendkim postfix-policyd-spf-python
    sudo apt install dovecot-imapd dovecot-core
    ```
    postfix:     本次作業主角，所有寄信功能的處理
    dovecot:     用於協助postfix進行使用者驗證
    postgrey:    用於greylist新來的使用者
    opendmarc:   用於
    opendkim:    用公鑰/私鑰簽署寄出的信件，確保信件內容沒有被竄改
    spf:         用於辨識寄信來源的IP是否是寄件者網域的合法MX
    
    記得在router上打開到mx server的防火牆
    
2. DNS part: spf dmarc dkim mx record
    mx/spf record
    解釋一下spf在幹嘛
    ```
    v   spf version
    a   DNS server裡面有紀錄的A  record，前面的+號是指所有record
    mx  DNS server裡面有紀錄的MX record，前面的+號是指所有record
    all 代表以上的紀錄 
    ```
    all的地方比較複雜，單獨拉出來一塊
    ```shell=on
    - 代表除了以上有紀錄的機器以外皆為非法的寄件者 
    ~ 代表以上的有紀錄的機器為合法的寄件者，但可能有其他的寄件者未記錄
    ```
    ```shell=on
    @    IN    A        10.113.ID.IPAddrYouLike
    @    IN    MX   0   mail
    @    IN    TXT      "v=spf1 +a +mx -all"
    @    IN    SPF      "v=spf1 +a +mx -all"
    mail IN    TXT      "v=spf1 +a +mx -all"
    mail IN    SPF      "v=spf1 +a +mx -all"
    mail IN    A        10.113.13.IPAddrYouLike
    mail IN    MX   0   mail
    ```
    
    dmarc record
    ```shell=on
    _dmarc    IN    TXT    "v=DMARC1;p=reject"
    ```
    
    dkim record
    ```
    -D 是要在哪邊生成key file
    -d 是domain name
    -s 是selector 這邊使用default 你也可以用你喜歡的selector 只是記得後面要記得全部換掉
    ```
    ```shell=on
    sudo mkdir /etc/opendkim/keys
    sudo opendkim-genkey -D /etc/opendkim/keys/ -d studentID.nasa -s default
    sudo chown -R opendkim: /etc/opendkim/keys
    ```
    以上都完成之後會有default.private跟default.txt
    將default.txt的內容物全部丟進去zone file
    以上內容全部完工之後重新簽署dnssec
    ### dkim還未完工，後面繼續講
    
3. postfix setup
    `sudo xed /etc/postfix/main.cf`打開postfix主要設定檔案
    更改以下內容(自行去除大括號)
    ```shell=on
    myhostname = mail.{studentID}.nasa
    mydomain   = {studentID}.nasa
    myorigin   = $myhostname
    mynetworks = 127.0.0.0/8, 10.113.ID.0/24
    mydestination   = localhost$mydomain, localhost 
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    ```
    
    ### check config file
    `sudo postfix check`
    
    ### restart postfix
    `sudo systemctl restart postfix`
    
4. dovecot setup
    這邊首先設定dovecot要支援的protocol 這邊是imap跟lmtp
    `sudo xed /etc/dovecot/dovecot.conf`
    
    ```shell=on
    # Enable installed protocols
    !include_try /usr/share/dovecot/protocols.d/*.protocol
    protocols = imap lmtp
    ```
    設定dovecot要listen的地方
    ```shell=on
    listen = *, ::
    ```
    設定登入時自動在使用者名稱後面加上的domain(?)
    ```shell=on
    auth_default_realm = mail.{studentID}.nasa
    ```
    以下部分為optional 關於logging的部分 對於記錄從OJ來的log有幫助
    ```shell=on
    log_path = /var/log/dovecot.log
    info_log_path = /var/log/dovecot-info.log
    debug_log_path = /var/log/dovecot-debug.log
    auth_verbose = yes
    auth_verbose_passwords = yes
    auth_debug = yes
    mail_debug = yes
    ```
    
    `sudo xed /etc/dovecot/conf.d/10-auth.conf`
    這邊要特別注意的是，dovecot跟postfix的設定檔案如果遇到相同的參數，後者會直接overwrite
    
    例如我在第4行的地方輸入了`auth_mechanisms = plain login` 而後面又多打了 `auth_mechanisms = plain` 那麼最後套用的設定會是後者
    ```shell=on
    disable_plaintext_auth = no
    
    auth_mechanisms = plain login
    ```
    
    `sudo xed /etc/dovecot/conf.d/10-mail.conf`
    這邊設定寄進來的信件的存放位置 根據conf的註解表示
    ```
    %u    username
    %n    user part in user@domain
    %d    domain part in user@domain
    %h    home directory
    ```
    你各位也可以選擇自己想放的位置 資料夾的權限懶得動腦的話就開給所有人都能寫入
    ```shell=on
    mail_location = maildir:/var/mail/%d/%n
    ```
    
    `sudo xed /etc/dovecot/conf.d/10-master.conf`
    
    ```shell=on
    unix_listener /var/spool/postfix/private/auth {
        mode = 0666
        user = postfix
        group = postfix
    }
    ```
    
5. STARTTLS
    這邊首先生成self-signed certificate
    可以自己決定certificate要放在哪邊 建議放在 /etc/ssl 或是 /etc/postfix 下面
    ```shell=on
    sudo mkdir /etc/ssl/private
    chmod 700 /etc/ssl/private
    
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/studentID.key -out /etc/ssl/certs/studentID.crt

    ```
    `sudo xed /etc/postfix/main.cf`
    
    ```
    smtpd_use_tls = yes
    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_cert_file = /etc/ssl/certs/studentID.crt
    smtpd_tls_key_file = /etc/ssl/private/studentID.key
    ```
    
    `sudo xed /etc/postfix/master.cf`
    ```
    submission inet n       -       n       -       -       smtpd
        -o syslog_name=postfix/submission
        -o smtpd_tls_security_level = encrypt
        -o smtpd_sender_restrictions = $submission_sender_checks
    ```
    
    `sudo xed /etc/dovecot/conf.d/10-ssl.conf`
    ```shell=on
    ssl = yes
    ssl_cert = </etc/ssl/certs/studentID.crt
    ssl_key = </etc/ssl/private/studentID.key
    ssl_protocols = !SSLv2 !SSLv3

    ```
    
    設定完成後可用以下指令進行測試
    `openssl s_client -connect imap.example.com:25 -starttls smtp`
    `openssl s_client -connect imap.example.com:143 -starttls imap`
    在smtp的console輸入ehlo {somedomain} 之後應該會看到 250 auth plain
    
6. DKIM
    使用上面DNS record的key
    
    `sudo xed /etc/opendkim.conf`
    
    ```
    Mode                    sv
    Canonicalization        relaxed/simple
    Domain                  studentID.nasa
    Socket                  inet:8891@localhost
    Selector                default
    KeyTable				refile:/etc/opendkim/KeyTable        
    SigningTable			refile:/etc/opendkim/SigningTable    
    ExternalIgnoreList		refile:/etc/opendkim/TrustedHosts
    InternalHosts			refile:/etc/opendkim/TrustedHosts
    On-BadSignature         reject
    UnprotectedKey          none
    ```
    
    `sudo xed /etc/opendkim/KeyTable` 要用哪個key來簽署
    請注意此處的default是上面提及的selector 如果不是使用這個 selector 的話請記得換掉
    ```
    default._domainkey.studentID.nasa    studentID.nasa:default:/etc/opendkim/keys/default.private
    ```
    `sudo xed /etc/opendkim/SigningTable` 哪個domain要簽
    ```
    *@studentID.nasa    default._domainkey.studentID.nasa
    ```
    `sudo xed /etc/opendkim/TrustedHosts`
    ```
    localhost
    mail.studentID.nasa
    studentID.nasa
    ```
    
    將下列參數放進`main.cf`
    `sudo xed /etc/postfix/main.cf`
    ```
    smtpd_milters = inet:127.0.0.1:8891 #opendkim的socket
    non_smtpd_milters = $smtpd_milters
    milter_default_action = accept
    ```
    
7.  opendmarc
    `sudo xed /opendmarc.conf`
    ```
    AuthservID mail.studentID.nasa
    RejectFailures true
    Socket inet:8893@localhost
    TrustedAuthservIDs mail.studentID.nasa
    ```
    
    修改下列參數為`main.cf`
    ```
    smtpd_milters           = inet:127.0.0.1:8891, inet:127.0.0.1:8893
    ```
    
8.  Greylisting
    `sudo xed /etc/default/postgrey`
    ```
    POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=30"
    ```