Mysql

強制 Postfix 使用 TLS 進行 MySQL 連接?

  • February 20, 2018

問題

我不知道如何強制 Postfix 使用與 MySQL 的 TLS 連接。我可以使用 TLS 作為 postfix 使用者從 Postfix 伺服器手動連接到 MySQL 伺服器,因此 MySQL 身份驗證沒有任何問題。問題很明顯:Postfix 沒有為 MySQL 連接請求 TLS。

版本:

  • 作業系統:CentOS 7
  • 後綴:2:2.10.1-6.el7 和 2:3.2.4-1.gf.el7
  • MySQL (MariaDB):5.5.56

我是怎麼來的

我一直在整個網路上搜尋,包括各種 StackExchange 站點,以尋找這個問題的答案。我已經反复閱讀了大量的 Postfix 和 MySQL 文件。我找到的最好的答案是我拒絕的一個不必要的複雜:“在你的 Postfix 和 MySQL 伺服器之間建立一個 SSH 隧道,然後通過它連接。 ”必須有一種方法來指示 Postfix 使用 TLS (SSL) 加密與 MySQL 客戶端。

在我們探索設置之前,讓我確定一下: 我的郵件伺服器設置在沒有 MySQL TLS 的情況下執行良好。我成功地將 TLS 用於 SMTPS 和 IMAPS,這與我的問題無關。除了 Postfix 和 MySQL 伺服器之間的 MySQL 連接未加密外,郵件正在安全地進出我的網路。除了暴露的 Postfix-MySQL 連結外,我的郵件基礎設施沒有任何問題。

然而,由於不斷變化的安全要求,我必須更新我現有的基礎設施來加密所有 MySQL 連接。為 MySQL 連接設置 TLS 很簡單。 手動測試表明 MySQL 客戶端可以通過 TLS 加密的連結從所有允許的主機成功連接。因此,MySQL TLS 設置也很可靠,適用於除 Postfix 之外的所有內容。

我試過的

Postfix Server上的相關配置:

/etc/postfix/main.cf 減少到只是幾個連接之一,以保持材料盡可能具體。

virtual_alias_maps = proxy:mysql:/etc/postfix/lookup_aliases.cf
proxy_read_maps = $virtual_alias_maps

/etc/postfix/lookup_aliases.cf 憑證和主機名被混淆。

hosts = mysql-server.domain.tld
user = postfix
password = *****
dbname = mail
option_file = /etc/my.cnf.d/client.cnf
option_group = client
tls_verify_cert = yes
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'

/etc/my.cnf 此文件未動。我包含它只是為了表明下一個配置文件已正確包含在 MySQL 客戶端配置中。

!includedir /etc/my.cnf.d

/etc/my.cnf.d/client.cnf

[client]
ssl = true

成功 – 手動 – 從 Postfix 伺服器作為 postfix 使用者輸出 MySQL TLS 連接

請特別注意 TLS 已成功使用:

# hostname -f
mail.domain.tld

# sudo -u postfix mysql -h mysql-server.domain.tld -u postfix -p mail
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 72
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [mail]> \s
--------------
mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:     72
Current database:  mail
Current user:      postfix@mail.domain.tld
SSL:           Cipher in use is DHE-RSA-AES256-GCM-SHA384
Current pager:     stdout
Using outfile:     ''
Using delimiter:   ;
Server:            MariaDB
Server version:        5.5.56-MariaDB MariaDB Server
Protocol version:  10
Connection:        mysql-server.domain.tld via TCP/IP
Server characterset:   latin1
Db     characterset:   utf8
Client characterset:   utf8
Conn.  characterset:   utf8
TCP port:      3306
Uptime:            1 hour 27 min 23 sec

Threads: 1  Questions: 271  Slow queries: 0  Opens: 13  Flush tables: 2  Open tables: 39  Queries per second avg: 0.051
--------------

MariaDB [mail]> \q
Bye

MySQL伺服器上的相關配置:

MySQL 贈款

請注意,TLS(SSL)是必需的,但在我解決這個 TLS 連接問題之前,權限相對寬鬆:

MariaDB [(none)]> SHOW GRANTS FOR 'postfix'@'10.0.101.%';
+-----------------------------------------------------------------------------------------------------+
| Grants for postfix@10.0.101.%                                                                       |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'postfix'@'10.0.101.%' IDENTIFIED BY PASSWORD '*SOMEPASSWORDHASH' REQUIRE SSL |
| GRANT SELECT ON `mail`.* TO 'postfix'@'10.0.101.%'                                                  |
+-----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

日誌

當 REQUIRE SSL 時 Postfix 連接失敗 即使這裡 MySQL TLS 連接的手動命令行測試成功,Postfix 仍然不會使用 MySQL TLS。

MySQL 正常日誌:

180217 14:45:15       16 Connect   postfix@mail.domain.tld as anonymous on mail
     16 Connect   Access denied for user 'postfix'@'mail.domain.tld' (using password: YES)

後綴日誌:

Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: proxy:mysql:/etc/postfix/lookup_aliases.cf lookup error for "root@mail.domain.tld"
Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: E2CCA2069823: virtual_alias_maps map lookup problem for root@mail.domain.tld -- message not accepted, try again later

