LeeLin2602
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: NA, Network, NCTU --- # NA-hw3 Postfix [HW3 spec](https://nasa.cs.nctu.edu.tw/na/2021/slides/HW3.pdf) ## Create virtual machine ### mail server os: CentOS 8.3 username: cychen passwd: interfaces: 1. enp0s3: Intranet(get IP addr 10.113.40.30 from DHCP) 2. enp0s8: Host-Only(only for ssh) 設置主機名稱: ``` hostname mail.40.nasa ``` 修改 `/etc/hosts`: ``` 127.0.0.1 localhost 10.113.40.30 mail.40.nasa 10.113.40.30 mail ``` #### 新增使用者: ``` $ useradd -d -g mail -s /sbin/nologin ta $ useradd -d -g mail -s /sbin/nologin cool-ta ``` ``` $ passwd ta Enter New UNIX password: Retype New UNIX password: $ passwd cool-ta Enter New UNIX password: Retype New UNIX password: ``` ## DHCP Server Spec 有說明:You are required to redirect any DNS query within .nasa to this DNS server(10.113.0.254),但這句話講的非常的爛。 你在 judge 的時候要和 judge 機器互相送 mail 來測試,judge 機是 54.nasa,意味著你必須要能解析 54.nasa 這個 domain name 的 records,包括 A、MX、SPF⋯⋯,但依照 Hw2 的 DNS Server,你是沒辦法的。所以需要讓 DHCP 在告知你的電腦們 DNS Server 要是 10.113.0.254,之後你去查詢例如 40.nasa,他就會去遞迴的查詢,所以此時你在 Hw2 架設的 DNS Server 是作為 Authoritative DNS Server 用。 作法在 Hw2 有講過了。 ## DNS - Add MX Record 你必須要新增 MX record 來告訴別人信件應該要轉發給哪台主機: ``` @ IN MX 10 mail.40.nasa. ``` Spec 強迫我選擇讓它發給 mail.40.nasa. 這個主機,而這裡的 10 意味著 Priority,此值越低表示有越高優先度。接下來我必須要讓 mail.40.nasa 指向到我的 Mail Server: ``` mail IN A 10.113.40.30 ``` ## Mail Server - Postfix 和 Dovecot Postfix 負責信件轉發、收件的服務,就是 Mail Server(MTA),負責 SMTP。 Dovecot 專門負責給使用者查詢信件的服務,也就是 Mail Receive Agent(MRA),負責 IMAP。 而在這裡 Dovecot 擔任的角色比 MRA 多一點,就是 Postfix 可以直接使用 Dovecot 的認證模塊。SASL(簡單認證與安全層)的設計把認證機制從程式中分離開,所以我們可以把 Postfix 的認證部分交給其他程式來做,這邊因為 Dovecot 本來就必須要對使用者進行認證才能讓他們檢索郵件,所以就一石二鳥,讓 Postfix 使用 Dovecot 的認證機制。 :::danger 所以 Debug 的時候如果發現 SMTP 無法登入,可能是 Dovecot 爛了。 ::: ### 防火牆設定: 你必須允許 SMTP 所需要的 25 port 和 IMAP 所需要的 143 port 先關掉 SELINUX,由於在 Hw2 被他坑了之後,我現在都會先關閉 SELINUX: ``` vim /etc/selinux/config ``` ``` SELINUX=disabled ``` 再關閉防火牆: ``` systemctl disable firewalld.service systemctl stop firewalld.service ``` ### Postfix 的安裝、設定: ``` $ dnf install postfix ``` :::info dnf(Dandified Yum),顧名思義就是拿來取代 yum 的,是一套效能比較好的套件管理程式,把他當作 yum 的升級版就好。 ::: ``` $ vim /etc/postfix/main.cf ``` 修改下面項(在 main.cf 對應項的附近都有比較詳細的參數的參數介紹): ``` myhostname = mail.40.nasa mydomain = 40.nasa myorigin = $mydomain inet_interfaces = all inet_protocols = all mydestination = $myhostname, $mydomain, localhost mynetworks = 10.113.40.0/24, 127.0.0.0/8 ``` 添加到開機啟動項以及啟動它: ``` systemctl enable postfix systemctl restart postfix ``` ### Dovecot 的安裝: ``` dnf install dovecot ``` 讓 Dovecot 為 Postfix SMTP 做 Auth: ``` vim /etc/dovecot/conf.d/10-master.conf ``` ``` unix_listener auth-userdb { #mode = 0666 #user = #group = } # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0666 } ``` 為認證機制做設定: ``` vim /etc/dovecot/conf.d/10-auth.conf ``` ``` auth_mechanisms = plain login ``` 允許 IMAP 登入: ``` vim /etc/dovecot/dovecot.conf ``` ``` protocols = imap ``` 還要設置讓 Dovecot 能有讀取 MailBox 的權限: ``` mail_location = mbox:~/mail:INBOX=/var/mail/%u mail_access_groups=mail ``` :::info plain 在登入的時候會把帳號和密碼依照特定格式組合成一行,再做 base64 一併傳送。 login 則會在登入的時候分開傳遞帳號的 base64 編碼 和密碼的 base64 編碼。 這邊同時允許這兩種認證方式,實際上大同小異。 [詳見 REF](https://www.samlogic.net/articles/smtp-commands-reference-auth.htm) ::: ### 讓 Postfix 使用 Dovecot 做 Auth ``` vim /etc/postfix/main.cf ``` 添加如下: ``` # Dovecot Auth smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous ``` ### 設定 Mailbox 的讀寫權限 ``` chmod 600 /var/mail/* ``` 給 Dovecot 讀取 Mailbox 的權限 ``` vim /etc/dovecot/conf.d/10-mail.conf ``` ``` mail_location = mbox:~/mail:INBOX=/var/mail/%u mail_privileged_group = mail ``` 添加到開機啟動項以及啟動它: ``` systemctl enable dovecot systemctl restart dovecot ``` ### SSL 設定 首先你要會如何使用 openssl 生成私鑰和憑證: ``` openssl req -newkey rsa:2048 -nodes -sha512 -x509 -days 365 -nodes -out public_cert.pem -keyout private_key.pem ``` 這邊的參數都很簡單: ```rsa:2048```:RSA 演算法,金鑰長度為 2048 bits。 ```sha512```:選定雜湊演算法來產生憑證。 ```nodes```:代表使用時不需要輸入密碼 ```x509```:使用 X.509 這個公鑰憑證的格式標準。 #### Postfix SSL 設定:STARTTLS ``` vim /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 = 私鑰位置 smtpd_tls_cert_file = 憑證位置 smtpd_tls_loglevel = 1 ``` #### Dovecot SSL 設定 ``` vim /etc/dovecot/conf.d/10-ssl.conf ``` ``` ssl = yes ssl_cert = <證書位置 ssl_key = <私鑰位置 ``` :::warning 這個 < 是必要的,我猜測他的意思是在程式啟動的時候從這兩個位置直接讀檔進來。 ::: ### 測試 SMTP 寄件和 IMAP 收件 由於有些資料是用 Base64 編碼傳遞的,所以要先知道怎麼編碼解碼 ``` $ echo -n "ta" | base64 dGE= $ echo -n "dGE=" | base64 -d ta ``` :::danger 這個 -n 代表 echo 不要換行,如果換行了,你的 base64 後的結果就會錯掉(多一個 \n 會被加進去編碼內) ``` $ echo "ta" | base64 | base64 -d | wc -c 3 echo -n "ta" | base64 | base64 -d | wc -c 2 ``` ```wc -c```:計算輸入了多少個字符。 ::: #### 用 telnet 測試 SMTP: ##### 登入 ``` $ telnet mail.40.nasa 25 220 mail.40.nasa ESMTP Postfix EHLO mail.40.nasa 250-mail.40.nasa 250-PIPELINING 250-SIZE 102400000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-DSN 250-SMTPUTF8 250 CHUNKING AUTH LOGIN 334 VXNlcm5hbWU6 dGE= 334 UGFzc3dvcmQ6 K0JIeFd2NUFxM0xxSjcranNuYkIyTFJUMzVZTmNYZEs2QUJXcVJLaGNtOD0= 235 2.7.0 Authentication successful ``` ```EHLO mail.40.nasa```:ECHO HELLO,和伺服器說 HELLO 以及你是哪位。 他回傳了: ``` 250-mail.40.nasa 250-PIPELINING 250-SIZE 102400000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-DSN 250-SMTPUTF8 250 CHUNKING ``` ```AUTH LOGIN```:告訴他說我現在要登入,然後使用 LOGIN 這種機制,意味著我要分開打帳號與密碼。 伺服器回傳:```334 VXNlcm5hbWU6```,```VXNlcm5hbWU6``` 用 Base64 解碼後是用戶名稱的意思,所以輸入 Base64 後的用戶名稱。 ```334 UGFzc3dvcmQ6``` 告訴我們輸入密碼。 分開輸入後,就得到結果:```235 2.7.0 Authentication successful```。 ##### 寄信 ``` MAIL FROM: ta@40.nasa 250 2.1.0 Ok RCPT TO: cychen@40.nasa 250 2.1.5 Ok DATA 354 End data with <CR><LF>.<CR><LF> This is a test mail. . 250 2.0.0 Ok: queued as 6C7B610DA8E4 ``` ```MAIL FROM: ta@40.nasa```:寄件者是 `ta@40.nasa`。 ```RCPT TO: cychen@40.nasa```:收件者是 `cychen@40.nasa`。 ```DATA```:接下來開始是信件內容。 ```.```:單獨一行 `.` 代表資料結束了。 ```quit```:請求結束連線。 #### 用 telnet 測試 IMAP: ##### 實際使用 ``` $ telnet mail.40.nasa 143 * OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ STARTTLS AUTH=PLAIN AUTH=LOGIN] Dovecot ready. A01 login ta <plaintext-password> A01 OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY LITERAL+ NOTIFY SPECIAL-USE] Logged in A02 list "" * * LIST (\HasNoChildren) "/" INBOX A02 OK List completed (0.004 + 0.000 + 0.003 secs). A03 SELECT INBOX * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted. * 32 EXISTS * 29 RECENT * OK [UNSEEN 1] First unseen. * OK [UIDVALIDITY 1620023446] UIDs valid * OK [UIDNEXT 33] Predicted next UID A04 SEARCH ALL * SEARCH 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 A04 OK Search completed (0.002 + 0.000 + 0.001 secs). A05 FETCH 32 FULL * 32 FETCH (FLAGS (\Recent) INTERNALDATE "04-May-2021 17:12:49 -0400" RFC822.SIZE 1828 ENVELOPE ("Tue, 4 May 2021 17:12:30 -0400 (EDT)" {6} 陽交 ((NIL NIL "ta" "40.nasa")) ((NIL NIL "ta" "40.nasa")) ((NIL NIL "ta" "40.nasa")) NIL NIL NIL NIL "<20210504211234.339FB10DA8E4@mail.40.nasa>") BODY ("text" "plain" ("charset" "us-ascii") NIL NIL "7bit" 0 0)) A05 OK Fetch completed (0.101 + 0.000 + 0.100 secs). A06 LOGOUT ``` ##### 純指令: ``` A01 LOGIN ta +BHxWv5Aq3LqJ7+jsnbB2LRT35YNcXdK6ABWqRKhcm8= A02 LIST "" * A03 SELECT INBOX A04 SEARCH ALL A05 FETCH 32 FULL A06 LOGOUT ``` ##### 指令格式: ``` COMMAND_NAME COMMAND PARAMETER1, ... ``` ##### 指令列表: ```LOGIN NAME PASSWORD```:登入某使用者。 ```LIST "" *```:列出所有收件箱。 ```SELECT INBOX```:選擇收件箱 `INBOX`。 ```SEARCH ALL```:列出所有信件。 ```FETCH 32 FULL```:下載第 32 號信全部。 ```LOGOUT```:登出。 #### 用 openssl 測試 SSL 連線: ``` $ openssl s_client -connect mail.{ID}.nasa:25 -starttls smtp $ openssl s_client -connect mail.{ID}.nasa:143 -starttls imap ``` 建立連線後和 telnet 中的使用方式相同,openssl 會幫你加密解密。 ## SPF、DKIM 和 DMARC 先知道 SPF、DKIM 和 DMARC 是什麼: [為郵件系統安全把關,新增 SPF, DKIM 和 DMARC 設定以避免有心人士的釣魚攻擊](https://www.richesinfo.com.tw/index.php/mxmail/mxmail-faq/267-dkim-dmarc)。 這邊設定 **Outgoing Mails** 的 Policy,如果設爛了你的信會被當垃圾信。 :::info 這邊基本上完全參考 [某一篇文章](https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf) [另一篇文章](https://blog.tiger-workshop.com/ubuntu-postfix-mail-server-mta-outgoing-spf-dkim-rdns-dmarc/) 他們寫的很好,如果設定不起來可以去看他的。我僅針對 Spec 做了一些調整。 ::: ### Mail Server - 安裝、配置 OpenDKIM OpenDKIM 是一隻很方便的程式,他可以幫我們: 1. 產生 DKIM Record 2. 簽署 Outgoing Mail 3. 檢查 Incoming Mails 的 DKIM(後面再設) 安裝 OpenDKIM: ``` dnf install opendkim opendkim-tools ``` 給予 OpenDKIM 的程式權限: ``` gpasswd -a postfix opendkim ``` 配置 OpenDKIM ``` vim /etc/opendkim.conf ``` ``` # Selects operating modes -> s (sign) and v (verify) Mode sv UserID opendkim:opendkim Socket inet:8891@localhost Domain 40.nasa KeyTable /etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts ``` 這兩個文件 `KeyTable`、`SigningTable` 是用來管理你對不同 Domain 的 DKIM 資料。 我現在要針對 `40.nasa` 和 `mail.40.nasa` 這兩個 domain name 來生 DKIM 的 Records 和 Key: ``` $ mkdir /etc/opendkim/keys/mail.40.nasa $ cd /etc/opendkim/keys/mail.40.nasa $ opendkim-genkey -t -s mail -d mail.40.nasa $ mkdir /etc/opendkim/keys/40.nasa $ cd /etc/opendkim/keys/40.nasa $ opendkim-genkey -t -s mail -d 40.nasa ``` 設定 Permissions: ``` chown -R opendkim:opendkim /etc/opendkim ``` 修改(若不存在則新增)`/etc/opendkim/KeyTable`: ``` mail._domainkey.40.nasa 40.nasa:mail:/etc/opendkim/keys/40.nasa/mail.private mail._domainkey.mail.40.nasa mail.40.nasa:mail:/etc/opendkim/keys/mail.40.nasa/mail.private ``` :::warning 這裡的 mail 必須要和上面 `opendkim-genkey` 的 `-s mail` 的參數相同。 ::: 修改(若不存在則新增)`/etc/opendkim/SigningTable`: ``` 40.nasa mail._domainkey.40.nasa mail.40.nasa mail._domainkey.mail.40.nasa ``` 啟動並且加入開機啟動項: ``` systemctl start opendkim systemctl enable opendkim ``` ### Mail Server - 讓 OpenDKIM 為 Postfix 的信件做簽名 ``` vim /etc/postfix/main.cf ``` ``` # milter configuration milter_default_action = accept milter_protocol = 6 smtpd_milters = inet:localhost:8891 non_smtpd_milters = $smtpd_milters # DKIM: inet:localhost:8891 ``` ### DNS - SPF Policy 在 DNS Server 增加此兩條 Records: ``` @ IN TXT "v=spf1 a mx ipv4:10.113.40.30 -all" mail IN TXT "v=spf1 a mx ipv4:10.113.40.30 -all" ``` 意思就是允許我這個 domain name 的 a records、mx records 和 10.113.40.30 這個IP 使用這個 domain name 來寄信,其他全部 REJECT。 ### DNS - DKIM Records ``` $ cat /etc/opendkim/keys/*/*.txt ``` 會得到 ``` mail._domainkey IN TXT ( "v=DKIM1; k=rsa; t=y; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBaohjhJh73YFC6EE9gzPH6MvkFTltrf4ZLs/22AO3Lhhphr18VLeaBxbWdHMDXmfovqDnMIm0jME30c3AG+cuo50vWFWiLUBXY3GTaiRTVxi2LwVSkUZCdHgTR9nFyY9PXG/h4QwINCRHN1wEnorUqBrGBImTpeDbxXi16bVELQIDAQAB" ) ; ----- DKIM key mail for 40.nasa mail._domainkey IN TXT ( "v=DKIM1; k=rsa; t=y; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzQ+eVqmFI+KBsCaCqqmWDQiyu7RDumA2/7M966tE/iMTKHaZvnyidQAueoVuTad0K812PU9iRqSMvBFpk1Mcz4Lz7YXeQ2Y5UhqSMl3jiJhpRw1Ccr4LZIpeM0spMBAdePDjLUefAQ6nxQS5SIynmafnNPYUzheyevbdM81RyzQIDAQAB" ) ; ----- DKIM key mail for mail.40.nasa ``` 我們要修改其中 `mail.40.nasa` 的 DKIM Key Record,滑到行末可以看到,在這裡是下面那一筆。 我們要改成這樣:mail.\_domainkey.mail,因為是 mail.40.nasa 底下的,原因是因為我們並未額外 mail.40.nasa 寫一個 zonefile。 :::danger 沒改你會爛掉。 ::: 所以最後變成這樣,放到 DNS Server 上就好了: ``` mail._domainkey IN TXT ( "v=DKIM1; k=rsa; t=y; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBaohjhJh73YFC6EE9gzPH6MvkFTltrf4ZLs/22AO3Lhhphr18VLeaBxbWdHMDXmfovqDnMIm0jME30c3AG+cuo50vWFWiLUBXY3GTaiRTVxi2LwVSkUZCdHgTR9nFyY9PXG/h4QwINCRHN1wEnorUqBrGBImTpeDbxXi16bVELQIDAQAB" ) ; ----- DKIM key mail for 40.nasa mail._domainkey.mail IN TXT ( "v=DKIM1; k=rsa; t=y; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzQ+eVqmFI+KBsCaCqqmWDQiyu7RDumA2/7M966tE/iMTKHaZvnyidQAueoVuTad0K812PU9iRqSMvBFpk1Mcz4Lz7YXeQ2Y5UhqSMl3jiJhpRw1Ccr4LZIpeM0spMBAdePDjLUefAQ6nxQS5SIynmafnNPYUzheyevbdM81RyzQIDAQAB" ) ; ----- DKIM key mail for mail.40.nasa ``` ### DNS - DMARC Policy DMARC 就是看如果 SPF 或 DKIM 的檢查 REJECT 掉一封信之後,收到這封信的郵件伺服器應該做什麼事情,按照 spec,直接 DROP 掉就好。 ``` _dmarc IN TXT "v=DMARC1; p=reject" _dmarc.mail IN TXT "v=DMARC1; p=reject" ``` ### 測試 OpenDKIM 是否有成功的為 Postfix 寄出的郵件簽名 重啟 OpenDKIM 和 Postfix 後,寄一封信給自己,然後查看(可直接用 ```cat /var/mail/user``` 來看): ``` From ta@40.nasa Tue May 4 17:12:49 2021 Return-Path: <ta@40.nasa> X-Original-To: cychen@40.nasa Delivered-To: cychen@40.nasa Received: from localhost (localhost [127.0.0.1]) by mail.40.nasa (Postfix) with ESMTP id 9703C10DA8E5 for <cychen@40.nasa>; Tue, 4 May 2021 17:12:49 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.40.nasa 9703C10DA8E5 Authentication-Results: mail.40.nasa; dkim=pass (1024-bit key; unprotected) header.d=40.nasa header.i=@40.nasa header.a=rsa-sha256 header.s=mail header.b=Sgq3za4h X-Virus-Scanned: amavisd-new at 40.nasa X-Amavis-Alert: BAD HEADER SECTION, MIME error: error: unexpected end of header X-Spam-Flag: NO X-Spam-Score: 2.093 X-Spam-Level: ** X-Spam-Status: No, score=2.093 tagged_above=2 required=6.2 tests=[ALL_TRUSTED=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FSL_BULK_SIG=0.001, MISSING_HEADERS=1.207, PYZOR_CHECK=1.985] autolearn=no autolearn_force=no Received: from mail.40.nasa ([127.0.0.1]) by localhost (mail.40.nasa [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vol_chT6ODyA for <cychen@40.nasa>; Tue, 4 May 2021 17:12:46 -0400 (EDT) Received: from mail.40.nasa (localhost [IPv6:::1]) by mail.40.nasa (Postfix) with ESMTPA id 339FB10DA8E4 for <cychen@40.nasa>; Tue, 4 May 2021 17:12:30 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.40.nasa 339FB10DA8E4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=40.nasa; s=mail; t=1620162766; bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=; h=Subject:Date:From:From; b=Sgq3za4hDGbMAnlX44D+NUoQVB4Oxulw3BAvWgEbyVwlt8IEz7sOfGOceOPyvTNn3 /A+IoF0BXYQJUL2uPn6ysPMHdSkH1Wa5bcoKqx/dsxYRdCwk4xtUiTGYf8oL8JOc5V GVOpdnAtEKFi7bEaYVUvvqRfaGjQJF3l1J/93Rqs= Subject: 陽交 Message-Id: <20210504211234.339FB10DA8E4@mail.40.nasa> Date: Tue, 4 May 2021 17:12:30 -0400 (EDT) From: ta@40.nasa X-UID: 32 Status: O ``` 發現的確是有 DKIM-Signature 這個 header field 的,有成功簽名。 ## 進階的 Postfix 設定 ### 防止冒名發信(avoid fake user) 修改 `/etc/postfix/main.cf`: ``` smtpd_sender_login_maps = regexp:/etc/postfix/sender_login_map smtpd_sender_restrictions = ... reject_sender_login_mismatch ... ``` :::warning 這邊 `smtpd_sender_restrictions` 的 `...` 只是讓你保留原有的資料,不要真的加 `...`。 ::: 修改(若不存在新增)`/etc/postfix/sender_login_map`: ``` /^(.+)@(mail\.)?40\.nasa$/ $1 ``` 這個意思就是: 對於所有符合 `/^(.+)@(mail\.)?40\.nasa$/` 這個 regex pattern 的使用者,我把這個使用者視為 `$1`,而這個 `$1` 就是第一個括號,也就是 `$(.+)$` 所匹配到的內容。 :::info `.` 在 regex 中代表任意字符,而 `+` 代表前面一個 pattern 出現 1 次及以上。所以 `(.)+` 就是一個可以匹配任意非空字串的正則。 ::: ### 防止 Null 使用者(avoid mail from: <Empty>) 我們修改 `/etc/postfix/main.cf`: ``` smtpd_sender_restrictions = ... check_sender_access hash:/etc/postfix/sender_check ... ``` 接著修改 `/etc/postfix/sender_check`: ``` <> REJECT null users are not allowed ``` 之後執行指令將文字檔變成資料庫: ``` postmap /etc/postfix/sender_check ``` ### 防止 Open Relay 設置 `/etc/postfix/main.cf`: ``` smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination smtpd_sender_restrictions = ... reject_non_fqdn_sender reject_unknown_sender_domain ... ``` ### Virtual alias 設置 `/etc/postfix/main.cf`: ``` virtual_alias_maps = hash:/etc/postfix/virtual regexp:/etc/postfix/virtual.regexp ``` 為 ```/etc/postfix/virtual``` 追加一行: ```NASATA TA``` 為 ```/etc/postfix/virtual.regexp``` 追加一行:```/^.+\|([^@]+)@(.+)$/ $1@$2``` ``` postmap /etc/postfix/virtual ``` ### Sender rewrite 設置 `/etc/postfix/main.cf`: ``` local_header_rewrite_clients = permit_mynetworks permit_sasl_authenticated sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps ``` 追加 `/etc/postfix/sender_canonical_maps` 兩行: ``` /cool-ta@(mail.)?40.nasa/ notcool-TA@40.nasa /(.+)@(mail.)?40.nasa/ $1@40.nasa ``` ## SPF、DKIM 和 DMARC 的 Incoming Check [參考資料](https://www.linuxbabe.com/redhat/opendmarc-postfix-centos-rhel) 安裝 `opendmarc`: ```dnf install opendmarc``` 修改 `/etc/postfix/main.cf`: ``` # Milter configuration milter_default_action = accept milter_protocol = 6 smtpd_milters = ... inet:127.0.0.1:8893 ``` 設定 `/etc/opendmarc.conf`: ``` Socket inet:8893@localhost SoftwareHeader true SPFIgnoreResults true SPFSelfValidate true Syslog true UMask 777 UserID opendmarc:mail TrustedAuthservIDs mail.40.nasa RejectFailures true RequiredHeaders false IgnoreAuthenticatedClients true ``` 開啟並加入開機啟動項: ``` systemctl enable opendmarc systemctl start opendmarc ``` ## Anti Spam Mail ### Greylisting Greylisting 假設正常信都是由 Mail Server 寄出, 所以它們都有著重寄的機制。故此機制會先將信件資料記錄後,拒絕收信,期待對方 mail server 重寄此信才要接受它。因為如果用腳本大量發送垃圾信件時,額外儲存被退件的並等一點時間之後再去寄件是不符合成本的,所以在廣發垃圾信的時候,最大收益將不會是重新寄信。因此 Greylisting 能起到不錯的防垃圾信的功效。 安裝 `portgrey`: ```dnf install postgrey``` 設定 `portgrey` 的灰名單時間: ``` vim /etc/sysconfig/postgrey ``` ``` POSTGREY_OPTS="--delay=30" ``` 為 greylist 添加 whitelist: ``` vim /etc/postfix/postgrey_whitelist_clients.local ``` ``` 40.nasa mail.40.nasa ``` 修改 `/etc/postfix/main.cf`: ``` smtpd_recipient_restrictions = ... check_policy_service unix:postgrey/socket ... ``` 重啟 postgrey 並加入啟動項: ``` systemctl enable postgrey systemctl restart postgrey ``` ### Spam Filtering and Virus Detection 這裡使用了另外兩個工具:`clamav`、`amavis` ``` dnf install install clamav clamav-update amavisd-new clamav-scanner-systemd ``` :::danger 安裝完後需要重新啟動,否則可能會有奇怪的問題。 ::: ``` sed -i -e "s/^Example/#Example/" /etc/freshclam.conf freshclam ``` :::info 實務考量可能要設個 cronjob,定期 `freshclam` 來更新資料庫。 ::: 編輯 `/etc/amavisd/amavisd.conf`: ``` $mydomain = '40.nasa'; $myhostname = 'mail.40.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 *** ' ]; ``` 這邊的 `D_PASS` 代表當他偵測到某個事項之後要做的事情,spec 要求我們讓他過,但是要在標題加一個 "*** SPAM ***"。 可以用這個指令檢查 amavisd 的設定檔: ``` amavisd -u amavis -c /etc/amavisd/amavisd.conf debug ``` 而後編輯 `/etc/postfix/main.cf`: ``` content_filter=amavis:127.0.0.1:10024 ``` 再修改 `/etc/postfix/master.cf` 追加此內容: ``` 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 ``` 啟用並且添加到開機啟動項: ``` systemctl enable clamd@amavisd amavisd spamassassin systemctl restart clamd@amavisd amavisd spamassassin postfix ``` :::danger 如果你有開啟 SELINUX,可能需要先執行: ``` setsebool -P antivirus_can_scan_system 1 setsebool -P clamd_use_jit on ``` ::: ### Outgoing Mail Filter 編輯 `/etc/postfix/main.cf`: ``` header_checks = regexp:/etc/postfix/header_checks ``` 修改 `/etc/postfix/header_checks`: ``` /^Subject:.*陽交.*/ REJECT /^Subject:.*=?UTF-8?B?6Zm95Lqk?=.*/ REJECT /^Subject:.*6Zm95Lqk.*/ REJECT /^Subject:.*NCTU.*/ REJECT ``` [參考資料](http://adminkk.blogspot.com/2014/01/postfixheadercheckscheck-httpwww.html) ## Debug 1. 如果這些東西裝不起來,你可能要加入 [milter-manager_repos](https://milter-manager.osdn.jp/reference/install-to-centos.html) 和 [EPEL_repo](https://www.tecmint.com/install-epel-repository-on-centos/)。 2. clamd@amavisd :::danger 我原本是用 clamd@scanner 來做,但後來失敗了,我改用 amavisd。 但 clamd 一次僅能使用一種服務,所以我很理所當然的 disable/stop 了 scanner,又 enable/start 了 amavisd,但這還沒完。 你還必須要修改:`/usr/lib/systemd/system/clamd\@amavisd.service`: ``` [Service] ExecStart = /usr/sbin/clamd -c /etc/clamd.d/amavisd.conf ``` 這個垃圾 Bug 坑了我好久的時間= =。 [參考資料](https://serverfault.com/questions/842589/error-with-clamd-amavisd-centos-7) :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully