1. 程式人生 > 其它 >OpenSSL安裝配置詳解

OpenSSL安裝配置詳解

轉載:http://www.jinbuguo.com/linux/openssl_install.html

OpenSSL 安裝與配置

作者:金步國


版權宣告

本文作者是一位開源理念的堅定支持者,所以本文雖然不是軟體,但是遵照開源的精神釋出。

  • 無擔保:本文作者不保證作品內容準確無誤,亦不承擔任何由於使用此文件所導致的損失。
  • 自由使用:任何人都可以自由的閱讀/連結/列印此文件,無需任何附加條件。
  • 名譽權:任何人都可以自由的轉載/引用/再創作此文件,但必須保留作者署名並註明出處。

其他作品

本文作者十分願意與他人分享勞動成果,如果你對我的其他翻譯作品或者技術文章有興趣,可以在如下位置檢視現有的作品集:

聯絡方式

由於作者水平有限,因此不能保證作品內容準確無誤。如果你發現了作品中的錯誤(哪怕是錯別字也好),請來信指出,任何提高作品質量的建議我都將虛心接納。

  • Email(QQ):70171448在QQ郵箱

系統需求

OpenSSL可以在多種作業系統上安裝,但是本文只討論 OpenSSL-0.9.8g 在Linux或BSD系統上的安裝。

安裝OpenSSL的系統需求很低,只要有 ANSI C 編譯器(推薦GCC)、Perl 5 、make 即可。但是OpenSSL的測試程式依賴於GNU BC,如果你需要執行測試程式的話,就要事先安裝好它。

配置

將下載回來的壓縮包解壓,進入解壓後的目錄,即可使用 config 或 Configure 指令碼進行配置。OpenSSL的配置指令碼與大多數典型的軟體包不同,它有自己的一套規則。詳細的安裝資訊位於原始碼樹下的 INSTALL Configure(特別是"PROCESS_ARGS"段) Makefile.shared Makefile.org 檔案中。安裝後的使用與配置資訊位於 doc 目錄中, FAQ 檔案也可以提供一些參考。

config 指令碼檢查系統環境並呼叫 Configure 完成配置,因此配置選項是通過 config 指令碼向 Configure 傳遞的。事實上 config 指令碼的作用相當於 config.guess ,所以如果你想直接呼叫 Configure 的話就一定要正確指定"作業系統-目標平臺"(筆者推薦這個用法)。所有可用的目標機器列表可以使用"./Configure LIST"命令獲取。Configure 指令碼除了根據 Makefile.org 生成 Makefile 之外,還在 crypto/opensslconf.h 中定義了許多巨集(基於 crypto/opensslconf.h.in)。

在 config 或 Configure 命令列上可以使用許多選項,大體上可以分為3類。

全域性選項

第一類是全域性性選項:

--openssldir=OPENSSLDIR
安裝目錄,預設是 /usr/local/ssl 。
--prefix=PREFIX
設定 lib include bin 目錄的字首,預設為 OPENSSLDIR 目錄。
--install_prefix=DESTDIR
設定安裝時以此目錄作為"根"目錄,通常用於打包,預設為空。
zlib
zlib-dynamic
no-zlib
使用靜態的zlib壓縮庫、使用動態的zlib壓縮庫、不使用zlib壓縮功能。
threads
no-threads
是否編譯支援多執行緒的庫。預設支援。
shared
no-shared
是否生成動態連線庫。
asm
no-asm
是否在編譯過程中使用匯編程式碼加快編譯過程。
enable-sse2
no-sse2
啟用/禁用SSE2指令集加速。如果你的CPU支援SSE2指令集,就可以開啟,否則就要關閉。
gmp
no-gmp
啟用/禁用GMP庫
rfc3779
no-rfc3779
啟用/禁用實現X509v3證書的IP地址擴充套件
krb5
no-krb5
啟用/禁用 Kerberos 5 支援
ssl
no-ssl
ssl2
ssl3
no-ssl2
no-ssl3
tls
no-tls
啟用/禁用 SSL(包含了SSL2/SSL3) TLS 協議支援。
dso
no-dso
啟用/禁用呼叫其它動態連結庫的功能。[提示]no-dso僅在no-shared的前提下可用。

