블로그 | NGINX

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

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 zone=kv:1m;
   
  server {   …    # Sets an njs function for the variable. Returns a value of cert/key     js_set $dynamic_ssl_cert main.js_cert;     js_set $dynamic_ssl_key main.js_key;  
    # use variable's data     ssl_certificate data:$dynamic_ssl_cert;     ssl_certificate_key data:$dynamic_ssl_key;    
   # a location to clear cache  location = /clear {     js_content main.clear_cache;     # allow 127.0.0.1;     # deny all;   }
  ... }

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

function js_cert(r) {  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.cert.pem');
  } else {
    return '';
  }
}

function js_key(r) {
  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.key.pem');
  } else {
    return '';
  }
}
/** 
   * Retrieves the key/cert value from Shared memory or fallback to disk
   */
  function 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 key = ['certs', path].join(':');
    const cache = zone && ngx.shared && ngx.shared[zone];
   
  if (cache) { data = cache.get(key) || ''; if (data) { r.log(`Read ${key} from cache`); return data; } } try { data = fs.readFileSync(path, 'utf8'); r.log('Read from cache'); } catch (e) { data = ''; r.log(`Error reading from file:${path}. Error=${e}`); } if (cache && data) { try { cache.set(key, data); r.log('Persisted in cache'); } catch (e) { const errMsg = `Error writing to shared dict zone: ${zone}. Error=${e}`; r.log(errMsg); } } return data }

/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 콘텐츠로 리디렉션됩니다."