apache多SSL证书虚拟主机使用mod_jk方式代理tomcat

1.问题背景

   公司旧版的客户端产品之前使用了早期的证书(其签名算法是SHA1),只能与带有 SHA1证书的tomcat服务器通信。
SHA1的证书今年年底都要进行吊销,也就是说年底需要重新签发成sha256证书。

Google关于淘汰SHA1的资料

https://security.googleblog.com/2015/12/an-update-on-sha-1-certificates-in.html

CA/Browser Forum关于通过淘汰SHA1的资料

https://cabforum.org/2014/10/16/ballot-118-sha-1-sunset/

同时,新版客户端产品能够支持sha256证书,也能支持sha1证书。因此,为了兼容性不同版本的客户端产品对证书签名算法的支持,需要在tomcat服务器端配置多SSL证书机制。


2.技术知识背景

“早期的SSLv2根据经典的公钥基础设施PKI(Public Key Infrastructure)设计,它默认认为:一台服务器(或者说一个IP)只会提供一个服务,所以在SSL握手时,服务器端可以确信客户端申请的是哪张证书。
但是让人万万没有想到的是,虚拟主机大力发展起来了,这就造成了一个IP会对应多个域名的情况。解决办法有一些,例如申请泛域名证书,对所有*.yourdomain.com的域名都可以认证,但如果你还有一个yourdomain.net的域名,那就不行了。
在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。
既然问题的原因是在SSL握手时缺少主机头信息,那么补上就是了。
SNI(Server Name Indication)定义在RFC 4366,是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。
[warning]要使用SNI,需要客户端和服务器端同时满足条件,幸好对于现代浏览器来说,大部分都支持SSLv3/TLSv1,所以都可以享受SNI带来的便利。”--参考自《 SNI: 实现多域名虚拟主机的SSL/TLS认证》
更多的参考资料:
《 Server Name Indication wiki》中文翻译请查看我的博文《 服务器支持tls双证书机制Server Name Indication翻译》
《 rfc4366规范的SNI部分》   HowTo setup Tomcat serving two SSL Certificates using SNI? 》  《服务器名字指示SNI介绍》

找了很多资料,并没有很好的对tomca的多证书支持的配置资料,而apahce对多证书的支持的资料较多,从后续的维护权衡,采用apahce的代理tomcat方式来配置web服务器的多证书。apache对SNI的支持能够采用mod_ssl和mod_gnutls来支持,mod_gnutls需要安装gnutls模块,安装步骤十分繁琐又容易出错,故不采用(本人安装过,绕了一大圈一大堆的依赖,最后不得不放弃。)。网上拷贝的文章有些是过时的,采用的是gnutls,其实mod_ssl早已支持SNI机制,因为它依赖于openssl,而openssl在 0.9.8f 版就已经支持SNI了,同时注意Apache的版本 2.2.12 and later才能实现SNI。

3.问题处理

3.1  软件环境

apache2.2.31   tomcat-7.0.64   mod_ssl( apache2.2.31编译自带的版本)   mod_jk  linux centos6操作系统

3.2  软件安装

先来安装apache2.2.31
下载Apache安装包apache2.2.31 ,下载地址:http://httpd.apache.org/
编译命令:
./configure --prefix=/usr/local/apache2 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ 
(除了指定Apache的安装目录外,还要安装apr、apr-util并指定参数)
make
make install
在编译Apache时分别出现了apr not found、APR-util not found  not found的问题,下面就这些问题解决来实际操作一把。
http://apr.apache.org/download.cgi  下载apr-1.4.5.tar.gz、apr-util-1.3.12.tar.gz
1.解决apr not found问题
  [root@localhost bin]# tar -zxf apr-1.4.5.tar.gz
  [root@localhost apr-1.4.5]# ./configure --prefix=/usr/local/apr
  [root@localhost apr-1.4.5]# make
  [root@localhost apr-1.4.5]# make install
