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 프로토콜을 사용중이라면 아래의 보안상 취약한 알고리즘은 제거해야 한다
TLS_DH_anon_WITH_AES_256_CBC_SHA
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_RC4_128_MD5
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에만 존재하며 중요한 데이터는 캐시 또는 저장하지 않는다
- 설정값
deny - 무조건 불러올 수 없다
sameorigin - 같은 도메인인 경우 불러올 수 있다
allow-from - 특정 도메인들을 허용한다
- 주의점
X-Frame-Options는 확장 헤더이기 때문에 모든 브라우저가 해당 옵션에 대하여 동일하게 동작하지 않는다
DENY, SAMEORIGIN은 모든 브라우저가 동일하게 동작한다
allow-from 은 일부 브라우저가 동작하지 않는다
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
클라이언트 요청의 body 내용을 읽기 위한 버퍼 크기 설정
32비트 8K, 64비트 16K가 기본 사이즈
- client_header_buffer_size
- 클라이언트 요청의 헤더를 읽기 위한 버퍼의 크기를 설정
- 대부분 1K 바이트 버퍼로 충분하다
- 요청에 킨 쿠키가 포함되어 있거나 WAP 클라이언트 요청인 경우 1K가 부족할 수 있다
- 요청 또는 요청 헤더 필드가 이 버퍼에 맞지 않으면 large_client_header_buffers 로 더 큰 버퍼를 할당해야 한다
- client_max_body_size
- 클라이언트 요청 body의 허용되는 최대 크기를 설정
- 설정한 최대 크기는 Content-Length 요청 헤더 필드에 지정된다
- 요청의 크기가 구성의 값을 초과하면 403이 리턴된다
- 크기를 0으로 설정하면 클라이언트 요청 바디 크기를 확인할 수 없다
- 100K 이상을 권장한다
- large_client_header_buffers
- 클라이언트 요청 헤더를 읽는데 사용되는 버퍼의 최대 크기를 설정한다
- 요청의 크기가 버퍼의 크기를 초과하면 414가 리턴된다
- 요청 헤더 필드가 버퍼 크기를 초과하면 400이 리턴된다
- 버퍼는 수요가 있을때만 할당된다
- 기본적인 버퍼 크기는 8K이다
- 요청 처리가 끝난 후에 연결이 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
- 클라이언트 요청에 대한 본문 읽기 시간 제한을 정의한다
- 전에 요청 본문의 전송이 아닌 두개의 연속 읽기 작업 사이의 기간에 대해서 설정된다
- 클라이언트가 이 시간 내에 전송하지 않으면 408이 리턴된다
- client_header_timeout
- 클라이언트 요청 헤더를 읽기 위한 제한시간 정의
- 클라이언트가 이 시간 내에 전체 헤더를 전송하지 않으면 408이 리턴된다
- keepalive_timeout
- keep-alive 제한시간을 설정
- 첫번째 매개변수는 서버측에서 keep-alive 클라이언트 연결이 열린 상태로 유지될 시간 제한을 설정한다
- 0값은 keep-alive 클라이언트 연결을 사용하지 않도록 한다
- 선택적인 두번째 파라미터는 keep-alive:timeout=time 응답 헤더필드에 값을 설정한다
- keep-alive:timeout=time 헤더필드는 Mozilla와 Konqueror에 의해 인식된다
- MSIE는 자체적으로 keep-alive 연결을 60초후에 닫는다
- send_timeout
- 클라이언트에 응답을 전송하기 위한 시간 제한을 설정
- 이 제한시간은 전체 응답을 전송하기 위한 것이 아니라 두개의 연속 쓰기 작업사이에서만 설정
- 클라이언트가 시간 내에 아무것도 수신하지 못하면 연결이 닫힌다
설정
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로 설정하지 않으면 공격 여부 파악, 공격자 사용 툴 파악, 공격자 위치 파악이 불가능하다.
- 로그 포맷 스트링
- $remote_addr : 원격의 IP 주소
- $remote_user [$time_local] : 시간
- $request : 요청값
- $status : 상태코드
- $body_bytes_sent : 전송 된 body 용량
- $http_referer : 현재 nginx 서버에 접속하기 전에 머물렀던 URL을 기록
- $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 |