Linux-centos/-Linux-centos__nginx-uwsgi

nginx security setting

말하는감자 2020. 9. 18. 11:32

request 방식 제한에 대한 설정

설정 - get, post 이외의 요청을 거부하게 설정

server {
    location / {
        limit_except GET POST {
            deny all;
        }
    }
}

설정 - get, post 이외의 메서드는 444로 리턴

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

테스트

curl -X PUT http://localhost:port
curl -X DELETE http://localhost:port

테스트 결과값

  • 403 : 해당 요청을 수행한 권한이 없는 access
  • 405 : 해당 uri에서 메서드를 허용하지 않는다
<html>
<head>
    <title>403 Forbidden</title>
</head>
<body>
    <center><h1>403 Forbidden</h1></center><hr><center>nginx</center>
</body>
</html>

nginx 버전 노출 방지

설정

  • 각 server별로 설정하지 않고 nginx.conf에서 공통 적용 가능하다
http {
    server_tokens   off;
}

테스트

curl -X GET http://localhost:port

테스트 결과값

  • Server: nginx 옆에 버젼이 표기되지 않다면 정상 적용된것
Server: nginx
Content-Type: text/html
Content-Length: 232
Connection: keep-alive

SSL/TLS 설정

  • 가능하면 SSLv2, SSLv3등을 사용하지 않도록 설정, TLS를 권장한다. TLSv1의 취약점이 최근에 노출되었기 때문에 TLSv1도 권장하지 않는다.
  • TLS 는 인터넷에서 정보를 암호화해서 송수신하는 프로토콜로 SSL에서 표준화된 기술로 국제 인터넷 표준화기구에서 표준으로 인정받은 프로토콜이다.
  • SSL은 POODLE 취약점을 비롯해 지속적으로 SSL 프로토콜의 취약점이 발견되어 TLS만 사용해야 한다
  • POODLE 취약점은 공격자가 클라이언트에게 서버가 TLS를 지원하지 않는다고 속여 클라이언트로 하여금 SSL v.3.0을 사용하게 강제한후 이 과정에서 중간 공격자가 보호된 HTTP 쿠키의 암호를 풀 수 있게 되는 취약점이다. 암호화 프로토콜 설정 중 SSL 통신을 제거함으로써 예방 가능하다.
  • TLS1.0 프로토콜을 사용중이라면 아래의 보안상 취약한 알고리즘은 제거해야 한다
    1. TLS_DH_anon_WITH_AES_256_CBC_SHA

    2. TLS_DH_anon_WITH_3DES_EDE_CBC_SHA

    3. TLS_DH_anon_WITH_AES_128_CBC_SHA

    4. TLS_DH_anon_WITH_RC4_128_MD5

    5. TLS_DH_anon_WITH_DESC_CBC_SHA

설정

http {
    ssl_protocols   TLSv1.2;
}

테스트

  • 외부에서 접근이 가능한 서버라면 진단 사이트를 이용하여 진단한다
cat /etc/nginx/nginx.conf | grep "ssl_protocols"

테스트 결과값

ssl_protocols TLSv1.2;

안전한 SSL 보안 설정

  • ssl stripping 공격을 당했을 때 피해자의 시스템의 모든 트래픽은 해커가 생성한 프록시를 통해 라우팅 되며 이는 MITM 공격으로 간주할 수 있다. 공격을 방지하기 위해서 보안 설정에 헤더를 추가한다

설정

http {
    add_header Strict-Transport-Security    "max-age=63072000; includeSubdomains; preload";
}

테스트

curl -v http://localhost:port

테스트 결과값

> GET HTTP/1.1
> User-Agent: curl
> Host: localhost:port
> Accept: */*
>
...
< Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
...

XSS 필터 설정 - Cross site scripting 공격을 방지하기 위해서 옵션 설정

설정

http {
    add_header X-XSS-Protection "1; mode=block";
}

테스트

curl -v http://localhost:port

테스트 결과값

> GET HTTP/1.1
> User-Agent: curl
> Host: localhost:port
> Accept: */*
>
...
< X-XSS-Protection: 1; mode=block
...

Content-Type 스니핑 차단 설정

  • Http 응답의 헤더에 MIME 형식을 추가하여 전송하여 보안 위협을 방지한다

설정

http {
    add_header X-Content-Type-Options   nosniff;
}

테스트

curl -v http://localhost:port

테스트 결과값

