웹사이트 검색

Nginx 웹 서버의 성능을 보호, 강화 및 개선하기 위한 최고의 가이드


Nginx에 대해 들어본 놀라운 소식을 바탕으로 아마도 한번 시도해 보기로 결정하셨을 것입니다. 이 사이트에 게시된 주제에 대한 일부 기사를 살펴본 후 Apache 설치를 Nginx로 교체하는 것을 고려하고 있다는 점이 마음에 들었을 것입니다.

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

놓치지 마세요:

13가지 Apache 웹 서버 보안 및 강화 팁

Apache 웹 서버를 보호하기 위한 25가지 Apache Htaccess 요령

Nginx 테스트 환경

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

  1. 데비안 GNU/리눅스 8.1(제시).
  2. IP 주소: IP 기반 가상 페이지에 설명된 대로 192.168.0.25(tecmintlovesnginx.com) 및 192.168.0.26(nginxmeanspower.com) 호스트 섹션

    1. "Nginx를 사용하여 이름 기반 및 IP 기반 가상 호스트(서버 블록)를 설정하는 방법"
  3. Nginx 버전: nginx/1.6.2.
  4. 귀하의 편의를 위해 최종 구성 파일은 다음과 같습니다(Pastebin 링크).

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

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

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

놓치지 마세요: 저장소 및 소스에서 Nginx의 최신 안정 버전을 설치하세요.

저장소에서 소프트웨어를 설치하는 것이 소스 코드에서 프로그램을 컴파일하는 것보다 쉽지만 이 마지막 옵션에는 두 가지 장점이 있습니다. 1) Nginx에 추가 모듈(예: mod_security)을 구축할 수 있고 2) 항상 최신 버전을 제공합니다. 저장소(현재 1.9.9)보다 릴리스 정보는 항상 Nginx 웹 사이트에서 확인할 수 있습니다.

놓치지 마세요:

Mod_Security 및 Mod_Evasive를 사용하여 무차별 공격 및 DDoS 공격으로부터 Apache를 보호하세요.

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

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

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

예를 들어:

./configure  --without-http_dav_module --withouthttp_spdy_module 

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

주의 사항: 구성 지시문은 모듈에서 제공됩니다. 앞으로 필요할 지시어가 포함된 모듈을 비활성화하지 않도록 하세요! 모듈 비활성화를 결정하기 전에 nginx 문서에서 각 모듈에서 사용할 수 있는 지시어 목록을 확인해야 합니다.

팁 #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, POSTHEAD만 허용하고 다른 모든 항목은 비활성화해야 합니다.

이렇게 하려면 서버 블록 안에 다음 줄을 배치하세요. 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 지시어를 추가합니다.

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

팁 #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;

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

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

자세한 내용은 다음 팁을 참조하세요.

팁 #8: Nginx용 모니터 로그 설정

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

팁 #7에 정의된 추가r 영역에 대한 실패한 요청에 대한 로그를 필터링하기 위해 grep을 사용할 수 있습니다.

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

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

  1. 클라이언트 IP
  2. 브라우저 유형
  3. HTTP 요청 유형
  4. 요청된 리소스
  5. 요청에 응답하는 서버 블록(여러 가상 호스트가 동일한 파일에 로깅하는 경우 유용함)

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

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

이미지 핫링크는 사용자가 호스팅하는 이미지를 다른 사이트에 표시할 때 발생합니다. 이로 인해 귀하가 지불하는 대역폭 사용량이 증가하는 반면 상대방은 마치 자신의 소유물인 것처럼 이미지를 즐겁게 표시합니다. 즉, 그것은 당신에게 이중 손실입니다.

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

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

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

192.168.0.26

192.168.0.25

<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Nginx means power</title>
</head>
<body>
<h1>Nginx means power!</h1>
<img src=”http://192.168.0.25/img/nginx.png” />
</body>
</html>



<head>

Tecmint는 Nginx를 좋아합니다

<body>

Tecmint는 Nginx를 좋아합니다!




이제 각 사이트를 탐색하면 보시다시피 192.168.0.25에서는 이미지가 올바르게 표시되지만 192.168.0.26403 응답으로 대체됩니다. 강한>:

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

팁 #10: SSL을 비활성화하고 Nginx에서는 TLS만 활성화합니다.

가능하다면 모든 버전에서 SSL을 피하고 대신 TLS를 사용하기 위해 필요한 모든 조치를 취하세요. 다음 ssl_protocols는 가상 호스트 파일의 서버 또는 http 컨텍스트에 배치되어야 하거나 include 지시문을 통해 별도의 파일입니다(어떤 사람들은 ssl.conf라는 파일을 사용합니다) , 그러나 이는 전적으로 귀하에게 달려 있습니다):

ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;

예를 들어:

팁 #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를 어떻게 사용하고 있는지 확인할 것입니다.

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

첫 번째 서버 블록에 다음 줄을 추가합니다.

return 301 https://$server_name$request_uri;

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

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

요약

이 기사에서는 Nginx 웹 서버를 보호하기 위한 몇 가지 팁을 공유했습니다. 우리는 여러분의 생각을 듣고 싶습니다. 커뮤니티의 다른 사람들과 공유하고 싶은 다른 팁이 있으면 아래 의견 양식을 사용하여 메모를 보내 자유롭게 알려주십시오.