暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Connector的安全配置属性分析(Tomcat深入研究文章之十七)

中间件技术讨论圈 2016-03-25
522

SSL Support - BIO, NIO and NIO2

The BIO, NIO and NIO2 connectors use the following attributes to configure SSL:

AttributeDescription
algorithm

The certificate encoding algorithm to be used. This defaults to KeyManagerFactory.getDefaultAlgorithm()
 which returns SunX509
 for Sun JVMs. IBM JVMs return IbmX509
. For other vendors, consult the JVM documentation for the default value.


证书编码算法,大白话就是证书的格式类型,默认就是 KeyManagerFactory.getDefaultAlgorithm()
 的返回值,在SUN的JDK返回的是SunX509
  ,对于IBM的JDK返回的默认算法是IbmX509 ,对于其它的版本的JDK也返回对应的默认值。

因为证书实际上都是X.509格式的,所以这个属性基本上就是填默认值即可。

allowUnsafeLegacyRenegotiation

Is unsafe legacy TLS renegotiation allowed which is likely to expose users to CVE-2009-3555, a man-in-the-middle vulnerability in the TLS protocol that allows an attacker to inject arbitrary data into the user's request. If not specified, a default of false
 is used. This attribute only has an effect if the JVM does not support RFC 5746 as indicated by the presence of the pseudo-ciphersuite TLS_EMPTY_RENEGOTIATION_INFO_SCSV. This is available JRE/JDK 6 update 22 onwards. Where RFC 5746 is supported the renegotiation - including support for unsafe legacy renegotiation - is controlled by the JVM configuration.


这个属性描述是TLS renegotiation,在Tomcat中默认是false,也就是没有打开,之所以没有默认打开,是因为老版本的协议中黑客利用协议上的缺陷,可以在用户发送的请求中加入一些非法的消息,用于攻击。

当然,这么重大的bug已经在JDK622中更新了,这个也就是RFC5746的规范的更新的实现。

因为TLS renegotiation用的很少,所以这个属性默认即可,从属性字面上理解,打开也是Unsafe。

useServerCipherSuitesOrder

Set to true
 to enforce the server's cipher order (from the ciphers
 setting). Set to false
 to choose the first acceptable cipher suite presented by the client. Use of this feature requires Java 8 or later. Default isundefined, leaving the choice up to the JSSE implementation.


ciphers 属性是SSL交互过程,Tomcat端配置支持的加密解密算法列表,这个useServerCipherSuitesOrder 属性如果设置成true,是需要严格的按照ciphers 属性配置的服务器端支持的加密解密算法列表的顺序,说白了也就是如果第一个配置的是RSA128,那么浏览器就一定要用RSA128进行加密和解密,否则浏览器要不支持,那再看看下一个,总之这个配置是指导SSL过程客户端和服务器端的交互的顺序。

默认的是false,也就是客户端的算法看看ciphers 属性支不支持,如果支持的话,那么SSL交互就用这个加密解密算法。

不过,值得一提的是这个属性是需要JAVA 8和之后才支持的,目前JDK老版本是无从享用的。

ciphers

If specified and using ',' as a separator, only the ciphers that are listed and supported by the SSL implementation will be used. The ciphers are specified using the JSSE cipher naming convention. The special value of ALL
 will enable all supported ciphers. This will include many that are not secure. ALL
 is intended for testing purposes only.

The list can also use ':' as a separator, in that case it will use the OpenSSL syntax (see OpenSSL documentation for the list of ciphers supported and the syntax). The behaviour of this filtering is kept aligned with the behaviour of the OpenSSL 1.0.2 stable branch.

If not specified, a default (using the OpenSSL notation) of HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5
 will be used.

Note that Java does not treat the order in which ciphers are defined as an order of preference. See useServerCipherSuitesOrder
.


客户端和服务器端需要通过SSL进行传输加密,这个ciphers实际上就是这个SSL过程所支持的加密和解密算法,以,作为分隔,下面给出一个例子:


