2022/10/14 업데이트
아래 업데이트 내용과 같이 apt upgrade로 이 글에서 설치한 xtables 최신버전(3.9)이 지워져서 xtables-addons-3.9.tar.xz 파일로 다시 설치하려 했지만, 이것저것 업데이트 된 탓인지 make에서 에러가 발생.
아래 사이트에서 아래 deb 파일을 다운로드 받아서 설치하고, iptables를 재설정(같은 설정 파일로 iptables-apply)하면 된다.
1. xtables-addons-common_3.9-1ubuntu0.2~20.04.3_amd64.deb
2. xtables-addons-dkms_3.9-1ubuntu0.2~20.04.3_all.deb
다운로드 – https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/4610-deletedppa/+build/21765689
deb 파일 설치 커맨드
|
sudo dpkg -i xtables-addons-common_3.9-1ubuntu0.2_20.04.3_amd64.deb sudo dpkg -i xtables-addons-dkms_3.9-1ubuntu0.2_20.04.3_all.deb |
2020/6/25 업데이트
xtables-addons-common, xtables-addons-dkms이 업데이트 되면서 설치한 xtables 최신버전(이글에서 xtables-addons-3.9.tar.xz 파일로 설치한 것)이 덮어씌워지면서 iptables 에 geoip 설정 내용이 적용 안되게 된다. xtables-addons-3.9.tar.xz 파일로 다시 설치하면 복구되니 아래 인스톨 방법대로 한번 더 설치해주면 된다.
2020년1월부터 maxmind사가 제공하는 geoip 정보 파일이 회원가입제로 바뀌었다. 다른 방법으로 국가별 IP 정보를 얻어서 차단하거나 허용하는 방법에 대해서 자세히 설명. iptables 애드온 xtables 와 KRNIC 에서 제공하는 국가별 IP 정보를 사용한다.
우분투 18.04 에서 방화벽 iptables 의 애드온 xtables 를 이용해 국가 별로 접속 차단 또는 허용하는 방법을 쓰려고 했는데 여러가지 문제에 부딪혀 아주 긴 글이 될 것 같다.
일단 과정을 기록하면서 쭉 써보겠는데 너무 글이 난잡해서 어려워지면 나중에 설정 순서만 따로 정리해보도록 해야겠다.
자, iptables 에 xtables 라는 애드온을 설치해서 국가별로 접속을 차단하거나 허용하는 설정을 해 보겠다.
===== 경고!!! =====
클라우드 서비스나 VPS 를 사용하고 있는 서버에서 SSH 접속 포트에 이 글의 내용을 적용할 경우에는 iptables 에 대한 충분한 지식을 갖고 설정하지 않으면 서버에 접속이 불가능해 질 수가 있으니 꼭!!! 잘 확인하고 적용하도록 합시다. 최소한 리부팅하면 되돌아 올 수 있도록 iptables 에 재기동시 디폴트 파일에는 적용하지 않을 것을 추천합니다! 이 블로그에서도 iptables 에 대한 내용은 많이 다루었으니 먼저 읽어 보시는걸 추천합니다.
원격 접속 상태에서 iptables 의 안전한 적용 방법
우분투 서버 18.04 iptables 서버 재기동으로 초기화 되는 문제
xtables 설치
|
sudo apt install xtables-addons-common |
관련 팩키지가 많아서 170메가쯤… 크다. 설치는 이게 전부.
xtables 에서 사용할 국가별 IP 바이너리 파일 작성
xtables 를 사용하기 위해선 /usr/lib/xtables-addons 에 국가별 IP 정보가 들어있는 파일을 다운로드하는 스크립트와 빌드하는 스크립트가 있는데 실행해도 작동하지 않는다.
원래라면 이 두 스크립트로 차례대로 실행해 CSV 파일로 되어 있는 국가별 IP 정보를 다운로드 하고, CSV 파일을 다시 바이너리 파일로 빌드해야 xtables 가 작동하게 된다.
Xtables-addons Git 에서 최신 버전 스크립트를 찾아서 열어보면, 다운로드 스크립트는 maxmind 라는 회사에서 제공하는 geoip 정보를 다운로드 하도록 만들어져 있다.
그런데 이 회사는 2020/01/01부터 정책을 변경해서, 회원가입을 해서 다운로드를 받도록 하고 있기 때문에 스크립트도 동작하지 않고, 회사 사이트에서 회원가입하고 geoip 정보는 받는것도 난 쓰기가 싫어서 다른 방법을 찾아봤다.
IP 를 관리하는 각 대륙별 인터넷 레지스트리에서 자기들이 할당한 IP 리스트에 IP 정보와 함께 국가 정보도 들어있다. 아래가 각 대륙별 인터넷 레지스트리들이 제공하는 IP 할당 정보 파일.
|
ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-extended-latest ftp://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest |
포멧은 CSV형식으로 되어있는데 자세한 포맷에 대해선 여기 문서에 잘 나와있다. (별거 없음)
이 파일들로 국가별로 정리하고 연속된 IP는 합치고하는 출력하는 프로그램을 자바로 다 만들고 나서 여기까지 글을 쓰는 도중에 발견한…
KRNIC (한국인터넷정보센터) 에서도 같은 국가별 IP 할당 정보를 전국가분을 하나의 CSV 파일로 제공하고 있는것이다… 두둥…
다운받은 시점으로 3일전 등록한 내용까지 있으니 꽤 자주 업데이트 되는것 같다. 이건 차차 더 보기로 하고.
xtables-addons 의 빌드 스크립트(파일명:xt_geoip_build 갱신일:2020/01/07)에서 사용하는 파일 포맷은 DB IP 라는 회사에서 제공하는 geoip 정보가 담긴 csv 파일인데, 구조가 시작IP,끝IP,국가코드(두자리) 이다.
KRNIC 에서 받은 CSV 파일을 위 형식으로 변환하고, 빌드 스크립트를 돌려서 바이너리 데이터베이스 파일을 만들면 xtables 설정을 위한 준비가 끝나는 것이다.
DB IP 포맷으로 변환한 파일은 자바로 작성해서 바로 출력했다.
변환시 사용한 자바 코드 – https://github.com/elmitash/geoip_convert_krnic2dbip/
go로도 만들었다. 실행파일과 쉘스크립트도 있으니 이쪽을 사용하는게 편하다. https://github.com/elmitash/geoip_krnic2dbip
CSV 파일명을 dbip-country-lite.csv 로 바꾸고 아무데나 넣어두고 그자리에서 빌드 스크립트를 실행하면 된다.
xt_geoip_build 스크립트 실행시 에러가 나온다.
|
$ /usr/lib/xtables-addons/xt_geoip_build Can't locate Net/CIDR/Lite.pm in @INC (you may need to install the Net::CIDR::Lite module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/lib/xtables-addons/xt_geoip_build line 9. BEGIN failed--compilation aborted at /usr/lib/xtables-addons/xt_geoip_build line 9. |
구글링 해보니 아래 라이브러리가 필요하단다. 설치하자.
|
sudo apt install libnet-cidr-lite-perl libtext-csv-perl |
다시 실행하면 잘 될거다. 안되면 구글링…
|
$ /usr/lib/xtables-addons/xt_geoip_build 487871 entries total 28 IPv4 ranges for AD 6 IPv6 ranges for AD 459 IPv4 ranges for AE 114 IPv6 ranges for AE ... |
빌드 스크립트를 실행한 디렉토리에 국가별로 바이너리로 빌드 된 파일들이 생기게 된다. xtables가 인식하는 지정된 디렉토리가 있으니 거기에 넣어야한다. 디렉토리를 작성해서 .iv4 .iv6 파일을 모두 이동시키자. 인터넷에서 xtables 설치 과정을 보면 xt_geoip 디렉토리 아래 BE 와 LE 디렉토리 이야기가 많이 나와서 BE 는 도대체 뭔가 했는데 Big Endian 과 Little Endian 의 약자이다. 우분투는 Little Endian 시스템이니까 LE 에 넣으면 될 것 같다.
|
sudo mkdir -p /usr/share/xt_geoip/LE sudo mv *.iv[46] /usr/share/xt_geoip/LE |
문제 발생
뭔가 버그가 있는건지 뭘 잘못한건지 모르겠는데, iptables 에 REJECT 를 한줄 추가하면 국가를 뭘로 지정하든 모든 국가가 다 블럭되는것 같다.
아주 수상한 상황이니 사용할 때는 꼭 리붓하면 되돌아 올 수 있도록 설정하고 사용해 보자. 클라우드 서버에서 SSH 막히면 망한다.
해결방법을 찾았다. xtables 를 최신 버전으로 빌드해서 설치하면 잘 작동된다.
xtables 최신버전 설치
소스포지에 xtables-addons 의 다운로드 페이지에 가서 최신버전의 xtables 압축파일을 다운로드 받자.
이 글에서는 xtables-addons-3.9.tar.xz 파일을 받아서 설치하는 방법으로 진행한다.
다운받은 파일을 서버에 올리고, xz 압축 파일을 써 본적이 없을 경우에 설치부터 해서 아래 명령으로 압축 해제.
|
sudo apt install xz-utils tar xvfJ xtables-addons-3.9.tar.xz |
압축해제된 디렉토리로 이동해서 configure 실행.
|
cd xtables-addons-3.9/ ./configure |
내경우에는 에러가 나서 에러 내용으로 검색해보니 pkg-config, iptables-dev 가 부족해서 설치했다.
|
sudo apt install pkg-config sudo apt install iptables-dev |
다시 실행하니 문제 없음.
|
./configure make sudo make install |
설치가 무사히 끝나면 다운로드 스크립트와 빌드 스크립트가 /usr/local/libexec/xtables-addons/ 디렉토리에 설치된다. 다운로드는 작동 안할 것이고, 빌드는 이글 위에서 사용했던 것과 같은 버전(최신버전)이 설치 된다.
이미 국가별 IP 파일은 모두 빌드해서 /usr/share/xt_geoip/LE 디렉토리에 넣어놓았으면 다시 빌드할 필요는 없다.
iptables 에 geoip 설정을 넣으니 에러가 발생해, 내용을 보니 이번 최신버전 xtables 는 LE 디렉토리를 사용하지 않는다.
/usr/share/xt_geoip 디렉토리에 빌드된 국가별 IP 파일을 넣어야한다.
파일들을 옮기고, LE 디렉토리는 필요없으니 지우자.
|
cd /usr/share/xt_geoip/LE sudo mv * .. cd .. sudo rm -rf LE |
이렇게 xtables 최신버전을 설치하고, 국가별 IP 파일도 옮기고 나니 아래에서 설정한 내용들이 잘 적용 된다. 만세 ㅠㅠ
iptables 에 국가별 차단 허용 등록
참고글:원격 접속 상태에서 iptables 의 안전한 적용 방법
안전하게 하려면 현재 iptables 내용을 파일로 백업하고 백업한 파일을 복사해서 geoip 설정을 추가한 파일을 만든 후에 iptables-apply 로 적용해 본다.
|
sudo iptables-save > iptables.bak sudo cp iptables.bak iptables.geoip |
iptables.geoip 파일을 열어 필요에 따라서 아래 예시를 참고해서 적당히 추가
예시: 포트 22 (SSH)로 들어오는 한국, 일본, 미국 IP 이외를 모두 블럭한다.
|
-A INPUT -p tcp -m tcp --dport 22 -m geoip ! --src-cc KR,JP,US -j REJECT |
예시: 포트 22 (SSH), 80 (http), 443 (https)로 들어오는 중국, 인도 IP 를 모두 블럭한다.
|
-A INPUT -p tcp -m multiport --dports 22,80,443 -m geoip --src-cc CN,IN -j REJECT |
예시: 포트 22 (SSH)로 들어오는 한국 IP 만 허용한다. ACCEPT 의 디폴트 폴리시가 ACCEPT 가 아닐 경우에는 아래 두번째 줄도 필요.
|
-A INPUT -p tcp -m multiport --dports 22 -m geoip ! --src-cc KR -j REJECT -A INPUT -p tcp -m multiport --dports 22 -m geoip --src-cc KR -j ACCEPT |
iptables.geoip 내용을 iptables에 적용 후, 10초 동안 적용할지 말지 선택하지 않으면 원래대로 되돌린다.
|
sudo iptables-apply iptables.geoip |
시험삼아 JP, US 를 블럭하니 SSH 접속이 끊겨버렸다. ㅋㅋㅋ
잘 적용 되었으니 이제부터는 SSH 포트로 접속하는 수많은 나라들 안녕!
===== 경고!!! =====
아래 내용은 클라우드 서비스나 VPS 를 사용하는 서버에서는 SSH 접속 포트에는 적용하지 않는 것이 안전합니다! 서버 재기동시 접속이 불가능해질 수 있습니다!
마지막으로 서버 재기동시 읽혀지는 iptables 디폴트 파일에도 같은 내용을 넣어주면, 서버가 재기동 되더라도 적용될 것이다.
참고글:우분투 서버 18.04 iptables 서버 재기동으로 초기화 되는 문제
국가코드는 아래에서 보자.
국가코드 조회