Nginx 웹 서버의 보안, 강화 및 성능 향상을위한 궁극적 인 가이드


Nginx에 대해 들었던 놀라운 것들을 바탕으로 시도해보기로 결정했을 것입니다. 이 사이트에 게시 한 주제에 대한 몇 가지 기사를 살펴본 후 Apache 설치를 Nginx로 교체하는 것을 고려하고있을 정도로 너무 마음에 들었을 것입니다.

그렇다면 Nginx 서버의 보안을 강화하기위한 12 가지 팁 (Nginx를 최신 상태로 유지하는 것부터 TLS를 사용하고 HTTP를 HTTPS)이며 그중 일부는 Apache로 수행하는 작업과 매우 유사합니다.

놓치지 마세요 :

이 가이드에서는 다음 환경을 사용합니다.

  1. Debian GNU/Linux 8.1 (jessie).
  2. IP address: 192.168.0.25 (tecmintlovesnginx.com) and 192.168.0.26 (nginxmeanspower.com), as described in the IP-based virtual hosts section at
    1. “How to Setup Name-based and IP-based Virtual Hosts (Server Blocks) with Nginx“

    이를 염두에두고 시작하겠습니다.

    팁 # 1 : Nginx를 최신 상태로 유지

    이 글을 쓰는 시점에서 CentOS (EPEL) 및 Debian 저장소의 최신 Nginx 버전은 각각 1.6.3 및 1.6.2-5입니다.

    리포지토리에서 소프트웨어를 설치하는 것이 소스 코드에서 프로그램을 컴파일하는 것보다 쉽지만이 마지막 옵션에는 1) Nginx에 추가 모듈 (예 : mod_security)을 빌드 할 수 있으며 2) 항상 최신 버전을 제공합니다. "리포지토리보다 (오늘날 1.9.9) "릴리스 노트는 항상 Nginx 웹 사이트에서 사용할 수 있습니다.

    놓치지 마세요 :

    팁 # 2 : Nginx에서 불필요한 모듈 제거

    소스에서 설치하는 동안 Nginx에서 모듈을 명시 적으로 제거하려면 다음을 수행하십시오.

    # ./configure --without-module1 --without-module2 --without-module3
    

    예를 들면 :

    # ./configure  --without-http_dav_module --withouthttp_spdy_module 
    

    짐작할 수 있듯이 소스에서 이전 Nginx 설치에서 모듈을 제거하려면 컴파일을 다시 수행해야합니다.

    주의 사항 : 구성 지시문은 모듈에서 제공합니다. 앞으로 필요한 지시문이 포함 된 모듈을 비활성화하지 마십시오! 모듈 비활성화에 대한 결정을 내리기 전에 각 모듈에서 사용할 수있는 지시문 목록에 대한 nginx 문서를 확인해야합니다.

    TIP # 3 : Nginx에서 server_tokens 지시문 비활성화

    server_tokens 지시문은 Nginx에게 오류 페이지에 현재 버전을 표시하도록 지시합니다. 특정 버전의 알려진 취약점으로 인한 웹 서버 공격을 방지하기 위해 해당 정보를 전 세계와 공유하고 싶지 않기 때문에 이는 바람직하지 않습니다.

    server_tokens 지시문을 비활성화하려면 서버 블록 내에서 if를 off로 설정합니다.

    server {
        listen       192.168.0.25:80;
        server_tokens        off;
        server_name  tecmintlovesnginx.com www.tecmintlovesnginx.com;
        access_log  /var/www/logs/tecmintlovesnginx.access.log;
        error_log  /var/www/logs/tecmintlovesnginx.error.log error;
            root   /var/www/tecmintlovesnginx.com/public_html;
            index  index.html index.htm;
    }
    

    nginx를 다시 시작하고 변경 사항을 확인합니다.

    팁 # 4 : Nginx에서 HTTP 사용자 에이전트 거부

    HTTP 사용자 에이전트는 웹 서버에 대한 콘텐츠 협상에 사용되는 소프트웨어입니다. 여기에는 시스템 리소스를 낭비하여 웹 서버의 성능에 영향을 미칠 수있는 악성 코드 봇 및 크롤러도 포함됩니다.

    원하지 않는 사용자 에이전트 목록을보다 쉽게 유지하려면 다음 내용으로 파일 (예 : /etc/nginx/blockuseragents.rules )을 만듭니다.

    map $http_user_agent $blockedagent {
            default         0;
            ~*malicious     1;
            ~*bot           1;
            ~*backdoor      1;
            ~*crawler       1;
            ~*bandit        1;
    }
    

    다음으로 서버 블록 정의 앞에 다음 줄을 추가합니다.

    include /etc/nginx/blockuseragents.rules;
    

    그리고 사용자 에이전트 문자열이 위에 정의 된 블랙리스트에있는 경우 403 응답을 반환하는 if 문 :

    nginx를 다시 시작하면 문자열이 위와 일치하는 모든 사용자 에이전트가 웹 서버에 액세스하지 못하도록 차단됩니다. 192.168.0.25를 서버의 IP로 바꾸고 wget의 -user-agent 스위치에 대해 다른 문자열을 자유롭게 선택하십시오.

    # wget http://192.168.0.25/index.html
    # wget --user-agent "I am a bandit haha" http://192.168.0.25/index.html 
    

    팁 # 5 : Nginx에서 원하지 않는 HTTP 메서드 비활성화

    동사라고도하는 HTTP 메서드는 Nginx에서 제공하는 리소스에 대해 수행 할 원하는 작업을 나타냅니다. 일반적인 웹 사이트 및 응용 프로그램의 경우 GET, POST 및 HEAD 만 허용하고 나머지는 모두 비활성화해야합니다.

    이렇게하려면 서버 블록 안에 다음 줄을 넣으십시오. 444 HTTP 응답은 빈 응답을 의미하며 Nginx에서 맬웨어 공격을 속이기 위해 자주 사용됩니다.

    if ($request_method !~ ^(GET|HEAD|POST)$) {
       return 444;
    }
    

    테스트하려면 curl을 사용하여 DELETE 요청을 보내고 일반 GET을 보낼 때 출력을 비교합니다.

    # curl -X DELETE http://192.168.0.25/index.html
    # curl -X POST http://192.168.0.25/index.html 
    

    팁 # 6 : Nginx에서 버퍼 크기 제한 설정

    Nginx 웹 서버에 대한 버퍼 오버플로 공격을 방지하려면 별도의 파일에 다음 지시문을 설정합니다 (예 : /etc/nginx/conf.d/buffer.conf 라는 새 파일 생성).

    client_body_buffer_size  1k;
    client_header_buffer_size 1k;
    client_max_body_size 1k;
    large_client_header_buffers 2 1k;
    

    위의 지시문은 웹 서버에 대한 요청으로 인해 시스템에서 버퍼 오버플로가 발생하지 않도록 보장합니다. 다시 한번, 각각의 기능에 대한 자세한 내용은 문서를 참조하십시오.

    그런 다음 구성 파일에 포함 지시문을 추가하십시오.

    include /etc/nginx/conf.d/*.conf;
    

    TIP # 7 : Nginx에서 IP로 연결 수 제한

    IP로 연결을 제한하려면 limit_conn_zone (http 컨텍스트 또는 적어도 서버 블록 외부) 및 limit_conn (http, 서버 블록 또는 위치 컨텍스트) 지시문을 사용하십시오.

    그러나 모든 연결이 계산되는 것은 아니라 서버에서 요청을 처리하고 전체 요청 헤더를 읽은 연결 만 계산된다는 점에 유의하십시오.

    예를 들어, addr라는 영역에서 최대 연결 수를 1 로 설정해 보겠습니다 (예, 과장이지만이 경우에는 제대로 작동합니다). 원하는 이름) :

    limit_conn_zone $binary_remote_addr zone=addr:5m;
    limit_conn addr 1;
    

    Apache Benchmark (Perform Nginx Load)를 사용한 간단한 테스트에서 2 개의 동시 요청으로 총 10 개의 연결이 이루어지면 우리의 요점을 입증하는 데 도움이됩니다.

    # ab -n 10 -c 2 http://192.168.0.25/index.html
    

    자세한 내용은 다음 팁을 참조하십시오.

    팁 # 8 : Nginx에 대한 모니터 로그 설정

    이전 팁에서 설명한 테스트를 수행 한 후 서버 블록에 대해 정의 된 오류 로그를 확인하십시오.

    grep을 사용하여 TIP # 7에 정의 된 addr 영역에 대한 실패한 요청에 대한 로그를 필터링 할 수 있습니다.

    # grep addr /var/www/logs/tecmintlovesnginx.error.log --color=auto
    

    마찬가지로 다음과 같은 관심 정보에 대한 액세스 로그를 필터링 할 수 있습니다.

    1. Client IP
    2. Browser type
    3. HTTP request type
    4. Resource requested
    5. Server block answering the request (useful if several virtual hosts are logging to the same file).

    비정상적이거나 원치 않는 활동이 감지되면 적절한 조치를 취하십시오.

    팁 # 9 : Nginx에서 이미지 핫 링크 방지

    이미지 핫 링크는 사용자가 다른 사이트에 호스팅 된 이미지를 표시 할 때 발생합니다. 이로 인해 대역폭 사용 (비용 지불)이 증가하고 다른 사람은 자신의 자산 인 것처럼 이미지를 즐겁게 표시합니다. "즉, 당신에게는 이중 손실입니다.

    예를 들어 해당 가상 호스트에서 사용되는 모든 이미지를 저장하는 서버 블록 내부에 img 라는 하위 디렉토리가 있다고 가정 해 보겠습니다. 다른 사이트에서 이미지를 사용하지 못하도록하려면 가상 호스트 정의 내에 다음 위치 블록을 삽입해야합니다.

    location /img/ {
      valid_referers none blocked 192.168.0.25;
       if ($invalid_referer) {
         return   403;
       }
    }
    

    그런 다음 각 가상 호스트에서 다음과 같이 index.html 파일을 수정합니다.

    이제 각 사이트를 찾아 보면 이미지가 192.168.0.25에서 올바르게 표시되지만 192.168.0.26에서 403 응답으로 대체됩니다.

    이 팁은 Referer 필드를 보내는 원격 브라우저에 따라 다릅니다.

    TIP # 10 : SSL 비활성화 및 Nginx에서만 TLS 활성화

    가능하면 모든 버전에서 SSL을 피하고 대신 TLS를 사용하십시오. 다음 ssl_protocols 는 가상 호스트 파일의 서버 또는 http 컨텍스트에 배치하거나 include 지시문을 통해 별도의 파일이어야합니다 (일부 사용자는 ssl.conf 라는 파일을 사용합니다). ,하지만 전적으로 귀하에게 달려 있습니다) :

    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    

    예를 들면 :

    TIP # 11 : Nginx에서 인증서 생성

    먼저 키와 인증서를 생성하십시오. 원하는 경우 다른 유형의 암호화를 자유롭게 사용하십시오.

    # openssl genrsa -aes256 -out tecmintlovesnginx.key 1024
    # openssl req -new -key tecmintlovesnginx.key -out tecmintlovesnginx.csr
    # cp tecmintlovesnginx.key tecmintlovesnginx.key.org
    # openssl rsa -in tecmintlovesnginx.key.org -out tecmintlovesnginx.key
    # openssl x509 -req -days 365 -in tecmintlovesnginx.csr -signkey tecmintlovesnginx.key -out tecmintlovesnginx.crt
    

    그런 다음 다음 팁 ( http-> https 리디렉션)을 준비하기 위해 별도의 서버 블록 내에 다음 줄을 추가하고 SSL 관련 지시문도 새 블록으로 이동합니다.

    server {
        listen 192.168.0.25:443 ssl;
        server_tokens off;
        server_name  tecmintlovesnginx.com www.tecmintlovesnginx.com;
        root   /var/www/tecmintlovesnginx.com/public_html;
        ssl_certificate /etc/nginx/sites-enabled/certs/tecmintlovesnginx.crt;
        ssl_certificate_key /etc/nginx/sites-enabled/certs/tecmintlovesnginx.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    }
    

    다음 팁에서는 사이트가 현재 자체 서명 된 인증서 및 TLS를 사용하는 방법을 확인합니다.

    TIP # 12 : Nginx에서 HTTP 트래픽을 HTTPS로 리디렉션

    첫 번째 서버 블록에 다음 행을 추가하십시오.

    return 301 https://$server_name$request_uri;
    

    위의 지시문은 가상 호스트의 포트 80에 요청이있을 때마다 영구 URL 리디렉션에 사용되는 301 (영구 이동) 응답을 반환하고 이전 팁에서 추가 한 서버 블록으로 요청을 리디렉션합니다.

    아래 이미지는 리디렉션을 보여주고 암호화에 TLS 1.2 및 AES-256을 사용하고 있다는 사실을 확인합니다.

    요약

    이 기사에서는 Nginx 웹 서버를 보호하기위한 몇 가지 팁을 공유했습니다. 여러분의 생각을 듣고 싶습니다. 다른 커뮤니티와 공유하고 싶은 다른 팁이 있으면 아래 댓글 양식을 사용하여 메모를 보내 주시기 바랍니다.