본문 바로가기
리눅스

Uncomplicated Firewall 특정 국가 ip 차단

by 다움위키 2021. 11. 3.

실제로 특정 포트를 통해 하루에도 수백 번의 불법적인 접근 시도가 있습니다. 모든 포트에 걸쳐서는 아마도 하루 동안에도 수천 번의 불법적인 접근 시도가 있다고 보입니다.

이런 상황에서, 특정 국가에서 지속적으로 불법적인 접근 시도가 계속되고 해당 국가에서 자신의 서비스를 이용할 가능성이 없으면, 결국은 해당 국가의 ip 블록 전체를 차단하는 것으로 결론이 납니다.

인터넷과 마찬가지로 여기에서 제공하는 몇 가지 스크립트와 방법이 알려져 있지만, 해당 국가의 ip 전체가 만 줄 이상이 되면, ufw 규칙을 삽입하고 지우기 위해, 너무 많은, 예를 들어, 10시간 이상이 걸리기도 합니다.

어떤 국가는 차단해야 할 ipv4와 ipv6를 합쳐서 거의 사만 줄에 이르는 ip 블록을 차단해야 하는데, 끝까지 해보지는 않았지만, 적어도 하루, 즉 24시간 이상이 걸립니다.

게다가, 이런 작업을 매월 초에 계속해야 하니, 너무나 귀찮습니다.

이제, 리눅스에 설치된 기본 도구와 vim을 사용하여, 이 작업을 대체해 보려고 합니다.

Using linux command and vim

먼저, 차단해야 할 나라의 ip 블록을 cidr 형식으로 ipv4, ipv6에 대해, 각각, ipv4.txt, ipv6.txt로 저장합니다. 물론, 파일 이름이 다르지만, 압축 해제하고, 이 이름으로 바꾸시고 진행하십시오!!

두 파일 각각 아래와 같이 복사합니다:

  • echo ipv4.tmp1 ipv4.tmp2 | xargs -n 1 cp ipv4.txt
  • echo ipv6.tmp1 ipv6.tmp2 | xargs -n 1 cp ipv6.txt

ipv4.tmp1 파일을 vim으로 열어서 다음 과정을 진행하십시오. Vim은 파일을 열면, 명령 모드로 열리므로, ⇧ Shift+:를 눌러서 아래의 내용을 그래도 입력하십시오.

줄의 시작 부분에 삽입 (Vim)

  • %s/^/### tuple ### deny any any 0.0.0.0\/0 any /

줄의 끝 부분에 삽입 (Vim)

  • %s/$/ in/

ipv4.tmp2 파일을 vim으로 열어서 다음 과정을 진행하십시오:

줄의 시작 부분에 삽입 (Vim)

  • %s/^/-A ufw-user-input -s /

줄의 끝 부분에 삽입 (Vim)

  • %s/$/ -j DROP/

두 파일을 줄 마다 합치기

  • paste -d "\n" ipv4.tmp1 ipv4.tmp2 > ipv4.rules

그런-다음 해당 ipv4.rules 파일의 내용을 복사해서, /etc/ufw/user.rules의 ### RULES ###### END RULES ### 사이에 삽입합니다.

같은 방법을 ipv6.txt에 계속하십시오.

ipv6.tmp1 파일을 vim으로 열어서 다음 과정을 진행하십시오.

줄의 시작 부분에 삽입 (Vim)

  • %s/^/### tuple ### deny any any ::\/0 any /

줄의 끝 부분에 삽입 (Vim)

  • %s/$/ in/

ipv6.tmp2 파일을 vim으로 열어서 다음 과정을 진행하십시오.

줄의 시작 부분에 삽입 (Vim)

  • %s/^/-A ufw6-user-input -s /

줄의 끝 부분에 삽입 (Vim)

  • %s/$/ -j DROP/

두 파일을 줄 마다 합치기

  • paste -d "\n" ipv6.tmp1 ipv6.tmp2 > ipv6.rules

그런-다음 해당 ipv6.rules 파일의 내용을 복사해서, /etc/ufw/user6.rules의 ### RULES ###### END RULES ### 사이에 삽입합니다.

여러 국가를 차단해야 하면, 위 과정을 나라별로 수행한 후에, ALLOW 규칙을 마지막에 입력하십시오. 같은 작업을 실제로 해보니, 10분 정도면 충분합니다!!

Other mothod

새로운 방법이 속도 면에서 유리하긴 하지만, 여전히 전체를 입력하는 데 몇 시간이 걸립니다. 그러나, ipv4만 올릴 때에는 크게 시간이 많이 걸리지는 않으며, 7천개 정도를 1시간 내에 입력해 줍니다.

아래 방법은 속도가 너무 느려서, 특정 국가의 ipv6 줄이 3만줄이 되니, 입력 또는 삭제에 거의 하루가 걸리는 문제가 생겼습니다. 새로운 방법이 필요해 보입니다. 다음 과정으로 진행해 보겠습니다.

  • 아래와 마찬가지로 두 개의 파일을 받습니다.
  • 파일 위의 몇 줄의 주석을 삭제합니다.
  • 이전의 규칙을 전부 지웁니다:
  • sudo ufw --force reset
  • sudo ufw enable

