logback官方文檔中文翻譯第十五章:使用 SSL

第十五章:使用 SSL

在從以 socket 為基礎(chǔ)的 appender 到遠(yuǎn)程 receiver 傳遞日志事件時(shí)陕贮,logback 支持使用安全套接字層壹置。當(dāng)使用支持 SSL 的 appender 以及響應(yīng)的 receiver 時(shí)科汗,通過安全通道來傳遞日志事件脐嫂。

SSL 與組件的角色

logback 的組件晃酒,例如 appender 以及 receiver 在網(wǎng)絡(luò)連接初始化時(shí)可能承當(dāng)服務(wù)器的角色或者客戶端的角色。當(dāng)充當(dāng)服務(wù)器角色時(shí)隙咸,logback 組件被動(dòng)的監(jiān)聽來自遠(yuǎn)程客戶端組件的連接沐悦。相反地成洗,充當(dāng)客戶端角色的 logback 組件會(huì)初始化一個(gè)連接到遠(yuǎn)程服務(wù)器組件。例如藏否,一個(gè)充當(dāng)客戶端角色的 appender 連接充當(dāng)服務(wù)端角色的 receiver瓶殃。或者一個(gè)充當(dāng)客戶端角色的 receiver 連接充當(dāng)服務(wù)端角色的 appender副签。

組件的角色通常由組件的類型決定遥椿。例如,SSLServerSocketAppender 是一個(gè)充當(dāng)服務(wù)端角色的 appender 組件淆储,但是 SSLSocketAppender 是一個(gè)充當(dāng)客戶端角色的 appender 組件冠场。因此開發(fā)者或者應(yīng)用管理人員可以配置 logback 組件來支持想要的網(wǎng)絡(luò)連接初始化方向。

網(wǎng)絡(luò)連接初始化方法在 SSL 上下文中非常重要本砰,因?yàn)樵?SSL 中碴裙,服務(wù)端組件連接客戶端必須具有 X.509 證書來標(biāo)識(shí)自身〉愣睿客戶端組件舔株,在連接服務(wù)端時(shí),使用服務(wù)端的證書來驗(yàn)證服務(wù)端是否可信还棱。開發(fā)人員或者應(yīng)用管理者必須清楚的知道 logback 組件的角色督笆,才能正確配置服務(wù)器的 keystore (包含服務(wù)器 X.509 證書) 以及客戶端的 truststore (包含用于驗(yàn)證服務(wù)器信任時(shí)的自簽名根證書)。

當(dāng)為 相互認(rèn)證 配置 SSL诱贿,服務(wù)器組件與客戶端組件必須擁有有效的 X.509 證書,它們的信任由它們各自對(duì)等的聲明咕缎。相互認(rèn)證配置在服務(wù)器組件中珠十,因此開發(fā)人員或者應(yīng)用管理者必須知道哪一個(gè)組件充當(dāng)?shù)氖欠?wù)器的角色。

在本章凭豪,我們使用術(shù)語 服務(wù)器組件 或者簡(jiǎn)單的 服務(wù)器 來表示 logback 中充當(dāng)服務(wù)器角色的 appender 或者 receiver焙蹭。使用 客戶端組件 或者建的 客戶端 來表示充當(dāng)客戶端角色的組件。

SSL 以及 X.509 證書

為了是用支持 SSL 的 logback 組件嫂伞,你需要一個(gè) X.509 的證書 (一個(gè)私鑰孔厉,相應(yīng)的證書,以及 CA 認(rèn)證鏈) 去標(biāo)識(shí)你的組件充當(dāng)了一個(gè) SSL 服務(wù)器帖努。如果你想要使用雙向認(rèn)證撰豺,那么充當(dāng) SSL 客戶端的組件還需要一個(gè)證書。

雖然你可以使用由商業(yè)認(rèn)證機(jī)構(gòu) (CA) 頒發(fā)的證書拼余,但是你也可以使用內(nèi)部 CA 頒發(fā)的證書污桦,甚至是自簽名的證書。下面是必須滿足的條件:

  1. 服務(wù)端組件必須配置一個(gè) key store匙监,包含服務(wù)器私鑰凡橱,相應(yīng)的證書小作,以及 CA 認(rèn)證鏈 (如果沒有使用自簽名證書)
  2. 客戶端組件必須配置一個(gè) trust store,包含可信任的根 CA 證書稼钩,或者服務(wù)器自簽名根證書

為 SSL 配置 logback 組件

Java 安全套接字拓展 (JSSE) 以及 Java 加密體系 (JCA) 用來實(shí)現(xiàn) logback 的 SSL顾稀,支持諸多的配置選項(xiàng)“映牛可插拔的提供框架允許替換或增強(qiáng)內(nèi)置的 SSL 以及平臺(tái)的加密功能静秆。為了滿足你的對(duì)安全的需要,支持 SSL 的 logback 組件提供完全指定 SSL 引擎以及密碼提供者配置方面的能力绍载。

