블로그 | NGINX

NGINX를 사용한 SSL 개인 키의 안전한 배포

NGINX-F5-수평-검정-유형-RGB의 일부
오웬 개렛 썸네일
오웬 개렛
2019년 4월 2일 게시

이 블로그 게시물에서는 NGINX가 SSL 암호화된 웹사이트를 호스팅할 때 사용하는 SSL 개인 키를 안전하게 배포하는 몇 가지 방법을 설명합니다. 설명은 다음과 같습니다.

많은 배포의 경우 표준적인 접근 방식이 충분합니다. 이 글에서 논의하는 두 가지 보다 정교한 접근 방식은 공격자가 SSL 개인 키를 얻을 수 있는 다른 방법을 차단합니다. 또한 후속 게시물에서 몇 가지 기술을 더 살펴보겠습니다.

  • HashiCorp Vault와 같은 타사 비밀 저장소를 사용하여 비밀번호를 안전하게 배포
  • Vault에서 NGINX Plus의 키-값 저장소 로 인증서 프로비저닝을 자동화하여 개인 키 자료가 디스크에 저장되지 않도록 합니다.

이 게시물에서 제시하는 접근 방식은 자신의 키를 관리하고 자체적인 보안 키 배포 전략을 구축해야 하는 사용자에게 적용됩니다. Kubernetes 와 같이 비밀 저장소와 이미 통합된 환경에서 NGINX를 실행하는 사용자에게는 필요하지 않습니다.

이 게시물은 NGINX 오픈 소스와 NGINX Plus에 모두 적용됩니다. 읽기 편하도록 이 문서 전체에서 NGINX를 참조하겠습니다.

편집자 - 이 게시물은 NGINX에서 SSL 개인 키 보안에 대한 시리즈의 첫 번째 게시물입니다. 이 시리즈의 다른 게시물도 참조하세요.

 

SSL 개인 키를 보호하는 이유는 무엇입니까?

SSL/TLS는 네트워크 거래의 인증, 암호화, 무결성을 확인하는 데 사용됩니다. 웹사이트는 인증 기관(CA)에서 서명한 공개 인증서를 사용하여 자체를 인증하고, 해당 개인 키 (비밀로 유지되어야 함)를 사용하여 계산을 수행하여 인증서를 소유하고 있음을 증명합니다.

개인 키가 손상되면(다른 기관에 공개되면) 두 가지 주요 위험이 발생합니다.

  • 위험 1: 사칭 . 개인 키를 보유한 공격자는 네트워크 트래픽을 가로채서 중간자 공격(MITM)을 감행할 수 있습니다. 이 공격은 클라이언트나 웹사이트가 알지 못하는 사이에 모든 트래픽을 캡처하고 해독하며, 심지어 수정할 수도 있습니다.
  • 위험 2: 복호화 . 개인 키를 보유하고 네트워크 트래픽을 기록한 공격자는 오프라인에서 네트워크 트래픽을 해독할 수 있습니다. 이 공격은 완벽한 전방 비밀성 (PFS) 암호를 사용하는 연결에는 사용할 수 없습니다.

개인 키가 손상된 경우, 유일한 대책은 인증기관에 연락하여 인증서를 해지해 달라고 요청하는 것입니다. 그런 다음 클라이언트가 해지 상태를 확인하고 이를 준수하도록 맡겨야 합니다.