2.解决APR-util not found问题
  [root@localhost bin]# tar -zxf apr-util-1.3.12.tar.gz
  [root@localhost apr-util-1.3.12]# ./configure --prefix=/usr/local/apr-util -with-apr=/usr/local/apr/bin/apr-1-config
  [root@localhost apr-util-1.3.12]# make
  [root@localhost apr-util-1.3.12]# make install

安装好了apache后再来看下在apache上安装mod_ssl模块(可以在安装apahce时就顺带安装mod_ssl,在configure 命令追加 --enable- mods-shared=all --enable-ssl,在此主要说明如何灵活地安装apahce的模块)
1. 首先定位到Apache源码的 proxy目录
# cd /root/Desktop/httpd-2.2.31
# cd modules/proxy/
2. 编译相应模块:
其中 "/usr/local/apache2" 为之前Apache的安装目录
# /usr/local/apache2/bin/apxs -c -i mod_proxy.c proxy_util.c
加载模块:
# /usr/local/apache2/bin/apxs -i -a -n proxy mod_proxy.la
这样,就将proxy安装成功了,你可以到httpd.conf中看到自动添加了如下语句:
LoadModule ssl_module        modules/mod_ssl.so
modules 文件夹中也生成了相应的  mod_ssl.so 模块,要安装其他模块也是同样的流程。
至于mod_jk如何安装和配置知识可参考《 Tomcat系列之Apache使用mod_proxy和mod_jk反向代理Tomcat》

3.3  配置

apache httpd.conf文件配置:
ServerRoot "/usr/local/apache2"

LoadModule ssl_module modules/mod_ssl.so



#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.  
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User daemon
Group daemon





ServerAdmin [email protected]


    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all



    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all


#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#

    DirectoryIndex index.html


#
# The following lines prevent .htaccess and .htpasswd files from being 
# viewed by Web clients. 
#

    Order allow,deny
    Deny from all
    Satisfy All


ErrorLog "logs/error_log"

LogLevel warn


    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    

    CustomLog "logs/access_log" common



    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"







    AllowOverride None
    Options None
    Order allow,deny
    Allow from all



DefaultType text/plain


    #
    # TypesConfig points to the file containing the list of mappings from
    # filename extension to MIME-type.
    #
    TypesConfig conf/mime.types

    #
    # AddType allows you to add to or override the MIME configuration
    # file specified in TypesConfig for specific file types.
    #
    #AddType application/x-gzip .tgz
    #
    # AddEncoding allows you to have certain browsers uncompress
    # information on the fly. Note: Not all browsers support this.
    #
    #AddEncoding x-compress .Z
    #AddEncoding x-gzip .gz .tgz
    #
    # If the AddEncoding directives above are commented-out, then you
    # probably should define those extensions to indicate media types:
    #
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

    #
    # AddHandler allows you to map certain file extensions to "handlers":
    # actions unrelated to filetype. These can be either built into the server
    # or added with the Action directive (see below)
    #
    # To use CGI scripts outside of ScriptAliased directories:
    # (You will also need to add "ExecCGI" to the "Options" directive.)
    #
    #AddHandler cgi-script .cgi

    # For type maps (negotiated resources):
    #AddHandler type-map var

    #
    # Filters allow you to process content before it is sent to the client.
    #
    # To parse .shtml files for server-side includes (SSI):
    # (You will also need to add "Includes" to the "Options" directive.)
    #
    #AddType text/html .shtml
    #AddOutputFilter INCLUDES .shtml

# Server-pool management (MPM specific)
#Include conf/extra/httpd-mpm.conf

# Multi-language error messages
#Include conf/extra/httpd-multilang-errordoc.conf

# Fancy directory listings
#Include conf/extra/httpd-autoindex.conf

# Language settings
#Include conf/extra/httpd-languages.conf

# User home directories
#Include conf/extra/httpd-userdir.conf

# Real-time info on requests and configuration
#Include conf/extra/httpd-info.conf

