nginx环境下配置ssl加密(单双向认证、部分https)

2019-10-17 19:13:22丽君
登录页面进行加密的栗子:

root /apps/www;
index index.html index.htm;

server {
  listen   80;
  server_name example.com;

  location ^~ /account/login {
    rewrite ^ https://$server_name:443$request_uri? permanent;
  }
  location / {
    proxy_pass http://localhost:8080;

    ### Set headers ####
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect   off; 
  }
}

server {
  listen 443 ssl;
  server_name example.com;

  ssl on;
  ssl_certificate ../SSL/ittest.pem;
  ssl_certificate_key ../SSL/ittest.key;
  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
  ssl_prefer_server_ciphers on;

  location ^~ /account/login {
    proxy_pass http://localhost:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect   off;

    ### Most PHP, Python, Rails, Java App can use this header -> https ###
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  location / {
    rewrite ^ http://$server_name$request_uri? permanent;
  }
}

关于rewrite与location的写法参考这里。当浏览器访问http://example.com/account/login.xx时,被301到https://example.com/account/login.xx,在这个ssl加密的虚拟主机里也匹配到/account/login,反向代理到后端服务器,后面的传输过程是没有https的。这个login.xx页面下的其它资源也是经过https请求nginx的,登录成功后跳转到首页时的链接使用http,这个可能需要开发代码里面控制。

上面配置中使用了proxy_set_header X-Forwarded-Proto$scheme,在jsp页面使用request.getScheme()得到的是https 。如果不把请求的$scheme协议设置在header里,后端jsp页面会一直认为是http,将导致响应异常。 ssl配置块还有个与不加密的80端口类似的