使用 JSSE 系統(tǒng)屬性的基本 SSL 配置

幸運(yùn)的是诡宗,支持 SSL 的 logback 組件幾乎所有的 SSL 屬性的配置都有合理的默認(rèn)值。在多數(shù)的情況下击儡,只需要配置一些 JSSE 的系統(tǒng)屬性塔沃。

本節(jié)剩余的部分將講述在大多數(shù)的環(huán)境中都需要被指定的 JSSE 屬性。查看定制 JSSE來獲取更多關(guān)于設(shè)置 JSSE 系統(tǒng)屬性的信息來定制 JSSE阳谍。

如果你使用任何 logback 中支持 SSL 的 appender 或者 receiver 組件充當(dāng)服務(wù)端角色 (例如蛀柴,SSLServerSocketReceiverSSLServerSocketAppender矫夯,SimpleSSLSocketServer)鸽疾。你需要提供 key store 包含的密鑰以及證書的 location,type 以及 password 來配置 JSEE 系統(tǒng)屬性训貌。

服務(wù)端 key store 配置的系統(tǒng)屬性

屬性名 描述
javax.net.ssl.keyStore 指定包含服務(wù)端組件的密鑰以及證書的文件的文件系統(tǒng)的路徑
javax.net.ssl.keyStoreType 指定 key store 類型制肮。如果這個(gè)屬性沒有指定,將默認(rèn)為 JKS
javax.net.ssl.keyStorePassword 指定訪問 key store 的密碼

查看下面 Examples 部分递沪,在應(yīng)用啟動(dòng)的時(shí)候通過利用 logback 支持 SSL 的服務(wù)端組件來設(shè)置這些系統(tǒng)屬性豺鼻。

如果你的服務(wù)端組件使用的證書是商業(yè)認(rèn)證機(jī)構(gòu) (CA) 認(rèn)證,你可能不需要在你應(yīng)用的客戶端組件中提供任何 SSL 配置款慨。當(dāng)在你的服務(wù)端組件使用商業(yè)簽名證書儒飒,僅僅只需要在運(yùn)行服務(wù)端組件的 JVM 上設(shè)置系統(tǒng)的 key store 屬性。

如果你使用自簽名的服務(wù)器證書或者你服務(wù)器證書是認(rèn)證機(jī)構(gòu) (CA) 簽名但是它們的根證書不再 Java 平臺(tái)默認(rèn)的 trust store 中 (例如檩奠,你的組織有自己的內(nèi)部簽名機(jī)構(gòu))桩了。你需要配置 JSSE 系統(tǒng)屬性,以提供包含你服務(wù)器證書的 trust store 或者認(rèn)證機(jī)構(gòu) (CA) 頒發(fā)的受信任根證書簽名的服務(wù)器證書的 location埠戳,type井誉,以及 password。這些屬性需要在每個(gè)利用支持 SSL 的客戶端組件中的應(yīng)用中設(shè)置乞而。

客戶端 trust store 配置的系統(tǒng)屬性

屬性名 描述
javax.net.ssl.trustStore 指定包含服務(wù)端組件的證書或者受信任根證書的文件的文件系統(tǒng)的路徑
javax.net.ssl.trustStoreType 指定 trust store 類型送悔。如果這個(gè)屬性沒有被指定,則默認(rèn)為 JKS
javax.net.ssl.trustStorePassword 指定訪問 trust store 的密碼

查看下面 Examples 部分,在應(yīng)用啟動(dòng)的時(shí)候通過利用 logback 支持 SSL 的客戶端組件來設(shè)置這些系統(tǒng)屬性欠啤。

高級(jí) SSL 配置

在特定的情況下荚藻,使用 JSEE 系統(tǒng)屬性的基本 SSL 配置是不恰當(dāng)?shù)摹1热缃喽危阆胍?web 應(yīng)用中使用 SSLServerSocketReceiver 組件应狱,你可能想要使用不同的證書為你的遠(yuǎn)程日志客戶端標(biāo)識(shí)你的日志服務(wù)器,而不是 web 服務(wù)器為了 web 客戶端使用證書來標(biāo)識(shí)自身祠丝。你可能想要在日志服務(wù)器上驗(yàn)證 SSL 客戶端疾呻,確保只有真正授權(quán)的遠(yuǎn)程 logger 才可以連接⌒窗耄或者你的組織對(duì)于在組織所在的網(wǎng)絡(luò)上使用 SSL 協(xié)議以及密碼套件有嚴(yán)格的策略岸蜗。為了滿足這些需求,你需要使用 logback SSL 高級(jí)配置選項(xiàng)叠蝇。

在配置 logback 組件支持 SSL 時(shí)璃岳,你需要在組件的配置中指定 ssl 屬性來指定 SSL 的配置。