[提示]為了安裝Apache-2.2的mod_ssl成功,SSLv2/SSLv3/TLS都必須開啟。

演算法選項

第二類用於禁用crypto目錄下相應的子目錄(主要是各種演算法)。雖然理論上這些子目錄都可以通過"no-*"語法禁用,但是實際上,為了能夠最小安裝libcrypto,libssl,openssl,其中的大部分目錄都必須保留,實際可選的目錄僅有如下這些:

no-md2,no-md4,no-mdc2,no-ripemd
這些都是摘要演算法,含義一目瞭然。
no-des,no-rc2,no-rc4,no-rc5,no-idea,no-bf,no-cast,no-camellia
這些都是對稱加密演算法,含義一目瞭然。"bf"是"Blowfish"的意思。
no-ec,no-dsa,no-ecdsa,no-dh,no-ecdh
這些都是不對稱加密演算法,含義一目瞭然。
no-comp
資料壓縮演算法。因為目前實際上並沒有壓縮演算法,所以只是定義了一些空介面。
no-store
物件儲存功能。更多細節可以檢視 crypto/store/README 檔案。

[提示]OpenSSH 只依賴於該軟體包的加密庫(libcrypto),而帶有 HTTPS 支援的 Apache 則依賴於該軟體包的加密庫和 SSL/TLS 庫(libssl)。因此,如果你不打算使用 HTTPS 的話,可以只安裝加密庫(no-ssl no-tls);更多介紹可以檢視 README 檔案的"OVERVIEW"部分。事實上,為了能夠讓OpenSSH安裝成功,ripemd,des,rc4,bf,cast,dsa,dh目錄不能被禁止。

編譯選項

大多數軟體包都是通過在執行 configure 指令碼的時候定義 CPPFLAGS CFLAGS LDFLAGS 環境變數來設定編譯選項的,但是OpenSSL卻不是這樣的。

OpenSSL的 Configure 指令碼允許你在命令列上直接輸入 CPPFLAGS CFLAGS 的內容。比如:-DDEVRANDOM='"/dev/urandom"' 可以用來指定隨機裝置, -DSSL_FORBID_ENULL 則可以用於禁止使用NULL加密演算法。`echo $CFLAGS` 則可以將 CFLAGS 變數新增上來。

另一方面,LDFLAGS卻是無法通過Configure進行設定的。因為Configure會強制清空Makefile中的LDFLAGS,所以在執行完Configure之後,可以使用一個sed修改所有Makefile中的 LDFLAGS(用於連線openssl)和SHARED_LDFLAGS(用於連線libcrypto,libssl庫)。

比如筆者就經常這樣使用 Configure 進行配置:

./Configure ... -DSSL_FORBID_ENULL -DDEVRANDOM='"/dev/urandom"' `echo $CFLAGS`
find . -name "Makefile*" -exec sed -r -i -e"s|^(SHARED_)?LDFLAGS=|& $LDFLAGS |" {} \;

[提示]不能省略find命令內"Makefile*"兩邊的引號。

編譯、測試、安裝

配置完畢後,需要使用 make depend 重新建立依賴關係,特別是你使用了"no-*"選項之後,否則編譯可能會失敗。

然後使用 make 命令編譯。如果編譯成功,那麼最好使用 make test 進行一下測試。

如果測試也通過了,那麼接下來就是安裝和配置了。安裝很簡單,一條 make install 命令即可。你還可以使用 make install INSTALL_PREFIX=/other/dir 來將 /other/dir 當作"根"進行安裝,這通常用於打包。

配置

安裝完畢之後,接下來就是配置。OpenSSL的配置檔案是 openssl.cnf ,位於 --openssldir 指定的目錄下。

在實踐中,OpenSSL 的一個重要用途就是證書籤發和管理,這需要配置檔案的配合。如果你只是使用它的加密庫,而不使用證書功能的話,就不需要了解如果配置OpenSSL 。

