# 安全域名相关

微信小程序的安全域名必须是HTTPS,同时必须是在国内ICP备案的域名,本章来介绍如何使用acme.sh+nginx配置https与申请SSL证书。

# SSL证书申请

# 前置准备

  • 申请域名:阿里云、腾讯云等各家云服务商;

  • 有一台云主机,有公网的IP,最好进行过备案;如果没有国内的服务器,也可以注册一台国外的服务器,地址1:搬瓦工 (opens new window),地址2:vultr (opens new window)

  • 云主机的操作系统:Centos 7+(以下所有演示内容,均为Centos 7)或者Ubuntu 16LTS+;

  • DNS解析:DNSpod,cloudflare;

    配置域名进行解析:

    image-20210810145545806

    使用A记录,配置自己的域名 -> 自己的云主机IP

    使用ping命令检查 是否已经网络通了:

    image-20210810145801200

# 整体架构

配置架构图:

image-20210810144327946

# 基本步骤

借助acme.sh (opens new window)进行申请SSL证书,以便微信接口部分的使用,下面演示的是DNSpod进行证书申请的过程。

主要步骤:

前置:使用ssh命令连接到服务器 ->

  1. 安装 acme.sh

  2. 生成证书 ——推荐DNS的方式 (opens new window)

    支持的DNS列表:https://github.com/acmesh-official/acme.sh/tree/master/dnsapi (opens new window)

  3. copy 证书到 nginx/apache 或者其他服务

  4. 更新证书

  5. 更新 acme.sh

# acme.sh安装

安装很简单, 一个命令:

curl  https://get.acme.sh | sh -s email=my@example.com

image-20210810145930893

再次打开一个新的ssh终端,使用crontab -e(Centos)查看acme.sh自动创建的定时任务:

image-20210810150236024

输入i进入编辑模式,调整如上图所示,使用:wq退出。

PS:上面的配置是每天的0点23分去执行一次脚本。

# 配置DNS密钥

下面介绍了DNSpod、阿里云、Cloudflare的配置过程,大家可以根据自己的云服务商选择,过程类似。

# DNSpod

  • 选择密钥管理:

    image-20210810150640094

  • 创建密钥

    image-20210810150731394

  • 记录下来,后续使用:

    image-20210810150751582

配置密钥:

export DPI_Id="1234"
export DPI_Key="sADDsdasdgdsf"

# 阿里云

点击:https://ak-console.aliyun.com/#/accesskey (opens new window),申请密钥:

image-20210810151001761

选择编程访问

image-20210810151252035

生成accessKey与密钥:

image-20210810151319187

配置过程:

export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

# Cloudflare

配置页面 (opens new window)

image-20210810151518194

配置过程:

export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="xxxx@sss.com"

# 产生证书

  • Dnspod:

    acme.sh --issue --dns dns_dpi -d example.com -d www.example.com
    
  • 阿里云:

    acme.sh --issue --dns dns_ali -d example.com -d www.example.com
    
  • Cloudflare:

    acme.sh --issue --dns dns_cf -d example.com -d www.example.com
    

推荐域名通配符的写法:example.com 与 *.example.com,那么二级子域名,全部都可以使用https。

过程1:

image-20210810152354761

上面的图片是展示出在对域名进行校验。

过程2:

image-20210810152415177

证书申请成功,证书所在位置。

cer 自签
key 密钥
CA 中间证书
把CA与cert链接到一起的证书,这个是后续放在nginx上的,用于服务器之间的协商

# Nginx配置

# 前置准备

image-20210810205823556

步骤:

  • 安装docker,docker-compose -> nginx
  • docker-compose来启动nginx
  • 创建一个https docker网络 -> 共享给github, jenkins 等需要https的服务
  • 配置nginx.conf配置文件,创建conf.d文件目录,可以创建虚拟域名vhost.conf文件
  • 使用证书安装命令安装ssl证书 -> 到指定的目录
  • docker-compose up -d运行nginx容器 -> 测试cron定时任务脚本

# 证书安装命令

Apache配置:

acme.sh --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

Nginx配置:

acme.sh --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

--reloadcmd可以指定docker容器进行重启,或者是指定运行shell脚本。

比如:

--reloadcmd "docker restart some-nginx"

# dhparam.pem证书

创建一个目录:/home/keys

# 生成 dhparam.pem 文件, 在命令行执行任一方法:

# 方法1: 很慢
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

# 方法2: 较快
# 与方法1无明显区别. 2048位也足够用, 4096更强
openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam.pem 4096

把dhparam.pem复制到个人SSL证书安装相同的目录/home/keys

# docker配置

  • 手动创建网络

    docker network create https
    

    image-20210810210138510

    查看网络 docker network ls

    检查网络的信息 docker network inspect https

  • 创建docker-compose.yml文件

version: "3"
services:
  web:
    image: nginx:latest
    container_name: "some-nginx"
    restart: always
    volumes:
      - /home/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /home/nginx/conf.d:/etc/nginx/conf.d
      - /home/keys:/home/keys
      # blog
      # - /home/blog:/var/www
    ports:
      - "80:80"
      - "443:443"

# docker network create https
networks:
  default:
    external:
      name: https

# nginx.conf配置

user nginx;
worker_processes auto;
pid /run/nginx.pid;
worker_rlimit_nofile 65535;

events {
	# 设置事件驱动模型,是内核2.6以上支持
	use epoll;
	worker_connections 65535;
	accept_mutex off;
	multi_accept off;
}

http {
	# Basic Settings
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	send_timeout 120;
	keepalive_timeout 300;
	client_body_timeout 300;
	client_header_timeout 120;

	proxy_read_timeout 300;
	proxy_send_timeout 300;
	#tcp_nopush on;
	types_hash_max_size 4096;
	client_header_buffer_size 16m;
	client_max_body_size 4096m;

  # 添加nginx的配置文件目录 -> 用户后期添加vhost文件
	include /etc/nginx/mime.types;
	include /etc/nginx/conf.d/*.conf;

	default_type application/octet-stream;
	# Logging Settings
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
	log_format main '$remote_addr - $remote_user [$time_local] "$request" '
	'$status $body_bytes_sent "$http_referer" '
	'"$http_user_agent" "$http_x_forwarded_for"';
	
	# 开启gzip
	gzip on;
	# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
	gzip_min_length 1k;
	# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
	gzip_comp_level 2;
	# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
	gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
	# 是否在http header中添加Vary: Accept-Encoding,建议开启
	gzip_vary on;
	# 禁用IE 6 gzip
	gzip_disable "MSIE [1-6]\.";
}

# 安装证书启动nginx

image-20210810211832312

测试Nignx的配置文件:

docker exec -it some-nginx nginx -t

image-20210810220403001