例如悔捶,如果你想要使用 SSLServerSocketReceiver 以及為日志服務(wù)器認(rèn)證配置 key store 屬性铃慷,你可以使用類似如下的配置:

<configuration>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
    </encoder>
  </appender>
  
  <root level="debug">
    <appender-ref ref="CONSOLE" />
  </root>

  <receiver class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
    <ssl>
      <keyStore>
        <location>classpath:/logging-server-keystore.jks</location>
        <password>changeit</password>
      </keyStore>
    </ssl>
  </receiver> 

</configuration>

該配置將 key store 的位置指定為位于應(yīng)用類路徑下的 logging-server-keystore.jks。你也可以通過 file: URL 來指定 key store 的位置蜕该。

如果你想要在你的應(yīng)用中使用 SSLSocketAppender犁柜,但是不想要改變默認(rèn) trust store 使用的 JSSE javax.net.ssl.trustStore 屬性。你可以通過如下的方式進(jìn)行配置:

<configuration>
  <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
    <ssl>
      <trustStore>
        <location>classpath:/logging-server-truststore.jks</location>
        <password>changeit</password>
      </trustStore>
    </ssl>
  </appender>
  
  <root level="debug">
    <appender-ref ref="SOCKET" />
  </root>

</configuration>

該配置將 key store 的位置指定為位于應(yīng)用類路徑下的 logging-server-keystore.jks堂淡。你也可以通過 file: URL 來指定 key store 的位置馋缅。

SSL 配置屬性

JSSE 公開 了大量的可配置選項(xiàng)。logback 的 SSL 支持幾乎所有這些可用的選項(xiàng)在支持 SSL 組件的配置中指定绢淀。在使用 XML 配置時(shí)股囊,在組件的配置中,SSL 屬性被嵌套在 <ssl> 元素中引入更啄。這個(gè)配置元素對(duì)應(yīng) SSLConfiguration 類。

當(dāng)為你的組件配置 SSL 時(shí)居灯,你僅僅只需要配置那些默認(rèn)值不適合的 SSL 屬性祭务。過度指定 SSL 配置經(jīng)常會(huì)導(dǎo)致一些難以診斷的問題。

下面的表格展示了頂層的 SSL 配置屬性怪嫌。許多頂層的屬性還有額外的子屬性义锥,這些子屬性將會(huì)頂層屬性之后描述。

屬性名 類型 描述
keyManagerFactory KeyManagerFactoryFactoryBean 指定用于創(chuàng)建 KeyManagerFactory 的配置岩灭。如果這個(gè)屬性沒有配置拌倍,那么將會(huì)使用 Java 平臺(tái)默認(rèn)的 factory。見 Key Manager Factory 配置
keyStore KeyStoreFactoryBean 指定用于創(chuàng)建 KeyStore 的配置。通過這個(gè)屬性創(chuàng)建的 KeyStore 必須包含唯一的 X.509 證書 (包含密鑰柱恤,相應(yīng)的證書以及 CA 認(rèn)證鏈)数初。這個(gè)證書由本地 SSL 提供給遠(yuǎn)程的 SSL。<br />當(dāng)配置一個(gè) SSL 客戶端時(shí) (例如梗顺,SSLSocketAppender)泡孩,僅僅只有在遠(yuǎn)程配置需要驗(yàn)證客戶端身份時(shí)才需要該屬性。<br />當(dāng)配置一個(gè) SSL 服務(wù)端時(shí) (例如寺谤,SimpleSSLSocketServer)仑鸥,該屬性指定的 key store 包含了服務(wù)端證書。如果沒有配置這個(gè)屬性变屁,JSSE 的 javax.net.ssl.keyStore 系統(tǒng)屬性必須配置用于提供服務(wù)端 key store 的位置眼俊。查看 定制 JSEE 來獲取更多關(guān)于 JSEE 系統(tǒng)屬性的信息。<br />更多的信息查看 Key Store 配置粟关。
parameters SSLParametersConfiguration 在 SSL 會(huì)話中疮胖,指定各種參數(shù)。見下面的 SSL 參數(shù)配置誊役。
protocol String 指定創(chuàng)建 SSLContext 的 SSL 協(xié)議获列。見命名規(guī)范。如果沒有配置該參數(shù)蛔垢,那么將使用 Java 平臺(tái)默認(rèn)的協(xié)議击孩。
provider String 指定創(chuàng)建 SSLContext 的 JSSE 提供者。如果沒有配置該參數(shù)鹏漆,那么將使用 Java 平臺(tái)默認(rèn)的 JSSE 提供者巩梢。
secureRandom SecureRandomFactoryBean 指定創(chuàng)建 SecureRandom (安全的隨機(jī)數(shù)生成器) 的配置。如果沒有配置該參數(shù)艺玲,那么將使用 Java 平臺(tái)默認(rèn)的生成器括蝠。見下面的 安全隨機(jī)數(shù)生成配置
trustManagerFactory TrustManagerFactoryFactoryBean 指定創(chuàng)建 TrustManagerFactory 的配置饭聚。如果沒有指定該參數(shù)忌警,那么將使用 Java 平臺(tái)默認(rèn)的 factory。見下面的 受信任的管理工廠秒梳。
trustStore KeyStoreFactoryBean 指定創(chuàng)建 KeyStore 的配置法绵,用于驗(yàn)證遠(yuǎn)程 SSL 的身份。通過這個(gè)屬性創(chuàng)建的 KeyStore 應(yīng)該包含一個(gè)或多個(gè)信任錨 (trust anchors) — keystore 中被標(biāo)記為受信任的自簽名證書酪碘。通常朋譬,trust store 包含自簽名的 CA 證書。<br />通過該屬性指定的 trust store 會(huì)覆蓋任何通過 JSSE 的 javax.net.ssl.trustStore 以及平臺(tái)默認(rèn)的 trust store兴垦。

