1、https的实现过程
Web网站的登录页面通常都会使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
https实现过程如下:
1.客户端发送请求:
客户端访问某个web端的https地址,一般都是443端口
2.服务器配置:
采用https协议的服务器必须要有一套证书,可以通过一些组织申请,也可以自己制作,目前国内很多网站都自己做的,当你访问一个网站的时候提示证书不可信任就表示证书是自己做的,证书就是一个公钥和私钥匙,就像一把锁和钥匙,正常情况下只有你的钥匙可以打开你的锁,你可以把这个送给别人让他锁住一个箱子,里面放满了钱或秘密,别人不知道里面放了什么而且别人也打不开,只有你的钥匙是可以打开的。
3.传送证书:
服务端给客户端传递证书,其实就是公钥,里面包含了很多信息,例如证书得到颁发机构、过期时间等等。
4.客户端解析证书:
这部分工作是有客户端完成的,首先回验证公钥的有效性,比如颁发机构、过期时间等等,如果发现异常则会弹出一个警告框提示证书可能存在问题,如果证书没有问题就生成一个随机值,然后用证书对该随机值进行加密,就像2步骤所说把随机值锁起来,不让别人看到。
5.传送4步骤的加密数据:
就是将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值进行加密解密了。
6.服务端解密信息:
服务端用私钥解密5步骤加密后的随机值之后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,对称加密就是将信息和私钥通过算法混合在一起,这样除非你知道私钥,不然是无法获取其内部的内容,而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性。
7.传输加密后的信息:
服务端将用私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容。
2、编译安装nginx1.18.0
2.1、准备环境
安装编译时依赖的包:
root@node1:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:5e:72:f9 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.100/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe5e:72f9/64 scope link
valid_lft forever preferred_lft forever
root@node1:~# apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
创建运行nginx访问的账号:
root@node1:~# useradd -s /sbin/nologin -r nginx
root@node1:~# id nginx
uid=999(nginx) gid=999(nginx) groups=999(nginx)
2.2、下载源码包,开始编译
官方源码包下载地址:(https://nginx.org/en/download.html)
这里我使用的是1.18.0版本的nginx
root@node1:~# cd /usr/local/src/
root@node1:/usr/local/src# wget https://nginx.org/download/nginx-1.18.0.tar.gz
root@node1:/usr/local/src# tar xf nginx-1.18.0.tar.gz
root@node1:/usr/local/src# ls
nginx-1.18.0 nginx-1.18.0.tar.gz
root@node1:/usr/local/src# cd nginx-1.18.0/
root@node1:/usr/local/src/nginx-1.18.0# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
root@node1:/usr/local/src/nginx-1.18.0# ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
root@node1:/usr/local/src/nginx-1.18.0# make -j 2 && make install
2.3、修改相关目录权限并验证版本,创建nginx.service文件
root@node1:/usr/local/src/nginx-1.18.0# chown -R nginx.nginx /apps/nginx
root@node1:/usr/local/src/nginx-1.18.0# ll /apps/nginx/
total 24
drwxr-xr-x 6 nginx nginx 4096 Jul 3 16:58 ./
drwxr-xr-x 3 root root 4096 Jul 3 16:58 ../
drwxr-xr-x 2 nginx nginx 4096 Jul 3 16:58 conf/
drwxr-xr-x 2 nginx nginx 4096 Jul 3 16:58 html/
drwxr-xr-x 2 nginx nginx 4096 Jul 3 16:58 logs/
drwxr-xr-x 2 nginx nginx 4096 Jul 3 16:58 sbin/
root@node1:/usr/local/src/nginx-1.18.0# ls /apps/nginx/sbin/
nginx
root@node1:/usr/local/src/nginx-1.18.0# ln -s /apps/nginx/sbin/nginx /usr/sbin/
root@node1:/usr/local/src/nginx-1.18.0# nginx -V
nginx version: nginx/1.18.0
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 1.1.1 11 Sep 2018
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
创建自启动nginx.service文件
root@node1:~# cat /lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStartPre=/bin/rm -f /apps/nginx/run/nginx.pid
ExecStartPre=/apps/nginx/sbin/nginx -t
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
LimitNOFILE=100000
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
创建pid目录
root@node1:~# mkdir /apps/nginx/run
root@node1:~# chown -R nginx.nginx /apps/nginx/
修改配置文件
root@node1:~# vim /apps/nginx/conf/nginx.conf
pid /apps/nginx/run/nginx.pid;
2.4、验证nginx的自启动文件
root@node1:~# systemctl daemon-reload
root@node1:~# systemctl enable --now nginx
root@node1:~# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2022-07-03 17:19:50 CST; 44s ago
Process: 5508 ExecStart=/apps/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 5507 ExecStartPre=/apps/nginx/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 5500 ExecStartPre=/bin/rm -f /apps/nginx/run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 5509 (nginx)
Tasks: 3 (limit: 4625)
CGroup: /system.slice/nginx.service
├─5509 nginx: master process /apps/nginx/sbin/nginx
├─5510 nginx: worker process
└─5511 nginx: worker process
Jul 03 17:19:50 node1.stars.org systemd[1]: Starting The nginx HTTP and reverse proxy server...
Jul 03 17:19:50 node1.stars.org nginx[5507]: nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
Jul 03 17:19:50 node1.stars.org nginx[5507]: nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
Jul 03 17:19:50 node1.stars.org systemd[1]: Started The nginx HTTP and reverse proxy server.
root@node1:~# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 64 0.0.0.0:13320 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:38996 0.0.0.0:*
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:45110 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 0.0.0.0:13756 0.0.0.0:*
LISTEN 0 64 0.0.0.0:2049 0.0.0.0:*
LISTEN 0 64 [::]:23786 [::]:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::]:55482 [::]:*
LISTEN 0 128 [::]:60602 [::]:*
LISTEN 0 64 [::]:2049 [::]:*
LISTEN 0 128 [::]:10658 [::]:*
3、web站点部署
企业在实际生产环境中其实会部署多个网站,或者利用Nginx来作为代理服务器来转发各种服务的请求,在这里我们可以利用Nginx主配置文件/apps/nginx/conf/nginx.conf中设置,但是管理的服务过多时,主配置文件会显得冗长而难以管理,因此就会考虑使用子配置文件形式来规划不同服务。
3.1、创建子配置文件的路径
root@node1:~# mkdir /apps/nginx/conf/conf.d
root@node1:~# vim /apps/nginx/conf/nginx.conf
root@node1:~# tail /apps/nginx/conf/nginx.conf
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
include /apps/nginx/conf/conf.d/*.conf;
}
root@node1:~# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
root@node1:~# nginx -s reload
3.2、创建子配置文件
root@node1:~# vim /apps/nginx/conf/conf.d/test.conf
server {
listen 80;
server_name www.stars.org;
location / {
root /data/nginx/test;
index index.html index.htm;
}
}
root@node1:~# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
root@node1:~# nginx -s reload
3.3、编写一个简单的index.html页面,并测试访问
root@node1:~# mkdir -p /data/nginx/test
root@node1:~# echo "`hostname -I` Welcome to test page" > /data/nginx/test/index.html
root@node1:~# vim /etc/hosts #加上下面内容
10.0.0.100 www.stars.org
root@node1:~# curl www.stars.org
10.0.0.100 Welcome to test page
4、实现站点https
4.1、自签名证书
自签名CA证书
root@node1:~# cd /apps/nginx/
root@node1:/apps/nginx# mkdir certs && cd $_
root@node1:/apps/nginx/certs# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
Can't load /root/.rnd into RNG
139760984830400:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
Generating a RSA private key
............................................++++
.............................................................................................++++
writing new private key to 'ca.key'
-----
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) [AU]:CN #国家代码
State or Province Name (full name) [Some-State]:GuangDong #省份
Locality Name (eg, city) []:ShenZhen #城市名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:stars.Ltd #公司名称
Organizational Unit Name (eg, section) []:stars #部门
Common Name (e.g. server FQDN or YOUR name) []:ca.stars.org #通用名称
Email Address []:admin@stars.org #邮箱
root@node1:/apps/nginx/certs# ls
ca.crt ca.key
自制key和csr文件
root@node1:/apps/nginx/certs# openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.stars.org.key -out www.stars.org.csr
Can't load /root/.rnd into RNG
139779887022528:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
Generating a RSA private key
....................++++
.........................++++
writing new private key to 'www.stars.org.key'
-----
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) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:ShenZhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:stars.Ltd
Organizational Unit Name (eg, section) []:stars
Common Name (e.g. server FQDN or YOUR name) []:www.stars.org
Email Address []:admin@stars.org
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
root@node1:/apps/nginx/certs# ll
total 24
drwxr-xr-x 2 root root 4096 Jul 3 18:04 ./
drwxr-xr-x 13 nginx nginx 4096 Jul 3 17:52 ../
-rw-r--r-- 1 root root 2143 Jul 3 17:57 ca.crt
-rw------- 1 root root 3272 Jul 3 17:55 ca.key
-rw-r--r-- 1 root root 1752 Jul 3 18:04 www.stars.org.csr
-rw------- 1 root root 3268 Jul 3 18:01 www.stars.org.key
签发证书
root@node1:/apps/nginx/certs# openssl x509 -req -days 365 -in www.stars.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.stars.org.crt
Signature ok
subject=C = CN, ST = GuangDong, L = ShenZhen, O = stars.Ltd, OU = stars, CN = www.stars.org, emailAddress = admin@stars.org
Getting CA Private Key
root@node1:/apps/nginx/certs# ll
total 32
drwxr-xr-x 2 root root 4096 Jul 3 18:07 ./
drwxr-xr-x 13 nginx nginx 4096 Jul 3 17:52 ../
-rw-r--r-- 1 root root 2143 Jul 3 17:57 ca.crt
-rw------- 1 root root 3272 Jul 3 17:55 ca.key
-rw-r--r-- 1 root root 41 Jul 3 18:07 ca.srl
-rw-r--r-- 1 root root 2021 Jul 3 18:07 www.stars.org.crt
-rw-r--r-- 1 root root 1752 Jul 3 18:04 www.stars.org.csr
-rw------- 1 root root 3268 Jul 3 18:01 www.stars.org.key
验证证书内容
root@node1:/apps/nginx/certs# openssl x509 -in www.stars.org.crt -noout -text
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
18:d0:21:4e:39:81:3e:d7:78:50:8b:59:23:a4:26:80:fd:41:c9:fe
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = GuangDong, L = ShenZhen, O = stars.Ltd, OU = stars, CN = ca.stars.org, emailAddress = admin@stars.org
Validity
Not Before: Jul 3 10:07:00 2022 GMT
Not After : Jul 3 10:07:00 2023 GMT
Subject: C = CN, ST = GuangDong, L = ShenZhen, O = stars.Ltd, OU = stars, CN = www.stars.org, emailAddress = admin@stars.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
....................
合并CA和服务器证书成一个文件,服务器证书一定要在前面
root@node1:/apps/nginx/certs# cat www.stars.org.crt ca.crt > www.stars.org.pem
root@node1:~# chown -R nginx.nginx /apps/nginx/ #修改目录权限
4.2、配置https证书
root@node1:~# cat /apps/nginx/conf/conf.d/test.conf
server {
listen 80;
listen 443 ssl;
server_name www.stars.org;
ssl_certificate /apps/nginx/certs/www.stars.org.pem;
ssl_certificate_key /apps/nginx/certs/www.stars.org.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 30m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
root /data/nginx/test;
index index.html index.htm;
}
}
root@node1:~# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
root@node1:~# nginx -s reload
4.3、测试使用https来访问
root@node1:~# curl https://www.stars.org -k
10.0.0.100 Welcome to test page
root@node1:~# curl https://www.stars.org -k
10.0.0.100 Welcome to test page
4.4、实现https强制跳转访问
用户的行为习惯,通常用户在使用域名进行web网页访问时是不会输入https的,要想实现https的强制跳转,需要用到Nginx的rewrite模块,rewrite模块可以实现url的重写。url的重写是经常用到的功能,⽐如它可以在我们改变⽹站结构之后,不需要客户端修改原来的书签,也⽆需其他⽹站修改我们的链接就可以设置为访问,另外这样还可以在⼀定程度上提⾼⽹站的安全性。
配置子配置文件
root@node1:~# vim /apps/nginx/conf/conf.d/test.conf
server {
listen 80;
listen 443 ssl;
server_name www.stars.org;
ssl_certificate /apps/nginx/certs/www.stars.org.pem;
ssl_certificate_key /apps/nginx/certs/www.stars.org.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 30m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
if ($scheme = http) {
rewrite ^(.*) https://www.stars.org$1 permanent; #permanent是永久重定向,想要临时重定向需要使用redirect。
}
location / {
root /data/nginx/test;
index index.html index.htm;
}
}
root@node1:~# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
root@node1:~# nginx -s reload
验证访问
root@node1:~# curl -iLk www.stars.org
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 03 Jul 2022 12:16:00 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.stars.org/
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 03 Jul 2022 12:16:00 GMT
Content-Type: text/html
Content-Length: 33
Last-Modified: Sun, 03 Jul 2022 09:45:35 GMT
Connection: keep-alive
ETag: "62c1653f-21"
Accept-Ranges: bytes
10.0.0.100 Welcome to test page