웹사이트 검색

Ubuntu 14.04에서 Nginx를 보호하는 방법


Nginx는 기본 설정으로도 매우 안전하고 안정적인 웹 서버입니다. 그러나 Nginx를 더 안전하게 보호할 수 있는 여러 가지 방법이 있습니다.

이 기사에서는 널리 사용되는 웹 서버 강화 접근 방식과 보안 표준을 따르면서 오픈 소스 소프트웨어를 독점적으로 사용할 것입니다. 즉, 정보 공개 방지, 암호화 시행, 감사 수행 및 액세스 제한에 대해 이야기하겠습니다.

전제 조건

이 자습서를 따르기 전에 다음 전제 조건을 완료했는지 확인하십시오.

  • Ubuntu 14.04 Droplet(자세한 내용은 Ubuntu 14.04를 사용한 초기 서버 설정 참조)\n
  • Ubuntu 14.04 LTS에 Nginx를 설치하는 방법에 설명된 대로 Nginx 웹 서버가 설치 및 구성되었습니다.\n
  • 등록된 도메인 또는 하위 도메인이 Droplet의 IP를 가리켰습니다. SSL 설정을 테스트하려면 이것이 필요합니다. 자세한 내용은 공통 도메인 등록 기관에서 DigitalOcean 이름 서버를 가리키는 방법에 대한 문서를 참조하십시오.\n
  • 루트가 아닌 sudo 사용자(자세한 내용은 Ubuntu 14.04로 초기 서버 설정 확인)\n

다른 언급이 없는 한 이 자습서에서 루트 권한이 필요한 모든 명령은 sudo 권한이 있는 루트가 아닌 사용자로 실행해야 합니다.

1단계 - 모든 소프트웨어 업데이트

소프트웨어를 최신 버전으로 업데이트하는 것은 Nginx뿐만 아니라 전체 시스템을 보호하는 훌륭한 첫 단계입니다.

경고: 시스템의 모든 패키지를 업데이트하기 전에 이것이 Nginx 이외의 시스템에서 실행 중인 항목에 문제를 일으킬지 여부를 확인하십시오. 한 번에 너무 많은 패키지에 영향을 미치는 작업을 수행하기 전에 전체 시스템을 백업하는 것이 좋습니다. 모든 패키지를 업데이트한 후 문제가 발생하면 백업으로 되돌릴 수 있습니다. 리포지토리 패키지 목록을 업데이트한 다음 Ubuntu 서버에서 apt-get으로 관리되는 현재 설치된 모든 패키지를 업데이트하려면 다음 명령을 실행합니다.

  1. sudo apt-get update && sudo apt-get upgrade

또는 Ubuntu 리포지토리에서 Nginx를 최신 버전으로 업그레이드할 수 있습니다. 이렇게 하면 Nginx 패키지와 필요한 모든 종속 항목이 업그레이드됩니다.

  1. sudo apt-get upgrade nginx

2단계 - 정보 유출 방지

Nginx 웹 서버 강화를 시작하려면 공개하는 정보를 제한하는 것부터 시작하겠습니다. HTTP 서버 헤더에서 애플리케이션 오류 보고에 이르기까지 모든 수준에서 귀중한 정보가 유출됩니다.

HTTP 헤더부터 시작하겠습니다. 기본적으로 Nginx는 HTTP 헤더에 이름과 버전을 표시합니다. 다음과 같이 curl로 이 정보를 확인할 수 있습니다.

  1. curl -I http://localhost

출력은 다음과 같아야 합니다.

Output of curl -I http://localhost
HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) ...

보시다시피 위 출력에서 Nginx 버전과 운영 체제 이름을 볼 수 있습니다. 이것은 반드시 심각한 문제는 아니지만 공격자가 Nginx 서버를 손상시키기 위해 해결하려고 시도하는 퍼즐의 일부입니다. 그렇기 때문에 다음과 같이 nano로 Nginx의 기본 구성 파일 /etc/nginx/nginx.conf를 열어 이 정보를 숨길 것입니다.

  1. sudo nano /etc/nginx/nginx.conf

그런 다음 http 구성 부분 내부에 다음과 같이 server_tokens off; 줄을 추가합니다.