Key Store 配置

KeyStoreFactoryBean 指定創(chuàng)建包含 X.509 證書的 KeyStore 所需要的配置徙赢。這個(gè) factory bean 的屬性能夠用于 SSL 配置 中的 keyStore 以及 trustStore 屬性字柠。

屬性名 類型 描述
location String 指定 key store 的位置 URL。使用 file: 指定 keystore 在文件系統(tǒng)中的位置狡赐。使用 classpath: 指定 keystore 在類路徑下的位置窑业。如果 URL 沒有指定具體的策略,那么將使用 classpath:阴汇。
password String 指定訪問 keystore 的密碼
provider String 指定用于創(chuàng)建 KeyStore 的 JCA 提供者的名字数冬。如果沒有指定該屬性,那么將使用 Java 平臺(tái)默認(rèn)的 keystore 提供者搀庶。
type String 指定 KeyStore 的類型拐纱。見 命名規(guī)范。如果沒有指定該屬性哥倔,那么將使用 Java 平臺(tái)默認(rèn)的 keystore 類型秸架。

Key Manager Factory 配置

KeyManagerFactoryFactoryBean 指定創(chuàng)建 KeyManagerFactory 需要的配置。通常咆蒿,沒有必要詳細(xì)的配置 key manager factory东抹,因?yàn)槠脚_(tái)默認(rèn)的 factory 就可以滿足大部分的需求。

屬性名 類型 描述
algorithm String 指定 KeyManagerFactory 算法的名字沃测。見 命名規(guī)范缭黔。如果沒有指定該屬性,那么將會(huì)使用 Java 平臺(tái)默認(rèn)的 key manager 算法蒂破。
provider String 指定生成 SecureRandom 生成器的 JCA 提供者的名字馏谨。如果沒有指定該屬性,那么將會(huì)使用 Java 平臺(tái)默認(rèn)的 JSSE 提供者附迷。

Secure Random Generator 配置

SecureRandomFactoryBean 指定創(chuàng)建 SecureRandom 生成器所需要的配置惧互。通常,沒有必要詳細(xì)的配置 secure random 生成器喇伯,因?yàn)槠脚_(tái)默認(rèn)的生成器就可以滿足大部分的需求喊儡。

屬性名 類型 描述
algorithm String 指定 SecureRandom 算法的名字。見 命名規(guī)范稻据。如果沒有指定該屬性艾猜,那么將會(huì)使用 Java 平臺(tái)默認(rèn)的隨機(jī)數(shù)生成器 (random number generation) 算法。
provider String 指定用于創(chuàng)建 SecureRandom 生成器的 JCA 提供者捻悯。如果沒有指定該屬性箩朴,那么將會(huì)使用 Java 平臺(tái)默認(rèn)的 JSSE 提供者。

SSL 參數(shù)配置

SSLParametersConfiguration 允許定制受允許的 SSL 協(xié)議秋度,密碼套件,以及客戶端認(rèn)證選項(xiàng)钱床。

Property Name Type Description
excludedCipherSuites String 指定以逗號(hào)分隔的 SSL 密碼套件的名字或者模式列表荚斯,用來在會(huì)話期間進(jìn)行禁用。這個(gè)屬性通過 SSL 引擎過濾密碼套件。任何被該屬性匹配到的密碼套件都會(huì)被禁用事期。<br />以逗號(hào)分割的各個(gè)字段可以是字符串或者正則表達(dá)式滥壕。<br />查看密碼套件的命名規(guī)則
includedCipherSuites String 與上一個(gè)屬性除了作用相反,其它都是一樣 (懶得翻譯了)兽泣。
excludedProtocols String 這個(gè)是表示需要排除的 SSL 協(xié)議绎橘。與上一個(gè)屬性,除了作用不同唠倦,其它都一樣称鳞。
includedProtocols String 與上一個(gè)協(xié)議作用相反,其它一致稠鼻。
needClientAuth boolean 設(shè)置屬性為 true 表示冈止,服務(wù)端需要一個(gè)有效的客戶端證書。當(dāng)客戶端組件為 SSLSocketAppender 時(shí)候齿,該屬性會(huì)被忽略熙暴。
wantClientAuth boolean 設(shè)置屬性為 true 表示,服務(wù)端想要一個(gè)有效的客戶端證書慌盯。當(dāng)客戶端組件為 SSLSocketAppender 時(shí)周霉,該屬性會(huì)被忽略。(與上一個(gè)屬性的差異亚皂,需要自己動(dòng)手去實(shí)踐俱箱。因?yàn)槲乙膊磺宄??)