ipv4를 먼저 삽입합니다:

  • while read line; do sudo ufw deny from $line; done < ipv4.txt

이 작업이 끝난 후에, ipv4 ALLOW 규칙을 이전의 백업된 파일로부터 복사를 합니다: ipv6 입력 중에 명령을 내려도 됩니다.

  • sudo systemctl restart ufw

ipv6를 삽입합니다.

  • while read line; do sudo ufw deny from $line; done < ipv6.txt
  • sudo systemctl restart ufw

확인해 봅니다.

  • sudo ufw status numbered

그리고, 원하는 규칙을 입력합니다.

위와 같이 처리하면, 다운 타임을 줄이기 위해, 룰을 지울 때에는 다음 방법을 이용할 수 있습니다:

  • while read line; do sudo ufw delete deny from $line; done < ipv4.txt
  • while read line; do sudo ufw delete deny from $line; done < ipv6.txt

Older

때때로 열려 있는 서비스로 인해, 관리자가 모르는 사이에 서버가 의도치 않은 행위를 하게 되는 경우가 있습니다. 예를 들어, Postfix (software)가 스팸 릴레이에 이용되는 경우, Fail2ban에서 기록된 sshd에 대한 해킹 정보, 등에서 볼 수 있습니다.

어쨌든, 현재의 서비스의 대상이 특정 국가에 한정되면, 해당 국가를 대상으로 서비스를 운영할 수 있지만, 그렇지 않다면, 해킹 시도가 많은 특정 국가의 IP 대역 전부를 차단할 수 있습니다. 이 기사는 특정국가의 IP 대역 전체를 UFW를 이용해서 차단하는 방법을 소개합니다.

먼저 해당 국가의 IP를 CIDR 포맷으로 다운로드합니다. 이때, IPv4와 IPv6를 각각 받습니다.

각 줄을 UFW 룰로 추가하는 파이썬 스크립트입니다.

#!/usr/bin/python

import os

cidr_old = ''
cidr_new = 'ipv4-20200329.txt'
number = 123

if cidr_old:
    with open(cidr_old) as f:
        for i, line in enumerate(f, start=1):
            if not line.startswith('#') or not line.strip():
                print('{} = {}'.format(i, line.strip()))
                os.system('ufw delete deny from {} to any'.format(line.strip()))
else:
    print('file not specified')

if cidr_new:
    with open(cidr_new) as f:
        for i, line in enumerate(f, start=1):
            if not line.startswith('#') or not line.strip():
                print('{} = {}'.format(i, line.strip()))
                os.system('ufw insert {} deny from {} to any'.format(number, line.strip()))
else:
  print('file not specified')

위 스크립트에서 주요 변수 설명은 다음과 같습니다.

  • cidr_old: 이전 달의 CIDR 포맷 파일
  • cidr_new: 이번 달의 CIDR 포맷 파일
  • number: 규칙을 추가할 때, 시작 위치

IP 대역이 매달 바뀌므로, 이전 달에 추가한 규칙을 제거하고, 이번 달의 대역을 규칙으로 추가하는데, 처음에는 cidr_old를 비워둡니다.

또한, 기존의 규칙은 적어도 하나는 존재해야 합니다. 규칙이 완전히 비어 있으면, 다음 오류가 발생합니다. 마찬가지로 IPv6의 규칙도 반드시 하나 이상 존재해야 합니다.

  • ERROR: Invalid position '1'

파일은 2개를 만들어서, 하나는 ipv4를 입력하고, 다른 하나는 ipv6를 입력하는 것이 좋습니다. 이전 달의 입력을 지우고, 새로운 대역을 추가하기 위해, 이전 달에 입력한 위치를 정확히 알고 있어야 합니다.

  1. 이때, IPv4는 기존의 적당한 위치, 예를 들어, 보통 DENY, ALLOW 순이므로, ALLOW의 첫 번째 룰의 숫자를 적습니다.
  2. 그런 다음 IPv6는 위의 과정이 끝난 후에 IPv6의 적당한 위치에 추가할 수 있는데, 적어도 하나의 IPv6 규칙이 존재해야 오류가 생기지 않습니다.
  3. 최초 이후에는 IPv6를 지우고, IPv4를 지우고 (앞의 두 프로세스는 서로 바뀌어도 상관 없을 것으로 보입니다), IPv4를 입력하고, IPv6를 입력하는 순서로 진행하는 것을 추천합니다.

실행은 다음입니다.

  • sudo python ban.py

마지막으로, 매달 IP 대역의 업데이트를 하기 전에 변경된 대역이 있는지 확인하는 과정이 필요할 수 있습니다. 새로운 CIDR 파일, 예를 들어 ipv4-20200401.txt, ipv6-20200401.txt로 저장합니다.

  • diff -urN ipv4-20200329.txt ipv4-20200401.txt > ipv4.diff
  • diff -urN ipv6-20200329.txt ipv6-20200401.txt > ipv6.diff

차이 파일에 내용이 있으면, 업데이트를 진행하고, 그렇지 않으면 업데이트를 할 필요가 없습니다.

External Resources