블로그 | NGINX

NGINX 오픈 소스에서 재시작 없이 SSL/TLS 인증서 순환

NGINX-F5-수평-검정-유형-RGB의 일부
Maxim Ivanitskiy 썸네일
막심 이바니츠키
2023년 9월 26일 게시

고성능 웹 서버 분야에서 NGINX는 가볍고 효율적인 아키텍처로 많은 양의 트래픽을 처리할 수 있어 인기 있는 선택입니다. NGINX JavaScript 모듈(njs) 의 일부로 공유 사전 기능이 도입되면서 NGINX의 성능이 새로운 차원으로 도약했습니다.

이 블로그 게시물에서는 njs 공유 사전의 기능과 이점을 살펴보고 SSL/TLS 인증서를 순환할 때 재시작 없이 NGINX 오픈 소스를 설정하는 방법을 보여줍니다.

공유 사전 기본 사항 및 이점

새로운 js_shared_dict_zone 지시어를 사용하면 NGINX 오픈 소스 사용자는 작업자 프로세스 간에 효율적인 데이터 교환을 위해 공유 메모리 영역을 활성화할 수 있습니다. 이러한 공유 메모리 영역은 키-값 사전 역할을 하여 실시간으로 액세스하고 수정할 수 있는 동적 구성 설정을 저장합니다.

공유 사전의 주요 이점은 다음과 같습니다.

  • 최소한의 오버헤드와 사용 편의성 - njs에 직접 내장되어 있어 직관적인 API와 간단한 구현으로 프로비저닝하고 활용하기 쉽습니다. 또한 작업자 프로세스 간에 데이터를 관리하고 공유하는 프로세스를 단순화하는 데 도움이 됩니다.
  • 가볍고 효율적 – NGINX와 완벽하게 통합되어 이벤트 기반, 비차단 I/O 모델을 활용합니다. 이러한 접근 방식은 메모리 사용량을 줄이고 동시성을 향상시켜 NGINX가 많은 동시 연결을 효율적으로 처리할 수 있게 합니다.
  • 확장성 – 여러 작업자 프로세스에 걸쳐 수평적으로 확장할 수 있는 NGINX의 기능을 활용하여 복잡한 프로세스 간 통신 메커니즘이 필요 없이 해당 프로세스 간에 데이터를 공유하고 동기화할 수 있습니다. TTL(수명) 설정을 사용하면 비활성 상태로 인해 공유 사전 항목의 레코드를 영역에서 제거하여 해당 레코드를 관리할 수 있습니다. evict 매개변수는 새로운 항목을 위한 공간을 만들기 위해 가장 오래된 키-값 쌍을 제거합니다.

공유 사전을 사용한 SSL 로테이션

공유 사전의 가장 큰 영향력 있는 사용 사례 중 하나가 SSL/TLS 순환입니다. js_shared_dict_zone을 사용하면 SSL/TLS 인증서나 키가 업데이트되는 경우 NGINX를 다시 시작할 필요가 없습니다. 또한 NGINX에서 인증서를 관리할 수 있는 REST와 유사한 API를 제공합니다.

다음은 js_setssl_certificate 지시어로 HTTPS 서버를 설정하는 NGINX 구성 파일의 예입니다. JavaScript 핸들러는 js_set을 사용하여 파일에서 SSL/TLS 인증서나 키를 읽습니다.

이 구성 스니펫은 공유 사전을 사용하여 인증서와 키를 공유 메모리에 캐시로 저장합니다. 키가 없으면 디스크에서 인증서나 키를 읽어 캐시에 넣습니다.

캐시를 지우는 위치를 공개할 수도 있습니다. 디스크에 있는 파일이 업데이트되면(예: 인증서와 키가 갱신됨) 공유 사전은 디스크에서 읽기를 강제로 실행합니다. 이 조정을 통해 NGINX 프로세스를 다시 시작하지 않고도 인증서/키를 교체할 수 있습니다.

http { ... js_shared_dict_zone 영역=kv:1m;
서버 { … # 변수에 대한 njs 함수를 설정합니다. 인증서/키 js_set $dynamic_ssl_cert main.js_cert; js_set $dynamic_ssl_key main.js_key의 값을 반환합니다.
# 변수의 데이터 ssl_certificate 사용 데이터:$dynamic_ssl_cert; ssl_certificate_key 데이터:$dynamic_ssl_key;
# 캐시를 지울 위치 location = /clear { js_content main.clear_cache; # 허용 127.0.0.1; # 모두 거부; }
... }

다음은 js_shared_dict_zone을 사용하여 SSL/TLS 인증서와 키를 순환하기 위한 JavaScript 구현입니다.

함수 js_cert(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.cert.pem'); } else { return ''; } } 함수 js_key(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.key.pem'); } else { return ''; } } /** * 공유 메모리나 디스크로 폴백에서 키/인증서 값을 검색합니다. */ 함수 read_cert_or_key(r, fileExtension) { let data = ''; let path = ''; const zone = 'kv'; let certName = r.variables.ssl_server_name; let prefix = '/etc/nginx/certs/'; path = prefix + certName + fileExtension; r.log('Resolving${path} '); const 키 = ['인증서', 경로].join(':'); const 캐시 = 영역 && ngx.공유 && ngx.공유[영역];
if (캐시) { data = cache.get(키) || ''; if (데이터) { r.log(`읽기${key} 캐시에서 `); return data; } } try { data = fs.readFileSync(path, 'utf8'); r.log('캐시에서 읽음'); } catch (e) { data = ''; r.log(`파일에서 읽는 중 오류:${path} . 오류 =${e} `); } if (cache && data) { try { cache.set(key, data); r.log('캐시에 저장됨'); } catch (e) { const errMsg = `공유 dict 영역에 쓰는 중 오류 발생:${zone} . 오류 =${e} `; r.log(errMsg); } } 데이터 반환 }

/clear 요청을 보내면 캐시가 무효화되고 NGINX는 다음 SSL/TLS 핸드셰이크에서 디스크에서 SSL/TLS 인증서나 키를 로드합니다. 또한, 캐시를 지속하고 업데이트하는 동안 요청에서 SSL/TLS 인증서나 키를 가져오는 js_content를 구현할 수도 있습니다.

이 예제의 전체 코드는 njs GitHub repo 에서 찾을 수 있습니다.

오늘 시작하세요

공유 사전 기능은 애플리케이션의 프로그래밍성을 강화하는 강력한 도구로, 간소화와 확장성 측면에서 상당한 이점을 제공합니다. js_shared_dict_zone 의 기능을 활용하면 성장을 위한 새로운 기회를 열고 증가하는 트래픽 수요를 효율적으로 처리할 수 있습니다.

js_shared_dict_zone 으로 NGINX 배포를 엄청나게 강화할 준비가 되셨나요? js_shared_dict_zone 으로 NGINX 배포를 업그레이드하면 새로운 사용 사례를 얻을 수 있으며, 설명서 에서 이 기능에 대해 자세히 알아볼 수 있습니다. 또한, 최근 도입된 njs-acme 프로젝트 에서 공유 사전 기능의 완전한 예를 볼 수 있습니다. 이를 통해 njs 모듈 런타임이 ACME 공급자와 함께 작동할 수 있습니다.

NGINX 오픈 소스를 시작하는 데 관심이 있고 궁금한 점이 있으면 NGINX 커뮤니티 Slack에 가입하세요 . 자신을 소개하고 NGINX 사용자 커뮤니티를 알아보세요!


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."