下面是一個簡單的 openssl.cnf 檔案,已經可以用於證書籤發了。當然,這份配置用來自己玩玩還行,別指望用這個去做真正的"Big Brother" :)

###############################
# OpenSSL-1.1.1g 配置檔案示範 #
###############################
# [注意]這個示範檔案的內容並不是預設設定。
# [來源] man 5 config , man 1 req , man 1 ca , man 5 x509v3_config
# 最新版本  https://github.com/openssl/openssl/blob/master/apps/openssl.cnf
# 此檔案的預設位置(RedHat系=/etc/pki/tls/openssl.cnf)(Debian系=/etc/ssl/openssl.cnf)
# 要指定其他位置,可以在 openssl 命令列上使用 -config 選項、也可以使用 OPENSSL_CONF 環境變數

########
# 語法 #
########
#
# 變數 = 值
#
# 語法很簡單,一看就懂,但是有幾點需要說明:
# 1. 字串值最好使用雙引號界定,並且其中可以使用"\n","\r","\t","\\"這些轉義序列。
# 2. 可以使用 ${變數名} 的形式引用同一欄位中的變數,使用 ${欄位名::變數名} 的形式引用其它欄位中的變數。
# 3. 可以使用 ${ENV::環境變數} 的形式引用作業系統中定義的環境變數,若變數不存在則會導致錯誤。
# 4. 可以在預設欄位定義與作業系統環境變數同名的變數作為預設值來避免環境變數不存在導致的錯誤。
# 5. 如果在同一欄位內有多個相同名稱的變數,那麼後面的值將覆蓋前面的值。
# 6. 可以通過 ".include = 絕對路徑" 語法或 OPENSSL_CONF_INCLUDE 環境變數引入其他配置檔案(*.cnf)。

############
# 預設欄位 #
############
#[ default ]
# 此部分是預設欄位,必須放在所有欄位之前。小節頭"[default]"是可選的。
# 讀取配置檔案時,會首先根據欄位名稱去尋找相應的配置段,如果沒有找到則會使用這裡的預設欄位。

# 定義 HOME 的預設值,防止作業系統中不存在 HOME 環境變數。
HOME = /tmp

# 預設的隨機數種子檔案,對應 -rand 命令列選項。
RANDFILE = /dev/random

# 擴充套件物件定義
# 如果沒有在 OpenSSL 命令列中定義X.509證書的擴充套件項,那麼就會從下面對擴充套件物件的定義中獲取。
# 定義方法有兩種,第一種(反對使用)是儲存在外部檔案中,也就是這裡"oid_file"變數定義的檔案。
#oid_file = ${ENV::HOME}/.oid
# 第二種是儲存在配置檔案的一個欄位中,也就是這裡"oid_section"變數值所指定的欄位。
oid_section = new_oids

# 要將此配置檔案用於 "openssl x509" 命令的 "-extfile" 選項,
# 請在此指定包含 X.509v3 擴充套件的小節名稱
#extensions =
# 或者使用一個預設欄位中僅包含 X.509v3 擴充套件的配置檔案

[ new_oids ]
# 新增可以被 'ca', 'req', 'ts' 命令使用的擴充套件物件。格式如下:
# 物件簡稱 = 物件數字ID
# 下面是一些增強型金鑰用法(extendedKeyUsage)的例子