# Virtual hosts
#Include conf/extra/httpd-vhosts.conf

# Local access to the Apache HTTP Server Manual
#Include conf/extra/httpd-manual.conf

# Distributed authoring and versioning (WebDAV)
#Include conf/extra/httpd-dav.conf

# Various default settings
#Include conf/extra/httpd-default.conf

# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf


SSLRandomSeed startup builtin
SSLRandomSeed connect builtin


# Load the mod_jk
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /usr/local/apache2/conf/extra/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel debug


  
    Options Indexes FollowSymLinks  
    AllowOverride None  
    Order allow,deny  
    Allow from all  
 



mod_jk的workers.properties文件配置:
#让mod_jk模块知道tomcat的位置 
workers.tomcat_home=/usr/local/apache-tomcat-7.0.64

worker.list=TomcatA
worker.TomcatA.port=8009
worker.TomcatA.host=localhost
worker.TomcatA.type=ajp13
worker.TomcatA.lbfactor=1

httpd-ssl.conf文件配置:
NameVirtualHost *:443
Listen 443

AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4


SSLHonorCipherOrder on 


SSLProtocol all -SSLv2 -SSLv3
SSLProxyProtocol all -SSLv2 -SSLv3


SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300

#   Semaphore:
#   Configure the path to the mutual exclusion semaphore the
#   SSL engine uses internally for inter-process synchronization. 
SSLMutex  "file:/usr/local/apache2/logs/ssl_mutex"

  
    Options Indexes FollowSymLinks  
    AllowOverride None  
    Order allow,deny  
    Allow from all  
 


DocumentRoot "/usr/local/apache-tomcat-7.0.64/webapps/rs"
ServerName ******************:443
ServerAdmin [email protected]
ErrorLog "/usr/local/apache2/logs/old_error_log"
TransferLog "/usr/local/apache2/logs/old_access_log"

JkMount /* TomcatA

SSLEngine on
SSLCertificateFile "/usr/local/apache-ssl-files/old/rps.crt"
SSLCertificateKeyFile "/usr/local/apache-ssl-files/old/rps.key"
SSLCertificateChainFile "/usr/local/apache-ssl-files/old/rps_ca2.cer"


    SSLOptions +StdEnvVars


    SSLOptions +StdEnvVars



BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog "/usr/local/apache2/logs/ssl_request_log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"




DocumentRoot "/usr/local/apache-tomcat-7.0.64/webapps/rs"
#DocumentRoot "/usr/local/apache2/htdocs"
DirectoryIndex index.html index.jsp
ServerName rps.test.com:443
ServerAdmin [email protected]
ErrorLog "/usr/local/apache2/logs/new_error_log"
TransferLog "/usr/local/apache2/logs/new_access_log"

JkMount /* TomcatA

SSLEngine on

SSLCertificateFile "/usr/local/apache-ssl-files/new/rps.cer"
SSLCertificateKeyFile "/usr/local/apache-ssl-files/new/rps.key"
SSLCertificateChainFile "/usr/local/apache-ssl-files/new/root.cer"


    SSLOptions +StdEnvVars


    SSLOptions +StdEnvVars


BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog "/usr/local/apache2/logs/ssl_request_log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
 
注意:默认的虚拟主机的配置  ServerName ******************:443 是采用通配符方式,有请求过来时先去匹配显示指定域名的主机,直到找不到,最后会匹配通配符的主机,apache 通配符的主机会对应tomcat的localhost的主机配置,所以DocumentRoot的路径配置要和tomcat的localhost的路径配置一致。

tomcat的server.xml配置:




  
  
  
  
  
  
  
  
  
  

  
  
    
    
  

  
  

    
    
    
    

    
    

      
      

      
      
        
        
      

      

        
        

        
        
	
      


      
        
     

    
  

apache采用mod_jk代理tomcat的原理配置具体可参考: apache+tomcat+mod_jk整合配置虚拟主机


你可能感兴趣的:(通信,web服务器,java安全)