Nginx SSL 빠른 양방향 인증 구성(스크립트)
这篇文章主要介绍了关于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.sh 0 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.com mkdir -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 -e show_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 ;; esac shift done # 创建客户端证书 # 非交互式方式创建以下内容: # 国家名(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}.crt" openssl 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.sh Generating 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 └── serial 2 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.com Generating a 2048 bit RSA private key ................................+++ .............................................................................+++ writing new private key to '财务经理/财务经理.key' ----- Using configuration from /usr/ssl/openssl.cnf Check that the request matches the signature Signature ok Certificate 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:0F Certificate is to be certified until May 21 16:03:46 2118 GMT (36500 days) Write out database with 1 new entries Data Base Updated tree 财务经理/ 财务经理/ ├── 财务经理.crt ├── 财务经理.csr ├── 财务经理.key └── 财务经理.p12 0 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.cnf Revoking Certificate 01. Data Base Updated Using configuration from /usr/ssl/openssl.cnf service 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服务端的功能,这里就不赘述了,可以自行查找相关资料。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
위 내용은 Nginx SSL 빠른 양방향 인증 구성(스크립트)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Tomcat 서버가 외부 네트워크에 액세스하도록 허용하려면 다음을 수행해야 합니다. 외부 연결을 허용하도록 Tomcat 구성 파일을 수정합니다. Tomcat 서버 포트에 대한 액세스를 허용하는 방화벽 규칙을 추가합니다. Tomcat 서버 공용 IP에 대한 도메인 이름을 가리키는 DNS 레코드를 만듭니다. 선택 사항: 역방향 프록시를 사용하여 보안 및 성능을 향상합니다. 선택 사항: 보안 강화를 위해 HTTPS를 설정합니다.

Nginx의 시작 및 중지 명령은 각각 nginx 및 nginx -s quit입니다. start 명령은 서버를 직접 시작하는 반면 stop 명령은 서버를 정상적으로 종료하여 모든 현재 요청이 처리되도록 합니다. 사용 가능한 기타 정지 신호에는 정지 및 재장전이 포함됩니다.

ThinkPHP Framework를 로컬에서 실행하는 단계: ThinkPHP Framework를 로컬 디렉터리에 다운로드하고 압축을 풉니다. ThinkPHP 루트 디렉터리를 가리키는 가상 호스트(선택 사항)를 만듭니다. 데이터베이스 연결 매개변수를 구성합니다. 웹 서버를 시작합니다. ThinkPHP 애플리케이션을 초기화합니다. ThinkPHP 애플리케이션 URL에 접속하여 실행하세요.

"Welcome to nginx!" 오류를 해결하려면 가상 호스트 구성을 확인하고, 가상 호스트를 활성화하고, Nginx를 다시 로드하고, 가상 호스트 구성 파일을 찾을 수 없으면 기본 페이지를 만들고, Nginx를 다시 로드해야 합니다. 그러면 오류 메시지가 나타납니다. 사라지고 웹사이트는 정상적으로 표시됩니다.

Node.js 프로젝트의 서버 배포 단계: 배포 환경 준비: 서버 액세스 권한 획득, Node.js 설치, Git 저장소 설정. 애플리케이션 빌드: npm run build를 사용하여 배포 가능한 코드와 종속성을 생성합니다. Git 또는 파일 전송 프로토콜을 통해 서버에 코드를 업로드합니다. 종속성 설치: SSH를 서버에 연결하고 npm install을 사용하여 애플리케이션 종속성을 설치합니다. 애플리케이션 시작: node index.js와 같은 명령을 사용하여 애플리케이션을 시작하거나 pm2와 같은 프로세스 관리자를 사용합니다. 역방향 프록시 구성(선택 사항): Nginx 또는 Apache와 같은 역방향 프록시를 사용하여 트래픽을 애플리케이션으로 라우팅합니다.

phpMyAdmin을 등록하려면 먼저 MySQL 사용자를 생성하고 권한을 부여한 다음 phpMyAdmin을 다운로드, 설치 및 구성하고 마지막으로 phpMyAdmin에 로그인하여 데이터베이스를 관리해야 합니다.

웹사이트에 접속할 때 nginx가 나타날 수 있습니다. 서버 유지 관리, 바쁜 서버, 브라우저 캐시, DNS 문제, 방화벽 차단, 웹사이트 구성 오류, 네트워크 연결 문제 또는 웹사이트 다운이 원인일 수 있습니다. 다음 해결 방법을 시도해 보십시오. 유지 관리가 끝날 때까지 기다리기, 사용량이 적은 시간에 방문하기, 브라우저 캐시 지우기, DNS 캐시 플러시하기, 방화벽 또는 바이러스 백신 소프트웨어 비활성화하기, 사이트 관리자에게 문의하기, 네트워크 연결 확인하기, 검색 엔진 사용하기 또는 사이트의 다른 사본을 찾으려면 웹 아카이브를 방문하세요. 문제가 지속되면 사이트 관리자에게 문의하세요.

Docker 환경에는 공유 네트워크, Docker Compose, 네트워크 프록시, 공유 볼륨 및 메시지 큐의 5가지 컨테이너 통신 방법이 있습니다. 격리 및 보안 요구 사항에 따라 Docker Compose를 활용하여 연결을 단순화하거나 네트워크 프록시를 사용하여 격리를 높이는 등 가장 적절한 통신 방법을 선택하세요.