> GET HTTP/1.1
> User-Agent: curl
> Host: localhost:port
> Accept: */*
>
...
< X-Content-Type-Options: nosniff
....

클릭재킹 방지

  • 다른 사이트에서 피해 사이트를 불러오는 것을 방지 할 수 있다. HSTS헤더는 HTTPS에만 존재하며 중요한 데이터는 캐시 또는 저장하지 않는다
  • 설정값
    1. deny - 무조건 불러올 수 없다

    2. sameorigin - 같은 도메인인 경우 불러올 수 있다

    3. allow-from - 특정 도메인들을 허용한다

  • 주의점
    1. X-Frame-Options는 확장 헤더이기 때문에 모든 브라우저가 해당 옵션에 대하여 동일하게 동작하지 않는다

    2. DENY, SAMEORIGIN은 모든 브라우저가 동일하게 동작한다

    3. allow-from 은 일부 브라우저가 동작하지 않는다

    4. allow-from 을 제대로 적용하기 위해서는 Content-Security-Policy를 추가해주어야 한다

  • 설정 관련 참고 - https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Frame-Options

설정 - 같은 도메인인 경우 불러올 수 있도록 한다

http {
    add_header X-Frame-Options SAMEORIGIN;
}

설정 - 특정 도메인들만 허용한다

http {
    add_header X-Frame-Options  "allow-from http://example-domains.com";
    add_header Content-Security-Policy "frame-ancestors http://example-domains.com";
}

테스트

curl -v http://localhost:port

테스트 결과값

> GET HTTP/1.1
> User-Agent: curl
> Host: localhost:port
> Accept: */*
>
...
< X-Frame-Options: SAMEORIGIN
...

버퍼오버플로우 방지

  • client_body_buffer_size
    1. 클라이언트 요청의 body 내용을 읽기 위한 버퍼 크기 설정

    2. 32비트 8K, 64비트 16K가 기본 사이즈

  • client_header_buffer_size
    1. 클라이언트 요청의 헤더를 읽기 위한 버퍼의 크기를 설정
    2. 대부분 1K 바이트 버퍼로 충분하다
    3. 요청에 킨 쿠키가 포함되어 있거나 WAP 클라이언트 요청인 경우 1K가 부족할 수 있다
    4. 요청 또는 요청 헤더 필드가 이 버퍼에 맞지 않으면 large_client_header_buffers 로 더 큰 버퍼를 할당해야 한다
  • client_max_body_size
    1. 클라이언트 요청 body의 허용되는 최대 크기를 설정
    2. 설정한 최대 크기는 Content-Length 요청 헤더 필드에 지정된다
    3. 요청의 크기가 구성의 값을 초과하면 403이 리턴된다
    4. 크기를 0으로 설정하면 클라이언트 요청 바디 크기를 확인할 수 없다
    5. 100K 이상을 권장한다
  • large_client_header_buffers
    1. 클라이언트 요청 헤더를 읽는데 사용되는 버퍼의 최대 크기를 설정한다
    2. 요청의 크기가 버퍼의 크기를 초과하면 414가 리턴된다
    3. 요청 헤더 필드가 버퍼 크기를 초과하면 400이 리턴된다
    4. 버퍼는 수요가 있을때만 할당된다
    5. 기본적인 버퍼 크기는 8K이다
    6. 요청 처리가 끝난 후에 연결이 keep-alive 상태로 전환되면 버퍼가 해제된다

설정

http {
       client_body_buffer_size     16K;
       client_header_buffer_size   1K;
       client_max_body_size        2m;
       large_client_header_buffers 2 1K;
}

테스트

cat /etc/nginx/nginx.conf | grep "client_body_buffer_size*"
client_body_buffer_size 16K;

cat /etc/nginx/nginx.conf | grep "client_header_buffer_size*"
client_header_buffer_size 1K;

cat /etc/nginx/nginx.conf | grep "client_max_body_size*"
client_max_body_size 2m;

cat /etc/nginx/nginx.conf | grep "large_client_header_buffers*"
large_client_header_buffers 2 1K;

slow http dos 공격 차단

  • client_body_timeout
    1. 클라이언트 요청에 대한 본문 읽기 시간 제한을 정의한다
    2. 전에 요청 본문의 전송이 아닌 두개의 연속 읽기 작업 사이의 기간에 대해서 설정된다
    3. 클라이언트가 이 시간 내에 전송하지 않으면 408이 리턴된다
  • client_header_timeout
    1. 클라이언트 요청 헤더를 읽기 위한 제한시간 정의
    2. 클라이언트가 이 시간 내에 전체 헤더를 전송하지 않으면 408이 리턴된다
  • keepalive_timeout
    1. keep-alive 제한시간을 설정
    2. 첫번째 매개변수는 서버측에서 keep-alive 클라이언트 연결이 열린 상태로 유지될 시간 제한을 설정한다
    3. 0값은 keep-alive 클라이언트 연결을 사용하지 않도록 한다
    4. 선택적인 두번째 파라미터는 keep-alive:timeout=time 응답 헤더필드에 값을 설정한다
    5. keep-alive:timeout=time 헤더필드는 Mozilla와 Konqueror에 의해 인식된다
    6. MSIE는 자체적으로 keep-alive 연결을 60초후에 닫는다
  • send_timeout
    1. 클라이언트에 응답을 전송하기 위한 시간 제한을 설정
    2. 이 제한시간은 전체 응답을 전송하기 위한 것이 아니라 두개의 연속 쓰기 작업사이에서만 설정
    3. 클라이언트가 시간 내에 아무것도 수신하지 못하면 연결이 닫힌다