# 任何目的(一次性包含所有增強用法)
anyExtendedUsage = 2.5.29.37.0
# 伺服器身份驗證
serverAuth = 1.3.6.1.5.5.7.3.1
# 客戶端身份驗證
clientAuth = 1.3.6.1.5.5.7.3.2
# 程式碼簽名
codeSigning = 1.3.6.1.5.5.7.3.3
# 安全電子郵件
emailProtection = 1.3.6.1.5.5.7.3.4
# IPSec 終端系統
ipsecEndSystem = 1.3.6.1.5.5.7.3.5
# IPSec 隧道
ipsecTunnel = 1.3.6.1.5.5.7.3.6
# IPSec 使用者
ipsecUser = 1.3.6.1.5.5.7.3.7
# 時間戳
timeStamping = 1.3.6.1.5.5.7.3.8
# OCSP 簽名
OCSPSigning = 1.3.6.1.5.5.7.3.9
# IPSec 金鑰交換
ipsecIKE = 1.3.6.1.5.5.7.3.17
# 微軟個人程式碼簽名
msCodeInd = 1.3.6.1.4.1.311.2.1.21
# 微軟商業程式碼簽名
msCodeCom = 1.3.6.1.4.1.311.2.1.22
# 微軟信任列表簽名
msCTLSign = 1.3.6.1.4.1.311.10.3.1
# 微軟加密檔案系統
msEFS = 1.3.6.1.4.1.311.10.3.4

####################
##  證書請求配置  ##
####################
# 在申請證書之前通常需要首先生成符合 PKCS#10 標準的證書請求。
# openssl 的 req 命令實現了產生證書請求的功能,其相關選項的預設值就來自於這裡的設定。
# 證書請求的配置涉及多個欄位,包括一個基本欄位(req)和幾個附屬欄位。

##### 證書請求配置的"基本欄位",其它附屬欄位都以它為入口 #####
[ req ]

# 讀取輸入金鑰檔案時的口令,如果未設定那麼將會提示輸入。對應 -passin 命令列選項。
#input_password = secret
# 儲存輸出金鑰檔案時的口令,如果未設定那麼將會提示輸入。對應 -passout 命令列選項。
#output_password = secret

# 生成的證書中RSA金鑰的預設長度,取值是2的整數次方。建議不小於2048。對應 -newkey 命令列選項。
default_bits = 2048

# 儲存生成的金鑰檔案的預設檔名。對應 -keyout 命令列選項。
default_keyfile = privkey.pem

# 生成的金鑰檔案是否採用口令保護,可設為yes或no(對應 -nodes 命令列選項)。
encrypt_key = yes

# 簽名預設使用的資訊摘要演算法,所有 dgst 命令都可以使用(sha256, sha3-256, sha512, sha3-512, ...)
# 此處的設定相當於在命令列上使用 -sha256 選項(對應於"-digest")。
default_md = sha256

# 為一些欄位設定預設的字串型別,比如證書請求中的城市和組織名稱。可能的取值和解釋如下:
# default: 包含了 PrintableString, T61String, BMPString 三種類型
# pkix  : 包含了 PrintableString, BMPString 兩種型別
# utf8only: 只使用 UTF8 字串。推薦使用這個,這樣可以完美的包含任意字元。
# nombstr : 包含了 PrintableString, T61String 兩種型別
string_mask = utf8only

# 證書請求擴充套件的欄位名,該擴充套件欄位定義了要加入到證書請求中的一系列 X.509v3 擴充套件項。
# 對應 -reqexts 命令列選項。
req_extensions = v3_req

# 生成自簽名根證書時要使用的證書擴充套件項欄位名,該擴充套件欄位定義了要加入到根證書中的一系列 X.509v3 擴充套件項。
# 對應 -extensions 命令列選項。
x509_extensions = v3_ca

# 如果設為no,那麼 req 指令將直接從配置檔案中讀取證書欄位的資訊,而不是提示使用者輸入。
prompt = yes

# 如果設為yes,那麼命令列與配置檔案中的字串都將按照UTF-8編碼看待。預設值no表示僅使用ASCII編碼。
# 對應 -utf8 命令列選項。
utf8 = yes

# 定義證書請求屬性的欄位名,該擴充套件欄位定義了證書請求的一些屬性,但openssl的證書籤發工具並不使用它們。
#attributes = req_attributes

# 定義輸入使用者資訊選項的"特徵名稱"欄位名,該擴充套件欄位定義了多項使用者資訊。
distinguished_name = req_distinguished_name

##### 要加入到證書請求中的一系列 X.509v3 擴充套件項,對應 -addext 命令列選項 #####
[ v3_req ]

# 基本約束(該證書是否為CA證書)。"CA:FALSE"表示非CA證書(不能簽發其他證書的"葉子證書")。
basicConstraints = CA:FALSE

