轉載: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