>  기사  >  백엔드 개발  >  nginx는 HTTPS 서버를 구성합니다

nginx는 HTTPS 서버를 구성합니다

WBOY
WBOY원래의
2016-08-08 09:30:14848검색

http://nginx.org/cn/docs/http/configuring_https_servers.html

HTTPS 서버 구성

번역된 콘텐츠가 누락되었을 수 있습니다. 날짜 . 영어 버전을 통해 최신 업데이트를 볼 수 있습니다.
HTTPS 서버 최적화
HTTPS服务器优化
SSL证书链
合并HTTP/HTTPS主机
基于名字的HTTPS主机
带有多个主机名的SSL证书
主机名指示
兼容性
SSL 인증서 체인HTTP/HTTPS 호스트 병합이름 기반 HTTPS 호스트여러 호스트 이름이 포함된 SSL 인증서호스트 이름 표시호환성

HTTPS 호스트를 구성하려면 서버 구성 블록에서 SSL 프로토콜을 열고 서버 측 인증서 및 키 파일의 위치를 ​​지정해야 합니다.

server {
    listen              443;
    server_name         www.example.com;
    ssl                 on;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

서버 인증서는 공개되어 있으며 서버에 연결된 모든 클라이언트로 전송됩니다. 개인 키는 공개되지 않으며 액세스가 제한된 파일에 저장되어야 합니다. 물론 nginx 기본 프로세스에는 키를 읽을 수 있는 권한이 있어야 합니다. 개인 키와 인증서는 동일한 파일에 저장할 수 있습니다.

    ssl_certificate     www.example.com.cert;
    ssl_certificate_key www.example.com.cert;

이 경우 인증서 파일에도 액세스 제한을 설정해야 합니다. 물론, 인증서와 키가 동일한 파일에 저장되어 있더라도 클라이언트에는 키가 아닌 인증서만 전송됩니다.

ssl_protocols 및 ssl_ciphers 지시어를 사용하면 사용자 연결이 SSL/TLS의 강력한 프로토콜 버전과 강력한 암호화 알고리즘만 도입하도록 할 수 있습니다. 버전 1.0.5부터 nginx는 "ssl_protocols SSLv3 TLSv1" 및 "ssl_ciphers HIGH:!aNULL:!MD5"을 기본적으로 사용하므로 이전 버전에서는 이를 명시적으로 구성하는 것만 의미가 있었습니다. 버전 1.1.13 및 1.0.12부터 nginx는 기본적으로 "ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2"를 사용합니다.

CBC 모드의 암호화 알고리즘은 일부 공격, 특히 BEAST 공격에 취약합니다(CVE-2011-3389 참조). 다음 구성을 통해 RC4-SHA 암호화 알고리즘에 우선순위를 부여하도록 조정할 수 있습니다.

    ssl_ciphers RC4:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

HTTPS 서버 최적화

SSL 작업에는 CPU 리소스가 필요하므로 다중 프로세서 시스템에서는 여러 작업자 프로세스를 시작해야 하며 그 수는 사용 가능한 CPU 수 이상이어야 합니다. 가장 많은 CPU 리소스를 소비하는 SSL 작업은 SSL 핸드셰이크입니다. 각 클라이언트에 대한 핸드셰이크 작업 수를 최소화하는 방법에는 두 가지가 있습니다. 첫 번째는 클라이언트 연결을 오랫동안 유지하고 하나의 SSL 연결에서 여러 요청을 보내는 것입니다. 동시 연결이나 후속 연결에서 SSL 세션 매개 변수를 재사용하여 SSL 핸드셰이크 작업을 방지하는 것입니다. 세션 캐시는 SSL 세션을 저장하는 데 사용되며 이러한 캐시는 작업자 프로세스 간에 공유되며 ssl_session_cache 지시문을 사용하여 구성할 수 있습니다. 1M 캐시는 약 4,000개의 세션을 저장할 수 있습니다. 기본 캐시 시간 제한은 5분이며, ssl_session_timeout을 사용하여 늘릴 수 있습니다. 다음은 10M 공유 세션 캐시를 사용하는 4코어 시스템에 대한 구성 최적화의 예입니다.

worker_processes  4;

http {
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;

    server {
        listen              443;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl                 on;
        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...

SSL 인증서 체인

일부 브라우저는 잘 알려진 인증 기관에서 서명한 인증서를 허용하지 않는 반면 다른 브라우저는 허용합니다. 이는 인증서 발급이 일부 중간 인증 기관을 사용하기 때문입니다. 이러한 중개 기관은 잘 알려진 인증서 인증 기관에서 인증서를 대신 발급하도록 권한을 부여하지만 자체적으로는 널리 인정받지 못하므로 일부 클라이언트에서는 이를 인식하지 못합니다. 이러한 상황에 대응하여 인증서 인증 기관은 잘 알려진 인증 기관과 자신 간의 관계를 선언하기 위해 인증서 체인 패키지를 제공합니다. 이 인증서 체인 패키지는 서버 인증서와 하나의 파일로 병합되어야 합니다. 이 파일에서 서버 인증서는 인증자 인증서 체인 앞에 나타나야 합니다.

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt

이 파일은 ssl_certificate 지시문을 사용하여 참조해야 합니다.

server {
    listen              443;
    server_name         www.example.com;
    ssl                 on;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

서버 인증서와 인증자 인증서 체인이 잘못된 순서로 병합되면 nginx가 정상적으로 시작되지 않고 다음과 같은 오류 메시지가 표시됩니다.

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

nginx는 먼저 개인 키를 사용하여 서버 인증서를 해독해야 하는데 인증자의 인증서를 만나기 때문입니다.

브라우저는 일반적으로 신뢰할 수 있는 인증 기관에서 인증한 중간 인증 기관을 저장합니다. 그러면 이러한 브라우저가 이러한 중간 인증 기관을 사용하지만 저장되었기 때문에 나중에 인증서 체인을 포함하지 않는 상황이 발생합니다. 이러한 중간인증기관의 정보가 포함되어 있어 오류가 발생하지 않습니다. openssl 명령줄 도구를 사용하여 서버가 전체 인증서 체인을 보냈는지 확인할 수 있습니다.

$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com
...

이 예에서 www.GoDaddy.com에 대한 서버 인증서( #0) 서명자("s")는 발급 기관("i")의 서명을 받고, 이 발급 기관이 인증서의 서명자(#1)이고, 인증서 발급 기관(#1)은 다음과 같습니다. 인증서(#2의 수신자), 최종 인증서(#2)는 잘 알려진 발급 기관인 ValiCert, Inc에서 발급되었습니다. ValiCert, Inc의 인증서는 브라우저에 내장되어 있으며 브라우저에서 자동으로 인식됩니다(이 구절은 영국 시 "In the House That Jack Build"의 내용과 유사합니다).

인증서 체인을 추가하지 않으면 서버 인증서(#0)만 표시됩니다.

HTTP/HTTPS 통합 호스트

HTTP 및 HTTPS 가상 호스트의 기능이 일관되면 HTTP 요청과 HTTPS 요청을 모두 처리하도록 가상 호스트를 구성할 수 있습니다. 구성 방법은 ssl on 명령을 삭제하고 *:443 포트에 ssl 매개변수를 추가하는 것입니다:

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}
버전 0.8.21 이전에는 default이 추가되었습니다 >매개변수의 수신 포트는 ssl 매개변수를 추가할 수 있습니다.
listen  443  default ssl;

이름 기반 HTTPS 호스트

동일한 IP에 여러 개의 HTTPS 호스트를 구성하면 매우 일반적인 문제가 발생합니다. :

server {
    listen          443;
    server_name     www.example.com;
    ssl             on;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443;
    server_name     www.example.org;
    ssl             on;
    ssl_certificate www.example.org.crt;
    ...
}

使用上面的配置,不论浏览器请求哪个主机,都只会收到默认主机www.example.com的证书。这是由SSL协议本身的行为引起的——先建立SSL连接,再发送HTTP请求,所以nginx建立SSL连接时不知道所请求主机的名字,因此,它只会返回默认主机的证书。

最古老的也是最稳定的解决方法就是每个HTTPS主机使用不同的IP地址:

server {
    listen          192.168.1.1:443;
    server_name     www.example.com;
    ssl             on;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          192.168.1.2:443;
    server_name     www.example.org;
    ssl             on;
    ssl_certificate www.example.org.crt;
    ...
}

带有多个主机名的SSL证书

也有其他一些方法可以实现多个HTTPS主机共享一个IP地址,但都有不足。其中一种方法是使用在“SubjectAltName”字段中存放多个名字的证书,比如www.example.comwww.example.org。但是,“SubjectAltName”字段的长度有限制。

另一种方式是使用主机名中含有通配符的证书,比如*.example.org。这个证书匹配www.example.org,但是不匹配example.orgwww.sub.example.org。这两种方法可以结合在一起——使用在“SubjectAltName”字段中存放的多个名字的证书,这些名字既可以是确切的名字,也可以是通配符,比如example.org*.example.org

最好将带有多个名字的证书和它的密钥文件配置在http配置块中,这样可以只保存一份内容拷贝,所有主机的配置都从中继承:

ssl_certificate      common.crt;
ssl_certificate_key  common.key;

server {
    listen          443;
    server_name     www.example.com;
    ssl             on;
    ...
}

server {
    listen          443;
    server_name     www.example.org;
    ssl             on;
    ...
}

主机名指示

在一个IP上运行多个HTTPS主机的更通用的方案是TLS主机名指示扩展(SNI,RFC6066),它允许浏览器和服务器进行SSL握手时,将请求的主机名传递给服务器,因此服务器可以知道使用哪一个证书来服务这个连接。但SNI只得到有限的浏览器的支持。下面列举支持SNI的浏览器最低版本和平台信息:

  • Opera 8.0;
  • MSIE 7.0(仅在Windows Vista操作系统及后续操作系统);
  • Firefox 2.0和使用Mozilla平台1.8.1版本的其他浏览器;
  • Safari 3.2.1(Windows版需要最低Vista操作系统);
  • Chrome(Windows版需要最低Vista操作系统)。
通过SNI只能传递域名,但是,当请求中包含可读的IP地址时,某些浏览器将服务器的IP地址作为服务器的名字进行了传送。这是一个错误,大家不应该依赖于这个。

为了在nginx中使用SNI,那么无论是在编译nginx时使用的OpenSSL类库,还是在运行nginx时使用的OpenSSL运行库,都必须支持SNI。从0.9.8f版本开始,OpenSSL通过“--enable-tlsext”配置选项加入SNI支持,从0.9.8j版本开始,此选项成为默认选项。当nginx被编译成支持SNI时,在使用“-V”选项运行时会显示如下信息:

$ nginx -V
...
TLS SNI support enabled
...

但是,当开启SNI支持的nginx被动态链接到不支持SNI的OpenSSL库上时,nginx会显示如下警告:

nginx was built with SNI support, however, now it is linked
dynamically to an OpenSSL library which has no tlsext support,
therefore SNI is not available

兼容性

  • 从0.8.21和0.7.62版本开始,使用“-V”选项运行nginx时,将显示SNI支持状态信息。
  • 从0.7.14版本开始,listen指令支持ssl参数。
  • 从0.5.32版本开始,支持SNI。
  • 从0.5.6版本开始,支持SSL会话缓存,并可在工作进程间共享。
  • 0.7.65、0.8.19及以后版本,默认SSL协议是SSLv3、TLSv1、TLSc1.1和TLSv1.2(如果OpenSSL库支持)。
  • 0.7.64、0.8.18及以前版本,默认SSL协议是SSLv2、SSLv3和TLSv1。
  • 1.0.5及以后版本,默认SSL密码算法是HIGH:!aNULL:!MD5
  • 0.7.65、0.8.20及以后版本,默认SSL密码算法是HIGH:!ADH:!MD5
  • 0.8.19版本,默认SSL密码算法是ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM
  • 0.7.64、0.8.18及以前版本,默认SSL密码算法是ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
作者: Igor Sysoev
编辑: Brian Mercer
翻译: cfsego

以上就介绍了nginx 配置HTTPS服务器,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.