Trust Manager Factory 配置

TrustManagerFactoryFactoryBean 指定創(chuàng)建 TrustManagerFactory 所需要的配置。通常孕讳,沒有必要明確的配置 trust manager factory匠楚,平臺(tái)默認(rèn)的 factory 就可以滿足大部分的需要。

屬性名 類型 描述
algorithm String 指定 TrustManagerFactory 算法的名字厂财。見 命名標(biāo)準(zhǔn)芋簿。如果沒有指定該屬性,那么將使用 Java 平臺(tái)默認(rèn)的 key manager 算法璃饱。
provider String 指定創(chuàng)建 SecureRandom 生成器的 JCA 提供者的名字与斤。如果沒有指定該屬性,那么將使用 Java 平臺(tái)默認(rèn)的 JSSE 提供者荚恶。

示例

使用 JSSE 系統(tǒng)屬性

JSEE 系統(tǒng)屬性可以用來指定包含服務(wù)端 X.509 證書的 keystore 的位置以及密碼撩穿。或者包含客戶端組件驗(yàn)證服務(wù)端信任的自簽名根 CA 證書的 truststore 的位置以及密碼谒撼。

指定服務(wù)端 keystore

在運(yùn)行服務(wù)端組件時(shí)食寡,需要指定包含服務(wù)端證書的 keystore 的位置以及密碼。一種方法是使用 JSSE 系統(tǒng)屬性廓潜。下面的例子通過命令行的方式啟動(dòng) SimpleSSLSocketServer

java -DkeyStore=/etc/logback-server-keystore.jks \
     -DkeyStorePassword=changeit -DkeyStoreType=JKS \
     ch.qos.logback.net.SimpleSSLSocketServer 6000 /etc/logback-server-config.xml

注意抵皱,在使用 JSSE keyStore 系統(tǒng)屬性時(shí)善榛,指定了 keystore 的路徑。在指定了 logback.xml 的路徑時(shí)呻畸,keystore 的 URL 被指定移盆。

雖然這個(gè)示例啟動(dòng)了一個(gè)提供 logback 的單機(jī)服務(wù)端應(yīng)用,但是同樣的系統(tǒng)屬性可以在任何使用支持 SSL 的 logback 服務(wù)端組件上指定并啟動(dòng)伤为。

指定客戶端 truststore

當(dāng)使用客戶端組件時(shí)咒循,需要指定包含根 CA 證書的 truststore 的位置與密碼,用于驗(yàn)證服務(wù)端的信任绞愚。一種方式是通過使用 JSSE 系統(tǒng)屬性叙甸。下面的示例通過命令行啟動(dòng)一個(gè)名為 com.example.MyLoggingApplication 的應(yīng)用,該應(yīng)用使用一個(gè)或多個(gè)支持 SSL 的 logback 客戶端組件爽醋。

java -DtrustStore=/etc/logback-client-truststore.jks \
     -DtrustStorePassword=changeit -DtrustStoreType=JKS \
     com.example.MyLoggingApplication

注意蚁署,在使用 JSSE trustStore 系統(tǒng)屬性時(shí),指定了 truststore 的路徑蚂四。在指定了 logback.xml 的路徑時(shí)光戈,truststore 的 URL 被指定。

創(chuàng)建以及使用自簽名的服務(wù)端組件證書

為了生成自簽名的證書遂赠,可以使用 JRE 自帶的 keytool 工具久妆。下面的指令在服務(wù)端組件的 keystore 中創(chuàng)建一個(gè)自簽名的 X.509 證書。以及創(chuàng)建在客戶端組件中使用的 truststore跷睦。

創(chuàng)建服務(wù)端組件證書

下面的命令在一個(gè)名為 server.keystore 的文件中生成自簽名客戶端證書筷弦。

keytool -genkey -alias server -dname "CN=my-logging-server" \
    -keyalg RSA -validity 365 -keystore server.keystore
Enter keystore password: <Enter password of your choosing>
Re-enter new password: <Re-enter same password>
Enter key password for <my-logging-server>
    (RETURN if same as keystore password):  <Press RETURN>

dname 中使用的名字 my-logging-server 可以是任何你選擇的有效的名字。你可能想要使用服務(wù)端主機(jī)上的全限定名抑诸。validity 參數(shù)可以指定從當(dāng)前日期開始直到證書過期的天數(shù)烂琴。

