목차
개요
사이트 내에 존재하지 않는 경로에 접속할 경우 일반적으로는 NodeBB같은 CMS에서 페이지가 존재하지 않는다는 내용을 출력한다.
하지만 CMS 외부에 접속 가능한 경로를 지정해뒀을 때 해당 경로에 없는 파일로의 접속을 시도하거나 오류가 나면 nginx에서 응답 코드를 출력한다.
이런 응답 코드도 서버 공격자에게는 정보가 될 수 있기 때문에 모두 404로 통합하는 것이 좋고, 기왕이면 응답 코드 페이지를 따로 설정해서 서버에 대한 정보(nginx)를 알려주지 않는 것이 좋다.
HTTP 응답 코드의 종류
1xx ~ 3xx는 응답 코드를 출력하지 않으니 따로 적진 않았다.
- 1xx (정보): 요청을 받았으며 프로세스를 계속한다.
- 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다.
- 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다.
- 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
- 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다.
응답 코드 관련 정보는 Wikipedia의 HTTP 상태 코드 문서를 참고해서 작성했다.
4xx(요청 오류) 응답 코드
4xx 클래스의 상태 코드는 클라이언트에 오류가 있음을 나타낸다.
- 400(잘못된 요청): 서버가 요청의 구문을 인식하지 못했다.
- 401(권한 없음): 이 요청은 인증이 필요하다. 서버는 로그인이 필요한 페이지에 대해 이 요청을 제공할 수 있다. 상태 코드 이름이 권한 없음(Unauthorized)으로 되어 있지만 실제 뜻은 인증 안됨(Unauthenticated)에 더 가깝다.
- 402(결제 필요): 이 요청은 결제가 필요합니다.
- 403(Forbidden, 금지됨): 서버가 요청을 거부하고 있다. 예를 들자면, 사용자가 리소스에 대한 필요 권한을 갖고 있지 않다. (401은 인증 실패, 403은 인가 실패라고 볼 수 있음)
- 404(Not Found, 찾을 수 없음): 서버가 요청한 페이지(Resource)를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다.
- 405(허용되지 않는 방법): 요청에 지정된 방법을 사용할 수 없다. 예를 들어 POST 방식으로 요청을 받는 서버에 GET 요청을 보내는 경우, 또는 읽기 전용 리소스에 PUT 요청을 보내는 경우에 이 코드를 제공한다.
- 406(허용되지 않음): 요청한 페이지가 요청한 콘텐츠 특성으로 응답할 수 없다.
- 407(프록시 인증 필요): 이 상태 코드는 401(권한 없음)과 비슷하지만 요청자가 프록시를 사용하여 인증해야 한다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 한다.
- 408(요청 시간초과): 서버의 요청 대기가 시간을 초과하였다.
- 409(충돌): 서버가 요청을 수행하는 중에 충돌이 발생했다. 서버는 응답할 때 충돌에 대한 정보를 포함해야 한다. 서버는 PUT 요청과 충돌하는 PUT 요청에 대한 응답으로 이 코드를 요청 간 차이점 목록과 함께 표시해야 한다.
- 410(사라짐): 서버는 요청한 리소스가 영구적으로 삭제되었을 때 이 응답을 표시한다. 404(찾을 수 없음) 코드와 비슷하며 이전에 있었지만 더 이상 존재하지 않는 리소스에 대해 404 대신 사용하기도 한다. 리소스가 영구적으로 이동된 경우 301을 사용하여 리소스의 새 위치를 지정해야 한다.
- 411(길이 필요): 서버는 유효한 콘텐츠 길이 헤더 입력란 없이는 요청을 수락하지 않는다.
- 412(사전조건 실패): 서버가 요청자가 요청 시 부과한 사전조건을 만족하지 않는다.
- 413(요청 속성이 너무 큼): 요청이 너무 커서 서버가 처리할 수 없다.
- 414(요청 URI가 너무 긺): 요청 URI(일반적으로 URL)가 너무 길어 서버가 처리할 수 없다.
- 415(지원되지 않는 미디어 유형): 요청이 요청한 페이지에서 지원하지 않는 형식으로 되어 있다.
- 416(처리할 수 없는 요청범위): 요청이 페이지에서 처리할 수 없는 범위에 해당되는 경우 서버는 이 상태 코드를 표시한다.
- 417(예상 실패): 서버는 Expect 요청 헤더 입력란의 요구사항을 만족할 수 없다.
- 418(I'm a teapot, RFC 2324 ,https://google.com/teapot)
- 420(Enhance Your Calm, 트위터)
- 422(처리할 수 없는 엔티티, WebDAV; RFC 4918)
- 423(잠김,WebDAV; RFC 4918): 접근하려는 리소스가 잠겨 있다.
- 424(실패된 의존성, WebDAV; RFC 4918)
- 424(메쏘드 실패, WebDAV)
- 425(정렬되지 않은 컬렉션, 인터넷 초안)
- 426(업그레이드 필요, RFC 2817): 클라이언트는 업그레이드 헤더 필드에 주어진 프로토콜로 요청을 보내야 한다.
- 428(전제조건 필요, RFC 6585)
- 429(너무 많은 요청, RFC 6585): 사용자가 일정 시간 동안 너무 많은 요청을 보냈다.
- 431(요청 헤더 필드가 너무 큼, RFC 6585)
- 444(응답 없음, Nginx)
- 449(다시 시도, 마이크로소프트)
- 450(윈도 자녀 보호에 의해 차단됨, 마이크로소프트)
- 451(법적인 이유로 이용 불가, 인터넷 초안)
- 451(리다이렉션, 마이크로소프트)
- 494(요청 헤더가 너무 큼, Nginx)
- 495(Cert 오류, Nginx)
- 496(Cert 없음, Nginx)
- 497(HTTP to HTTPS, Nginx)
- 499(클라이언트가 요청을 닫음, Nginx)
5xx(서버 오류) 응답 코드
서버가 유효한 요청을 명백하게 수행하지 못했음을 나타낸다.
- 500(내부 서버 오류): 서버에 오류가 발생하여 요청을 수행할 수 없다.
- 501(구현되지 않음): 서버에 요청을 수행할 수 있는 기능이 없다. 예를 들어 서버가 요청 메소드를 인식하지 못할 때 이 코드를 표시한다.
- 502 (Bad Gateway, 불량 게이트웨이): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 잘못된 응답을 받았다.
- 503(서비스를 사용할 수 없음): 서버가 오버로드되었거나 유지관리를 위해 다운되었기 때문에 현재 서버를 사용할 수 없다. 이는 대개 일시적인 상태이다.
- 504(게이트웨이 시간초과): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 제때 요청을 받지 못했다.
- 505(HTTP 버전이 지원되지 않음): 서버가 요청에 사용된 HTTP 프로토콜 버전을 지원하지 않는다.
- 506(Variant Also Negotiates, RFC 2295)
- 507(용량 부족, WebDAV; RFC 4918)
- 508(루프 감지됨, WebDAV; RFC 5842)
- 509(대역폭 제한 초과, Apache bw/limited extension)
- 510(확장되지 않음, RFC 2774)
- 511(네트워크 인증 필요, RFC 6585)
- 520(Unknown Error, 알 수 없음)
- 598(네트워크 읽기 시간초과 오류, 알 수 없음)
- 599(네트워크 연결 시간초과 오류, 알 수 없음)
Nginx 오류 페이지 설정
우선 에러 페이지로 사용할 html 파일을 만들어준다.
구글이나 Codepen에 responsive 404 html로 검색하면 괜찮은 것들이 많다.
보통 html/css/js 3개의 파일로 만들어졌을 것이다.
html 파일을 404.html로 이름을 변경하고 3개의 파일을 사이트의 루트 디렉토리에 업로드한다.
4xx와 5xx 응답 코드에도 여러가지가 있지만 주로 나오는 코드는 400~404와 500~504이다.
이 정보를 공격자에 주지 않기 위해 404로 통합을 할 것이다.
nginx의 서버 블록에 아래 내용을 추가한다.
error_page 404 400 401 403 500 502 503 504 = /404.html;
400~404 오류와 500~504 오류가 발생할 경우 루트 디렉토리에 있는 404.html의 내용을 불러온다.
수정을 마치고 nginx를 재시작하면 정상적으로 적용된다.
$ sudo service nginx restart