刪除 REQUIRE SSL 後,後綴連接成功 這是 Postfix 在將權限從 REQUIRE SSL 更改為 REQUIRE NONE 後成功連接。但是,連接未加密

180217 15:17:21       26 Connect   postfix@mail.domain.tld as anonymous on mail
         26 Query show databases
         26 Query show tables
         26 Field List    admin
         26 Field List    alias
         26 Field List    alias_domain
         26 Field List    config
         26 Field List    domain
         26 Field List    domain_admins
         26 Field List    fetchmail
         26 Field List    log
         26 Field List    mailbox
         26 Field List    quota
         26 Field List    quota2
         26 Field List    vacation
         26 Field List    vacation_notification
         26 Query select @@version_comment limit 1

結論

我所需要的只是讓 Postfix 尊重ssl = true其 MySQL 客戶端連接。如果您需要任何進一步的資訊,請告訴我。

更新:

發布此問題後,我通過更仔細的閱讀發現,2.11 之前的 Postfix 版本根本不支持讀取 MySQL 配置文件。因此,不可能將供應商提供的 Postfix 版本(2.10 版)配置為使用 MySQL TLS。我覺得 Postfix 文件中的措辭選擇不佳,其中MySQL 配置的 Postfix 文件的上半部分如下:

Postfix 3.1 and earlier don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

作者沒有說明:

These options are ignored for Postfix 2.10 and earlier.  Postfix 2.11 through 3.1 don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

因此,我將 CentOS 7 上的 Postfix 從供應商提供的 2.10 版升級到GhettoForge Plus 提供的3.2 版。我確實安裝了附加postfix3-mysql軟體包。我寄予厚望,但這些都破滅了。現在,即使使用 Postfix 3.2,它仍然無法通過 TLS 連結連接到 MySQL

我都嘗試過option_file = /etc/my.cnf(應該是預設的和不必要的)option_file = /etc/my.cnf.d/client.cnf但無濟於事。

我什至試圖通過添加tls_verify_cert = yes. 這也沒有效果。請注意,證書名稱確實匹配,因此如果實際嘗試過,此驗證將通過。

概要

為了從 Postfix 建立 MySQL TLS 連接,您需要:

  1. Postfix 2.11 或更新版本。CentOS 7 只提供Postfix 版本 2.10。您必須通過非 CentOS 方式獲得 Postfix 的升級。我選擇使用GhettoForge Pluspostfix3的和postfix3-mysql軟體包,因為它似乎受到 CentOS 社區的大力推薦

  2. 在您的mysql_table配置文件中設置:

  3. 至少一種允許的tls_ciphers設置;

  4. 客戶端 TLS 證書及其匹配的私鑰,由 MySQL 伺服器和 Postfix 客戶端通用的證書頒發機構簽名;或者

  5. 兩個都。

  6. 不要依賴在 /etc/my.cnf 或 /etc/my.cnf.d/ 文件中設置這些!* Postfix MySQL 程式碼不會讀取這些文件來確定是否建立 MySQL TLS 連接;他們被解析得太晚了。促使 Postfix 打開 MySQL TLS 連接的唯一mysql_table方法是在配置文件中指定 TLS 設置。時期。

我是怎麼來的

我終於求助於閱讀 Postfix 3.2 原始碼。src/global/dict_mysql.c 的第 653-658 行特別有用。

最終解決方案

如果要模擬 的行為ssl = true,只需在mysql_table配置文件中添加類似於以下內容的行:

tls_ciphers = TLSv1.2

我們的配置要求只使用 TLS 1.2——並且早已在我們的 MySQL 伺服器的配置中強制執行,所以我並沒有自動想到在客戶端上也強制執行它——但是您可以自由添加其他如果您的組織允許使用較舊的密碼,則使用密碼。

請注意,我們很高興不使用客戶端證書。我們使用其他方式來保護和主動監控我們的數據庫連接;我們只是不想要額外的複雜性。

替代解決方案

如果您希望強制僅已知的、受信任的客戶端連接到您的 MySQL 伺服器——而您不能通過其他策略強制機制(如嚴格的防火牆、嚴格的密碼複雜性、密碼輪換週期性、連接審計等)來做到這一點——那麼您可以還可以通過mysql_table配置文件中的這些附加設置使用客戶端證書:

tls_key_file = /path/to/private.key
tls_cert_file = /path/to/public.certificate
tls_CAfile = /path/to/common.CA.certificate # OR tls_CApath = /path/to/CA-and-intermediate-chain-certificates/

同樣,在 /etc/my.cnf 或 /etc/my.cnf.d/* 中設置這些也無濟於事直到已經確定了連接類型(TLS 或非 TLS)之後,才會解析這些文件。

如果您選擇使用客戶端證書,請在伺服器上強制執行它們!當您只想加密 MySQL 流量時,您不需要客戶端證書**;相反,只需使用tls_ciphers上面的替代方法。添加客戶端證書使 MySQL 能夠驗證連接的客戶端是否已知且受信任,但前提是您告訴 MySQL 如何這樣做**!它不會猜測並且僅依賴於客戶端和伺服器之間存在的公共 CA 只是這個強大工具的部分實現。如果您對這個 MySQL 安全模型感興趣,我發現至少有一個How To guide 提供瞭如何使用客戶端證書驗證的好例子

引用自:https://serverfault.com/questions/897693