0%

nginx如何配置https?我们今天通过Docker容器启动一台Centos服务器,从自签证书,到nginx安装配置,最终完成配置通过https访问web服务。

运行Centos容器

拉取镜像

1
2
3
4
5
6
docker pull centos
Using default tag: latest
latest: Pulling from library/centos
729ec3a6ada3: Pull complete
Digest: sha256:f94c1d992c193b3dc09e297ffd54d8a4f1dc946c37cbeceb26d35ce1647f88d9
Status: Downloaded newer image for centos:latest

如果拉取得慢的话,可以设置国内的registry镜像。

启动Centos容器

1
2
docker run -dit centos
759dee099156155c7b55b1e4c67bc7a89a52eed1acf865a9fdc1b299d57c33b1

进入容器

1
docker exec -it 759dee099156 bash

生成自签名证书

安装openssl工具

1
yum install openssl

实验原因,我们统一在/opt目录下生成证书。

1
cd /opt

生成CA证书

生成CA私钥ca.key

1
2
3
4
5
openssl genrsa -out ca.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
........................................................................+++++
...............+++++
e is 65537 (0x010001)

注意,centos版本如果是CentOS Linux release 8.0.1905 (Core)版本,私钥长度不能设置成1024位,必须2048位。不然再最后启动nginx时会出如下错误。

1
2
nginx: [emerg] SSL_CTX_use_certificate("/opt/server.crt") failed
(SSL: error:140AB18F:SSL routines:SSL_CTX_use_certificate:ee key too small)

生成ca.csr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
openssl req -new -key ca.key -out ca.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shanghai
Locality Name (eg, city) [Default City]:Shanghai
Organization Name (eg, company) [Default Company Ltd]:Issuer Co., Ltd
Organizational Unit Name (eg, section) []:Issuer Section
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

生成CA证书ca.crt

1
2
3
4
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
Signature ok
subject=C = CN, ST = Shanghai, L = Shanghai, O = "Issuer Co., Ltd", OU = Issuer Section, CN = localhost
Getting Private key

生成服务器证书

生成服务器端私钥server.key

1
2
3
4
5
openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.........+++++
...............................................................................................+++++
e is 65537 (0x010001)

生成服务器端公钥server.pem

1
2
openssl rsa -in server.key -pubout -out server.pem
writing RSA key

生成服务器端csr

服务器端需要向自己的CA机构申请签名证书,在申请签名证书之前,先创建CSR文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shanghai
Locality Name (eg, city) [Default City]:Shanghai
Organization Name (eg, company) [Default Company Ltd]:My Company
Organizational Unit Name (eg, section) []:My Section
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

向自己的CA机构申请证书,签名过程需要CA的证书和CA的私钥。最终生成服务器端的CA签名证书server.crtca.srl

1
2
3
4
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
Signature ok
subject=C = CN, ST = Shanghai, L = Shanghai, O = My Company, OU = My Section, CN = localhost
Getting CA Private Key

安装配置nginx 1.16

下载nginx源码包

如果没有wget命令需要执行yum install -y wget安装wget工具。

下载源码包

1
wget http://nginx.org/download/nginx-1.16.1.tar.gz

解压

1
tar -zxvf nginx-1.16.1.tar.gz

更改文件所属用户及用户组

在我在docker容器中做实验,所以才会改为root。真实环境改为登录用户帐户就可以了。

1
chown -R root:root nginx-1.16.1

进入目录

1
cd nginx-1.16.1

编译安装

源码编译安装,需要带上--with-http_ssl_module参数以支持ssl。

1
./configure --with-http_ssl_module --with-http_stub_status_module

一路上,有可能会遇到如下问题

1
2
3
4
5
checking for OS
+ Linux 5.0.0-31-generic x86_64
checking for C compiler ... not found

./configure: error: C compiler cc is not found

安装C编译器以解决

1
yum install -y gcc

找不到PCRE library

1
2
3
4
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

安装pcre-devel

1
yum install -y pcre-devel

找不到OpenSSL library

1
2
3
4
./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.