这个是一个典型的配置,说明目前SSL的过程支持这么多的加密算法,在SSL的过程中,算法根据你的浏览器的默认的配置来的,例如你通过浏览器的插件自己搞一个算法,然后通过浏览器SSL加密过来,因为Tomcat仅仅配置了这些算法列表,所以直接会抛出异常,从服务器端告知服务器不支持该算法。


对于服务器端支持的算法,可以在https://www.ssllabs.com/ssltest/index.html 中进行测试;

对客户端浏览器支持的算法,可以在https://www.ssllabs.com/ssltest/viewMyClient.html 中进行测试;

以当前笔者的浏览器为例,支持的算法为:


你也可以将Tomcat发布的站点搞到互联网中,然后通过这个站点进行测试,而Tomcat其实默认也支持很多种算法,这个可以在源码中看到。

对于当前的ciphers属性的配置,从上面的第二段英文描述可以看到,也支持:这种分隔方式,这种方式是openssl的语法。

clientAuth

Set to true
 if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. Set to want
 if you want the SSL stack to request a client Certificate, but not fail if one isn't presented. A false
 value (which is the default) will not require a certificate chain unless the client requests a resource protected by a security constraint that uses CLIENT-CERT
 authentication.


Tomcat双向SSL认证的配置,也就是客户端的证书在服务端的密钥库中“注册”后,所有的客户端SSL请求携带的证书都需要服务器的认证,也就是这个clientAuth属性配置为true;

配置为false的话,说明无需证书,但是如果你在应用中的web.xml中配置了 CLIENT-CERT
  那么相当于对于当前的应用来说,这个属性设为true;

此属性还提供了一个配置,为want,也就是说如果客户端证书那么就校验一下,校验失败了,也不会报错,属性设置成这个,兼容性比较好;

clientCertProvider

When client certificate information is presented in a form other than instances of java.security.cert.X509Certificate
 it needs to be converted before it can be used and this property controls which JSSE provider is used to perform the conversion. For example it is used with the AJP connectors, the HTTP APR connector and with the org.apache.catalina.valves.SSLValve. If not specified, the default provider will be used.


通过浏览器访问https前缀名,浏览器会自动将证书以X509的格式发送到后端,服务器后端进行解析这个证书格式,也就是使用 java.security.cert.X509Certificate
 进行拿到这个证书,这个是SSL流程中默认的流程。
但是,还有一种情况,就是你可以将证书以form表单的形式跟随者你的form内的数据进行提交,不通过浏览器的机制,自定义SSL客户端的请求,这种以表单的方式的SSL请求在服务器端必须有一个provider进行转换,如果不配置,走服务器默认的provider。

这个属性通常没有这种特殊form请求的需要,不用进行配置。

crlFile

The certificate revocation list to be used to verify client certificates. If not defined, client certificates will not be checked against a certificate revocation list. The file may be specified using a URL, an absolute path or a relative (to CATAINA_BASE) path.


客户端提交的证书是否需要通过CRL进行校验,什么是CRL,这个就是CA中心搞出来的一个证书过期列表,这个列表实际上就是一个文件,可以传递给服务器端作为校验的内容,也就是可以将这个文件的路径放到Tomcat的内部的路径下,相对于CATAINA_BASE 的路径。
对于CRL文件还需要动态的变化,所以一般上面的做法不太好,最好的方式是CA中心一般会提供一个远程的URL的在线服务,也就是可以通过http方式去实时在线获取CRL列表,那么这种就需要配置一个URL了。

keyAlias

The alias used for the server key and certificate in the keystore. If not specified, the first key read from the keystore will be used. The order in which keys are read from the keystore is implementation dependent. It may not be the case that keys are read from the keystore in the same order as they were added. If more than one key is present in the keystore it is strongly recommended that a keyAlias is configured to ensure that the correct key is used.


服务器端的密钥别名,所谓的别名就是一个keystore生成的秘钥库中,有n多的密钥对,后面的Tomcat指定了keystoreFile 这个属性,但这个属性是一个大的密钥库,这个属性就是你需要指定其中哪一个密钥是作为服务器端的密钥。

