[우분투 18.04 데스크톱] LEMP : 엔진엑스(Nginx) 설정 - VirtualHost로 멀티도메인(서브도메인) 한 서버에 연결하기
에 이어...
제가 적용한 나머지 엔진엑스(Nginx) 추가 설정들을 정리할텐데, 아무래도 글이 길어질 것 같아서 주제별로 포스팅을 나누어야 할 것 같아요. 포스팅 하단의 "카테고리의 다른 글"을 보고 다음 글로 따라와주시면 감사하겠습니다.
---------------------------------------------------------
방화벽(iptable, UFW 등)을 만질 수 없는 상황인데 사이트에 공격성 접근이 계속 들어온다면?
차선책으로 Nginx에서 해당 IP를 차단하는 것이 가능합니다. 엔진엑스에서 처리하기 때문에 그만큼 Nginx 자원을 소모하겠지만, 막지 않은 채로 당하는 것보다는 자원 소모가 적을 것 같습니다. 403 Forbidden 페이지만 딸랑 띄우고 처리를 끝낼 테니까요.
http://nginx.org/en/docs/http/ngx_http_access_module.html
ngx_http_access_module 덕분인데요,
문서를 보면 http, server, location, limit_except Context 내에 allow나 deny를 적절하게 적어주면 된다고 나와 있습니다.
1. Nginx로 특정 IP 차단하는 방법
▲ 저는 위에 적은 링크에 있는 예제처럼 location 영역에 차단할 IP를 넣어봤습니다.
/etc/nginx/sites-enabled/ 경로에 있는 서버블록 conf 파일을 에디터로 연 다음, location / { } 안에
deny IP주소;
형식으로 입력한 것이지요(스샷 붉은 밑줄 참고). 저는 한 줄에 IP 하나씩 적는 게 보기 편하더군요.
차단할 IP들을 다 적었으면 저장하고 빠져나옵니다.
※ 참고로 deny, allow 명령어는 제일 위에서부터 순차적으로 처리되는 것을 알아둘 필요가 있습니다. 예를 들어
allow all;
deny 123.123.123.123;
이라고 설정을 구성했다면 모든 접근 허용(allow all;)이 먼저 처리되기때문에 이후의 deny 명령어는 무력화됩니다. 123.123.123.123 주소의 접근도 허용되는 것이지요. 그러므로 deny 명령어로 차단막을 구성하고 싶다면 allow all; 명령어를 아예 쓰지 말거나 deny 위에 두지 말아야 하겠습니다.
deny 123.123.123.123;
allow all;
이렇게는 쓸 수 있겠죠? 123.123.123.123 주소는 거부+나머지는 통과시키라고 해석되니까.
▲ Nginx 설정파일 테스트 명령어(sudo nginx -t)로 설정파일 수정시 문법에 오류를 일으키지 않았는지 점검해봅니다. 위 스크린샷의 첫번째 결과처럼 configuration file systax is ok / configuration file test is successful 이라고 뜨면 문제가 없는 것이고, 두번째 결과처럼 [emerg] invalid parameter / configuration file test is failed 라고 뜨면 문제가 있는 것이니 찾아 들어가서 수정해줍니다. 스샷을 보니까 /etc/nginx/sites-enabled/jimnongtest1 파일의 13번째 줄에 k라는 값이 잘못 들어갔다고 안내하네요. 이렇게 문제 있는 곳을 자세하게 짚어주니까 쉽게 찾아갈 수 있습니다.
▲ Nginx 설정파일 테스트를 통과했다면 Nginx 서비스를 재시작하거나(sudo service nginx restart 또는 sudo systemctl restart nginx.service) 설정파일을 다시 로드하면(sudo nginx -s reload) conf 파일 변경사항이 반영되고, 해당 IP 차단 처리가 완료됩니다.
▲ 제 IP를 차단처리 해봤는데, 웹브라우저로 접근해보니까 403 에러 띄우면서 잘 차단되네요. -_-;;
2. Nginx로 IP 대역 차단하는 방법
특정 IP 차단 리스트가 쌓이다보면 특정 IP대역에서 지속적인 침투 작업이 들어오는 게 보이는 경우가 있습니다. PC방처럼 작업장 차려놓고 작정하고 들어오는 게 아닌가 싶을 정도인데, 매 번 차단처리 하는 것이 번거로워서 해당 대역 전체를 차단하고 싶을 때가 있었습니다.
아파치(Apache)에서는...
Deny from 31.163.114.237
Deny from 31.184.238.
Deny from 5.188.
Deny from 178.
이런 식으로 차단하고 싶은 대역을 비우고 Deny from 명령어를 구성하면 해당 IP 대역이 차단됐었습니다. 31.163.114.237 단일 IP 차단, 31.184.238.0~31.184.238.255 범위 차단, 5.188.0.0~5.188.255.255 범위 차단, 178.0.0.0~178.255.255.255 범위 차단. 178로 시작하는 대역은 너무 심하게 들어오길래 전체를 막아버린 거예요.
그런데 엔진엑스(Nginx)에서는 아파치처럼 적는 게 아니더라고요. Nginx에서는 IP 뒤에 CIDR(Classless Inter-Domain Routing. 사이더) 블록을 추가해서 대역 차단을 구현하라고 하는데, 제가 CIDR 알못이라 CIDR 계산기를 동원해서 IP 대역 차단을 구성해봤습니다.ㅠㅠ
https://www.ipaddressguide.com/cidr
▲ CIDR 계산기 주소(IPv4).
https://www.ipaddressguide.com/ipv6-cidr
▲ IPv6 CIDR 블록 계산기 주소
▲ 국내는 아직 IPv4 기반입니다. 계산기에서 IP Range To CIDR 란을 활용했습니다.
Deny from 31.184.238.
Deny from 5.188.
Deny from 178.
아파치에서 위처럼 표현하던 것을 CIDR 계산기를 이용해서 Nginx용으로 바꿔봤더니...
deny 31.184.238.0/24;
deny 5.188.0.0/16;
deny 178.0.0.0/8;
이렇게 되더군요. 설명하면 길어질 것 같아서 사례를 소개해봤는데, 전달이 잘 됐을지 모르겠네요.
▲ 예를 들어 /etc/nginx/sites-enabled/ 경로에 있는 서버블록 conf 파일을 에디터로 연 다음 127로 시작하는 IP대역 전체를 막아봤습니다. 이렇게 하면 서버에서 웹브라우저 띄우고 주소창에 127.0.0.1(localhost) 넣었을 때 403 에러가 뜨겠죠?
▲ 빙고!
3. Nginx로 VirtualHost 전체에 IP 차단 적용하는 방법
지금까지 설명했던 방법들은 /etc/nginx/sites-enabled/ 경로에 있는 단일 서버블록 conf 파일을 수정해서 IP를 차단하는 식이었죠. 그래서 VirtualHost에 있는 도메인 하나에만 IP차단이 적용되었고, 서버 전체에 차단목록을 적용하기 위해서는 /etc/nginx/sites-enabled/에 있는 모든 conf 파일에 차단 목록을 복붙해야만 되지 않았을까 싶습니다. 이렇게 복붙혀서 VirtualHost 단에서 중복처리를 많이 할수록 Nginx에 부담을 주겠죠?
그렇다면 VirtualHost가 분기되기 전의 상단에서 deny 명령을 구성해주면 어떨까요? 모든 도메인에 일괄적으로 적용되니까 약간이나마 부하를 줄일 수 있지 않을까요?
▼ /etc/nginx/nginx.conf 파일을 에디터로 열어보면 http { } 블록 안에...
▲ /etc/nginx/sites-enabled/ 경로에서 VirtualHost 서버블록 파일들을 불러오는 것 외에
/etc/nginx/conf.d/ 디렉토리에서 conf 확장자 형식의 설정파일을 불러오도록 되어 있습니다.
그러니까 /etc/nginx/nginx.conf 파일에 deny 구문을 넣거나 /etc/nginx/conf.d/ 에 임의의 conf 파일을 만들고 그 파일에 deny 구문을 넣으면 VirtualHost 전체에 IP 차단을 적용시킬 수 있겠죠?
▼ 저는 기존에 www.jimnongtest1.top 에 연결된 서버블록 설정 파일에만 deny 127.0.0.0/8; 구문을 넣어서 blog.jimnongtest1.top 주소에는 접근할 수 있었는데요,
▼ 기존 서버블록 설정파일의 deny 명령어를 지우고 /etc/nginx/conf.d/ 디렉토리에 deny-ip.conf 파일을 만든 다음 그 파일에 deny 명령어를 넣어봤습니다.
▲ sudo nginx -t 명령어로 설정파일 테스트 후 이상이 없어서 nginx 서비스 재시작(또는 conf 파일 reload).
▲ 모든 사이트에 deny 명령어가 적용되는 것을 확인할 수 있었습니다.
VirtualHost 전체에 IP 차단 적용하는 방법 설명은 이것으로 충분히 되지 않았나 싶네요.
4. Nginx로 특정 IP만 접근 허용하는 방법
다른 사람들이 내 서버에 접근하는 것이 싫다! 나 혼자 놀 거다! 하신다면 특정 IP만 접근 허용하고 나머지는 접근을 허용하지 않는 설정이 필요하겠죠? 개인위키 운영하시는 분들은 이 기능이 유용할 겁니다.
▼ 아래 스크린 샷을 참고해서 서버블록 설정파일(/etc/nginx/sites-enabled/)을 구성하면 됩니다.
allow 허용할 IP주소(CIDR블록 추가도 가능);
deny all;
의 순서로 allow 명령어들을 필요한만큼 넣고, 마지막에 deny all; 을 넣는 겁니다. 저는 로컬호스트(127.0.0.1)의 접속만 허용해봤습니다.
▲ nginx 설정파일들의 무결성을 테스트하고 이상이 없길래 nginx 서비스를 재시작했습니다. 그리고 웹브라우저에서 접속 테스트.
localhost에서의 접근은 되고 외부망에서는 접근이 안되는 것을 보니 허용 명령어가정상 작동하는 듯하네요.
/etc/nginx/conf.d/deny-ip.conf 라는 공통 접근제한 설정파일이 있는데도 /etc/nginx/sites-enabled/의 개별 서버블록 설정파일 상의 접근허용 설정이 우선적으로 적용되는 것 같습니다.
완료!
특정 IP 접근 차단/허용에 대한 설명은 이것으로 마치겠습니다.
다음 글에서 다른 설정사항에 대해 다루겠습니다.
※ 참고 링크
- http://www.ysh.kr/2015/01/ip-nginx.html
▲ 갈수록 어려워지는 젓가락 행진곡