您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Nginx SSL快速双向认证配置(脚本)

2024/6/27 19:11:29发布32次查看
这篇文章主要介绍了关于nginx ssl快速双向认证配置(脚本),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下
目前遇到一个项目有安全性要求,要求只有个别用户有权限访问。本着能用配置解决就绝不用代码解决的原则,在nginx上做一下限制和修改即可。
这种需求其实实现方式很多,经过综合评估考虑,觉得ssl双向认证方案对用户使用最简单,遂决定用此方案。
注: 本方案在ubuntu server 16.04 lts实施,其他操作系统请酌情修改ssl双向认证绝大多数ssl应用都以单向认证为主,即客户端只要信任服务端,就可以使用服务端的公钥加密后向服务端发起请求,由服务端的私钥解密之后获得请求数据。
如果这个过程反过来,让服务端信任客户端,服务端使用客户端的公钥加密之后将数据返回给客户端,其实也是可以做到的,原理和实现跟单向认证都差不多。
服务端信任客户端的操作往往也会伴随着客户端认证服务端的过程,所以让服务端信任客户端的ssl认证方式往往也被称为ssl双向认证,并且要配置ssl双向认证必须先开启服务端ssl,先配置客户端信任服务端。
nginx的ssl双向认证配置第一步 开启https访问根据理论知识,我们必须先开启nginx的ssl配置,即启用https。这个过程较为简单,目前有let's encrypt这种免费的证书方案,再也不用发愁自己搭建ca自签了。申请免费证书的过程略过,直接贴启用https的配置:
server {  listen 80;  listen 443 ssl http2;  server_name example.com;  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;  # 只有nginx >= 1.13.0 版本才支持tlsv1.3协议  # ssl_protocols tlsv1.3;  # nginx低于1.13.0版本用这个配置  ssl_protocols tlsv1 tlsv1.1 tlsv1.2;  ssl_prefer_server_ciphers on;   ssl_dhparam dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096  ssl_ciphers 'eecdh+aesgcm:edh+aesgcm:aes256+eecdh:aes256+edh';  ssl_ecdh_curve secp384r1; # requires nginx >= 1.1.0  ssl_session_timeout  10m;  ssl_session_cache shared:ssl:10m;  ssl_session_tickets off; # requires nginx >= 1.5.9  ssl_stapling on; # requires nginx >= 1.3.7  ssl_stapling_verify on; # requires nginx => 1.3.7  resolver 223.5.5.5 114.114.114.114 valid=300s;  resolver_timeout 5s;   # 启用hsts的配置,如果你的域名下还有非标准端口访问的http应用,请勿启用hsts  # add_header strict-transport-security max-age=63072000; includesubdomains; preload;  # 下面这个配置会拒绝frame标签内容,请确认你的网站没有frame / iframe  add_header x-frame-options deny;  add_header x-content-type-options nosniff;  add_header x-xss-protection 1; mode=block;  # 为了let's encrypt续期用,不用let's encrypt不需要这个location  location /.well-known {    root /usr/share/nginx/html;  }   ... snip ...  # 强制http跳转为https  if ($scheme != https) {    return 301 https://$http_host$request_uri;  }}
以上那一大堆ssl的配置参考来自于: https://cipherli.st/ 加强ssl的安全性配置特别注意最后的强制https跳转,我们的目的是ssl双向认证,不走https无任何意义,所以必须强制跳转https。
第二步 生成客户端证书并签证(脚本)这个过程详细描述的文章太多了,这里就不啰嗦介绍openssl和签证过程了,本篇内容是快速生成双向认证配置的证书,所以直接贴脚本就行了,命令都是参考互联网上各种openssl双向配置文档,在此基础之上进行了命令上的简化与非交互式的支持。
整个目录结构如图:
# tree /etc/nginx/ssl_certs//etc/nginx/ssl_certs/├── create_ca_cert.sh├── create_client_cert.sh├── revoke_cert.sh0 directories, 3 files
自行创建/etc/nginx/ssl_certs/,放入三个脚本,分别用于生成ca证书以及ca目录(create_ca_cert.sh脚本的作用,只有第一次需要运行),创建客户端证书,并用ca证书签证(create_client_cert.sh脚本的作用,必须先生成ca证书),revoke_cert.sh脚本用于吊销证书,需要收回权限的时候可以使用。
每个脚本内容如下:
create_ca_cert.sh
#!/bin/bash -e# 创建ca根证书# 非交互式方式创建以下内容:# 国家名(2个字母的代号)c=cn# 省st=shannxi# 市l=xian# 公司名o=my company# 组织或部门名ou=技术部# 服务器fqdn或颁发者名cn=www.example.com# 邮箱地址emailaddress=admin@example.commkdir -p ./democa/{private,newcerts}touch ./democa/index.txt[ ! -f ./democa/seria ] && echo 01 > ./democa/serial[ ! -f ./democa/crlnumber ] && echo 01 > ./democa/crlnumber[ ! -f ./democa/cacert.pem ] && openssl req -utf8 -new -x509 -days 36500 -newkey rsa:2048 -nodes -keyout ./democa/private/cakey.pem -out ./democa/cacert.pem -subj /c=${c}/st=${st}/l=${l}/o=${o}/ou=${ou}/cn=${cn}/emailaddress=${emailaddress}[ ! -f ./democa/private/ca.crl ] && openssl ca -crldays 36500 -gencrl -out ./democa/private/ca.crl
create_client_cert.sh
#!/bin/bash -eshow_help() {    echo $0 [-h|-?|--help] [--ou ou] [--cn cn] [--email email]    echo -h|-?|--help    显示帮助    echo --ou            设置组织或部门名,如: 技术部    echo --cn            设置fqdn或所有者名,如: 冯宇    echo --email         设置fqdn或所有者邮件,如: fengyu@example.com}while [[ $# -gt 0 ]]do    case $1 in        -h|-\?|--help)            show_help            exit 0            ;;        --ou)            ou=${2}            shift            ;;                --cn)            cn=${2}                        shift            ;;        --email)            emailaddress=${2}                        shift            ;;        --)            shift            break        ;;        *)            echo -e error: $0 invalid option '$1'\ntry '$0 --help' for more information.\n >&2            exit 1        ;;    esacshiftdone# 创建客户端证书# 非交互式方式创建以下内容:# 国家名(2个字母的代号)c=cn# 省st=shannxi# 市l=xian# 公司名o=my company# 组织或部门名ou=${ou:-测试部门}# 服务器fqdn或授予者名cn=${cn:-demo}# 邮箱地址emailaddress=${emailaddress:-demo@example.com}mkdir -p ${cn}[ ! -f ${cn}/${cn}.key ] && openssl req -utf8 -nodes -newkey rsa:2048 -keyout ${cn}/${cn}.key -new -days 36500 -out ${cn}/${cn}.csr -subj /c=${c}/st=${st}/l=${l}/o=${o}/ou=${ou}/cn=${cn}/emailaddress=${emailaddress}[ ! -f ${cn}/${cn}.crt ] && openssl ca -utf8 -batch -days 36500 -in ${cn}/${cn}.csr -out ${cn}/${cn}.crt[ ! -f ${cn}/${cn}.p12 ] && openssl pkcs12 -export -clcerts -capath ./democa/ -inkey ${cn}/${cn}.key -in ${cn}/${cn}.crt -certfile ./democa/cacert.pem -passout pass: -out ${cn}/${cn}.p12
revoke_cert.sh
#!/bin/bash -e# 吊销一个签证过的证书openssl ca -revoke ${1}/${1}.crtopenssl ca -gencrl -out ./democa/private/ca.crl
简单分析一波脚本,首先是创建ca,对于ubuntu系统来说,/etc/ssl/openssl.cnf配置中默认的ca路径就是./democa,为了不改动默认配置,直接按照默认配置的内容创建这些目录和文件即可。还有就是openssl子命令非常多,但是也和git一样,可以合并命令,比如用一条命令同时生成私钥和签证请求openssl req -nodes -newkey rsa:2048 -keyout client.key -new -out client.csr,在req的同时就做了genrsa。由于创建ca脚本只是第一次运行需要,因此把证书配置直接写死在脚本中就完事了。
接下来是创建客户端证书,为了简化用户的使用,在服务端帮助用户生成证书并签证,把签证过的证书下发给用户就可以了。由于用户可能是不同部门,不同姓名,不同邮件地址,因此将这三个参数外部化,做一下参数解析,加上友好的命令行提示防止遗忘。这个脚本特别注意最后一行,会生成一个pkcs12格式的证书。openssl默认产生的证书格式都是pem的,会将公钥和私钥分开,但是浏览器导入的时候需要将这些内容合并起来形成证书链,所以需要将签证过的证书和私钥文件合并成一个pkcs12格式的证书,直接将这个.p12格式的证书交给用户就可以了。
最后是吊销证书了,当希望收回某个用户的访问权限时,直接运行这个脚本跟上目录名就可以了。
接下来运行创建ca的脚本:
./create_ca_cert.shgenerating a 2048 bit rsa private key.......................+++........................................................................................................+++writing new private key to './democa/private/cakey.pem'-----using configuration from /usr/ssl/openssl.cnf
此时产生的./democa目录结构如下:
democa/├── cacert.pem├── crlnumber├── crlnumber.old├── index.txt├── newcerts├── private│   ├── ca.crl│   └── cakey.pem└── serial2 directories, 7 files
此时就可以配置nginx了,在上面单向ssl的配置中,追加以下配置:
ssl_client_certificate ssl_certs/democa/cacert.pem;  ssl_crl ssl_certs/democa/private/ca.crl;  ssl_verify_client on;
ssl_client_certificate就是客户端证书的ca证书了,代表此ca签发的证书都是可信的,ssl_verify_client on;代表强制启用客户端认证,非法客户端(无证书,证书不可信)都会返回400错。
特别注意ssl_crl这个配置,代表nginx会读取一个crl(certificate revoke list)文件,之前说过,可能会有收回用户权限的需求,因此我们必须有吊销证书的功能,产生一个crl文件让nginx知道哪些证书被吊销了即可。
注意: nginx配置都是静态的,读取配置文件之后都会加载到内存中,即使文件内容变化也不会重新读取。因此当crl文件发生变更之后,nginx并不能意识到有新的证书被吊销了,所以必须使用reload指令让nginx重新读取配置文件: service nginx reload或nginx -s reload此时重启nginx服务,就可以完成ssl双向认证配置了。
我们签发一个证书看看:
./create_client_cert.sh --ou 财务部 --cn 财务经理 --email cy@example.comgenerating a 2048 bit rsa private key................................+++.............................................................................+++writing new private key to '财务经理/财务经理.key'-----using configuration from /usr/ssl/openssl.cnfcheck that the request matches the signaturesignature okcertificate details:        serial number: 1 (0x1)        validity            not before: jun 14 16:03:46 2018 gmt            not after : may 21 16:03:46 2118 gmt        subject:            countryname               = cn            stateorprovincename       = shannxi            organizationname          = my company            organizationalunitname    = \u8d22\u52a1\u90e8            commonname                = \u8d22\u52a1\u7ecf\u7406            emailaddress              = cy@example.com        x509v3 extensions:            x509v3 basic constraints:                ca:false            netscape comment:                openssl generated certificate            x509v3 subject key identifier:                b5:91:0b:1f:fc:25:3b:2a:f9:ef:39:39:51:e3:1f:64:78:8a:c3:75            x509v3 authority key identifier:                keyid:86:55:76:15:a3:f5:58:cb:8f:39:a3:56:8e:ff:18:97:ae:27:60:0fcertificate is to be certified until may 21 16:03:46 2118 gmt (36500 days)write out database with 1 new entriesdata base updatedtree 财务经理/财务经理/├── 财务经理.crt├── 财务经理.csr├── 财务经理.key└── 财务经理.p120 directories, 4 files
这个脚本生成了私钥文件key,签证请求文件csr,经过ca签证后的证书文件crt(里面没有私钥),以及将crt文件和key进行bundle之后的pkcs12格式的证书文件p12,将p12文件下载到本地,双击一路next导入证书即可。
注: 由于ca的证书文件不会发生变化,因此签证新的客户端证书不需要restart或reload nginx这次打开我们的网站https://www.example.com,浏览器就会提示我们选择一个已有的客户端证书进行认证了,没问题就可以看到网站内容了
注: 每次导入新的证书之后,必须重启浏览器才能提示使用新的证书文件按照这种方式,有多少人需要授权,就可以用这个脚本签发多少个这样的证书,用户将p12证书导入本地就可以正常访问网站了。
当我们需要收回某人的权限的时候(比如离职了),我们需要吊销他的证书:
./revoke_cert.sh 财务经理using configuration from /usr/ssl/openssl.cnfrevoking certificate 01.data base updatedusing configuration from /usr/ssl/openssl.cnfservice nginx reload
这个脚本会自动吊销他的签证文件crt,并且自动更新crl文件。特别注意需要reload或restart nginx才能让nginx重新加载crl。这样被吊销的证书将无法访问网站了。
小结本文我们通过nginx配置ssl双向认证实现对客户端的加密认证,我们使用了简易的脚本帮助我们快速生成各种证书与签证,免除记忆繁琐openssl命令行,简化使用。
当然这只是一个最小可用集,当规模比较大的时候可能需要做很多改进,比如加入ca的web ui,直接可以操作签证和吊销证书,并且可以自动重启nginx。
再比如crl这种静态配置文件不适合你的场景,希望的动态更新吊销证书列表,那么可以考虑ocsp方案,这个nginx也是支持的,通过ssl_stapling_responder配置指定一个ocsp地址,这样将不需要每次吊销证书的时候都去重启nginx了,openssl也提供了ocsp服务端的功能,这里就不赘述了,可以自行查找相关资料。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注!
相关推荐:
nginx 部署静态页面
nginx关于root与alias的区别
以上就是nginx ssl快速双向认证配置(脚本)的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product