如果不指定的话,默认keystoreFile 中就是一个密钥对,找第一个密钥直接返回。

这个属性,如果你的keystore是通过keytools创建的,并且里面就有一个密钥,那你不指定也无所谓,但是里面存储了n多的条目,那必须要指定。

keyPass

The password used to access the server certificate from the specified keystore file. The default value is "changeit
".


服务器端的密钥的密码,这个密码不是keystore的密码,是上面定义的keyAlias 的key的密码。

默认的情况下,当你使用keytools创建的时候,会默认将其设置为和keystorePass一样的密码,你也可以自定义设定,如果没设定,默认就是changeit。

keystoreFile

The pathname of the keystore file where you have stored the server certificate to be loaded. By default, the pathname is the file ".keystore
" in the operating system home directory of the user that is running Tomcat. If your keystoreType
 doesn't need a file use ""
 (empty string) for this parameter. The file may be specified using a URL, an absolute path or a relative (to CATAINA_BASE) path.


服务器端的keystore的位置,大白话也就是服务器端存储密钥的“数据库”。

keystorePass

The password used to access the specified keystore file. The default value is the value of the keyPass
 attribute.


服务器端的keystore的密码,注意和前面的keypass属性区分。

keystoreProvider

The name of the keystore provider to be used for the server certificate. If not specified, the list of registered providers is traversed in preference order and the first provider that supports the keystoreType
 is used.


对于keystore其实是可以进行定制的,也就是你需要实现一个keystoreProvider,然后安装到JSSE的环境中。

如果没有指定的话,默认就是Tomcat自带的keystoreProvider,这个看你需不需要扩展了,一般没必要。

keystoreType

The type of keystore file to be used for the server certificate. If not specified, the default value is "JKS
".


keystoreType是keystore文件的格式,一般就是jks,有的还可能支持P12这种的。

通过keytools生成的就是jks的(虽然有的后缀名是.keystore),当你要导入其它格式的keytore的话,需要设置。

sessionCacheSize

The number of SSL sessions to maintain in the session cache. Use 0 to specify an unlimited cache size. If not specified, a default of 0 is used.


SSL的Sesssion的数量控制,设置为0的话,就是不限制。

一般这个数量控制根据你的应用的需求,如果Session特别耗内存的话,那么可以设置控制一下。

sessionTimeout

The time, in seconds, after the creation of an SSL session that it will timeout. Use 0 to specify an unlimited timeout. If not specified, a default of 86400 (24 hours) is used.


SSL的Session超时时间,设置为0为无限制,一直存在于Session中。

一般都会设定一个值,如30分钟左右,否则长时间运行的服务器肯定受不了。

sslEnabledProtocols

The comma separated list of SSL protocols to support for HTTPS connections. If specified, only the protocols that are listed and supported by the SSL implementation will be enabled. If not specified, the JVM default (excluding SSLv2 and SSLv3 if the JVM enables either or both of them by default) is used. The permitted values may be obtained from the JVM documentation for the allowed values forSSLSocket.setEnabledProtocols()
 e.g. Oracle Java 7. Note: There is overlap between this attribute and sslProtocol
.


该属性是SSL支持的协议类型,以逗号进行分割,如SSLv1,TLS等这种。

如果不指定的话,那么就根据当前Tomcat运行的JVM中的默认配置,也就是SSLSocket.setEnabledProtocols()
 的返回值。

这个属性提供了一个列表,和下面的sslProtocol有重复。

sslImplementationName

The class name of the SSL implementation to use. If not specified, the default of org.apache.tomcat.util.net.jsse.JSSEImplementation
 will be used which wraps JVM's default JSSE provider. Note that the JVM can be configured to use a different JSSE provider as the default.


这个属性是可以扩展JSSE的实现的JDK的provider的,如果不设置,默认就是用的 org.apache.tomcat.util.net.jsse.JSSEImplementation
 。

sslProtocol

