SSL/TLS 인증서 재시작 없이 교체하기
이 포스트에서는 njs shared dictionary 기능과 이점을 살펴보고 SSL/TLS 인증서 교체를 진행할 때 재시작할 필요 없이 NGINX 오픈 소스를 설정하는 방법을 보여줍니다.
고성능 웹 서버의 세계에서는 가볍고 효율적인 아키텍처로 대량의 트래픽을 처리할 수 있는 NGINX가 인기 있는 선택입니다. NGINX JavaScript 모듈(njs)의 일부로 shared dictionary 기능이 도입되면서 NGINX의 성능은 한 차원 더 높아졌습니다.
목차
1. Shared Dictionary 기본 사항 및 이점
2. Shared Dictionary를 사용한 SSL/TLS 인증서 교체
3. 지금 시작하세요.
1. Shared Dictionary 기본 사항 및 이점
새로운 js_shared_dict_zone 지시문을 사용하면 NGINX 오픈 소스 사용자가 worker process 간의 효율적인 데이터 교환을 위해 공유 메모리 영역을 활성화할 수 있습니다. 이러한 공유 메모리 영역은 실시간으로 액세스하고 수정할 수 있는 동적 구성 설정을 저장하는 key-value dictionary 역할을 합니다.
Shared dictionary의 주요 이점은 다음과 같습니다:
- 최소한의 오버헤드 및 간편한 사용 – njs에 직접 구축되어 직관적인 API와 간단한 구현으로 프로비저닝 및 활용이 용이합니다. 또한 worker process 간에 데이터를 관리하고 공유하는 프로세스를 간소화하는 데 도움이 됩니다.
- 가볍고 효율적 – 이벤트 중심의 non-blocking I/O 모델을 활용하여 NGINX와 원활하게 통합됩니다. 이 접근 방식은 메모리 사용량을 줄이고 동시성을 개선하여 NGINX가 많은 동시 연결을 효율적으로 처리할 수 있도록 합니다.
- 확장성 – 여러 worker process에 걸쳐 수평적으로 확장할 수 있는 NGINX의 기능을 활용하여 복잡한 프로세스 간 통신 메커니즘 없이도 해당 프로세스 간에 데이터를 공유하고 동기화할 수 있습니다. TTL(Time-to-Live) 설정을 사용하면 shared dictionary 항목의 레코드를 비활성화로 인해 영역에서 제거하여 관리할 수 있습니다. evict 매개변수는 가장 오래된 key-value 쌍을 제거하여 새 항목을 위한 공간을 확보합니다.
2. Shared Dictionary를 사용한 SSL/TLS 인증서 교체
Shared dictionary의 가장 영향력 있는 사용 사례 중 하나는 SSL/TLS 인증서 교체입니다. js_shared_dict_zone을 사용하면 SSL/TLS 인증서 또는 키가 업데이트되는 경우 NGINX를 재시작할 필요가 없습니다. 또한 NGINX에서 인증서를 관리할 수 있는 REST와 유사한 API를 제공합니다.
다음은 js_set 및 ssl_certificate 지시문을 사용하여 HTTPS 서버를 설정하는 NGINX 구성 파일의 예입니다. JavaScript 핸들러는 js_set을 사용하여 파일에서 SSL/TLS 인증서 또는 키를 읽습니다.
이 구성 스니펫은 shared dictionary를 사용하여 인증서 및 키를 공유 메모리에 캐시로 저장합니다. 키가 없는 경우 디스크에서 인증서 또는 키를 읽고 캐시에 넣습니다.
캐시를 지우는 위치를 노출할 수도 있습니다. 디스크의 파일이 없데이트되면(예: 인증서 및 키가 갱신됨) shared dictionary는 디스크에서 읽기를 적용합니다. 이 조정을 통해 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 리포지토리에서 확인할 수 있습니다.
3. 지금 SSL/TLS 인증서 교체를 시작해보세요.
Shared dictionary 기능은 애플리케이션의 프로그래밍 기능을 위한 강력한 도구로, 간소화 및 확장성 측면에서 상당한 이점을 제공합니다. js_shared_dict_zone의 기능을 활용하면 새로운 성장 기회를 포착하고 증가하는 트래픽 수요를 효율적으로 처리할 수 있습니다.
js_shared_dict_zone으로 NGINX 배포를 강화할 준비가 되셨나요? js_shared_dict_zone으로 NGINX 배포를 업그레이드하여 새로운 사용 사례를 활용하고 이 기능에 대해 자세히 알아보려면 가이드에서 확인하세요. 또한 최근에 소개된 njs-acme 프로젝트에서 shared dictionary 기능의 전체 예제를 확인할 수 있으며, 이를 통해 njs 모듈 런타임이 ACME 공급자와 함께 작동할 수 있습니다.
NGINX 오픈 소스 또는 NGINX Plus를 시작하는 데 관심이 있고, NGINX Plus를 직접 사용해 보시려면 30일 무료 평가판을 신청하거나 NGINX STORE에 연락하여 문의하십시오.
NGINX에 대한 최신 정보들을 빠르게 전달받고 싶으시다면, 아래의 뉴스레터를 구독하세요.