Nginx 启用 https

在nginx.conf中增加新server配置

    server {
        listen 443;
        server_name www.some.com;
        ssl on;
        ssl_certificate sslkey/some.com.crt;
        ssl_certificate_key sslkey/some.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL;
        ssl_prefer_server_ciphers on;

        location / {
            proxy_pass http://tomcat_www;
        }
        access_log logs/www-ssl.access.log main;
    }

对于需要强制跳转的80端口访问, 使用

    server {
        listen       80;
        server_name www.some.com;
        location / {
            root   /var/www/html;
            index  index.html; # meta jump to https
        }
        access_log logs/www.access.log main;
    }

index.html使用

<html>
<meta http-equiv="refresh" content="0;url=https://www.some.com/">
</html>

 

其他的跳转方案一:

    server {  
        listen  192.168.1.111:80;  
        server_name test.com;  
          
        rewrite ^(.*)$  https://$host$1 permanent;  
    }  

方案二

    server {  
        listen       192.168.1.11:443;  #ssl端口  
        listen       192.168.1.11:80;   #用户习惯用http访问,加上80,后面通过497状态码让它自动跳到443端口  
        server_name  test.com;  
        #为一个server{......}开启ssl支持  
        ssl                  on;  
        #指定PEM格式的证书文件   
        ssl_certificate      /etc/nginx/test.pem;   
        #指定PEM格式的私钥文件  
        ssl_certificate_key  /etc/nginx/test.key;  
          
        #让http请求重定向到https请求   
        error_page 497  https://$host$uri?$args;  
    }  

使用openssl 给nginx生成证书的shell脚本

#!/bin/sh

# Preparing directories and files
mkdir -p demoCA/private
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo -e "01\n" >> demoCA/serial

read -p "Enter your Organization [RockBB]: " ORGANIZATION
read -p "Enter your Organization Unit [Board]: " ORGANIZATION_UNIT
read -p "Enter your domain [www.example.com]: " DOMAIN
read -p "Enter your client name [client]: " CLIENT_NAME
read -p "Enter your p12 password [111111]: " PASSWORD
SUBJECT="/C=CN/ST=Beijing/L=Chaoyang/O=$ORGANIZATION/OU=$ORGANIZATION_UNIT/CN=$DOMAIN"
echo ""
echo "create self-signed certificate:"
# create private server key
openssl genrsa -out demoCA/private/cakey.pem 2048
# self-signed certificate
openssl req -new -subj $SUBJECT -x509 -key demoCA/private/cakey.pem -out demoCA/cacert.pem -days 3655

echo ""
echo "create server certificate:"
openssl genrsa -out $DOMAIN.key 1024
openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr
openssl ca -in $DOMAIN.csr -out $DOMAIN.crt -days=3650

echo ""
echo "create client certificate"
SUBJECT_CLIENT="/C=CN/ST=Beijing/L=Chaoyang/O=$ORGANIZATION/OU=$ORGANIZATION_UNIT/CN=$CLIENT_NAME"
openssl genrsa -out $DOMAIN.client.key 1024
openssl req -new -subj $SUBJECT_CLIENT -key $DOMAIN.client.key -out $DOMAIN.client.csr
openssl ca -batch -in $DOMAIN.client.csr -out $DOMAIN.client.crt -days=3650
openssl pkcs12 -export -clcerts -in $DOMAIN.client.crt -inkey $DOMAIN.client.key -out $DOMAIN.client.p12 -pasword pass:$PASSWORD

echo ""
echo "Update the Nginx configuration:"

: <<'END'
upstream tomcat_admin {
    server 10.1.1.3:8080;
}
server {
    listen       80;
    server_name www.rockbb.com;
    location / {
        rewrite ^(.*)$ https://$host$1 permanent;
    }
    access_log logs/www.access.log main;
}
server {
    listen       443;
    server_name www.rockbb.com;
    ssl on;
    ssl_certificate sslkey/www.rockbb.com.crt;
    ssl_certificate_key sslkey/www.rockbb.com.key;
    ssl_client_certificate sslkey/www.rockbb.com.cacert.pem;
    ssl_session_timeout 5m;
    ssl_verify_client on;
    ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://tomcat_admin;
        proxy_redirect http:// $scheme://;
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } access_log logs/www-ssl.access.log main; } END

