Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法


Posted in Python onAugust 16, 2015

HTTPS简介
HTTPS(Hyper Text Transfer Protocol Secure),是一种基于SSL/TLS的HTTP,所有的HTTP数据都是在SSL/TLS协议封装之上进行传输的。HTTPS协议是在HTTP协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。Https使用的默认端口是443。更多HTTPS原理可以参考阮一峰老师的文章:http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

SSL证书
证书类型简介
要设置安全服务器,使用公共钥创建一对公私钥对。大多数情况下,发送证书请求(包括自己的公钥),你的公司证明材料以及费用到一个证书颁发机构(CA)。CA验证证书请求及您的身份,然后将证书返回给您的安全服务器。
但是内网实现一个服务器端和客户端传输内容的加密,可以自己给自己颁发证书,只需要忽略掉浏览器不信任的警报即可!
由CA签署的证书为您的服务器提供两个重要的功能:

  1.     浏览器会自动识别证书并且在不提示用户的情况下允许创建一个安全连接。
  2.     当一个CA生成一个签署过的证书,它为提供网页给浏览器的组织提供身份担保。

    多数支持ssl的web服务器都有一个CA列表,它们的证书会被自动接受。当一个浏览器遇到一个其授权CA并不在列表中的证书,浏览器将询问用户是否接受或拒绝连接。

制作CA证书
ca.key CA私钥:

    openssl genrsa -des3 -out ca.key 2048  

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

    ca.crt CA根证书(公钥):

openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

制作网站的证书并用CA签名认证
这里,假设网站域名为www.example.com,生成com.example.com证书私钥:

 

openssl genrsa -des3 -out www.example.com.pem 1024

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

    制作解密后的www.example.com证书私钥:

openssl rsa -in www.example.com.pem -out www.example.com.key

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

    生成签名请求:

openssl req -new -key www.example.com.pem -out www.example.com.csr

   

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

    可以在Common Name中填入网站域名,即可生产该网站的证书。
用CA进行签名:

   
openssl ca -policy policy_anything -days 365 -cert ca.crt -keyfile ca.key -in www.example.com.csr -out www.example.com.crt 
可能执行签名时,会出现“I am unable to access the ./demoCA/newcerts directory”问题:

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

解决方法:

mkdir -p demoCA/newcerts 
  touch demoCA/index.txt 
  touch demoCA/serial 
  echo "01" > demoCA/serial

然后,再执行签名命令即可。

基于Nginx搭建HTTPS虚拟主机
虚拟主机配置文件

upstream sslfpm { 
    server 127.0.0.1:9000  weight=10  max_fails=3 fail_timeout=20s; 
  } 
   
  server {  
    listen    192.168.1.*:443;  
    server_name 192.168.1.*;  
     
    #为一个server开启ssl支持 
    ssl         on; 
    #为虚拟主机指定pem格式的证书文件 
    ssl_certificate   /home/wangzhengyi/ssl/wangzhengyi.crt;  
    #为虚拟主机指定私钥文件 
    ssl_certificate_key /home/wangzhengyi/ssl/wangzhengyi_nopass.key;  
    #客户端能够重复使用存储在缓存中的会话参数时间 
    ssl_session_timeout 5m; 
    #指定使用的ssl协议  
    ssl_protocols SSLv3 TLSv1;  
    #指定许可的密码描述 
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;  
    #SSLv3和TLSv1协议的服务器密码需求优先级高于客户端密码 
    ssl_prefer_server_ciphers  on;  
   
    location / {  
      root  /home/wangzhengyi/ssl/; 
      autoindex on; 
        autoindex_exact_size  off; 
        autoindex_localtime on; 
    }  
      # redirect server error pages to the static page /50x.html 
      # 
      error_page  500 502 503 504 /50x.html; 
      error_page  404 /404.html; 
   
    location = /50x.html { 
        root  /usr/share/nginx/www; 
      } 
    location = /404.html { 
        root  /usr/share/nginx/www; 
      } 
     
      # proxy the PHP scripts to fpm 
      location ~ \.php$ { 
      access_log /var/log/nginx/ssl/ssl.access.log main; 
      error_log /var/log/nginx/ssl/ssl.error.log; 
      root /home/wangzhengyi/ssl/;  
      fastcgi_param  HTTPS  on; 
        include /etc/nginx/fastcgi_params;  
        fastcgi_pass  sslfpm; 
      } 
  }

HTTPS服务器优化
方法
SSL操作需要消耗CPU资源,所以在多处理器的系统,需要启动多个工作进程,而且数量需要不少于可用CPU的个数。最消耗CPU资源的SSL操作是SSL握手,有两种方法可以将每个客户端的握手操作数量降到最低:

    保持客户端长连接,在一个SSL连接发送多个请求
    在并发的连接或者后续的连接中重用SSL会话参数,这样可以避免SSL握手操作。