在實(shí)際的設(shè)置中,為包含服務(wù)端證書的 keystore 選擇一個(gè)強(qiáng)密碼是非常重要的蜕乡。密碼用來保護(hù)服務(wù)端的密碼奸绷,防止被已授權(quán)方使用。記下剛才設(shè)置的密碼层玲,因?yàn)樵诮酉聛砼渲梅?wù)端的時(shí)候需要使用号醉。

為客戶端組件創(chuàng)建 truststore

由于要配置客戶端組件,在前一個(gè)步驟中創(chuàng)建的服務(wù)端證書需要從 keystore 中導(dǎo)出辛块,并且導(dǎo)入到 truststore 中畔派。下面的命令將會(huì)導(dǎo)出證書并且導(dǎo)入到名為 server.truststore 的 truststore。

keytool -export -rfc -alias server -keystore server.keystore \
    -file server.crt
Enter keystore password: <Enter password you chose for in previous step>

keytool -import -alias server -file server.crt -keystore server.truststore
Enter keystore password: <Enter password of your choosing>
Re-enter new password: <Re-enter same password>
Owner: CN=my-logging-server
Issuer: CN=my-logging-server
Serial number: 6e7eea40
Valid from: Sun Mar 31 07:57:29 EDT 2013 until: Mon Mar 31 07:57:29 EDT 2014

   ...

Trust this certificate? [no]:  <Enter "yes">

第一個(gè)命令從 keystore 中導(dǎo)出服務(wù)端證書 (但是不是服務(wù)端密鑰) 到一個(gè)名為 server.crt 的文件润绵。第二個(gè)步驟創(chuàng)建一個(gè)名為 server.truststore线椰,包含服務(wù)端證書的新的 truststore。

在實(shí)際的設(shè)置中尘盼,為 truststore 選擇一個(gè)不同于服務(wù)端 keystore 的強(qiáng)密碼非常的重要憨愉。記住這個(gè)密碼呜魄,因?yàn)樵谂渲每蛻舳?appender 時(shí)需要使用。

配置服務(wù)端組件

拷貝 server.keystore 到你的服務(wù)端應(yīng)用的配置中莱衩。keystore 可以放在應(yīng)用的類路徑下,或者放在服務(wù)器主機(jī)文件系統(tǒng)的某個(gè)位置娇澎。在配置文件中指定 keystore 位置 URL 時(shí)笨蚁,可以使用 classpath: 或者 file:。一個(gè)示例的服務(wù)端配置如下:

<configuration debug="true">
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
    </encoder>
  </appender>
  
  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>

  <server class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
    <ssl>
      <keyStore>
        <location>classpath:server.keystore</location>
        <password>${server.keystore.password}</password>
      </keyStore>
    </ssl>
  </server>
</configuration>

示例假設(shè) keystore 放在應(yīng)用類路徑的根路徑下趟庄。

配置文件中使用 server.keystore.password 替換符指定 keystore 的密碼括细。這種方式可以避免將密碼直接存儲(chǔ)在配置文件中。例如戚啥,在啟動(dòng)的時(shí)候奋单,你的應(yīng)用可能會(huì)在控制臺(tái)提示密碼,之后在配置日志系統(tǒng)之前使用輸入的密碼將 server.keystore.password 設(shè)置為系統(tǒng)屬性猫十。

配置客戶端組件

你需要將 server.truststore 文件拷貝到使用支持 SSL 組件充當(dāng)客戶端角色的每個(gè)應(yīng)用的配置中览濒。truststore 可以放置在應(yīng)用的類路徑下,或者文件系統(tǒng)的某個(gè)地方拖云〈眩可以通過 classpath: 或者 file: 來指定 truststore 位置的 URL≈嫦睿客戶端 appender 的配置示例如下:

Example:

<configuration debug="true">
  <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
    <remoteHost>${host}</remoteHost>
    <ssl>
      <trustStore>
        <location>classpath:server.truststore</location>
        <password>${server.truststore.password}</password>
      </trustStore>
    </ssl>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="SOCKET" />
  </root>
</configuration>

示例中假設(shè) truststore 位于應(yīng)用類路徑的根路徑下乏苦。

配置中使用 server.truststore.password 替換符來指定 truststore 的密碼。這種方式可以避免直接將密碼存儲(chǔ)在配置文件中尤筐。例如汇荐,應(yīng)用啟動(dòng)時(shí)會(huì)在控制臺(tái)提示密碼,之后可以在配置日志系統(tǒng)之前通過輸入密碼將 server.truststore.password 設(shè)置為系統(tǒng)屬性盆繁。

審核 SSL 配置

在需要安全通行的設(shè)置中掀淘,經(jīng)常需要審核組件的 SSL 配置,驗(yàn)證與本地策略的一致性改基。在 logback 初始化時(shí)繁疤,logback 中的 SSL 通過提供 SSL 配置的詳細(xì)日志來滿足這一需求似枕≈簦可以在配置中使用 debug 屬性來開啟這個(gè)功能。

