Rocky Linux - IPtables 방화벽 국가 GeoIP 적용 (by MAXMIND)

    요즘 CentOS(Stream), RedHat, Rocky Linux를 설치하면 기본적인 방화벽 패키지로 「Firewall」 설치됩니다. 필자는 대부분 테스트서버에서 적응을 위해 그대로 이용을 했었으나, 사용하기 불편하고 가독성도 떨어져서 어느 순간부터 사용하지 않게 되었습니다. 대신 오래전부터 계속 사용해 왔던 「IPtables」를 다시 활용하면서 좀 더 효율적으로 보안 관리를 위해 IP주소를 국가별로 관리할 수 있는 「GeoIP」를 적용해 보도록 하겠습니다. ※ 「GeoIP Databases」 파일을 다운로드하기 위해서는 「MAXMIND」 가입이 필수, 본문에 설명하면서 같이 다루도록 하겠습니다.

    ◇ 테스트 OS

    Rocky Linux release 8.8 (Green Obsidian) - 최소 설치

    ※ 커널 kernel-4.18.X

     

    Rocky Linux release 9.4 (Blue Onyx) - 최소 설치

    ※ 커널 kernel-5.14.X


    ◇ 서버(사전) 준비

    ① SELinux 비활성화(OS 재시작 필요)

    [root@]# sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

    [root@]# cat /etc/selinux/config | grep disabled    [변경 확인]

    #    disabled - No SELinux policy is loaded.

    SELINUX=disabled

     

    ② 기본 툴 설치 및 업데이트

    [root@]# dnf install net-tools vim wget git unzip

    [root@]# dnf update

     

    ③ IPtables 설치 및 기본 활성화

    [root@]# systemctl stop firewalld    [Firewalld 방화벽 중지]

    [root@]# systemctl mask firewalld    [Firewalld 자동실행 중지]

    [root@]# dnf install -y iptables-services    [iptables 서비스 관련 패키지 설치]

    [root@]# systemctl enable iptables    [iptables기본 사용 설정]

    [root@]# systemctl start iptables    [iptables서비스 시작]

    [root@]# iptables -nL    [작동 확인]

    [root@]# /etc/sysconfig/iptables    [설정 파일 위치]

     

    ④ 저장소 추가 설치(Rocky 8 예시)

    ※ 참고

    ◇ xtables-addons 관련 패키지는 Redhat 또는 Rocky 기본 저장소에 없기 때문에 자동으로 설치하려면 RPM 퓨전 같은 저장소를 별도로 설치할 필요가 있습니다. 공식(저장소) 사이트 : https://rpmfusion.org/

    Rocky Linux 8 OS : rpmfusion-free-release-8

    Rocky Linux 9 OS : rpmfusion-free-release-9


    ◇ IPtables 관련 패키지 및 xtables-addons 설치

    ① IP주소 및 네트워크 관리 패키지 설치

    [root@]# dnf install perl-NetAddr-IP iptables-devel perl-Text-CSV_XS xtables-addons

    ※ 참고

    xtables-addons 패키지를 설치하면 현재 사용 중인 커널에 자동으로 모듈 확장 설치가 됩니다. 우리가 필요한 모듈은 「xt_geoip.ko」이며, 커널에 해당 모듈이 올라가 있어야 나중에 IPtables에 적용이 가능합니다. 예전에는 복잡하게 커널에 직접 컴파일을 해야 했지만 요즘은 자동으로 설치할 수 있도록 RPM을 제공하고 있어서 편하게 적용이 가능합니다.

     

    설치 위치(모듈) : /lib/modules/커널/extra/xtables-addons/xt_geoip.ko

     

    ② GeoLite2xtables 스크립트 다운 및 설정 「③ MaxMind 라이선스 먼저 필독」

    [root@]# mkdir /root/script    [다운로드 경로는 임의]

    [root@]# cd /root/script    [경로 이동]

    [root@]# git clone https://github.com/mschmitt/GeoLite2xtables    [다운]

    [root@]# cd GeoLite2xtables/    [경로 이동]

    [root@]# cp -arp geolite2.license.example geolite2.license    [라이선스 설정 파일 복사]

    [root@]# vim geolite2.license    [Maxmind 발급받은 라이선스 입력]

    YOUR_LICENSE_KEY='asdfqwer1234'

    ※ 라이선스 발급은 ③란 확인

    [root@]# ./00_download_geolite2    [첫 번째 스크립트 실행]

    ※ 예외 상황 발생 Curl 명령어를 이용한 다운로드 및 압축해제가 제대로 되지 않아 다음과 같이 변경

    [root@]# vim 00_download_geolite2    [스크립트 수정]

    # curl $GEOLITEURL > $TEMPZIP    [ #(주석) 처리 후]

    wget $GEOLITEURL -O $TEMPZIP    [ 추가, 옵션은 대문자 영문 -O]

    [root@]# ./00_download_geolite2    [재 실행]

    Archive:  /tmp/tmp.vPipitOWWt    [정상 패턴, 아래의 두 개의 CSV 파일 확인]
      inflating: /tmp/GeoLite2-Country-Blocks-IPv6.csv
      inflating: /tmp/GeoLite2-Country-Blocks-IPv4.csv

    [root@]# ./10_download_countryinfo    [두 번째 스크립트 실행]

     

    ③ MaxMind-GeoLite2 가입 및 라이선스 발급받기

    ※ 공식 사이트 : https://www.maxmind.com/

    ※ 공식 가입 URL : MaxMind-GeoLite2

    스크린샷 순서대로 진행, 특정값이나 선택은 임의로 해도 되지만 인증을 받기 위한 「Email address」 부분은 실제 메일을 수신받을 수 있는 주소를 입력할 것

    ◎ 대략적인 순서

    1. GeoLite2 Sign Up 가입 정보 입력, 「Email address」 정확히 입력

    2. 「Email address」 메일주소로 제목 「Welcome To MaxMind」 수신 확인 후 「Set-password?token=」 URL 링크를 클릭하여 패스워드 설정

    3. 「Click here to sign in」 클릭하여 로그인 후 2차 인증을 위한 인증 메일 수신 확인

    4. 제목 「MaxMind Account Access Code」 6자리 코드를 30분 내에 「Enter Code」 입력

     

    5. 로그인 후 왼쪽 메뉴에서 「Manage License Keys」「Generate new license key」 새로운 라이선스 생성 하여 발급받기, 여러 개 가능

    6. 성공하면 「Account ID/License key」 정보와 자동 업데이트 적용 시 필요한 설정 파일을 다운로드할 수 있습니다. ※ 해당 화면은 전체적으로 표시되는 유일한 시간으로, 키를 안전한 곳에 복사할 것


    ◇ Perl 모듈 설치 및 Geolite2 컨버터

    ① Perl-CPAN 설치

    [root@]# dnf install perl-CPAN

    CPAN「Comprehensive Perl Archive Network」 모듈을 관리하는 기본 도구로, Perl 환경에서 CPAN 모듈을 설치하고 관리할 수 있게 도와줍니다. CPAN은 Perl 모듈을 위한 중앙 저장소 역할을 하며, Perl 개발자들이 쉽게 모듈을 설치하고 업데이트할 수 있는 환경을 제공

     

    ② CPAN 콘솔 접근 및 IP주소 및 네트워크 관련 모듈 설치

    [root@localhost]# perl -MCPAN -e shell

     

    Would you like to configure as much as possible automatically? [yes] yes

    가능한 한 많은 것을 자동으로 구성하시겠습니까?

    cpan [1]> install NetAddr::IP    [Perl에서 IP 주소와 네트워크를 처리하기 위한 모듈]

    cpan [2]> install Getopt::Long    [Perl에서 명령줄 옵션을 쉽게 처리할 수 있도록 해주는 모듈]

    cpan [3]> install Net::CIDR::Lite

    [Perl에서 CIDR(클래스 없는 도메인 라우팅) 블록을 처리하고, IP 주소가 특정 CIDR 블록에 속하는지 여부를 효율적으로 확인할 수 있는 모듈]

     

    ③ 다른 방법「② 과정을 보여주기 위함으로 편한 방법을 선택」

    [root@]# dnf install perl-App-cpanminus

    perl-App-cpanminus(Cpanm)는 Perl-CPAN보다 경량화된 도구로, 설정 없이 빠르게 Perl 모듈을 설치하고 관리할 수 있는 툴입니다. Cpanm이 더 가볍고 사용이 간편한 반면, Perl-CPAN은 더 많은 기능을 제공합니다.

    [root@]# cpanm install NetAddr::IP

    [root@]# cpanm Net::CIDR::Lite

    [root@]# cpanm Text::CSV_XS

     

    ④ 세 번째 컨버터 스크립트 실행

    [root@]# cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv | ./20_convert_geolite2 /tmp/CountryInfo.txt > GeoLite2-Country.csv    [전체 한 줄]

    ※ IP4, IP6 정보와 국가 코드 정보를 하나의 CSV 파일로 컨버터 하는 작업

     

    ⑤ 최종 빌드 작업

    [root@]# /usr/libexec/xtables-addons/xt_geoip_dl

    [root@]# /usr/libexec/xtables-addons/xt_geoip_build GeoLite2-Country.csv 

    ※ xtables-addons를 Dnf(yum)으로 RPM 자동 설치했다면 기본 경로는 위와 같습니다. 소스로 설치했다면 설치한 소스 경로에서 위 빌드 명령어 실행 하면 됩니다.

     

    ⑥ xt_geoip 모듈 적용을 위한 마무리

    [root@]# mkdir -p /usr/share/xt_geoip    [폴더 경로 생성]

    [root@]# mv ./*.iv* /usr/share/xt_geoip/    [작업했던 경로에서 진행]

    [root@]# modprobe xt_geoip    [모듈 (재)로드]

    [root@]# modinfo xt_geoip    [모듈 확인]


    ◇ IPtables 방화벽에 GeoIP 규칙 적용 방법

    이제 「IPtables」 방화벽에 국가 코드로 차단/허용 설정이 가능해졌습니다. 국가 코드는 알파벳이나 숫자로 된 지역 코드로, 예시로 한국「KR」, 미국「US」, 일본「JP」등으로 표시가 가능합니다.

    ※ 기본 설정 파일 경로 : /etc/sysconfig/iptables

     

    ① 전부 허용하고 특정 국가만 차단할 경우

    -A INPUT -m geoip --src-cc RU -j DROP    [러시아만 차단]

    -A INPUT -m geoip --src-cc RU,CN,NL -j DROP    [복수일 경우, 러시아/중국/네덜란드만 차단]

     

    ② 전부 차단하고 특정 국가만 허용할 경우

    -A INPUT -m geoip --src-cc KR -j ACCEPT    [한국만 허용]

    -A INPUT -m geoip --src-cc KR,US,JP -j ACCEPT    [복수일 경우, 한국/미국/일본만 허용]

    [root@]# systemctl restart iptables    [재시작 적용]

    [root@]# iptables -nL    [방화벽 규칙 확인]

    Chain INPUT (policy ACCEPT)    [표시 예시]
    target        prot opt  source        destination
    ACCEPT      0   --   0.0.0.0/0      0.0.0.0/0       -m geoip --source-country KR,US,JP

    ※ IPtables 특성상 위에서부터 순서대로 규칙 적용(보안상 맨 위에 설정하는 게 좋음)

    DROP은 해당 트래픽을 원천 차단, REJECT는 차단하지만 상대방에게 리턴 코드를 알려줌, 즉 차단되었다는 것을 알리기 때문에 보안적으로는 DROP으로 하는 게 좋음

     

    ③ 상황별 차단 및 허용 방법

    3-1 해당 국가를 차단하고 차단한 국가 특정 IP를 허용할 경우

    ※ 예시로 한국을 차단했지만 접근하려는 특정 한국 IP를 접근하게 하고 싶을 때 (표시는 사설 IP이지만 한국 IP라고 가정합니다)

    -A INPUT -s 192.168.0.1 -j ACCEPT    [한국 특정 IP 허용]

    -A INPUT -m geoip --src-cc KR -j DROP    [한국 차단]

     

    3-2 해당 국가를 차단했지만 특정 포트를 허용하고 싶을 경우

    -A INPUT -p tcp --dport 80 -j ACCEPT    [한국 IP 차단하더라도 해당 포트(80)로 접근 가능]
    -A INPUT -p tcp --dport 443 -j ACCEPT    [한국IP 차단하더라도 해당 포트(443)로 접근 가능]

    -A INPUT -m geoip --src-cc KR -j DROP    [한국 차단]

     

    3-3 GeoIP 정책에 ! 사용하기

    -A INPUT -s 192.168.18.132 -j ACCEPT    [같은 내부 서버 사설 IP 허용]
    -A INPUT -s 192.168.18.1 -j ACCEPT    [같은 내부 사설 IP 허용 (VMware가 설치된 개인 PC 내부 사설 IP)]

    -A INPUT -m geoip ! --src-cc KR -j DROP    [한국을 제외한 모든 국가 차단, 한국만 허용한다는 의미]

    ※ 프로그래밍에서 느낌표「 ! 」는 반전의 의미가 있습니다. 또 특이한 점은 느낌표로 적용하게 되면 같은 사설 내부 구간도 허용을 하지 않습니다. SSH로 원격을 붙거나 같은 사설구간의 서버에서 통신 및 접근을 하기 위해서는 IP나 포트 허용이 필요합니다.

     

    이런 식으로 여러 방법으로 운영이 가능합니다.

    생각나는 게 있다면 계속 추가하겠습니다.

    ...


    최근에 특정 서버가 갑자기 부하가 심해서 로그 및 네트워크 추적을 해보니 특정 국가에서 유독 비정상적인 트래픽이 많이 유입이 되는 것을 확인하였습니다. GeoIP 적용을 하기 위해 평소대로 기존 매뉴얼을 보고 적용하는데 갑자기 잘 안 돼서 다시 한번 정리를 했네요. 이제 구 CentOS는 EOL도 완전히 끝나서 점점 예외 상황이 많이 발생하네요. 그래서 그런지 서버를 새로 구축하는 경우가 많아지는 것 같습니다.

     

    GeoIP Databases가 완벽하지는 않지만 거의 80~90% 정도는 국가별로 커버가 가능합니다. 국가별로 IP를 할당받는 게 쉽게 바뀌지는 않지만 돌아가면서 사용을 하기에 적어도 1년에 한 번 정도는 업데이트를 하는 게 좋습니다. 위에 작업을 자동 업데이트 하는 스크립트를 작성하여 Crontab에 등록하면 더 좋겠죠? 현재 완성된 부분까지 작성하여 먼저 포스팅을 올려봅니다. 아직 완성본은 아니므로 차근차근 업데이트를 하도록 하겠습니다.

    Designed by JB FACTORY