还记得我们前面只安装了openssl么?这里还需要安装

1
yum install -y openssl-devel

上面三个问题解决以后,就可以成功安装nginx了

执行make时,如果没有还需要安装

1
yum install -y make
1
make & make install

配置nginx

1
vi /usr/local/nginx/conf/nginx.conf

按照HTTPS server段的模板内容,进行配置。

配置的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# HTTPS server
#
server {
listen 443 ssl;
server_name localhost;

ssl_certificate /opt/server.crt;
ssl_certificate_key /opt/server.key;

# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;

# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;

location / {
root html;
index index.html index.htm;
}
}

启动nginx

1
/usr/local/nginx/sbin/nginx

这个时候访问https://172.17.0.2/,就能看到nginx的欢迎页面了。

当然,你也可以直接访问http://172.17.0.2/也是可以访问的。

优化nginx配置

先注释或删除掉默认的server段配置。这个时候,80端口就没有监听了。然后再添加如下配置。

1
2
3
4
5
server {
listen 80;
server_name localhost;
rewrite ^(.*) https://$host$1 permanent;
}

这个时候,访问http://172.17.0.2/就会自动跳转到https://172.17.0.2/

查看证书详情

1
2
3
4
5
6
7
8
9
Issued To
Common Name (CN) localhost
Organization (O) My Company
Organizational Unit (OU) My Section

Issued By
Common Name (CN) localhost
Organization (O) Issuer Company
Organizational Unit (OU) Issuer Section

Docker镜像制作好以后,发现有些名字命名得并不合理,需要修改。

查看镜像列表

1
2
3
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
simon/basic_centos latest 3816db78c729 3 weeks ago 284MB

修改镜像名字

如果不知道怎么执行命令,可以先看看帮助文档。

1
2
3
4
5
6
7
docker tag
"docker tag" requires exactly 2 arguments.
See 'docker tag --help'.

Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

修改名称

1
docker tag simon/basic_centos simon/basic-centos

删除旧镜像

我们再次查看一下镜像列表

1
2
3
4
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
simon/basic-centos latest 3816db78c729 3 weeks ago 284MB
simon/basic_centos latest 3816db78c729 3 weeks ago 284MB

发现上面两个镜像都拥有相同的IMAGE ID。我们需要把旧的镜像删除掉。

1
2
docker rmi simon/basic_centos
Untagged: simon/basic_centos:latest

安装Docker

1
sudo apt install docker.io

添加账户到Docker组

Docker安装好以后,我们执行docker command时,前面都要加一个sudo,极为不方便。

现在把登录用户添加到docker用户组中。

1
2
3
sudo gpasswd -a ${USER} docker

Adding user simon to group docker

重新启动

1
2
3
4
5
6
systemctl restart docker
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'docker.service'.
Authenticating as: Simon,,, (simon)
Password:
==== AUTHENTICATION COMPLETE ===

重新登录

1
newgrp docker

或者重新登录一下。

这时,你会发现在运行Docker命令时,已经不再需要sudo了。

设置镜像源

1
vi /etc/docker/daemon.json

添加如下内容:

1
2
3
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}

重启Docker

1
systemctl restart docker

查看Docker信息

1
docker info

可以看到如下内容,说明已经设置成功了。

1
2
Registry Mirrors:
http://hub-mirror.c.163.com/

导入镜像

导出镜像

先从其他环境导出镜像。比如在MacOS上执行命令。

1
docker save simon/gluster-centos > gluster-centos.tar

迁移

再把gluster-centos.tar拷贝到Ubuntu里面。

1
scp gluster-centos.tar simon@172.16.64.225:/tmp

导入镜像

1
2
3
4
docker load -i /tmp/gluster-centos.tar
877b494a9f30: Loading layer [==================================================>] 209.6MB/209.6MB
ad844b10918d: Loading layer [==================================================>] 198.2MB/198.2MB
Loaded image: simon/gluster-centos:latest

验证

1
2
3
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
simon/gluster-centos latest 140348a9e5de 2 weeks ago 396MB