http {

        ##
        # Basic Settings
        ##
        server_tokens off;
...

그런 다음 파일을 저장하고 종료하고 Nginx를 다시 로드하여 변경 사항을 적용합니다.

  1. sudo service nginx reload

이제 동일한 curl 명령을 다시 시도하면 다음과 같습니다.

  1. curl -I http://localhost

더 적은 정보가 표시됩니다.

Output of curl -I http://localhost
HTTP/1.1 200 OK Server: nginx ...

위의 출력은 이것이 Nginx 서버라는 사실만 공개합니다. 이것도 제거할 수 있는지 궁금할 수 있습니다. 불행히도 이것은 구성 옵션이 없기 때문에 쉽게 달성되지 않습니다. 대신 노력할 가치가 없는 소스에서 Nginx를 다시 컴파일해야 합니다.

Server 헤더 외에도 중요한 정보가 포함된 또 다른 헤더인 X-Powered-By가 있습니다. 이 헤더는 일반적으로 PHP, Tomcat 또는 Nginx 뒤에 있는 서버 측 엔진의 버전을 보여줍니다. PHP로 Nginx를 실행하면 curl의 출력은 다음과 같습니다.

Output of curl -I http://localhost on nginx with php
HTTP/1.1 200 OK Server: nginx ... X-Powered-By: PHP/5.5.9-1ubuntu4.14 ...

위의 X-Powered-By 헤더는 서버가 PHP 버전 5.5.9를 실행하는 Ubuntu 14임을 보여줍니다. X-Powered-By 헤더에서 이 정보를 숨기는 것이 매우 중요합니다. Nginx에서는 이 작업을 수행할 수 없지만 대신 백엔드 엔진에서 해당 옵션을 찾아야 합니다. 예를 들어 PHP의 경우 기본 php.ini 구성 파일에서 expose_php = Off 옵션을 설정해야 합니다. 기본적으로 이 옵션은 On으로 설정됩니다.

다음으로 할 일은 공격자가 사용할 수 있는 정보인 4xx(클라이언트 측) 오류 페이지를 변경하는 것입니다. 일반적으로 Unauthorized 401Forbidden 403 오류 페이지입니다. 문제를 디버깅하지 않는 한 일반적으로 일반 방문자에게 이러한 오류를 표시할 필요가 없습니다. 이러한 오류에 대해 알아야 하는 경우 Nginx 오류 로그(/var/log/nginx/error.log)에서 찾을 수 있습니다.

이 두 오류 페이지를 변경하려면 서버 블록에 대한 구성 파일(예: 기본 파일)을 엽니다.

  1. sudo nano /etc/nginx/sites-enabled/default

기본 서버 server 구성 부분 내에서 다음을 지정합니다.

server {
...
        error_page 401 403 404 /404.html;
...

변경 사항을 파일에 저장한 후 다음 명령으로 적용되도록 Nginx를 다시 로드해야 합니다.

  1. sudo service nginx reload

위의 힌트는 정보 공개를 방지하는 아이디어를 제공합니다. 즉, 필수적이지 않은 웹 콘텐츠를 가능한 한 적게 표시합니다. Nginx뿐만 아니라 백엔드 엔진(PHP, Tomcat 등)과 웹 애플리케이션에서도 서비스 및 디버깅 정보를 숨겨야 합니다.

2단계 - SSL 구성

Nginx에서 SSL을 사용하여 보안 HTTPS 프로토콜을 실행하는 것은 사용자 자격 증명, 개인 데이터 등과 같은 민감한 정보를 처리하는 모든 사이트에서 필수입니다. SSL은 사이트 사용자가 어디에 있고 어떤 인터넷 연결이 있는지에 관계없이 유일한 수단입니다. 그들이 사용하고 수신하고 보내는 정보는 보호됩니다.

Ubuntu 14.04용 Nginx에서 SSL 인증서를 만드는 방법 문서에서는 기본 HTTPS 구성으로 무료 SSL을 쉽게 설정하는 방법을 설명합니다. 이 문서는 좋은 시작이지만 데이터를 효율적으로 보호하지는 않습니다. 현재 기본 SSL 설정 및 알고리즘은 공격자가 트래픽을 해독하는 것을 방지할 만큼 강력하지 않습니다.

그래서 더 강력한 암호화 알고리즘과 설정으로 Nginx용 SSL 인증서를 구성할 것입니다. 이렇게 하면 데이터에 대한 더 높은 수준의 보호가 보장되며 HTTPS 서비스는 최고의 보안 표준 및 관행을 준수합니다.

다음 명령을 사용하여 SSL 인증서용 디렉토리를 생성하는 것부터 시작하겠습니다.

  1. sudo mkdir /etc/nginx/ssl/

SSL의 경우 강력한 서명 알고리즘인 SHA256이 있는 인증서가 필요합니다. 테스트 목적 또는 비프로덕션 환경의 경우 자체 서명된 인증서를 사용하고 SSL 경고를 무시할 수 있습니다. 다음 명령으로 하나를 만들어 보겠습니다.

  1. sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

이 명령은 사이트 및 비즈니스 세부 정보에 대한 몇 가지 간단한 질문을 합니다. 그런 다음 /etc/nginx/ssl/nginx.key 파일에 2048비트 RSA 암호화 키를 생성하고 /etc/nginx/ssl/nginx 파일에 SHA256 인증서를 생성합니다. crt.

다음으로 더 강력한 4096비트 길이의 DH 매개변수를 생성해야 합니다. Droplet에 따라 최대 30분까지 걸릴 수 있으므로 잠시 기다릴 준비를 하세요. 다음 명령을 실행합니다.

  1. sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

이제 서버 블록의 SSL 부분을 구성할 수 있습니다. 예를 들어 기본 서버 블록을 구성해 보겠습니다. nano로 편집하기 위해 구성 파일을 엽니다.

sudo nano /etc/nginx/sites-enabled/default

이 파일에서 다음과 같이 server_name 지시문 뒤에 SSL 부분을 추가하여 서버 구성 부분을 편집합니다.

server {
...
       server_name localhost;

        ### SSL Part
        listen 443 ssl;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

...

다음은 위의 지시문으로 지정한 지침입니다.

  • listen — 포트 443, 즉 HTTPS 포트에서 SSL 수신기를 활성화합니다.
  • ssl_protocols — 현재 보안 프로토콜로 간주되는 이 세 가지 프로토콜인 TLSv1 TLSv1.1 TLSv1.2만 활성화합니다.
  • ssl_ciphers — 다음 보안 SSL 암호만 활성화: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
  • ssl_prefer_server_ciphers — 클라이언트가 서버의 암호 기본 설정을 준수하는지 확인합니다.
  • ssl_dhparam — 이전에 생성한 사용자 지정 강력한 DH 매개변수를 사용합니다.
  • ssl_certificate — 자체 서명된 SSL 인증서를 사용합니다. 다른 인증서를 사용하는 경우 변경해야 합니다.
  • ssl_certificate_key — 이전에 생성한 SSL 개인 키를 사용합니다.

위의 설정을 적용하려면 다음 명령을 사용하여 nginx를 다시 로드해야 합니다.

  1. sudo service nginx reload

새 SSL 구성을 테스트하려면 SSL Labs에서 제공하는 것과 같은 외부 도구를 사용하는 것이 가장 좋습니다. 거기에서 SSL을 신뢰할 수 없다는 경고를 무시해야 합니다. 이는 자체 서명 인증서이기 때문에 당연합니다. 이 사이트는 등록된 도메인 이름이 있는 사이트만 테스트합니다. Droplet의 IP 주소만으로는 SSL 연결을 테스트할 수 없습니다.

전체 결과는 "Testing\과 같은 "T\여야 하지만 본질적으로 A(가장 높은 값)이고 \신뢰 문제가 무시되는 경우: A\라고 표시되어야 합니다.

나중에 SSL 경고를 제거하고 SSL 테스트를 깨끗한 \A\로 만들고 싶을 것입니다. 한 가지 옵션은 Ubuntu 14.04에서 Let's Encrypt로 Nginx를 보호하는 방법 문서에 설명된 대로 Let's Encrypt를 사용하는 것입니다. 무료입니다. , 최대 4096까지 RSA 키 크기를 지정할 수 있으며 자체 서명에 대한 경고를 표시하지 않습니다. 그렇지 않으면 상용 SSL 공급자를 선택할 수 있습니다. 하나를 선택할 때 선택했는지 확인하십시오. SHA256 인증서.

3단계 - IP로 액세스 제한

암호 인증은 사이트 제어판, phpmyadmin 등과 같은 사이트의 민감한 영역의 보안을 보장하기에 항상 충분하지 않습니다. 때때로 공격자는 이러한 영역에서 취약한 암호 또는 소프트웨어 취약성을 악용하여 무단 액세스 권한을 얻습니다. 그렇기 때문에 합법적인 사용자의 IP를 확인할 수 있는 경우 추가 IP 제한을 추가하는 것이 좋습니다.

예를 들어 WordPress 사이트가 있고 관리 영역이 /wp-admin/에 있는 경우 해당 사이트에 대한 액세스를 귀하의 IP 또는 모든 관리자의 IP로 제한해야 합니다. 이를 위해 해당 서버 블록을 엽니다. Nginx의 기본 서버 블록은 /etc/nginx/sites-enabled/default입니다.

sudo nano /etc/nginx/sites-enabled/default

server 구성 부분에 다음을 추가합니다.

server {
...
	location /wp-admin/ {
    	allow 192.168.1.1/24;
     allow 10.0.0.1/24;
    	deny  all;
}
...
...

위의 192.168.1.110.0.0.1을 귀하의 IP로 바꾸십시오. 마찬가지로 네트워크 마스크(/24)를 변경하여 다른 IP 또는 네트워크에 대한 액세스를 허용할 수 있습니다.

이러한 설정을 적용하려면 다음 명령을 사용하여 Nginx를 다시 로드해야 합니다.

  1. sudo service nginx reload

이제 허용된 IP 주소 범위를 벗어난 브라우저로 사이트의 /wp-admin/ 부분에 액세스하려고 하면 오류가 발생합니다. 이 오류는 403 Forbidden이 됩니다(앞서 설명한 대로 이 오류를 404 찾을 수 없음으로 변경하지 않은 경우). 동시에 다음 명령을 사용하여 오류 로그에서 실제 오류 코드를 볼 수 있습니다.

  1. sudo tail /var/log/nginx/error.log

액세스 금지 오류는 다음과 같이 표시됩니다.

Output of sudo tail -f /var/log/nginx/error.log
... 2016/01/02 04:16:12 [error] 4767#0: *13 access forbidden by rule, client: X.X.X.X, server: localhost, request: "GET /wp-admin/ HTTP/1.1", host: "Y.Y.Y.Y" ...

오류 페이지 변경, IP별 접근 제한 등 보안에 한 가지 이상의 접근 방식을 적용한 조합은 Nginx 강화의 누적 효과를 보여준다. 예에 따라 일반적인 WordPress 관리 페이지 대신 공격자와 그들이 사용하는 자동화 도구는 404 찾을 수 없음 페이지를 보게 됩니다. 이것은 혼란스럽고 WordPress를 손상시키는 다른 접근 방식을 시도하지 못하게 할 수 있습니다.

4단계 — 보안 감사 수행

자신의 의견과는 별개로 보안 검사를 받는 것이 항상 좋은 생각입니다. 이를 위해 웹 취약점을 검색하는 보안 감사 도구를 사용할 수 있습니다. 상업용 도구를 포함하여 이러한 도구가 많이 있으며 처음에는 무료 오픈 소스인 wapiti를 사용할 수 있습니다. Wapiti는 고급 도구의 일부 기능이 부족할 수 있지만 보안 감사가 무엇인지에 대한 아이디어를 제공합니다.

apt를 통해 Ubuntu에 wapiti를 설치할 수 있습니다.

  1. sudo apt-get install wapiti

그런 다음 다음 명령을 사용하여 wapiti로 사이트 스캔을 시작합니다.

wapiti http://example.org -n 10 -b folder

example.org를 사이트 이름으로 바꿔야 합니다. 명령에 두 가지 추가 인수를 제공했습니다. 첫 번째 -n 10은 무한 루프를 방지하기 위해 동일한 패턴의 URL 수를 10개로 제한합니다. 두 번째 인수 -b 폴더는 검사 범위를 주어진 도메인으로만 설정합니다.

스캔이 완료되면 스캔을 실행한 디렉토리 내의 generated_report라는 디렉토리에 결과가 표시됩니다. 최상의 보기를 위해 이 디렉토리를 로컬 컴퓨터에 다운로드하고 웹 브라우저에서 index.html 파일을 엽니다.

보고서 내에는 SQL 주입, 블라인드 SQL 주입, 파일 처리, 교차 사이트 스크립팅, CRLF, 명령 실행, 리소스 소비, Htaccess 우회, 백업 파일 및 잠재적으로 위험한 파일의 10가지 범주로 분류된 취약점이 표시됩니다.

이상적으로는 취약점이 발견되지 않은 보고서가 다음과 같이 표시되어야 합니다.

취약점이 있는 경우 스캔의 해당 부분을 확장하여 자세한 정보를 확인할 수 있습니다.

Nginx 및 웹 사이트를 가장 완전하고 철저하게 감사할 수 있도록 다양한 도구를 사용하여 이러한 스캔을 자주 실행해야 합니다.

5단계 — 추가 보안 조치 취하기

Nginx 보안에 관한 일부 주제는 이미 훌륭한 기사가 있기 때문에 이 기사에서 다루지 않습니다. 다음 사항을 숙지하시기 바랍니다.

  • Ubuntu 14.04에서 Naxsi를 설치 및 구성하는 방법

Naxsi는 Nginx용 웹 애플리케이션 방화벽입니다. 악성 서명 모음을 사용하여 알려진 웹 취약점과 알려지지 않은 웹 취약점 모두로부터 사용자를 보호합니다.

Naxsi는 복잡한 소프트웨어이며 조정에는 시간과 노력이 필요합니다. 다행스럽게도 필요한 경우 추가로 사용자 지정할 수 있는 가장 인기 있는 웹 응용 프로그램에 대해 쉽게 사용할 수 있는 구성이 있습니다.

  • Ubuntu 14.04에서 Fail2Ban으로 Nginx 서버를 보호하는 방법

Fail2ban은 웹 보안을 한 단계 끌어올리고 nginx 서버를 사전에 보호하는 훌륭한 도구입니다. 지금까지 우리는 사용자가 특정 정보를 찾고 사이트의 일부에 액세스하는 것을 제한했습니다. fail2ban을 사용하면 공격자가 악의적인 활동을 수행하고 있음을 감지하면 특정 기간 동안 공격자를 추가로 차단할 수 있습니다.

  • Ubuntu 14.04에서 Monit로 LEMP 스택 모니터링

모니터링은 보안에 필수적이며 Monit은 Nginx를 잘 지원하는 훌륭한 도구입니다. 웹 로그는 악의적인 활동의 흔적을 보여줄 뿐만 아니라 CPU 로드 및 메모리 사용량의 급증도 보여줍니다.

이 문서에서는 5단계 — 오류 및 키워드에 대한 로그 모니터링에 특히 주의를 기울이십시오. 여기에서 누군가가 사이트의 중요한 부분에 액세스하거나 액세스를 시도하는 경우와 같은 보안 이벤트에 대해 사용자 정의 알림을 보내도록 구성할 수 있습니다.

  • Ubuntu 14.04에서 Iptables를 사용하여 방화벽을 설정하는 방법

방화벽을 갖는 것은 nginx와 드롭릿 전체의 보안에 매우 중요합니다. 표준 http(tcp 80) 포트 외에 허용되는 수신 연결에 https(tcp 443) 포트를 추가해야 합니다.

  • DigitalOcean VPS에 Aide를 설치하는 방법

AIDE와 같은 파일 및 디렉터리 무결성 검사기는 파일 및 디렉터리의 변경 사항에 대해 경고합니다. 이것은 사이트의 일부가 변경되고 새 파일/디렉토리가 추가될 때를 알아야 하기 때문에 웹 파일에 특히 유용합니다. AIDE에 대해 자세히 알아보려면 기사로 시작할 수 있습니다.

위의 문서는 약간 구식이며 특별히 우분투용으로 작성되지 않았습니다. 그러나 쉽게 적응하고 Ubuntu 14.04에도 적용할 수 있어야 합니다. AIDE 또는 다른 유사한 도구를 구성할 때 웹 로그 및 웹 캐시와 같은 임시 파일이 모니터링되지 않도록 제외하십시오.

결론

이 기사를 읽고 나면 Nginx 보안에 대해 더 확신을 갖게 될 것입니다. 기능과 보안 사이의 균형을 찾으면 웹 환경이 설계된 대로 안전하게 작동한다는 사실에 안심할 수 있습니다. 또한 Nginx 보안은 정기적인 업데이트, 재구성, 스캔 등이 필요한 진행 중인 작업임을 명심하십시오.