# 金鑰用法:防否認(nonRepudiation)、數字簽名(digitalSignature)、金鑰加密(keyEncipherment)。
# 金鑰協商(keyAgreement)、資料加密(dataEncipherment)、僅加密(encipherOnly)、僅解密(decipherOnly)
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# 增強型金鑰用法(參見"new_oids"欄位):伺服器身份驗證、客戶端身份驗證、時間戳。
extendedKeyUsage = critical, serverAuth, clientAuth, timeStamping

# 使用者備用名稱(email, URI, DNS, RID, IP, dirName)
# 例如,DNS常用於實現泛域名證書、IP常用於繫結特定的IP地址、"copy"表示直接複製
#subjectAltName = DNS:www.example.com, DNS:example.com, DNS:*.example.net, IP:192.168.7.1, IP:13::17, email:copy

# OCSP必須裝訂(OCSP Must-Staple)
1.3.6.1.5.5.7.1.24 = DER:30:03:02:01:05
# 如果是使用openssl 1.1.0或更高的版本,可以這樣設定:
tlsfeature = status_request

#### 生成自簽名證書(RootCA)時使用的 X.509v3 證書擴充套件項,對應 -addext 命令列選項 #####
[ v3_ca ]

# 基本約束(該證書是否為CA證書)。"CA:TRUE"表示是CA證書(可簽發其他證書)。
# "pathlen:N"字尾表示允許簽發下級CA證書的深度("0"表示禁止簽發下級CA證書),"critical"表示關鍵擴充套件。
# 例如"critical,CA:TRUE, pathlen:0"表示禁止簽發下級CA證書(僅能簽發"葉子證書")。
basicConstraints = critical,CA:TRUE

# 金鑰用法:證書撤銷列表簽名(cRLSign)、證書籤發(keyCertSign)、數字簽名(digitalSignature)
keyUsage = cRLSign, keyCertSign, digitalSignature

# 增強型金鑰用法(參見"new_oids"欄位):OCSP 簽名
extendedKeyUsage = OCSPSigning

# 使用者金鑰識別符號(根據RFC3280規範自動生成)
subjectKeyIdentifier = hash

# 頒發機構金鑰識別符號("always"表示始終包含)
authorityKeyIdentifier = keyid:always,issuer

# 跳過 OCSP 檢查
noCheck = ignored

##### "特徵名稱"欄位包含了使用者的標識資訊,對應 -subj 命令列選項 #####
[ req_distinguished_name ]
countryName = CN  #必須是兩字母國家程式碼
stateOrProvinceName = 省份或直轄市
localityName = 城市
organizationName = 組織名或公司名
organizationalUnitName = 部門名稱
commonName = 全限定域名或個人姓名
emailAddress = Email地址

####################
##  證書籤發配置  ##
####################
# openssl 的 ca 命令實現了證書籤發的功能,其相關選項的預設值就來自於這裡的設定。
# 這個欄位只是通過唯一的 default_ca 變數來指定預設CA主配置欄位的入口(-name 命令列選項的預設值)
[ ca ]
default_ca = CA_default

##### 預設CA主配置欄位,(★)標記表示必需項 #####
[ CA_default ]

# 儲存所有資訊的資料夾,這個變數只是為了給後面的變數使用
dir = /etc/pki/CA

#(★)存放新簽發證書的預設目錄,證書名就是該證書的系列號,字尾是.pem 。對應 -outdir 命令列選項。
new_certs_dir = $dir/newcerts

#(★)存放CA自身證書的檔名。對應 -cert 命令列選項。
certificate = $dir/cacert.pem

#(★)存放CA自身私鑰的檔名。對應 -keyfile 命令列選項。
private_key = $dir/private/cakey.pem

# 新簽發的證書預設有效期,以天為單位。依次對應 -days , -startdate , -enddate 命令列選項。
default_days = 365
# 新證書預設的生效日期,如果未設定則使用簽發時的時間,格式為:YYMMDDHHNNSSZ(年月日時分秒Z)
#default_startdate = 080303223344Z
# 新證書預設的失效日期,格式為:YYMMDDHHNNSSZ(年月日時分秒Z)
#default_enddate = 090303223344Z

