웹사이트 검색

SSL 종료로 Nginx 로드 밸런싱을 설정하는 방법


소개

이 문서에서는 로드 밸런서에서 단 하나의 SSL 인증서를 사용하여 SSL 종료로 Nginx 로드 밸런싱을 설정하는 방법을 보여줍니다. 이제 OpenSSL 업데이트와 키 및 인증서를 로드 밸런서 자체에서 관리할 수 있으므로 SSL 관리 오버헤드가 줄어듭니다.

SSL 종료 정보

Nginx는 들어오는 트래픽을 여러 백엔드 서버에 분산시키는 로드 밸런서로 구성할 수 있습니다. SSL 종료는 로드 밸런서와 백엔드 서버 간의 트래픽이 HTTP에 있도록 SSL 암호화/복호화를 처리하는 로드 밸런서에서 발생하는 프로세스입니다. 이 문서의 뒷부분에서 설명하는 로드 밸런서의 IP에 대한 액세스를 제한하여 백엔드를 보호해야 합니다.

전제 조건

이 자습서에서 명령은 루트 사용자 또는 sudo 권한이 있는 사용자로 실행해야 합니다. 사용자 자습서에서 설정 방법을 확인할 수 있습니다.

다음 가이드를 참조할 수 있습니다.

  • Ubuntu 14.04에서 LAMP 서버 설정
  • Nginx에서 SSL 설정
  • Nginx에서 부하 분산 설정

LAMP 서버는 필요하지 않지만 이 자습서에서는 이를 예로 사용합니다.

설정

이 자습서에서는 다음 3개의 드롭릿을 사용합니다.

물방울 1(프런트엔드)

  • 이미지: 우분투 14.04
  • 호스트 이름: loadbalancer
  • 비공개 IP: 10.130.227.33

물방울 2(백엔드)

  • 이미지: 우분투 14.04
  • 호스트 이름: web1
  • 비공개 IP: 10.130.227.11

물방울 3(백엔드)

  • 이미지: 우분투 14.04
  • 호스트 이름: web2
  • 비공개 IP: 10.130.227.22

도메인 이름 - example.com

이러한 모든 Droplet에는 사설 네트워킹이 활성화되어 있어야 합니다.

세 서버 모두에서 소프트웨어 업데이트 및 업그레이드:

apt-get update && apt-get upgrade -y

업그레이드를 적용하려면 각 서버를 재부팅하십시오. OpenSSL은 보안을 위해 최신 버전이어야 하므로 이는 중요합니다.

우리는 업스트림 모듈이 백엔드를 로드 밸런싱하는 도메인 이름에 대한 새로운 Nginx 가상 호스트를 설정할 것입니다.

Nginx 로드 밸런싱을 설정하기 전에 VPS에 Nginx가 설치되어 있어야 합니다. apt-get을 사용하여 빠르게 설치할 수 있습니다.

apt-get install nginx

두 백엔드 서버에서 리포지토리를 업데이트하고 Apache를 설치합니다.

apt-get install apache2

두 백엔드 서버 모두에 PHP를 설치합니다.

apt-get install php5 libapache2-mod-php5 php5-mcrypt

자세한 내용은 이 문서를 참조하세요.

키 생성 및 SSL 인증서 생성

이 섹션에서는 SSL 인증서를 만드는 데 필요한 단계를 실행합니다. 이 기사에서는 Nginx의 SSL 인증서에 대해 자세히 설명합니다.

SSL 인증서 디렉터리를 만들고 여기로 전환합니다.

mkdir -p /etc/nginx/ssl/example.com
cd /etc/nginx/ssl/example.com

개인 키를 만듭니다.

openssl genrsa -des3 -out server.key 2048

암호를 제거하십시오.

openssl rsa -in server.key -out server.key

CSR(인증서 서명 요청) 만들기:

openssl req -new -key server.key -out server.csr

이 CSR을 사용하여 인증 기관에서 유효한 인증서를 얻거나 다음 명령으로 자체 서명된 인증서를 생성하십시오.

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

