自学微信小程序时,看到小程序现在只支持https了。而且现在chrome中浏览http的网站,网址前都会直接显示“不安全”字样。http是明文传输,相当于所有信息在网络上裸奔,没有安全性可言。现在都2018年了,大家在做新项目的时候还是都上https吧。
这篇文章会简单介绍https的连接过程,然后用go语言实现一个简单的http服务,最后用例子演示了如何用nginx和腾讯负载均衡来改造http服务,使其切换到https。
https可以理解为http over ssl,既把http明文流量通过ssl协议进行加密传送,从而保证数据的安全性。这里依赖的是非对称加密和对称加密。网上相关介绍的文章很多,简单列一下。
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。
(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
(5)Web服务器利用自己的私钥解密出会话密钥。
(6)Web服务器利用会话密钥加密与客户端之间的通信。
引自:https://www.cnblogs.com/wqhwe/p/5407468.html
在http传输前建立了一个安全的加密通道。几个地方小白可能不清晰,解释下:
https的好处:
基于 SSL 证书,可将站点由 HTTP(Hypertext Transfer Protocol)切换到 HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)—— 即基于安全套接字层(SSL)进行安全数据传输的加密版 HTTP协议。
站点应用 HTTPS 后将有以下优势:
1. 防流量劫持
全站 HTTPS 是根治运营商、中间人流量劫持的解决方案,不仅可以杜绝网页中被插入的小广告,更可以保护用户隐私安全。
2. 提升搜索排名
采用 HTTPS 可以帮忙搜索排名的提升,提高站点的可信度和品牌形象。
3. 杜绝钓鱼网站
HTTPS 地址栏绿色图标可以帮助用户识别出钓鱼网站,保障用户和企业的利益不受损害,增强用户信任。
下面会用golang实现一个简单web服务,它会返回get请求参数中name的参数,并返回当前服务器的时间。web服务走http,作为例子方便后面的演示。
买了个最低配的腾讯云服务器,操作系统是:Ubuntu Server 16.04.1 LTS 64位。
登录服务器,然后go应该是没有安装的。先下载当前最新的go安装包:
ubuntu@VM-45-13-ubuntu:~$ wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
解压缩:
ubuntu@VM-45-13-ubuntu:~$ sudo tar -C /usr/local -xzf go1.11.linux-amd64.tar.gz
设置环境变量,文件~/.profile中增加一行:
export PATH=$PATH:/usr/local/go/bin
生效:
source ~/.profile
测试下,查看当前go版本:
ubuntu@VM-45-13-ubuntu:~$ go version
go version go1.11 linux/amd64
2.1.2 运行web服务
设置go的workplace的路径为$HOME/go,在文件~/.profile中增加一行:
export GOPATH=$HOME/go
然后source下:
source ~/.profile
创建文件夹:
mkdir -p ./go/src/testhttps/
我写了个简单的web服务,创建文件main.go:
vi ~/go/src/testhttps/main.go
将下面代码复制进去:
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func sayHelloTime(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //parse request
log.Print(r.Form)
name := r.Form.Get("name") // get argument
result := fmt.Sprintf("Hello, %s! Current time : %s\n", name, time.Now()) // send data to client
fmt.Fprintf(w, result)
}
func main() {
http.HandleFunc("/", sayHelloTime)
err := http.ListenAndServe("127.0.0.1:8765", nil) // run on 127.0.0.1:8765
if err != nil {
log.Fatal("error:", err)
}
}
然后就可以运行啦,go build会生成一个可执行文件testhttps:
cd ~/go/src/testhttps
go build
./testhttps
另开个ssh,我们发送get请求,地址http://127.0.0.1:8765/?name=jj。返回信息如下:
ubuntu@VM-45-13-ubuntu:~$ curl http://127.0.0.1:8765/?name=jj
Hello, jj! Current time : 2018-10-03 01:09:45.860019907 +0800 CST m=+23.075722862
这时候web服务是跑在本地端口,外部网络是访问不到了。接下来要设置反向代理,让外部访问到。
安装nginx:
sudo apt-get install nginx
设置反向代理,文件/etc/nginx/sites-available/default中添加如下:
server {
listen 8766;
server_name *.test.cn;#这里乱弄得,后面有用
location / {
proxy_pass http://localhost:8765;
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;
}
}
上面的意思是,nginx监听外部8766端口,将请求转发给localhost:8765。
打开浏览器访问网址,http://你的腾讯云公网ip:8766/。可以看到,我们在外网访问到了该服务。
接下来,我们将上面使用http协议的web服务切换到https。
对于https协议,我们可以简单理解为:通过非对称加密技术建立起一个加密通道,然后http的明文消息走加密信道,保证安全。这里的基础是非对称加密,所以要求有公钥和私钥。而通常说的https证书,它里面包含了公钥等信息。我们向可信的证书颁发机构申请证书,浏览器收到服务器发来的证书会去机构进行签名验证,确认无误后就可以进行开始建立安全的加密通信了。
写到这里就会想到很多事情:
言归正传,我用腾讯云里购买的域名作为例子:
这里不进行详细描述了,直接买了交钱就行。
进入可以申请亚洲诚信颁发的免费1年的域名型证书,按照提示申请即可,通过审核后可以下载证书。
使用web服务器来做,这里以nginx为例子。
文件/etc/nginx/sites-available/default中添加如下,www.example.com替换为自己的域名。
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/www.example.com.crt;# crt的位置
ssl_certificate_key /etc/nginx/www.example.com.key;# key的位置
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass http://localhost:8765;
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;
}
443端口默认是https使用,然后我们将请求转发给http://localhost:8765。这里还有一步就是需要设置域名解析到此云服务器ip。可以看到,https正常访问,返回结果正常,我们的域名前有把锁啦!
使用腾讯云的负载均衡来实现https是更推荐的,2个原因:
有唯一一个弊端就是,目前公网负载均衡是收费的,0.02元每小时,折算每个月才15块钱。所以大家可以根据自己的情况来做选择,我是认为这点钱无所谓额。
基本流程:负载均衡CLB就是一台服务器,给我们转发用。所以我们对域名设置解析,A类型记录,ip填入负载均衡CLB的vip。访问域名就会直接找到负载均衡CLB,然后CLB再把请求分发给我们绑定的云服务器。
ps:这里我们针对第二部分的http后台服务改造,端口8766。
先购买一个应用型负载均衡实例:
然后将https证书部署至该负载均衡上,证书列表
然后就去负载均衡里面配置,这里的概念其实文档描述的并不够清晰,我捋一下:
我们测试下https,可以看到证书和返回结果都正常,成功。
这里只是简单举例,其中还涉及到很多东西没有囊括进来。例如依赖负载均衡来实现https,如何进行自动伸缩?云服务器如何设置安全组?等等,后面会继续写文章。
文中一些内容和示例还略简陋,抛砖引玉,共同交流~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。