The SSL protocol(s) to use (a single value may enable multiple protocols - see the JVM documentation for details). If not specified, the default is TLS
. The permitted values may be obtained from the JVM documentation for the allowed values for algorithm when creating an SSLContext
 instance e.g. Oracle Java 7. Note: There is overlap between this attribute and sslEnabledProtocols
.


和上面的sslEnabledProtocols属性类似,但这个仅仅能指定一个协议,默认就是TLS。

这个属性直接用于创建SSLContext的,也就是唯一指定。

这个属性和下面的sslEnabledProtocols有重复,设置的时候如果明确采用哪个协议,尽量使用这个属性,否则可能产生冲突,尽量二选一

trustManagerClassName

The name of a custom trust manager class to use to validate client certificates. The class must have a zero argument constructor and must also implement javax.net.ssl.X509TrustManager
. If this attribute is set, the trust store attributes may be ignored.


这个属性是设置客户端的证书的验证类的,如果你设置这个类,需要有一个无参的构造函数,还需要实现一个 javax.net.ssl.X509TrustManager
 。

如果这个属性被设置了,那么下面的truststore的这些属性都被忽略掉了,由这个类自定义服务器对客户端的验证。

trustMaxCertLength

The maximum number of intermediate certificates that will be allowed when validating client certificates. If not specified, the default value of 5 will be used.


证书有证书链,也即是从根证书到对应的客户端的证书,一共分几个层级,Tomcat验证客户端的证书的时候,可以设置验证过程中,走的证书的级数,也就是最大的证书的长度,默认为5,也就是5级。

truststoreAlgorithm

The algorithm to use for truststore. If not specified, the default value returned by javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()
 is used.


truststore也就是客户端的证书存放的keystore位置,这个属性是设置这个truststore的采用什么算法生成密钥,公钥证书签名和摘要算法的。

默认这个就是javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm() 的返回值。

truststoreFile

The trust store file to use to validate client certificates. The default is the value of the javax.net.ssl.trustStore
 system property. If neither this attribute nor the default system property is set, no trust store will be configured. The file may be specified using a URL, an absolute path or a relative (to CATAINA_BASE) path.


客户端的证书需要导入到服务器端一个位置,也就是对客户端证书进行“注册”,这个路径就是truststoreFile的属性。

同理,这个路径可以相对于CATAINA_BASE,也可以指定一个网上的URL。

truststorePass

The password to access the trust store. The default is the value of the javax.net.ssl.trustStorePassword
 system property. If that property is null, no trust store password will be configured. If an invalid trust store password is specified, a warning will be logged and an attempt will be made to access the trust store without a password which will skip validation of the trust store contents.


truststore的密码,默认就是javax.net.ssl.trustStorePassword
  环境变量中的值。

如果不设置值,那么就没有密码。

truststoreProvider

The name of the truststore provider to be used for the server certificate. The default is the value of the javax.net.ssl.trustStoreProvider
 system property. If that property is null, the value ofkeystoreProvider
 is used as the default. If neither this attribute, the default system property nor keystoreProvider
is set, the list of registered providers is traversed in preference order and the first provider that supports the truststoreType
 is used.


这个属性是扩展truststore的实现,默认值就是 javax.net.ssl.trustStoreProvider
 的环境变量,如果环境变量为null,这个值就会被设置成keystoreProvider
 ,也就是用keystore的provider来支持truststore。

truststoreType

The type of key store used for the trust store. The default is the value of the javax.net.ssl.trustStoreType
 system property. If that property is null, the value of keystoreType
 is used as the default.


truststore支持的类型,和keystoreType一样,也是jks,当然你也可以设置其他的,如p12.


总结一下:

http://tomcat.apache.org/tomcat-8.0-doc/config/http.html#SSL_Support_-_BIO,_NIO_and_NIO2  这个链接是配置的属性 。

本属性解释,是针对于JSSE的实现的,并不包括APR的,APR后续再进行研究。



文章转载自中间件技术讨论圈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论