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 相关文章推荐
Python实现队列的方法
May 26 Python
python中matplotlib实现最小二乘法拟合的过程详解
Jul 11 Python
python opencv设置摄像头分辨率以及各个参数的方法
Apr 02 Python
python os.listdir按文件存取时间顺序列出目录的实例
Oct 21 Python
Python 通过requests实现腾讯新闻抓取爬虫的方法
Feb 22 Python
python下PyGame的下载与安装过程及遇到问题
Aug 04 Python
Python实现栈和队列的简单操作方法示例
Nov 29 Python
关于Python中定制类的比较运算实例
Dec 19 Python
matplotlib 对坐标的控制,加图例注释的操作
Apr 17 Python
Python嵌入C/C++进行开发详解
Jun 09 Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 Python
python中pow函数用法及功能说明
Dec 04 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 Mssql操作简单封装支持存储过程
2009/12/11 PHP
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
Zend Framework教程之Zend_Db_Table用法详解
2016/03/21 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
PHP按一定比例压缩图片的方法
2018/10/12 PHP
JavaScript RegExp方法获取地址栏参数(面向对象)
2009/03/10 Javascript
FF IE兼容性的修改小结
2009/09/02 Javascript
jQuery中add实现同时选择两个id对象
2010/10/22 Javascript
js导出txt示例代码
2014/01/14 Javascript
js实现网页标题栏闪烁提示效果实例分析
2014/11/20 Javascript
JavaScript学习笔记之基础语法
2015/01/22 Javascript
js确认框confirm()用法实例详解
2016/01/07 Javascript
基于jquery实现智能表单验证操作
2016/05/09 Javascript
jQuery 插件实现随机自由弹跳气泡样式
2017/01/12 Javascript
利用Vue.js实现求职在线之职位查询功能
2017/07/03 Javascript
JS+canvas绘制的动态机械表动画效果
2017/09/12 Javascript
vue组件间通信子与父详解(二)
2017/11/07 Javascript
javascript与PHP动态往类中添加方法对比
2018/03/21 Javascript
微信小程序实现打卡签到页面
2020/09/21 Javascript
[51:27]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
Python的批量远程管理和部署工具Fabric用法实例
2015/01/23 Python
python使用正则表达式分析网页中的图片并进行替换的方法
2015/03/26 Python
Python实现的批量修改文件后缀名操作示例
2018/12/07 Python
python集合是否可变总结
2019/06/20 Python
windows python3安装Jupyter Notebooks教程
2020/04/13 Python
Python新手如何理解循环加载模块
2020/05/29 Python
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
高一英语教学反思
2014/01/22 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
本科生导师推荐信范文
2014/05/18 职场文书
委托代理人授权委托书范本
2014/09/24 职场文书
死亡赔偿协议书
2015/01/28 职场文书
秦兵马俑导游词
2015/02/02 职场文书
大学毕业晚会开场白
2015/05/29 职场文书
Go timer如何调度
2021/06/09 Golang