将网络模式设置成桥接模式:
由于是通过Vmare虚拟机部署的Nginx服务,而虚拟机默认的NAT模式是不支持其他机器进行访问的,即只能本机访问(虚拟机或本机),所以要把他改成桥接模式,然后重启虚拟机,之后查看网卡的地址,这个地址稍后有大用,后面的nginx.conf和fd.ext文件都用到了这个ip地址:
ifconfig
192.168.10.224
首先在本地创建一个Nginx目录,用于存放nginx.conf
sudo mkdir /home/pc/Nginx
sudo chmod 777 /home/pc/Nginx
安装openssl,用于生成自签名证书:
sudo apt-get update && apt-get install openssl
# 查看openssl版本
openssl version
# openssl生成自签名:fd.key fd.crt
openssl genpkey -out pem/fd.key \
-algorithm EC \
-pkeyopt ec_paramgen_curve:P-256 \
&& openssl req -new -x509 -days 365 -key pem/fd.key -out pem/fd.crt \
-subj "/CN=localhost"
# openssl通过fd.ext生成自签名
openssl genpkey -out /pem/fd.key \
-algorithm EC \
-pkeyopt ec_paramgen_curve:P-256 \
&& openssl req -new -config /pem/fd.cnf -key /pem/fd.key -out /pem/fd.csr \
&& openssl x509 -req -days 365 \
-in /pem/fd.csr -signkey /pem/fd.key -out /pem/fd.crt \
-extfile /pem/fd.ext
#fd.ext
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
req_extensions = san
extensions = san
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Definesys
localityName = Definesys
organizationName = Definesys
[SAN]
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = 192.168.10.224
编辑nginx.conf文件,添加常用配置:
sudo vim /home/pc/Nginx/nginx.conf
events {
use epoll;
worker_connections 65535;
}
http{
server {
listen 80;
server_name localhost 192.168.10.224;
listen 443 ssl;
#ssl_password_file /pem/pass.txt;
ssl_certificate /pem/fd.crt;
ssl_certificate_key /pem/fd.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
编写fd.cnf文件用于生成csr:
sudo vim /home.pc/Nginx/fd.cnf
#fd.cnf
[req]
prompt = no
distinguished_name = dn
req_extensions = ext
input_password = PASSPHRASE
[dn]
CN = localhost
emailAddress = webmaster@feistyduck.com
O = Feisty Duck Ltd
L = London
C = GB
[ext]
subjectAltName = DNS:localhost,DNS:192.168.10.224
编写fd.ext文件用于生成crt:
sudo vim /home.pc/Nginx/fd.ext
#fd.ext
subjectAltName = DNS:localhost, DNS:192.168.10.224
编写Dockerfile文件:
sudo vim /home/pc/Nginx/Dockerfile
#Dockerfile
# 使用官方的NGINX镜像作为基础镜像
FROM nginx
# 将本地的NGINX配置文件复制到容器中
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir /pem
COPY fd.cnf fd.ext /pem
RUN openssl genpkey -out /pem/fd.key \
-algorithm EC \
-pkeyopt ec_paramgen_curve:P-256 \
&& openssl req -new -config /pem/fd.cnf -key /pem/fd.key -out /pem/fd.csr \
&& openssl x509 -req -days 365 \
-in /pem/fd.csr -signkey /pem/fd.key -out /pem/fd.crt \
-extfile /pem/fd.ext
构建Docker镜像:
docker build -f /home/pc/Nginx/Dockerfile -t m_nginx_img /home/pc/Nginx/
运行NGINX容器:
docker run --name=Nginx -d -p 80:80 -p 443:443 --restart=always m_nginx_img
docker run --name=Nginx -p 80:80 -p 443:443 -v /home/pc/Nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/pc/Nginx/log/:/var/log/nginx/ -d --restart=always m_nginx_img
docker run --name=Nginx -p 80:80 -p 443:443 -v /home/pc/Nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/pc/Nginx/log/:/var/log/nginx/ m_nginx_img
docker exec -it Nginx bash
验证NGINX部署:
http://localhost
https://localhost
openssl s_client -crlf \
-connect localhost:443 \
-servername localhost
将生成的证书从容器中拷贝出来备用:
docker cp Nginx:/pem/fd.crt /home/pc/Nginx/fd.crt
验证证书:
openssl x509 -text -in /home/pc/Nginx/fd.crt -noout
然后我们可以再通过shell客户端将Nginx/fd.crt拷贝到我们的电脑上
as配置CA证书:
若不配置服务器CA证书的话,则as访问https会报错。
先将 服务器提供的CA 证书拷贝到 res/raw/ 目录下
再在 `res/xml/` 目录下创建 `network_security_config.xml` 文件:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<!-- 引入 CA 证书 -->
<trust-anchors>
<certificates src="@raw/证书名(不含后缀,比如.crt)"/>
</trust-anchors>
</base-config>
</network-security-config>
注意填入的证书名称不要包含扩展名,比如fd.crt,则只需填入@raw/fd
高版本的as会不允许直接返回http,cleartextTrafficPermitted="true"的作用可以使得能正常访问http地址。
再在 `AndroidManifest.xml` 中应用网络安全性配置:
android:networkSecurityConfig="@xml/network_security_config"
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
但是经测试发现as好像不支持访问openssl生成的证书的https,就算配置了CA证书也没用,所以最好还是用mkcert生成自签名CA证书
或者直接用本地已经生成好的CA,要注意的是本地的openssl版本和容器内的openssl版本不一致,会导致容器内解析签名文件出错,所以请不要用下面这种方式,最好由容器内部的openssl来生成:
#Dockerfile
# 使用官方的NGINX镜像作为基础镜像
FROM nginx
# 将本地的NGINX配置文件复制到容器中
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir /pem
# 将提前生成好的CA证书拷贝进容器
COPY fd.key fd.crt /pem