설정

http {
    client_body_timeout 60;
    client_header_timeout 60;
    keepalive_timeout 90;
    send_timeout 120;
}

테스트

cat /etc/nginx/nginx.conf | grep "client_body_timeout"
client_body_timeout 60;

cat /etc/nginx/nginx.conf | grep "client_header_timeout"
client_header_timeout 60;

cat /etc/nginx/nginx.conf | grep "keepalive_timeout"
keepalive_timeout 90;

cat /etc/nginx/nginx.conf | grep "send_timeout"
send_timeout 120;

beast 공격 차단을 위한 서버 사이드 설정

  • SSL/TLS 와 함께 사용되는 암호 블록 체인(CBC)에 대한 공격을 방지하기 위해서 클라이언트 대신에 서버에 의해 결정되도록 암호에 대한 선호도를 설정한다.

설정

http {  
    ssl_prefer_server_ciphers on;  
}

테스트

cat /etc/nginx/nginx.conf | grep "ssl_prefer_server_ciphers"  
ssl_prefer_server_ciphers on;

안전하지 않은 암호 방식 금지

설정

http {  
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;  
}

테스트

cat /etc/nginx/nginx.conf | grep "ssl_ciphers"  
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;

그 외 추가할 수 있는 보안 설정

데몬 관리

  • 웹 서버 데몬이 root 권한으로 구동될 경우 취약점을 이용하여 공격자가 root 권한을 사용할 수 있으므로 이를 방지한다

설정

vim /etc/nginx/nginx.conf  
User daemon daemon

테스트

cat /etc/nginx/nginx.conf | grep "User"  
ps -ef | grep nginx

디렉토리 권한 설정

설정

chown daemon:daemon /etc/nginx/  
chmod 750 /etc/nginx

테스트

  • nginx 구동 계정의 소유이며 750 권한이어야 한다.

ls -ald /etc/nginx/

설정 파일 권한 설정

  • 설정 파일을 일반 사용자가 삭제, 수정하지 못하도록 한다

설정

chown daemon:daemon /etc/nginx/*.conf
chmod 600/etc/nginx/*.conf

테스트

chown daemon:daemon /etc/nginx/_.conf chmod 600/etc/nginx/_.conf

검색 기능 제거

설정

server {  
    location / {  
        autoindex off;  
    }  
}

테스트

cat /etc/nginx/conf/nginx.conf | grep "autoindex"

로그 포맷 설정

  • 로그 포맷을 Combined로 설정하지 않으면 공격 여부 파악, 공격자 사용 툴 파악, 공격자 위치 파악이 불가능하다.
  • 로그 포맷 스트링
    1. $remote_addr : 원격의 IP 주소
    2. $remote_user [$time_local] : 시간
    3. $request : 요청값
    4. $status : 상태코드
    5. $body_bytes_sent : 전송 된 body 용량
    6. $http_referer : 현재 nginx 서버에 접속하기 전에 머물렀던 URL을 기록
    7. $http_user_agent : 접속자의 웹 브라우저(OS 포함) 종류를 기록

설정

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  combined;

테스트

cat /etc/nginx/nginx.conf | grep “/access_log”

개발 언어, xml 데이터 전송 노출 제한

  • X-Powered-By은 어떠한 언어로 개발되어 있는지
  • X-Pingback은 http 프로토콜에서 xml 데이터를 전송하기위해 사용
  • X-link도 xml 관련된 W3C 표준

설정

http {
    fastcgi_hide_header X-Powered-By;
    fastcgi_hide_header X-Pingback;
    fastcgi_hide_header Link;
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Pingback;
    proxy_hide_header X-Link;
}

테스트

curl -I GET http://localhost:port

'Linux-centos > -Linux-centos__nginx-uwsgi' 카테고리의 다른 글

pip install uwsgi 실패시  (0) 2020.02.17
flask + nginx + uwsgi  (0) 2019.09.25
nginx no such file or dirctory  (0) 2019.07.22