# 從當前CRL(證書撤銷列表)到下次CRL釋出的間隔小時數或天數。依次對應 -crlhours , -crldays 命令列選項。
#default_crl_hours = 72
default_crl_days = 30

# 簽發新證書以及CRL時預設的摘要演算法,所有 dgst 命令都可以使用(sha256, sha3-256, sha512, sha3-512, ...)
#(★)此處的設定相當於在命令列上使用 -sha256 選項(對應於"-digest")。
default_md = sha256

#(★)儲存已簽發證書的文字資料庫檔案,初始時可為空。
database = $dir/index.txt

# 同一個"subject"是否只能建立一個證書,預設值為 yes 但建議設為 no 以方便根CA自簽名( -selfsign )。
unique_subject = no

#(★)簽發證書時使用的序列號文字檔案,裡面必須包含下一個可用的16進位制數字。
serial = $dir/serial

# 存放當前CRL編號的檔案
crlnumber = $dir/crlnumber

# 定義X.509證書擴充套件項的欄位。對應 -extensions 命令列選項。
x509_extensions = usr_cert

# 定義生成CRL時需要加入的擴充套件項欄位。對應 -crlexts 命令列選項。
#crl_extensions = crl_ext

# 通常,證書籤發的特種名稱(DN)域的各個引數順序與證書策略的引數順序一致。
# 但是,如果這裡設為yes則保持與證書請求中的引數順序一致。對應 -preserveDN 命令列選項。
preserve = no

# 預設值為 yes ,設為 no 表示從證書的DN中刪除 EMAIL 欄位。對應 -noemailDN 命令列選項。
email_in_dn = yes

# 強烈建議不要使用它,對應 -msie_hack 命令列選項。
#msie_hack =

#(★)定義用於證書請求DN域匹配策略的欄位,用於決定CA要求和處理證書請求提供的DN域的各個引數值的規則。
# 對應 -policy 命令列選項。
policy  = policy_match

# 當用戶需要確認簽發證書時可讀證書DN域的顯示格式。可用值與 x509 指令的 -nameopt 選項相同。
name_opt = ca_default
# 當用戶需要確認簽發證書時證書域的顯示格式。
# 可用值與 x509 指令的 -certopt 選項相同,不過 no_signame 和 no_sigdump 總被預設設定。
cert_opt  = ca_default

# 是否將證書請求中的擴充套件項資訊加入到證書擴充套件項中去。取值範圍以及解釋:
# none: 忽略所有證書請求中的擴充套件項
# copy: 將證書擴充套件項中沒有的專案複製到證書中
# copyall: 將所有證書請求中的擴充套件項都複製過去,並且覆蓋證書擴充套件項中原來已經存在的值。
# 此選項的主要用途是允許證書請求提供例如 subjectAltName 之類擴充套件的值。
copy_extensions = copy

##### 為簽發的證書設定擴充套件項 #####
[ usr_cert ]

# 基本約束(該證書是否為CA證書)。"CA:FALSE"表示非CA證書(不能簽發其他證書的"葉子證書")。
#basicConstraints = CA:FALSE

# 一般只能給常規證書這些用途
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# PKIX工作組推薦將使用者與頒發機構的金鑰識別符號包含在證書中
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

##### 證書請求資訊的匹配策略 #####
# 變數名稱是DN域物件的名稱,變數值可以是:
# match: 該變數在證書請求中的值必須與CA證書相應的變數值完全相同,否則拒籤。
# supplied: 該變數在證書請求中必須提供(值可以不同),否則拒籤。
# optional: 該變數在證書請求中可以存在也可以不存在(相當於沒有要求)。
# 除非preserve=yes或者在ca命令中使用了-preserveDN,否則在簽發證書時將刪除匹配策略中未提及的物件。
[ policy_match ]
countryName  = match
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName  = supplied
emailAddress  = optional