<configuration debug="true">
  
  ...
  
</configuration>

當(dāng)使用了 debug 屬性畸陡,在日志系統(tǒng)初始化時(shí)鸣哀,所有與 SSL 配置產(chǎn)生的相關(guān)信息都會(huì)被打印出來架忌。一個(gè)典型的示例如下:

Example:

06:46:31,941 |-INFO in SSLServerSocketReceiver@4ef18d37 - SSL protocol 'SSL' provider 'SunJSSE version 1.6'
06:46:31,967 |-INFO in SSLServerSocketReceiver@4ef18d37 - key store of type 'JKS' provider 'SUN version 1.6': file:src/main/java/chapters/appenders/socket/ssl/keystore.jks
06:46:31,967 |-INFO in SSLServerSocketReceiver@4ef18d37 - key manager algorithm 'SunX509' provider 'SunJSSE version 1.6'
06:46:31,973 |-INFO in SSLServerSocketReceiver@4ef18d37 - secure random algorithm 'SHA1PRNG' provider 'SUN version 1.6'
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: SSLv2Hello
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: SSLv3
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: TLSv1
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_MD5
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_SHA
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA

為了簡(jiǎn)便起見,這里的輸出被截?cái)嗔艘徊糠治页摹5前藚f(xié)議叹放、提供者饰恕、算法、密碼套件以及在配置中所使用的 keystore 與 truststore 位置井仰。

雖然沒有一個(gè)審核日志是敏感的埋嵌,但是為了安全,在實(shí)際的設(shè)置中俱恶,在配置被驗(yàn)證之后雹嗦,日志信息不應(yīng)該被啟用。將 debug 屬性移除合是,或者設(shè)置為 false了罪,將禁用日志審核。

解決 SSL 異常

當(dāng) SSL 配置錯(cuò)誤時(shí)聪全,普遍的結(jié)果是客戶端與服務(wù)端組件不能正常的通常泊藕。當(dāng)客戶端嘗試連接服務(wù)端時(shí),這個(gè)問題通常會(huì)被雙方拋出的異常表現(xiàn)出來难礼。

異常消息內(nèi)容的不容取決于你查看的是客戶端的日志還是服務(wù)端的日志娃圆。最主要的原因是在會(huì)話期間,錯(cuò)誤報(bào)告受限制于內(nèi)部的協(xié)議鹤竭。由于這種情況踊餐,為了定位會(huì)話問題,需要查看客戶端與服務(wù)端的日志臀稚。

Server's Certificate is Not Available

當(dāng)啟動(dòng)服務(wù)端組件時(shí)吝岭,你會(huì)在日志中看到如下的異常:

javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled

大部分情況下表示你沒有配置包含服務(wù)端密鑰的 keystore 以及相應(yīng)的證書。

解決辦法

使用 keystore 系統(tǒng)屬性 或者服務(wù)端組件 ssl 屬性中的 keyStore 屬性吧寺。你必須指定包含服務(wù)端密鑰以及證書的 keystore 的路徑以及密碼窜管。

Client Does Not Trust the Server

當(dāng)客戶端嘗試連接服務(wù)端時(shí),在日志中看到如下的異常:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

這個(gè)問題表示服務(wù)端展示的證書稚机,客戶端不相信幕帆。大部分情況下是使用自簽名的證書 (或者服務(wù)端證書由你組織內(nèi)部的認(rèn)證機(jī)構(gòu)所簽名) 并且你還沒有配置客戶端,導(dǎo)致它引用了包含服務(wù)端自簽名證書 (或者你的服務(wù)器證書是由 CA 簽名的受信任的根證書) 的 truststore赖条。

這個(gè)問題還會(huì)發(fā)生在服務(wù)端證書過期或者被取消的情況下失乾。在客戶端每次嘗試進(jìn)行連接時(shí),你在服務(wù)端的日志中會(huì)看到如下的異常信息:

javax.net.ssl.SSLHandshakeException: Received fatal alert: ...

異常信息的余下部分通常會(huì)提供一個(gè)代碼來表明為什么客戶端拒絕服務(wù)端證書:

代碼 描述
certificate_unknown 通常表示客戶端 truststore 沒有被正確的配置
certificate_expired 表示服務(wù)端證書已過期纬乍,需要更換
certificate_revoked 表示頒發(fā)的 CA 已經(jīng)撤銷了服務(wù)端證書碱茁,需要更換

解決辦法

如果服務(wù)端日志顯示 certificate_unknown,那么使用 truststore 系統(tǒng)屬性 或者 appender 組件 ssl 屬性中的 trustStore 屬性仿贬,指定包含服務(wù)端自簽名證書或者頒發(fā)的 CA 根證書的 truststore 的路徑以及密碼纽竣。

