返回文章列表

Linux 建立私有憑證授權中心

本文詳細說明如何在 Linux 系統上使用 OpenSSL 建立私有的憑證授權中心(CA),包含建立根憑證、簽署憑證請求、保護 CA 基礎設施等步驟,並提供相關程式碼範例和安全建議,適用於需要在內部網路建立安全憑證管理機制的工程師。

資安 系統管理

在 Linux 環境下,建立私有憑證授權中心(CA)對於內部網路安全至關重要。OpenSSL 提供了建立和管理 PKI 的必要工具,讓工程師可以自行產生根憑證、下屬 CA,並簽署憑證請求。本文將逐步示範使用 OpenSSL 建立 CA 的過程,包含設定目錄結構、初始化序號和索引檔、編輯 OpenSSL 設定檔等步驟,並提供建立自簽名根憑證的程式碼範例。此外,文章也涵蓋了請求和簽署憑證簽署請求(CSR)的流程,以及如何保護 CA 基礎設施的安全,包括傳統建議和現代虛擬化環境下的安全策略。

在Linux上建立憑證服務

現在我們已經瞭解憑證的工作原理,接下來讓我們在Linux上建立一個私有的憑證授權中心(CA)。我們將會使用幾種不同的方法來達成這一點,以便為您提供在自己的組織中可選擇的方案。我們也會在下一章(第9章:Linux上的RADIUS服務)中使用CA,因此這些範例非常重要,請仔細跟隨。

建立私有的憑證授權中心

建立私有的CA首先需要決定使用哪個CA套件。與許多伺服器解決方案一樣,有多種選擇。以下是一些選項:

  • OpenSSL提供了所有必要的工具來撰寫自己的指令碼並維護公鑰基礎設施(PKI)的目錄結構。您可以建立根CA和下屬CA,產生憑證簽署請求(CSR),然後簽署這些憑證以產生真實的憑證。然而,這種方法通常被認為太過手動。
  • Certificate Manager是Red Hat Linux和相關發行版中附帶的CA。
  • openSUSE和相關發行版可以使用原生的YaST組態和管理工具作為CA。
  • Easy-RSA是一套指令碼,基本上是對OpenSSL命令的封裝。
  • Smallstep實作了更多的自動化,可以組態為私有的ACME伺服器,並可以輕鬆地允許客戶端請求和履行自己的憑證。
  • Boulder是一個根據ACME的CA,發布在Let’s Encrypt的GitHub頁面上,用Go語言編寫。

如您所見,有相當多的CA套件可供選擇。大多數較舊的套件都是對各種OpenSSL命令的封裝。較新的套件具有額外的自動化功能,特別是在ACME協定方面,該協定由Let’s Encrypt開創。

使用OpenSSL建立CA

由於我們只使用幾乎所有Linux發行版中都包含的命令,因此在使用此方法建立CA之前,無需安裝任何東西。

步驟1:建立CA的位置

首先,我們將為CA建立一個位置。/etc/ssl目錄應該已經存在於您的主機檔案結構中,我們將在其中新增兩個新的目錄:

$ sudo mkdir /etc/ssl/CA
$ sudo mkdir /etc/ssl/newcerts

步驟2:初始化序號和索引檔案

接下來,請記住,當憑證被頒發時,CA需要跟蹤序號(通常是順序的),以及每個憑證的一些詳細資訊。讓我們從一個serial檔案開始,序號從1開始,並建立一個空的索引檔案以進一步跟蹤憑證:

$ sudo sh -c "echo '01' > /etc/ssl/CA/serial"
$ sudo touch /etc/ssl/CA/index.txt

注意在建立serial檔案時使用的sudo語法。這是因為如果您只是在echo命令前面加上sudo,您就沒有在/etc目錄下的許可權。這種語法的作用是啟動一個臨時的sh shell,並將引號中的字元串傳遞給-c引數執行。這相當於執行sudo shsu,執行命令,然後離開迴歸常規使用者上下文。然而,使用sudo sh -c比這些其他方法更可取,因為它消除了保持root上下文的誘惑。保持root上下文會帶來各種機會,讓您無意中永久更改系統上的內容——從意外刪除重要檔案(只有root有權存取),到錯誤地安裝惡意軟體,或允許勒索軟體或其他惡意軟體以root身份執行。

步驟3:編輯OpenSSL組態檔案

接下來,我們將編輯現有的/etc/ssl/openssl.cnf組態檔案,並導航到[CA_default]部分。該部分在預設檔案中如下所示:

[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
x509_extensions = usr_cert # The extensions to add to the cert

我們將更新該部分中的以下行:

dir = /etc/ssl # Where everything is kept
database = $dir/CA/index.txt # database index file.
certificate = $dir/certs/cacert.pem # The CA certificate
serial = $dir/CA/serial # The current serial number
private_key = $dir/private/cakey.pem# The private key

無需更改private_key行,但請務必在編輯檔案時檢查其正確性。

步驟4:建立自簽名的根憑證

接下來,我們將建立一個自簽名的根憑證。這對於私有的CA根是正常的。(在公共CA中,您將建立一個新的CSR,並讓其由另一個CA簽署,以提供連結到受信任的根。)


#### 內容解密:
1. 這段程式碼主要是在設定OpenSSL的組態,以建立私有的CA。首先,我們需要建立必要的目錄結構,包括`/etc/ssl/CA``/etc/ssl/newcerts`2. 初始化序號和索引檔案,分別是`/etc/ssl/CA/serial``/etc/ssl/CA/index.txt`,用於跟蹤頒發的憑證。
3. 編輯OpenSSL組態檔案`/etc/ssl/openssl.cnf`,更新`[CA_default]`部分中的路徑和檔案名稱,以符合我們的CA設定。
4. 最後,建立自簽名的根憑證,這是私有的CA根的正常做法。

建立私有憑證授權中心(Certificate Authority)

在組織內部建立私有 CA 時,通常會選擇較長的生命週期,以避免頻繁重建整個 CA 基礎設施。讓我們選擇 10 年(3650 天)作為範例。請注意,此命令會要求輸入密碼(請勿遺失!)以及識別憑證的其他資訊。

建立私有 CA 金鑰與根憑證

$ openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650
Generating a RSA private key
...............+++++
.................................................+++++
writing new private key to 'cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
---
--
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
---
--
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:ON
Locality Name (eg, city) []:MyCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Coherent Security
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:ca01.coherentsecurity.com
Email Address []:

內容解密:

  1. openssl req -new -x509:此命令用於建立新的憑證請求並輸出自簽名的根憑證。
  2. -extensions v3_ca:指定使用 OpenSSL 組態檔案中的 v3_ca 擴充套件,確保生成的根憑證符合 CA 標準。
  3. -keyout cakey.pem:將生成的私鑰輸出到 cakey.pem 檔案中。
  4. -out cacert.pem:將生成的根憑證輸出到 cacert.pem 檔案中。
  5. -days 3650:設定根憑證的有效期為 10 年。

移動 CA 金鑰與根憑證到正確位置

sudo mv cakey.pem /etc/ssl/private/
sudo mv cacert.pem /etc/ssl/certs/

內容解密:

  1. 使用 sudo 命令以管理員許可權執行移動操作。
  2. 將私鑰 cakey.pem 移至 /etc/ssl/private/ 目錄,確保私鑰的安全性。
  3. 將根憑證 cacert.pem 移至 /etc/ssl/certs/ 目錄,使其可供系統使用。

請求與簽署憑證簽署請求(CSR)

建立測試 CSR

首先,在同一個範例主機上建立一個測試 CSR。先建立此憑證的私鑰:

$ openssl genrsa -des3 -out server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................................+++++
........................+++++
e is 65537 (0x010001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

內容解密:

  1. openssl genrsa:生成 RSA 私鑰。
  2. -des3:使用 DES-EDE3 加密私鑰。
  3. -out server.key:將私鑰輸出到 server.key 檔案中。
  4. 2048:指定私鑰的位數為 2048 位。

移除私鑰密碼(可選)

對於某些服務,可能需要無密碼的私鑰:

$ openssl rsa -in server.key -out server.key.insecure
Enter pass phrase for server.key:
writing RSA key
$ mv server.key server.key.secure
$ mv server.key.insecure server.key

內容解密:

  1. openssl rsa -in server.key -out server.key.insecure:移除私鑰的密碼保護。
  2. 將原始有密碼的私鑰重新命名為 server.key.secure,將無密碼的私鑰命名為 server.key

建立 CSR

~$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
---
--
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:ON
Locality Name (eg, city) []:MyCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Coherent Security
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:www.coherentsecurity.com
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:passphrase
An optional company name []:

內容解密:

  1. openssl req -new:建立新的憑證請求。
  2. -key server.key:使用指定的私鑰檔案。
  3. -out server.csr:將 CSR 輸出到 server.csr 檔案中。

簽署 CSR

在憑證伺服器上,執行以下命令簽署 CSR:

$ sudo openssl ca -in server.csr -config /etc/ssl/openssl.cnf

內容解密:

  1. openssl ca:用於簽署 CSR 的命令。
  2. -in server.csr:輸入 CSR 檔案。
  3. -config /etc/ssl/openssl.cnf:指定 OpenSSL 組態檔案。

簽署完成後,新的憑證將儲存在 /etc/ssl/newcerts/01.pem

檢視簽署結果

$ ls /etc/ssl/newcerts/
01.pem
$ cat /etc/ssl/CA/index.txt
V 220415165738Z 01 unknown /C=CA/ST=ON/O=Coherent Security/OU=IT/CN=www.coherentsecurity.com
$ cat /etc/ssl/CA/serial
02

內容解密:

  1. /etc/ssl/newcerts/01.pem:新簽署的憑證檔案。
  2. /etc/ssl/CA/index.txt:包含已簽署憑證的詳細資訊。
  3. /etc/ssl/CA/serial:下一個可用序號,用於後續簽署請求。

保護憑證授權機構(CA)基礎架構的安全

保護組織的憑證基礎架構(Certificate Authority, CA)是至關重要的。隨著虛擬化技術在大多數資料中心的普及,這為簡化和保護CA基礎架構提供了額外的機會。

傳統建議

傳統上,保護組織憑證基礎架構的建議利用了CA僅在頒發憑證時才會被使用的事實。如果能夠很好地管理何時需要新憑證,可以簡單地在不需要時關閉CA伺服器。

如果需要更多的彈性,可以建立一個層次化的憑證基礎架構。首先建立一個根CA,其唯一任務是簽署用於建立下屬CA(或多個下屬CA)的憑證。然後,這些下屬CA用於建立所有客戶端和伺服器憑證。根CA可以關閉或離線存放,除了進行補丁更新外。

對於特別關注CA安全的組織,可以使用特殊用途的硬體,如硬體安全模組(HSM),來離線儲存CA的私鑰和憑證,通常存放在保險箱或其他安全的異地位置。商業HSM的例子包括Nitrokey HSM和YubiHSM。NetHSM是一個開源HSM的良好範例。

現代建議

上述建議在現代基礎架構中仍然100%有效。伺服器虛擬化是現代基礎架構中的新要素,它有助於保護CA。在大多數環境中,由於虛擬機器的備份方式,每個伺服器都有一個或多個映像備份儲存在本地磁碟上。因此,如果主機因惡意軟體(通常是勒索軟體)或嚴重的組態錯誤而損壞,可以在5分鐘內將整個伺服器還原到前一晚的映像,或者在最壞的情況下,還原到兩晚前的映像。

這種還原方式所丟失的只是那些在丟失的時間間隔內頒發的憑證相關的伺服器資料。參照TLS會話協商的過程,這些伺服器資料實際上從未用於建立會話。這意味著伺服器還原到過去某一時間點並不會影響使用頒發的憑證進行加密(或驗證)協商的客戶端或伺服器。

小型環境

在小型環境中,根據具體情況,可以輕鬆地使用單一CA伺服器來保護基礎架構的安全——只需保留映像備份,以便在需要時可以在幾分鐘內還原到位元組級別的映像。

大型環境

在大型環境中,採用層次化模型仍然是有意義的——例如,這可以使合併和收購變得更加容易。層次化模型有助於將基礎架構維護為一個單一的組織,同時簡化了將多個業務單位的CA置於單一主CA下的過程。可以使用根據作業系統(OS)的安全措施來限制惡意軟體事件的影響範圍,或者在日常營運中限制不同業務單位之間的憑證管理許可權。

CA特定風險

在現代基礎架構中,CA伺服器面臨的一個主要風險與其傳統使用方式有關。在某些環境中,憑證可能很少被需要。如果只保留一週的伺服器映像備份,但需要一個月(或幾個月)才能意識到所應用的指令碼或補丁已經摧毀了CA伺服器,那麼從備份中還原將變得非常困難。隨著憑證使用變得更加普遍(如在無線客戶端認證中),以及自動化的憑證頒發解決方案(如Certbot和ACME協定)的出現,這種情況得到了改善。這些技術,尤其是結合使用,使得CA的使用變得更加頻繁,以至於如果CA伺服器執行不正常,情況很可能會在幾個小時或幾天內升級,而不是幾周或幾個月。

風險管理

給CA伺服器命名時,應避免使用容易被誤解的名字。例如,使用ORGNAME-CA01這樣的名字,雖然對管理員來說很明顯,但對於其他人(如經理、程式設計師或臨時工)來說可能並不明顯。因此,在虛擬化基礎架構中,CA虛擬機器可能會被意外刪除。為了避免這種情況,可以在建立新的CA虛擬機器時,使用類別似ORGNAME-CA01 – 請勿刪除,聯絡RV這樣的名稱,其中RV代表擁有該伺服器的管理員的姓名首字母縮寫。

程式碼範例:虛擬機器命名指令碼

#!/bin/bash
# 為新的CA虛擬機器產生名稱
ORGNAME="範例組織"
CA_NAME="${ORGNAME}-CA01 – 請勿刪除,聯絡RV"
echo "新的CA虛擬機器名稱:${CA_NAME}"

內容解密:

  1. ORGNAME變數定義了組織的名稱,用於生成CA虛擬機器的名稱。
  2. CA_NAME變數結合了組織名稱和其他重要資訊,生成最終的虛擬機器名稱。
  3. 指令碼輸出新的CA虛擬機器名稱,以便管理員使用。

這種做法可以提高CA伺服器的可見性和安全性,從而減少意外刪除或組態錯誤的風險。透過結合傳統的最佳實踐和現代虛擬化技術,可以有效地保護組織的憑證基礎架構。