이 작업이 완료되면 이 디렉토리에는 다음 파일이 포함됩니다.

  • server.key - 개인 키
  • ca-certs.pem - CA의 루트 및 중간 인증서 모음입니다. CA에서 유효한 인증서를 받은 경우에만 표시됩니다.
  • server.crt - 도메인 이름의 SSL 인증서

가상 호스트 파일 및 업스트림 모듈

Nginx 디렉토리 내에 가상 호스트 파일 생성

nano /etc/nginx/sites-available/example.com

백엔드 서버의 개인 IP 주소를 포함하는 업스트림 모듈을 추가합니다.

upstream mywebapp1 {
    server 10.130.227.11;
    server 10.130.227.22;
}

이 줄 다음에 서버 블록을 시작합니다. 이 블록에는 도메인 이름, 업스트림 서버에 대한 참조 및 백엔드로 전달되어야 하는 헤더가 포함됩니다.

server {
    listen 80;
    server_name example.com www.example.com;
	
    location / {
        proxy_pass http://mywebapp1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

proxy_set_header 지시문은 요청에 대한 필수 정보를 업스트림 서버에 전달하는 데 사용됩니다.

이 파일을 저장하고 sites-enabled 디렉토리에 대한 심볼릭 링크를 만듭니다.

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

구성 테스트를 수행하여 오류를 확인하십시오.

service nginx configtest

오류가 표시되지 않으면 nginx 서비스를 다시 로드합니다.

service nginx reload

이제 로드 밸런싱이 HTTP에 대해 구성되었습니다.

SSL 활성화

server {} 블록 내부의 가상 호스트 파일(/etc/nginx/sites-available/example.com)에 다음 지시문을 추가합니다. 이러한 줄은 다음 예에서 컨텍스트에 표시됩니다.

listen 443 ssl;
ssl on;
ssl_certificate         /etc/nginx/ssl/example.com/server.crt;
ssl_certificate_key     /etc/nginx/ssl/example.com/server.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;

자체 서명된 인증서를 사용하는 경우 ssl_trusted_certificate 지시문을 무시하십시오. 이제 server 블록은 다음과 같아야 합니다.

server {
    listen 80;
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl on;
    ssl_certificate         /etc/nginx/ssl/example.com/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/example.com/server.key;
    ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;

    location / {
        proxy_pass http://mywebapp1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

구성 오류를 확인하고 Nginx 서비스를 다시 로드합니다.

service nginx configtest && service nginx reload

백엔드 서버 보안

현재 백엔드 서버에서 호스팅되는 웹사이트는 공용 IP 주소를 아는 사람이면 누구나 직접 액세스할 수 있습니다. 비공개 인터페이스에서만 수신 대기하도록 백엔드의 웹 서버를 구성하여 이를 방지할 수 있습니다. Apache에서 이를 수행하는 단계는 다음과 같습니다.

ports.conf 파일을 편집합니다.

nano /etc/apache2/ports.conf

다음 줄을 찾으십시오.

Listen 80

백엔드 서버의 자체 사설 IP 주소로 바꿉니다.

Listen 10.130.227.22:80

모든 백엔드 서버에서 이 작업을 수행하고 Apache를 다시 시작합니다.

service apache2 restart

다음 단계는 로드 밸런서의 사설 IP에 대한 HTTP 액세스를 제한하는 것입니다. 다음 방화벽 규칙은 이를 달성합니다.

iptables -I INPUT -m state --state NEW -p tcp --dport 80 ! -s 10.130.227.33 -j DROP

예제를 로드 밸런서의 사설 IP 주소로 바꾸고 모든 백엔드 서버에서 이 규칙을 실행합니다.

설정 테스트

모든 백엔드 서버(이 예에서는 web1 및 web2)에 PHP 파일을 만듭니다. 이는 테스트용이며 설정이 완료되면 제거할 수 있습니다.

nano /var/www/html/test.php

액세스한 도메인 이름, 서버의 IP 주소, 사용자의 IP 주소 및 액세스한 포트를 인쇄해야 합니다.

<?php
    header( 'Content-Type: text/plain' );
    echo 'Host: ' . $_SERVER['HTTP_HOST'] . "\n";
    echo 'Remote Address: ' . $_SERVER['REMOTE_ADDR'] . "\n";
    echo 'X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n";
    echo 'X-Forwarded-Proto: ' . $_SERVER['HTTP_X_FORWARDED_PROTO'] . "\n";
    echo 'Server Address: ' . $_SERVER['SERVER_ADDR'] . "\n";
    echo 'Server Port: ' . $_SERVER['SERVER_PORT'] . "\n\n";
?>

브라우저 또는 curl을 사용하여 이 파일에 여러 번 액세스하십시오. 컬이 SSL 오류를 무시하도록 하려면 자체 서명된 인증서 설정에서 curl -k를 사용하십시오.

curl https://example.com/test.php https://example.com/test.php https://example.com/test.php

출력은 다음과 유사합니다.

   Host: example.com
   Remote Address: 10.130.245.116
   X-Forwarded-For: 117.193.105.174
   X-Forwarded-Proto: https
   Server Address: 10.130.227.11
   Server Port: 80

   Host: example.com
   Remote Address: 10.130.245.116
   X-Forwarded-For: 117.193.105.174
   X-Forwarded-Proto: https
   Server Address: 10.130.227.22
   Server Port: 80

   Host: example.com
   Remote Address: 10.130.245.116
   X-Forwarded-For: 117.193.105.174
   X-Forwarded-Proto: https
   Server Address: 10.130.227.11
   Server Port: 80

각 요청에 대해 서버 주소가 변경되어 다른 서버가 각 요청에 응답하고 있음을 나타냅니다.

SSL 구성 강화

이 섹션에서는 모범 사례에 따라 SSL을 구성하여 이전 암호 및 프로토콜의 취약성을 제거하는 방법을 설명합니다. 이 섹션에는 개별 행이 표시되며 전체 구성 파일은 이 튜토리얼의 마지막 섹션에 표시됩니다.

SSL 세션 캐시를 활성화하면 HTTPS 웹사이트의 성능이 향상됩니다. 다음 지시문은 ssl_trusted_certificate 뒤에 배치해야 합니다. 10분의 캐시 수명으로 20MB 크기의 공유 캐싱을 활성화합니다.

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;

SSL 연결에 사용할 프로토콜 및 암호를 지정합니다. 여기서는 SSLv2를 생략하고 MD5 및 DSS와 같은 안전하지 않은 암호를 비활성화했습니다.

ssl_prefer_server_ciphers       on;
ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers                     ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

엄격한 전송 보안은 모든 지원 웹 브라우저가 HTTPS만 사용하도록 지시합니다. add_header 지시문으로 활성화하십시오.

add_header Strict-Transport-Security "max-age=31536000";

구성 오류를 확인하고 Nginx 서비스를 다시 로드합니다.

service nginx configtest && service nginx reload

구성 완료

SSL 종료를 구성하고 강화한 후 전체 구성 파일은 다음과 같습니다.

/etc/nginx/sites-available/example.com

upstream mywebapp1 {
    server 10.130.227.11;
    server 10.130.227.22;
}

server {
    listen 80;
    listen 443 ssl;
    server_name example.com www.emxaple.com;

    ssl on;
    ssl_certificate         /etc/nginx/ssl/example.com/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/example.com/server.key;
    ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;
	
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 10m;
	
    ssl_prefer_server_ciphers       on;
    ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                     ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
	
    add_header Strict-Transport-Security "max-age=31536000";

    location / {
        proxy_pass http://mywebapp1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

SSL 서버 테스트를 수행하면 이 설정이 A+ 등급을 받아야 합니다. 컬 테스트를 다시 실행하여 모든 것이 제대로 작동하는지 확인하십시오.

curl https://example.com/test.php https://example.com/test.php https://example.com/test.php

추가 자료

로드 밸런싱 알고리즘에 대해 자세히 알아보려면 이 문서를 읽으십시오.