网络和通信层面的身份鉴别
根据GB/T 39786,网络和通信层面的身份鉴别在一~三级时是单向鉴别,在第四级时是双向鉴别。单向鉴别是针对服务端的身份鉴别,主要目的是防止钓鱼网站等情况,明确你的访问地址是合规、正确、有效的;双向鉴别是针对客户端和服务端双方的身份鉴别,不仅需要服务端证明身份,还需要客户端是合规、有效的,但此时的客户端不等同于用户,只能证明访问服务端的设备终端是合规的。
举个例子,小红和小黑两人访问网站A,若网站A仅设置了单向鉴别,小红和小黑使用各自的电脑红PC和黑PC访问网站A;若网站A设置了双向鉴别,并给予了红PC权限,此时小红从红PC依然能访问网站A,但小黑从黑PC是无法访问网站A了,若小黑趁小红不在,利用红PC访问网站A,这时小黑就能访问网站A了,这就是双向鉴别只甄别客户端设备,无法限制用户。
单向鉴别
单向鉴别在实际环境中十分常见,所有的HTTPS网站都支持单向鉴别,在登录任一HTTPS网站后,都可以在浏览器中找到服务端的数字证书(如下图),该数字证书就是服务端的“身份证”,进行服务端的身份鉴别。
谷歌浏览器证书查询
火狐浏览器证书查询
双向鉴别
双向鉴别一般需要特定网站,且需要服务端为客户端签发私钥证书,并由浏览器导入该证书后,才能正常访问,如下图:
若未导入有效证书,访问该网站时,会报未提供有效证书无法访问,如下图
测试双向鉴别
自行测试双向鉴别很简单,利用nginx自身的代理即可,除此以外还需要有证书签发功能,可以采用openssl进行证书签发。
搭建测试环境
首先需要准备好openssl和nginx的环境,此处省略安装过程。
签发证书
因为要测试双向鉴别,所以需要明确证书体系包含根证书、服务端证书和客户端证书,其中服务端证书和客户端证书均应由根证书进行签发,这样才方便证书校验。
# 生成根证书
openssl req -new -x509 -days 3650 -sha256 -extensions v3_ca -key ca-root.key -out ca-root.cer -subj "/C=CN/ST=beijing/L=beijing/O=test/OU=test/CN=root"
# 生成服务端证书私钥
openssl genrsa -out server.key 2048
# 生成签发请求csr,证书请求文件,这个并不是证书,而是向证书颁发机构获得签名证书的申请文件
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=beijing/L=beijing/O=test/OU=test/CN=server"
# 这个文件影响到ca颁发的证书的序号,而证书序号应该是唯一的,所以这点需要控制好。
echo "01" > ca-root.srl
# 用CA证书签发服务端证书
openssl x509 -req -days 3650 -sha256 -CA ca-root.cer -CAkey ca-root.key -in server.csr -out server.cer
# 配置客户端证书,与服务端证书生成方式类似
openssl genrsa -out client1.key 2048
openssl req -new -key client1.key -out client1.csr -subj "/C=CN/ST=beijing/L=beijing/O=test/OU=test/CN=admin"
openssl x509 -req -days 3650 -sha256 -CA ca-root.cer -CAkey ca-root.key -in client1.csr -out client1.cer
openssl pkcs12 -export -clcerts -in client1.cer -inkey client1.key -out client1.p12
这样就生成了一系列文件
然后配置nginx,打开nginx.conf,将443端口代理成双向鉴别:
若只需要单向鉴别,只配置红框即可。
# /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/root/ssl/ca/server.cer"; #服务器证书
ssl_certificate_key "/root/ssl/ca/server.key"; #服务器私钥
ssl_verify_client on;
ssl_client_certificate "/root/ssl/ca/ca-root.cer"; #签发客户端证书的证书,即客户端证书的父证书
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
nginx配好后重启nginx即可。
PS:如果重启nginx报错,根据错误提示进行调整网络防火墙等权限即可。