制作的过程中, 如果需要重新制作, 删除demoCA目录以及同级目录下的其他文件即可.

如果在浏览器上重复安装同参数但是第二次生成的证书, 会出现这样的错误

An error occurred during a connection to internal.yihuicai.cn. You have received an invalid certificate. Please contact the server administrator or email correspondent and give them the following information: Your certificate contains the same serial number as another certificate issued by the certificate authority. Please get a new certificate containing a unique serial number. Error code: SEC_ERROR_REUSED_ISSUER_AND_SERIAL

这是因为浏览器的旧证书没有清除干净导致的, 除了我的/个人部分外, 服务器证书下, 也需要清理.

 

其中 proxy_redirect http:// $scheme://; 用于让上游的tomcat知道访问者使用的是https协议, 避免java应用在request中得到错误的schema而使用http进行跳转

Update 2017-02-03 在同一服务器上同时使用商业证书和自签发证书时, 安卓客户端访问出现 java.security.cert.CertPathValidatorException: Trust anchor for certification path not found 错误的解决:

在命令行下, 检查证书是否正确

# 
openssl s_client -connect app.somedomain.cn:443 | openssl x509 -noout -subject -issuer
# 明细
openssl s_client -debug -connect app.somedomain.cn:443

如果上面的结果中, 出现的证书是自签发证书或者 verify error:num=21:unable to verify the first certificate , 就说明商业证书未生效. 解决的办法, 是在nginx中将对应IP的证书也设置为商业证书, 而原来直接用IP访问的应用, 新建一个二级域名来访问.

Update 2019-06-28 对于通过upstrean来映射到公网的Jenkins服务器, 来源端口是8080, 公网端口是6443, 虽然已经在Jenkins配置中, 将带端口的URL配置上, 但是在登录跳转和登出跳转时, 还是会跳到不带端口的URL上, 经过各种尝试, 发现是nginx配置中, 未将来源端口信息带给upstrean, 应当在 proxy_set_header Host 时, 加上端口信息 $host:$server_port, 如下

  location /jenkins/ {
    proxy_pass http://jenkins_main;
    #proxy_set_header Host $host;
    proxy_set_header Host $host:$server_port;
    proxy_redirect http:// $scheme://;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_intercept_errors on;
  }

 

 

Nginx启用 HTTP/2

参考 https://www.nginx.com/blog/nginx-1-9-5/

在nginx中启用http2必须先启用ssl, 然后只需要在listen中增加 http2 参数, reload就可以了.

server {
  listen       443 ssl http2;
  server_name www.aa.cn;
  ssl_certificate sslkey/aa.cn_bundle.crt.201806;
  ssl_certificate_key sslkey/aa.cn.key.201806;
  ssl_session_timeout 5m;
  ...

.这里有一个问题, 如果你配置了多个virtual server, 对应的都是同一个IP+Port, 那么在其中一个server上启用http2会同时在这个IP+Port对应的其他Virtual Server上也启用http2. 这里是这么解释的 https://stackoverflow.com/questions/40987592/can-i-enable-http-2-for-specific-server-blocks-virtual-hosts-only-on-nginx

When starting, nginx first creates a separate process for every group of virtual hosts that listen on the same IP:port combination, and then sets the capabilities of that process to be the sum of all capabilities of every virtual host in that group handled by said process.

In your case, there's only one process that handles all the virtual hosts bound to *:443, so the process includes the http2 capability.

In order to achieve what you want, you need to make nginx spawn a different process that doesn't have the http2 capability on a separate IP:port combination.

For the virtual hosts you want to be accessed via http2, you must either:

use a different port - trivial, just use another port for them (e.g. listen 8443 ssl http2;) and remove http2 from all the others (e.g. `listen 443 ssl;)
use a different IP - you need to add another IP to the same NIC that uses your current IP and modify your virtual hosts accordingly (e.g. listen new_ip:443 ssl http2; and listen current_ip:443 ssl; respectively)

 

posted on 2016-01-09 16:42  Milton  阅读(1297)  评论(0编辑  收藏  举报

导航