ngx_stream_ssl_module
ngx_stream_ssl_module 모듈(1.9.0)은 SSL/TLS 프로토콜에 사용할 스트림 프록시 서버에 대한 필수적인 지원을 제공합니다. 이 모듈은 기본적으로 구축되지 않으므로 –with-stream_ssl_module 구성 매개변수로 활성화해야 합니다.
예제 구성
프로세서 로드를 낮추려면 다음과 같은 방법을 사용하는 것이 좋습니다.
- 작업자 프로세스의 수를 프로세서 수와 동일하게 설정합니다.
- 공유 세션 캐시를 활성화합니다.
- 내부 세션 캐시를 비활성화합니다.
- 세션 수명을 늘립니다(기본값: 5분).
worker_processes auto;
stream {
...
server {
listen 12345 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
...
}
Directives
Syntax: ssl_alpn protocol ...;
Default: —
Context: stream, server
This directive appeared in version 1.21.4.
지원되는 ALPN 프로토콜의 목록을 지정합니다. 클라이언트가 ALPN을 사용할 경우 프로토콜 중 하나는 협상되어야 합니다.
map $ssl_alpn_protocol $proxy {
h2 127.0.0.1:8001;
http/1.1 127.0.0.1:8002;
}
server {
listen 12346;
proxy_pass $proxy;
ssl_alpn h2 http/1.1;
}
Syntax: ssl_certificate file;
Default: —
Context: stream, server
특정 서버에 대해 PEM 형식으로 인증서가 포함된 file을 지정합니다. 기본 인증서 외에 중간 인증서를 지정해야 하는 경우, 동일한 파일에 지정해야 합니다. 순서로는 기본 인증서가 먼저 오고, 중간 인증서가 뒤에 와야 합니다. PEM 형식의 시크릿 키를 같은 파일에 넣을 수도 있습니다.
1.11.0버전 이후로 이 명령을 여러 번 지정하여 다른 유형의 인증서(예: RSA, ECDSA)를 로드할 수 있습니다.
server {
listen 12345 ssl;
ssl_certificate example.com.rsa.crt;
ssl_certificate_key example.com.rsa.key;
ssl_certificate example.com.ecdsa.crt;
ssl_certificate_key example.com.ecdsa.key;
...
}
OpenSSL 1.0.2 이상만 각 인증서에 별도의 인증서 체인을 지원합니다. 이전 버전에서는 인증서 체인을 1개만 사용할 수 있습니다.
1.15.9버전 이후로 OpenSSL 1.0.2 이상을 사용할 때 file 이름에서 변수를 사용할 수 있습니다.
ssl_certificate $ssl_server_name.crt;
ssl_certificate_key $ssl_server_name.key;
단, 변수를 사용하면 인증서가 각 SSL 핸드셰이크에 로드되고 성능에 부정적 영향을 미칠 수 있습니다.
file(1.15.10) 대신 data:$variable 값을 지정할 수 있는데, 이는 중간 파일 없이 변수에서 인증서를 로드합니다. 이 구문을 잘못 사용하면 보안에 영향을 미칠 수 있습니다. 예를 들어, 시크릿 키 데이터가 오류 로그에 기록됩니다.
Syntax: ssl_certificate_key file;
Default: —
Context: stream, server
지정된 서버에 대해 PEM 형식으로 시크릿 키를 포함한 file을 지정합니다.
file 대신 engine:name:id 값을 지정할 수 있는데, 이는 OpenSSL 엔진 name에서 지정된 id가 포함된 시크릿 키를 로드합니다.
file(1.15.10) 대신 data:$variable 값을 사용할 경우, 중간 파일을 사용하지 않고 변수에서 시크릿 키를 로드합니다. 이 구문을 잘못 사용하면 보안에 영향을 미칠 수 있습니다. 예를 들어, 시크릿 키 데이터가 오류 로그에 기록됩니다.
1.15.9버전 이후로 OpenSSL 1.0.2 이상 사용 시 file 이름에 변수를 사용할 수 있습니다.
Syntax: ssl_ciphers ciphers;
Default: ssl_ciphers HIGH:!aNULL:!MD5;
Context: stream, server
활성화된 암호를 지정합니다. 암호는 OpenSSL 라이브러리에서 이해하는 형식으로 지정됩니다. 예시는 아래와 같습니다.
ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
전체 목록은 “openssl ciphers” 명령을 사용하여 확인할 수 있습니다.
Syntax: ssl_client_certificate file;
Default: —
Context: stream, server
This directive appeared in version 1.11.8.
클라이언트 인증서를 인증하는 데 사용한 신뢰할 수 있는 CA 인증서를 PEM 형식으로 포함한 file을 지정합니다.
인증서 목록은 클라이언트에 전송됩니다. 이를 원하지 않을 경우 ssl_trusted_certificate 명령을 사용할 수 있습니다.
Syntax: ssl_conf_command command;
Default: —
Context: stream, server
This directive appeared in version 1.19.4.
임의의 OpenSSL 구성 명령을 설정합니다.
이 명령은 OpenSSL 1.0.2 이상을 사용할 때 지원됩니다.
동일한 수준에서 여러 ssl_conf_command 명령을 지정할 수 있습니다.
ssl_conf_command Options PrioritizeChaCha;
ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;
이러한 명령은 현재 수준에서 ssl_conf_command 명령이 정의되지 않은 경우에만 이전 구성에서 상속합니다.
OpenSSL을 직접 구성하면 예상치 못한 동작이 발생할 수 있습니다.
Syntax: ssl_crl file;
Default: —
Context: stream, server
This directive appeared in version 1.11.8.
클라이언트 인증서를 인증하는 데 사용한 취소된 인증서(CRL)를 PEM 형식으로 포함한 file을 지정합니다.
Syntax: ssl_dhparam file;
Default: —
Context: stream, server
DHE 암호에 대한 DH 매개변수를 포함한 file을 지정합니다.
기본적으로는 매개변수가 설정되지 않으므로 DHE 암호를 사용하지 않습니다.
1.11.0버전 이전에는 내장된 매개변수를 기본으로 사용했습니다.
Syntax: ssl_ecdh_curve curve;
Default: ssl_ecdh_curve auto;
Context: stream, server
ECDHE 암호에 대해 curve를 지정합니다.
OpenSSL 1.0.2 이상을 사용할 때는 여러 커브를 지정할 수 있습니다(1.11.0). 예를 들면 다음과 같습니다.
ssl_ecdh_curve prime256v1:secp384r1;
특수 값 auto(1.11.0)를 사용하면 nginx가 OpenSSL 1.0.2 이상 또는 이전 버전의 prime256v1을 사용할 때 OpenSSL 라이브러리에 내장된 목록을 사용합니다.
1.11.0버전 이전에는 prime256v1 커브를 기본으로 사용했습니다.
OpenSSL 1.0.2 이상을 사용할 경우, 이 명령이 서버에서 지원되는 커브 목록을 설정합니다. 그러므로 ECDSA 인증서가 작동하려면 인증서에서 사용한 커브를 포함하는 것이 중요합니다.
Syntax: ssl_handshake_timeout time;
Default: ssl_handshake_timeout 60s;
Context: stream, server
SSL 핸드셰이크를 완료할 시간제한을 설정합니다.
Syntax: ssl_password_file file;
Default: —
Context: stream, server
시크릿 키에 대한 패스프레이즈가 포함된 file을 지정합니다. 각 패스프레이즈는 별도의 행으로 지정합니다. 키를 로딩할 때 순서대로 패스프레이즈를 시도합니다.
예:
stream {
ssl_password_file /etc/keys/global.pass;
...
server {
listen 127.0.0.1:12345;
ssl_certificate_key /etc/keys/first.key;
}
server {
listen 127.0.0.1:12346;
# named pipe can also be used instead of a file
ssl_password_file /etc/keys/fifo;
ssl_certificate_key /etc/keys/second.key;
}
}
Syntax: ssl_prefer_server_ciphers on | off;
Default: ssl_prefer_server_ciphers off;
Context: stream, server
SSLv3 및 TLS 프로토콜을 사용할 때 클라이언트 암호보다 서버 암호를 우선할지 지정합니다.
Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
Default: ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Context: stream, server
지정된 프로토콜을 활성화합니다.
OpenSSL 1.0.1 이상을 사용할 경우에만 TLSv1.1 및 TLSv1.2 매개변수가 작동합니다.
TLSv1.3 매개변수(1.13.0)는 OpenSSL 1.1.1 이상을 사용할 때만 작동합니다.
Syntax: ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
Default: ssl_session_cache none;
Context: stream, server
세션 매개변수를 저장하는 캐시의 유형과 크기를 설정합니다. 캐시는 다음 유형 중 하나를 사용합니다.
off
세션 캐시 사용을 엄격히 금지합니다. ngnix가 클라이언트에게 세션을 재사용하지 못하도록 지시합니다.
none
세션 캐시 사용을 적절히 금지합니다. nginx가 클라이언트에게 세션을 다시 사용할 수 있지만, 캐시에 세션 매개변수를 저장하지 못하도록 지시합니다.
builtin
OpenSSL에 내장된 캐시로, 작업 프로세서 1개에서만 사용합니다. 캐시 용량은 세션에서 지정됩니다. 용량을 지정하지 않을 경우, 20,480개 세션이 됩니다. 내장 캐시를 사용하면 메모리가 조각날 수 있습니다.
shared
모든 작업자 프로세스 사이에서 공유되는 캐시입니다. 캐시 크기는 바이트로 지정됩니다. 1MB는 약 4,000개의 세션을 저장할 수 있습니다. 각 공유된 캐시는 임의의 이름으로 지정해야 합니다. 이름이 동일한 캐시를 여러 서버에 사용할 수 있습니다.
다음과 같이 두 가지 캐시 유형을 동시에 사용할 수 있습니다.
ssl_session_cache builtin:1000 shared:SSL:10m;
하지만 내장 캐시 없이 공유된 캐시만 사용하는 것이 더욱 효율적입니다.
Syntax: ssl_session_ticket_key file;
Default: —
Context: stream, server
TLS 세션 티켓을 암호화, 복호화하는 데 사용하는 시크릿 키를 포함한 file을 설정합니다. 동일한 키를 여러 서버에서 공유해야 할 경우에 이 명령이 필요합니다. 기본적으로 무작위로 생성된 키를 사용합니다.
여러 키를 지정하는 경우, 첫 키만 TLS 세션 티켓을 암호화하는 데 사용합니다. 그러면 다음과 같이 구성 키가 순환됩니다.
ssl_session_ticket_key current.key;
ssl_session_ticket_key previous.key;
file에는 무작위 데이터 80바이트 또는 48바이트가 포함되어야 하며, 다음의 명령을 사용하여 생성할 수 있습니다.
openssl rand 80 > ticket.key
파일 용량에 따라 AES256(80바이트 키, 1.11.8) 또는 AES128(48바이트 키)을 암호화에 사용할 수 있습니다.
Syntax: ssl_session_tickets on | off;
Default: ssl_session_tickets on;
Context: stream, server
TLS 세션 티켓을 통해 세션 재개를 활성화하거나 비활성화합니다.
Syntax: ssl_session_timeout time;
Default: ssl_session_timeout 5m;
Context: stream, server
클라이언트가 세션 매개변수를 재사용하는 시간을 지정합니다.
Syntax: ssl_trusted_certificate file;
Default: —
Context: stream, server
This directive appeared in version 1.11.8.
클라이언트 인증서를 인증하는 데 사용한 신뢰할 수 있는 CA 인증서를 PEM 형식으로 포함한 file을 지정합니다.
ssl_client_certificate에서 설정한 인증서와 달리, 이 인증서 목록은 클라이언트로 보내지 않습니다.
Syntax: ssl_verify_client on | off | optional | optional_no_ca;
Default: ssl_verify_client off;
Context: stream, server
This directive appeared in version 1.11.8.
클라이언트 인증서의 인증을 활성화합니다. 인증 결과는 $ssl_client_verify 변수에 저장됩니다. 클라이언트 인증서 인증 도중에 오류가 발생하거나 클라이언트가 필요한 인증서를 제출하지 않은 경우 연결이 종료됩니다.
optional 매개변수가 클라이언트 인증서를 요청하고 인증서가 있는지 확인합니다.
optional_no_ca 매개변수는 클라이언트 인증서를 요청하지만, 신뢰할 수 있는 CA 인증서의 서명이 필요하지 않습니다. 이는 nginx 외부의 서버가 인증서를 실제로 인증하는 경우에 필요합니다. 인증서 내용은 $ssl_client_cert 변수를 통해 액세스할 수 있습니다.
Syntax: ssl_verify_depth number;
Default: ssl_verify_depth 1;
Context: stream, server
This directive appeared in version 1.11.8.
클라이언트 인증서 체인에서 인증 깊이를 설정합니다.
임베디드 변수
ngx_stream_ssl_module 모듈은 1.11.2버전 이후로 변수를 지원합니다.
$ssl_alpn_protocol
SSL 핸드셰이크에서 ALPN이 선택한 프로토콜을 반환하거나, 빈 문자열(1.21.4)을 반환합니다.
$ssl_cipher
설정된 SSL 연결에 사용한 암호 이름을 반환합니다.
$ssl_ciphers
클라이언트가 지원하는 암호 목록을 반환합니다(1.11.7). 알려진 암호는 이름으로 목록이 작성되며, 알려지지 않은 암호는 16진법으로 표시됩니다.
AES128-SHA:AES256-SHA:0x00ff
OpenSSL 1.0.2버전 이상을 사용할 경우에만 변수가 완전히 지원됩니다. 이전 버전의 경우, 새로운 세션에만 변수를 사용할 수 있고 알려진 암호만 목록으로 작성합니다.
$ssl_client_cert
설정된 SSL 연결에 대해 PEM 형식으로 클라이언트 인증서를 반환합니다. 첫 번째 행을 제외한 각 행은 Tab 문자로 구분됩니다(1.11.8).
$ssl_client_fingerprint
설정된 SSL 연결에 대해 클라이언트 인증서의 SHA1 핑거프린트를 반환합니다(1.11.8).
$ssl_client_i_dn
RFC 2253에 따라 설정된 SSL 연결에 대해 클라이언트 인증서의 “issuer DN” 문자열을 반환합니다(1.11.8).
$ssl_client_raw_cert
설정된 SSL 연결에 대해 PEM 형식으로 클라이언트 인증서를 반환합니다(1.11.8).
$ssl_client_s_dn
RFC 2253에 따라 설정된 SSL 연결에 대해 클라이언트 인증서의 “subject DN” 문자열을 반환합니다(1.11.8).
$ssl_client_serial
설정된 SSL 연결에 대해 클라이언트 인증서의 일련번호를 반환합니다(1.11.8).
$ssl_client_v_end
클라이언트 인증서의 종료 날짜를 반환합니다(1.11.8).
$ssl_client_v_remain
클라이언트 인증서가 만료되기까지 기간을 반환합니다(1.11.8).
$ssl_client_v_start
클라이언트 인증서의 시작 날짜를 반환합니다(1.11.8).
$ssl_client_verify
클라이언트 인증서의 인증 결과를 반환합니다(1.11.8). “SUCCESS”, “FAILED:reason” 및 “NONE”(인증서가 없는 경우)이 있습니다.
$ssl_curve
SSL 핸드셰이크 키 교환 프로세스(1.21.5)에 사용된 협상 곡선을 반환합니다. 알려진 곡선은 이름별로 나열되며, 알 수 없는 곡선은 16진수로 표시됩니다. 예를 들면 다음과 같습니다.
prime256v1
변수는 OpenSSL 버전 3.0 이상을 사용하는 경우에만 지원됩니다. 이전 버전에서는 변수 값이 빈 문자열이 됩니다.
$ssl_curves
클라이언에서 지원하는 커브 목록을 반환합니다(1.11.7). 알려진 커브는 이름으로 목록이 작성되고, 알려지지 않은 커브는 16진수로 표시됩니다.
예를 들어 다음과 같은 형식입니다.
0x001d:prime256v1:secp521r1:secp384r1
이 변수는 OpenSSL 1.0.2버전 이상을 사용할 때만 지원됩니다. 이전 버전에서 변수 값은 빈 문자열이 됩니다.
이 변수는 새로운 세션에만 제공됩니다.
$ssl_protocol
설정된 SSL 연결의 프로토콜을 반환합니다.
$ssl_server_name
SNI를 통해 요청한 서버 이름을 반환합니다.
$ssl_session_id
설정된 SSL 연결의 세션 식별자를 반환합니다.
$ssl_session_reused
SSL 세션을 다시 사용할 경우 “r”을 반환하고 그 외에는 “.”을 반환합니다.