如果服務(wù)端日志顯示 certificate_expired 或者 certificate_revoked,表示服務(wù)端需要一個(gè)新的證書。新的證書以及相關(guān)的密鑰需要在服務(wù)端配置的 keystore 中更換蜓氨。并且聋袋,如果使用自簽名服務(wù)端證書,那么還需要更換在客戶端 appender 中配置的 truststore 服務(wù)端證書穴吹。

Server Does Not Trust the Client

注意:這個(gè)問題僅僅發(fā)生在你明確的配置服務(wù)端請(qǐng)求客戶端證書時(shí)幽勒。(使用 needClientAuth 或者 wantClientAuth 屬性)。

當(dāng)客戶端嘗試連接日志服務(wù)器時(shí)港令,可以在客戶端日志中看到如下的異常信息:

javax.net.ssl.SSLHandshakeException: Received fatal alert: ...

異常信息的其余部分會(huì)提供一個(gè)代碼表明為什么服務(wù)端拒絕客戶端證書代嗤。

代碼 描述
certificate_unknown 通常表示服務(wù)端 truststore 沒有正確的配置
certificate_expired 表示客戶端證書已經(jīng)過期,需要更換
certificate_revoked 表示頒發(fā)的 CA 已經(jīng)撤銷了客戶端證書缠借,需要更換

解決辦法

如果客戶端日志信息顯示 bad_certificate,那么使用 truststore 系統(tǒng)屬性 或者服務(wù)端組件 ssl 屬性中的 trustStore 屬性宜猜,指定包含客戶端自簽名證書或者頒發(fā)的 CA 根證書的 truststore 的路徑以及密碼泼返。

如果服務(wù)端日志信息顯示 certificate_expired 或者 certificate_revoked,表示客戶端需要一個(gè)新的證書姨拥。需要更換在客戶端配置中指定的 keystore 的新證書以及相應(yīng)的密鑰绅喉。

Client and Server Cannot Agree on a Protocol

注意:這個(gè)問題僅僅只在你的配置中明確的配置了 excludedProtocols 或者 includedProtocols SSL 協(xié)議時(shí)。

當(dāng)客戶端嘗試連接服務(wù)端時(shí)叫乌,你會(huì)在日志中看到如下異常信息:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

服務(wù)端的日志信息通常更加詳細(xì)柴罐,例如:

javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled

通常,表示你已經(jīng)排除其中的一個(gè)協(xié)議憨奸。

解決辦法

檢查服務(wù)端與客戶端指定的 excludedProtocols 以及 includedProtocols 屬性的值革屠。

Client and Server Cannot Agree on a Cipher Suite

注意:通常這個(gè)問題只發(fā)生在你明確的在配置文件中指定了 excludedCipherSuites 或者 includedCipherSuites SSL 密碼套件時(shí)。

當(dāng)客戶端嘗試去連接服務(wù)端時(shí)排宰,你會(huì)在日志中看到如下的異常信息:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

服務(wù)端的日志信息通常會(huì)更加詳細(xì):

javax.net.ssl.SSLHandshakeException: no cipher suites in common

這意味著你已經(jīng)在服務(wù)端與客戶端配置了密碼套件似芝,但是它們各自密碼套件的交集為空。

解決辦法

檢查服務(wù)端與客戶端指定的 excludedCipherSuites 以及 includedCipherSuites 屬性的值板甘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末党瓮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盐类,更是在濱河造成了極大的恐慌寞奸,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件在跳,死亡現(xiàn)場(chǎng)離奇詭異枪萄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)硬毕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門呻引,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吐咳,你說我怎么就攤上這事逻悠≡” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵童谒,是天一觀的道長(zhǎng)单旁。 經(jīng)常有香客問我,道長(zhǎng)饥伊,這世上最難降的妖魔是什么象浑? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮琅豆,結(jié)果婚禮上愉豺,老公的妹妹穿的比我還像新娘。我一直安慰自己茫因,他們只是感情好蚪拦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冻押,像睡著了一般驰贷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洛巢,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天括袒,我揣著相機(jī)與錄音,去河邊找鬼稿茉。 笑死锹锰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的漓库。 我是一名探鬼主播城须,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼米苹!你這毒婦竟也來了糕伐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤蘸嘶,失蹤者是張志新(化名)和其女友劉穎良瞧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體训唱,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褥蚯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了况增。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赞庶。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出歧强,到底是詐尸還是另有隱情澜薄,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布摊册,位于F島的核電站肤京,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茅特。R本人自食惡果不足惜忘分,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望白修。 院中可真熱鬧妒峦,春花似錦、人聲如沸兵睛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卤恳。三九已至,卻和暖如春寒矿,著一層夾襖步出監(jiān)牢的瞬間突琳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國打工符相, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拆融,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓啊终,卻偏偏與公主長(zhǎng)得像镜豹,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蓝牲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容