会话缓存用于保存SSL会话,这些缓存在工作进程间共享,可以使用ssl_session_cache指令进行配置。1M缓存可以存放约4000个会话。默认的缓存超时时间是5m,可以使用ssl_session_timeout加大它。
ssl_session_cache指令

    语法:ssl_session_cache off|none|builtin:size|shared:name:size 
    使用环境:main,server 
    缓存类型: 
    off -- 硬关闭,nginx明确告诉客户端这个会话不可重用 
    none -- 软关闭,nginx告诉客户端会话能够被重用,但是nginx实际上不会重用它们 
    bultin -- openssl内置缓存,仅可用于一个工作进程.可能导致内存碎片 
    shared -- 所有工作进程的共享缓存。(1)缓存大小用字节数指定(2)每个缓存必须拥有自己的名称(3)同名的缓存可用于多个虚拟主机 

优化示例

#优化ssl服务 
  ssl_session_cache  shared:wzy:10m;  
  #客户端能够重复使用存储在缓存中的会话参数时间 
  ssl_session_timeout 10m;

nginx强制使用https访问(http跳转到https)

基于nginx搭建了一个https访问的虚拟主机,监听的域名是test.com,但是很多用户不清楚https和http的区别,会很容易敲成http://test.com,这时会报出404错误,所以我需要做基于test.com域名的http向https的强制跳转

nginx的rewrite方法

思路
这应该是大家最容易想到的方法,将所有的http请求通过rewrite重写到https上即可

配置

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

搭建此虚拟主机完成后,就可以将http://test.com的请求全部重写到https://test.com上了

nginx的497状态码

error code 497

  497 - normal request was sent to HTTPS

解释:当此虚拟站点只允许https访问时,当用http访问时nginx会报出497错误码

思路
利用error_page命令将497状态码的链接重定向到https://test.com这个域名上

配置

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; 
  }

index.html刷新网页

思路
上述两种方法均会耗费服务器的资源,我们用curl访问baidu.com试一下,看百度的公司是如何实现baidu.com向www.baidu.com的跳转

Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法

可以看到百度很巧妙的利用meta的刷新作用,将baidu.com跳转到www.baidu.com.因此我们可以基于http://test.com的虚拟主机路径下也写一个index.html,内容就是http向https的跳转

index.html

  <html> 
  <meta http-equiv="refresh" content="0;url=https://test.com/"> 
  </html>
Python 相关文章推荐
wxPython学习之主框架实例
Sep 28 Python
python实现提取百度搜索结果的方法
May 19 Python
浅谈Python 集合(set)类型的操作——并交差
Jun 30 Python
python中defaultdict的用法详解
Jun 07 Python
Python面向对象程序设计类的封装与继承用法示例
Apr 12 Python
python批量解压zip文件的方法
Aug 20 Python
python GUI库图形界面开发之PyQt5布局控件QVBoxLayout详细使用方法与实例
Mar 06 Python
完美解决keras 读取多个hdf5文件进行训练的问题
Jul 01 Python
pandas.DataFrame.drop_duplicates 用法介绍
Jul 06 Python
python time()的实例用法
Nov 03 Python
python 操作excel表格的方法
Dec 05 Python
python 命令行传参方法总结
May 25 Python
使用Python操作MySQL的一些基本方法
Aug 16 #Python
Python中list列表的一些进阶使用方法介绍
Aug 15 #Python
Python中的super()方法使用简介
Aug 14 #Python
在Python中使用正则表达式的方法
Aug 13 #Python
简单讲解Python中的闭包
Aug 11 #Python
Python实现短网址ShortUrl的Hash运算实例讲解
Aug 10 #Python
python实现web方式logview的方法
Aug 10 #Python
You might like
提升PHP执行速度全攻略(下)
2006/10/09 PHP
PHP图片上传类带图片显示
2006/11/25 PHP
初识ThinkPHP控制器
2016/04/07 PHP
PHP yield关键字功能与用法分析
2019/01/03 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
自己做的模拟模态对话框实现代码
2012/05/23 Javascript
javaScript 动态访问JSon元素示例代码
2013/08/30 Javascript
如何书写高质量jQuery代码(使用jquery性能问题)
2014/06/30 Javascript
Javascript实现Web颜色值转换
2015/02/05 Javascript
详解使用nvm安装node.js
2017/07/18 Javascript
Vue自定义弹窗指令的实现代码
2018/08/13 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
如何写好一个vue组件,老夫的一年经验全在这了(推荐)
2019/05/18 Javascript
JavaScript简单编程实例学习
2020/02/14 Javascript
[53:10]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs VG 第一场
2018/04/11 DOTA
python获取从命令行输入数字的方法
2015/04/29 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
详解python中的index函数用法
2019/08/06 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
Python3开发环境搭建详细教程
2020/06/18 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
2020/12/07 Python
澳大利亚最大的在线美发和美容零售商之一:My Hair Care & Beauty
2019/08/24 全球购物
Java中实现多态的机制是什么?
2014/12/07 面试题
优秀求职自荐信怎样写
2013/12/18 职场文书
财务工作个人求职的自我评价
2013/12/19 职场文书
应届毕业生求职信范文分享
2013/12/26 职场文书
国际贸易专业个人求职信格式
2014/02/02 职场文书
yy婚礼主持词
2014/03/14 职场文书
村抢险救灾方案
2014/05/09 职场文书
领导班子个人对照检查剖析材料
2014/09/29 职场文书
对外汉语教师推荐信
2015/03/27 职场文书
2015年体育教师个人工作总结
2015/05/12 职场文书
肖申克救赎观后感
2015/06/02 职场文书
2016年6月份红领巾广播稿
2015/12/21 职场文书