또한 만료 기간이 짧은 인증서를 사용하는 것이 좋습니다(예: Let's Encrypt 인증서는 90일 후에 만료됨). 인증서가 만료되기 직전에 새로운 개인 키를 생성하고 CA에서 새로운 인증서를 받아야 합니다. 이렇게 하면 개인 키가 손상될 경우 노출 위험이 줄어듭니다.

NGINX 보안 경계

NGINX에서 SSL 개인 키에 액세스할 수 있는 사람과 프로세스는 무엇입니까?

우선, NGINX를 실행하는 서버에 대한 루트 액세스 권한을 얻은 모든 사용자는 NGINX 자체가 사용하는 모든 리소스를 읽고 사용할 수 있습니다. 예를 들어, 실행 중인 프로세스의 메모리에서 SSL 개인 키를 추출하는 방법이 알려져 있습니다.

따라서 개인 키를 어떻게 저장하고 배포하더라도 호스트 서버에서 루트 권한을 가진 공격자로부터 개인 키를 보호하는 것은 불가능합니다.

다음으로, NGINX 구성을 수정하고 커밋할 수 있는 모든 사용자는 그 권한을 여러 가지 방법으로 사용할 수 있습니다. 예를 들어, 내부 서비스에 대한 프록시 액세스를 열거나 인증 조치를 우회하는 등입니다. 관리자는 NGINX 구성을 수정하여 서버에 대한 루트 액세스(또는 이와 동등한 권한)를 얻을 수 있지만 SELinuxAppArmor 와 같은 도구는 이러한 가능성을 완화하는 데 도움이 됩니다.

따라서 NGINX 구성을 수정하고 커밋할 수 있는 공격자로부터 개인 키를 보호하는 것은 일반적으로 불가능합니다.

다행히도, 유능한 조직에는 공격자가 루트 권한을 얻거나 NGINX 구성을 수정하는 것을 어렵게 만드는 견고한 보안 프로세스가 있습니다.

그러나 권한이 낮은 공격자가 개인 키에 액세스할 수 있는 방법은 두 가지가 더 있습니다.

  • 사용자는 NGINX 구성을 확인해야 할 정당한 이유가 있거나 구성 데이터베이스 또는 백업에 대한 액세스 권한을 얻을 수도 있습니다. NGINX 개인 키는 일반적으로 구성에 저장됩니다.
  • 사용자는 하이퍼바이저나 시스템 백업을 통해 NGINX 서버의 파일 시스템에 액세스할 수도 있습니다. 개인 키 자료를 포함하여 파일 시스템에 저장된 모든 데이터는 잠재적으로 액세스할 수 있습니다.

이 문서에 설명된 프로세스는 이 두 가지 공격 방법을 차단합니다.

표준 NGINX 구성

먼저 SSL/TLS를 사용한 일반적인 NGINX 구성이 어떤 것인지 살펴보겠습니다.

서버 { 수신 443 ssl; 서버 이름 a.dev0; ssl_certificate ssl/a.dev0.crt; ssl_certificate_key ssl/a.dev0.key; 위치 / { return 200 "Hello from service A\n"; } }

SSL 공개 인증서( a.dev0.crt )와 개인 키( a.dev0.key )는 /etc/nginx/ssl/ 에 있는 파일 시스템에 저장됩니다. 개인 키는 일반적으로 루트 로 실행되는 NGINX 마스터 프로세스에서만 읽을 수 있으므로 가능한 가장 엄격한 액세스 권한을 설정할 수 있습니다.

root@web1:/etc/nginx/ssl# ls -l a.dev0.key -r-------- 1 root root 1766 8월 15일 16:32 a.dev0.key

개인 키는 항상 사용할 수 있어야 하며, NGINX 소프트웨어가 시작되거나, 구성이 다시 로드되거나, 구문 검사가 수행될 때마다 NGINX 마스터 프로세스가 개인 키를 읽습니다( nginx -t ).

SSL/TLS 구성에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.

표준 구성의 보안 의미

위에서 언급했듯이 SSL 개인 키는 NGINX 소프트웨어를 실행하는 실행 중인 컨테이너, 가상 머신 또는 서버에 대한 루트 액세스 권한을 얻은 공격자가 읽을 수 있습니다.

SSL 개인 키 암호화

NGINX는 AES256과 같은 보안 알고리즘을 사용하여 암호화된 개인 키를 지원합니다.

root@web1:/etc/nginx/ssl# mv a.dev0.key a.dev0.key.plain root@web1:/etc/nginx/ssl# openssl rsa -aes256 -in a.dev0.key.plain -out a.dev0.key RSA 키 쓰기 PEM 암호문구를 입력하세요: 보안 암호 확인 - PEM 암호문구를 다시 입력하세요: 보안 암호

그런 다음 NGINX를 시작하거나 NGINX 구성을 다시 로드하거나 테스트하면 NGINX는 대화형으로 복호화 비밀번호를 요청합니다.

root@web1:/etc/nginx# nginx -t PEM 암호 문구를 입력하세요: 보안 암호 nginx: 구성 파일 /etc/nginx/nginx.conf 구문은 정상입니다 nginx: 구성 파일 /etc/nginx/nginx.conf 테스트가 성공했습니다

SSL 암호 파일 사용

비밀번호를 대화형으로 입력하는 것은 불편하고 자동화하기 어렵지만, ssl_password_file 지시어로 명명된 별도 파일에 저장된 비밀번호 목록을 사용하도록 NGINX를 구성할 수 있습니다. NGINX가 개인 키를 읽어야 할 때는 파일에 있는 각 비밀번호를 차례로 사용하여 키의 암호를 해독하려고 시도합니다. 유효한 비밀번호가 없으면 NGINX는 시작되지 않습니다.

ssl_password_파일 /var/lib/nginx/ssl_passwords.txt;

ssl_password_file 은 구성과 별도로 배포되어야 하며, 루트 사용자만 읽을 수 있어야 합니다. 이는 신뢰할 수 있는 서버에 배치된 인증 토큰으로 간주할 수 있습니다. NGINX는 인증 토큰이 있는 서버에서 실행되는 경우에만 개인 키를 해독할 수 있습니다.

별도 파일에 암호화된 키의 보안 의미

이 방법은 공격자에게 NGINX 구성 자체만은 쓸모없게 만들어 공격 표면을 줄여줍니다. 공격자는 또한 ssl_password_file 의 내용을 얻어야 합니다.

공격자가 ssl_password_file 이 저장된 파일 시스템에 대한 루트 액세스 권한을 얻으면(예: 백업이나 호스트 시스템을 통해) 해당 파일을 읽고 비밀번호를 사용하여 SSL 개인 키를 해독할 수 있습니다.

ssl_password_file 을 RAM 디스크나 tmpfs 에 저장하면 이러한 위험을 줄일 수 있습니다. 이러한 저장소는 일반적으로 외부 공격자가 쉽게 접근할 수 없습니다(예를 들어, 서버를 다시 시작하면 삭제됨). 따라서 시스템 백업에서 제외할 수 있습니다. 시스템 부팅시 비밀번호 파일이 초기화되는지 확인해야 합니다.

SSL 비밀번호 목록을 보다 안전하게 배포

아래 프로세스는 중앙 배포 지점에서 SSL 비밀번호 목록을 배포하는 보다 안전한 방법을 설명합니다.

NGINX가 SSL 키를 복호화해야 할 때마다 중앙 배포 지점에 쿼리를 보내고 로컬 디스크에 비밀번호를 저장하지 않고 사용합니다. NGINX 인스턴스는 중앙 비밀번호 서버에 자신을 인증하기 위해 토큰을 사용하는데, 언제든지 이 토큰을 취소하여 비밀번호에 대한 액세스를 차단할 수 있습니다.

중앙 비밀번호 배포 지점 생성

먼저, 비밀번호 배포 지점(PDP)을 만듭니다. 이 간단한 구현을 위해 HTTPS 서비스를 사용하여 사용자 이름과 비밀번호로 인증된 비밀번호 목록을 제공합니다.

$ curl -u dev0:mypassword https://pdpserver.local/ssl_passwords.txt 비밀번호1 비밀번호2 ...

그런 다음 필요에 따라 PDP에서 인증 토큰을 추가하거나 제거하여 액세스를 활성화하거나 취소할 수 있습니다. NGINX와 같은 웹 서버를 사용하여 비밀번호 배포 서버를 구현하고, 적절한 종류의 인증 토큰을 사용할 수 있습니다.

다음으로, PDP에서 비밀번호를 검색하기 위해 NGINX를 설정해야 합니다. 다음 내용으로 connector.sh 라는 쉘 스크립트를 만드는 것으로 시작합니다.

#!/bin/sh
# 사용법: connector.sh 

CONNECTOR=$1
CREDS=$2
PDP_URL=$3

[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR

mkfifo $CONNECTOR; chmod 600 $CONNECTOR

참인 동안; do
curl -s -u $CREDS -k $PDP_URL -o $CONNECTOR
완료

스크립트는 백그라운드 프로세스로 실행되어야 하며 다음과 같이 호출됩니다.

root@web1:~# ./connector.sh /var/run/nginx/ssl_passwords \dev0:내 비밀번호 https://pdpserver.local/ssl_passwords.txt &

커넥터는 지정된 로컬 경로( /var/run/nginx/ssl_passwords )에 연결되고 ssl_password_file 지시어를 사용하여 NGINX가 해당 경로에 액세스하도록 구성합니다.

ssl_password_file /var/run/nginx/ssl_passwords;

커넥터 경로에서 읽어 커넥터를 테스트합니다.

root@web1:~# cat /var/run/nginx/ssl_passwords 비밀번호1 비밀번호2 ...

NGINX가 비밀번호를 읽고 SSL 키를 해독할 수 있는지 확인하세요.

root@web1:~# nginx -t nginx: 설정 파일 /etc/nginx/nginx.conf 구문은 정상입니다. nginx: 설정 파일 /etc/nginx/nginx.conf 테스트가 성공했습니다.

중앙 PDP 방식을 사용하면 NGINX가 일반적으로 디스크에서 읽는 모든 리소스(개별 개인 키나 기타 민감한 데이터)를 안전하게 배포할 수 있습니다.

PDP의 보안 의미

이 솔루션은 디스크에 SSL 비밀번호를 저장하는 것에 비해 여러 가지 이점이 있습니다.

  • SSL 비밀번호는 서버의 파일 시스템에 저장되지 않으므로 파일 시스템에 접근할 수 있는 공격자는 비밀번호에 직접 접근할 수 없습니다.
  • 비밀번호는 중앙 접속 지점에서 배포되므로 모니터링과 감사를 보다 쉽게 수행할 수 있습니다.
  • 개별 서버의 접근은 중앙에서 제어될 수 있습니다 . 예를 들어, 서버가 폐기되면 액세스 토큰을 취소합니다.

파일 시스템에 접근할 수 있는 사용자는 PDP에 접근하는 데 사용된 자격 증명을 추출할 가능성이 있습니다. 더 이상 필요하지 않은 자격 증명은 취소하는 것이 중요합니다.

요약

SSL 개인 키가 공개되지 않도록 보호하는 방법에는 여러 가지가 있으며 보안 수준과 복잡성이 점점 높아지고 있습니다.

  • 대부분의 조직에서는 NGINX를 실행하는 환경에 대한 액세스를 제한하여 권한 없는 사용자가 루트 액세스 권한을 얻고 NGINX 구성을 볼 수 없도록 하는 것으로 충분합니다.
  • 일부 환경에서는 NGINX 구성에 대한 액세스를 완전히 제한하는 것이 불가능할 수 있으므로 SSL 비밀번호 파일을 사용할 수 있습니다.
  • 제한된 경우지만, 조직에서는 키와 비밀번호가 디스크에 저장되지 않도록 하고 싶을 수도 있습니다. 비밀번호 배포 지점 프로세스는 이 솔루션의 개념 증명을 보여줍니다.

이 시리즈의 다른 게시물에서는 SSL 키를 보호하기 위해 취할 수 있는 추가 단계를 설명합니다.

  • HashiCorp Vault를 사용하여 NGINX에서 SSL 개인 키 보호 – HashiCorp Vault를 PDP로 설정하여 세분화된 액세스 제어를 통해 확장 가능하고 안전한 비밀 배포를 제공하는 방법을 보여줍니다. 또한 개인 키를 원격으로 저장하고, 키 작업을 수행하기 위해 주문형으로 사용할 수 있는 API를 제공하기 위해 하드웨어 보안 모듈(HSM)을 사용하는 방법에 대해서도 설명합니다.
  • NGINX Plus 키-값 저장소를 사용하여 HashiCorp Vault의 임시 SSL 키 보호 – HashiCorp Vault에서 임시 SSL 키를 생성하고 이를 NGINX Plus 메모리 내 키-값 저장소에 저장하여 SSL 키의 디스크 저장을 우회하는 방법을 보여줍니다.

NGINX Plus를 직접 사용해 보세요. 오늘 무료 30일 체험판을 시작하거나 저희에게 연락하여 사용 사례에 대해 논의해 보세요 .


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