[linux] 리눅스 UFW 방화벽 기초 사용법 - UFW 설치, 규칙 추가/삭제, 로깅 팁

UFW는

UFW는 Uncomplicated FireWall의 약자입니다. 말 그대로 "어렵지 않은 방화벽"이라는 뜻으로 설정 방법이 다소 어렵고 전문적인 iptables 방화벽을 대신해서 설정과 사용을 최대한 쉽게 단순화 한 방화벽입니다.

우분투는 UFW를 기본 방화벽 프로그램으로 사용합니다.

윈도우 방화벽 프로그램처럼 프로그램을 방화벽에 직접 등록할 수 있어 직관적이고 이해하기가 쉬운 것이 장점입니다.

윈도우11 방화벽

UFW에서 방화벽 규칙 추가하면 IPv4와 IPv6 규칙을 자동으로 추가해 주는 것도 복잡한 설정을 어려워하는 리눅스 사용자에게는 쉽게 다가오는 UFW 방화벽의 장점입니다.

물론 이런 직관적이고 쉬운 사용 방법은 정밀한 방화벽 설정을 할 수 없거나 어렵게 하는 제약이 되기도 합니다.

보다 전문적이고 정밀한 방화벽 설정을 원하면 iptables 방화벽을 사용하면 되므로 ufw는 방화벽의 어려운 규칙 설정 보다는 쉽고 단순한 사용 방법에 초점을 맞춰서 사용하면 됩니다.

UFW 설치

터미널 커맨드라인에서 다음 커맨드를 입력합니다. 루트 권한이 없는 계정으로 설치하려면 sudo를 붙여서 루트 권한으로 설치해야 합니다.

sudo apt install ufw

ufw의 상태를 확인하는 커맨드는 다음과 같습니다.

ufw status

처음 설치 후에는 ufw 서비스가 실행되고 있지 않으므로 "Status: inactive" 메시지를 만나게 됩니다. ufw를 시작하고 종료하는 방법을 먼저 알아야 합니다.

UFW 서비스의 시작과 종료

UFW enable/disable

ufw는 enable/disable로 ufw 방화벽 서비스를 활성화/비활성화 합니다. ufw를 설치 후에는 "enable"로 방화벽 서비스를 활성화 해야 합니다. 활성화 된 UFW 방화벽은 다음번 부팅때부터는 자동으로 부팅과 함께 백그라운드로 실행됩니다.

$> ufw enable
Firewall is active and enabled on system startup

방화벽이 시작되었으므로 status 커맨드로 방화벽의 상태(active/inactive)와 등록 규칙을 확인해봅니다. 초기에는 등록된 규칙이 없으므로 방화벽의 실행 상태만 출력됩니다.

$> ufw status
Status: active

등록한 방화벽 규칙을 삭제하거나 제어하기 위해서는 해당 방화벽 규칙을 선택할 수 있어야 합니다. ufw는 등록한 방화벽 규칙을 번호로 식별합니다. 규칙의 일련 번호를 확인하려면 다음처럼 "numbered"를 커맨드 추가 옵션으로 사용합니다.

UFW 규칙 목록 왼쪽의 숫자로 표시되는 것이 방화벽 규칙을 식별하는 일련 번호입니다.

$> ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] Nginx Full                 ALLOW IN    Anywhere
[ 3] 3306/tcp                   ALLOW IN    Anywhere
[ 4] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 5] Nginx Full (v6)            ALLOW IN    Anywhere (v6)
[ 6] 3306/tcp (v6)              ALLOW IN    Anywhere (v6)

방화벽 서비스를 비활성화 할 때는 "disabled" 커맨드를 사용합니다. 즉시 방화벽 서비스가 정지되고 비활성화 되며, 다음 부팅 시부터 방화벽 서비스는 실행되지 않습니다.

ufw disable

UFW start/stop/restart

앞서 설명한 enable/disable은 UFW 방화벽 서비스를 활성호/비활성화 한다고 설명했습니다. 정확하게 말하면 enable은 start + 서비스 등록, disable은 stop + 서비스 제거입니다.

"서비스", 또는 데몬은 부팅될 때 프로그램이 백그라운드로 실행되어 항상 구동되고 있는 것을 말합니다. 여기서는 UFW 방화벽이 됩니다.

UFW에는 서비스 등록/제거 없이 방화벽을 시작/정지/재시작하는 커맨드가 별도로 있습니다. 각각 start/stop/restart 입니다.

커맨드 사용은 다음과 같습니다.

  • ufw start
  • ufw stop
  • ufw restart

이 커맨드들은 ufw enable로 서비스를 등록해서 활성화 된 상태일 때만 사용할 수 있습니다. 주의해야 합니다.

UFW 방화벽 규칙 추가

UFW 기본 정책 설정

UFW 방화벽의 기본 정책을 설정합니다. 방화벽 규칙에 없는 접속, 또는 연결 시도를 어떤 규칙으로 처리할 지를 지정합니다. 허용(ALLOW), 또는 차단(DENY) 중 한가지를 기본 정책으로 사용하게 됩니다.

안전한 보안을 위해 방화벽의 기본 정책은 "차단"이 기본 설정 값이어야 합니다.

기본 정책을 허용으로 설정하면 별도의 방화벽 규칙으로 차단하지 않는 한, 모든 트래픽을 허용합니다. 공개된 서버를 운영할 때 이런 허용 기본 정책은 방화벽이 없는 것과 마찬가지가 됩니다.

방화벽 기본 정책은 default 커맨드를 사용합니다.

ufw default deny

기본 정책을 인바운드(들어오는 트래픽)와 아웃바운드(나가는 트래픽)을 구분해서 설정할 수도 있습니다.

앞서 설명했듯인 인바운드는 기본 정책이 항상 차단이어야 합니다. 다만 나가는 트래픽은 운영상의 편의 또는 외부 서비스에 접속하기 위해 기본 정책을 허용하는 것도 가능합니다.

설정 값은 인바운드가 "incoming", 아웃바운드가 "outgoing"입니다.

  • ufw default deny incoming
  • ufw default allow outgoing

접속 소스(From)와 서비스 포트(To)로 규칙 추가

접속 소스(From)은 외부에서 서버로 접속하는 대상을 가리킵니다. IP로 식별을 하고 IPv4, IPv6 프로토콜로 각각 지정할 수 있습니다. UFW로 인바운드 규칙(외부에서 서버로 접속)을 추가할 때는 from 지시자로 인바운드 접속 소스를 표시합니다. UFW 상태 보기를 하면 From 컬럼에 표시됩니다.

ufw allow from 192.168.0.11

서비스 포트는 서버의 포트, 또는 서비스하고 있는 프로그램이 사용하는 포트를 말합니다. 서버에서 웹사이트를 서비스하면 80포트와 443포트가 기본 서비스 포트가 됩니다.

예를 들어 서버 입장에서 외부에서 443 포트로 접속하는 것을 허용하려면 다음과 같이 규칙을 작성합니다.

ufw allow 443/tcp

두 가지를 조합해서 접속하려는 특정 대상에 대해서 특정 포트를 개방/차단할 수 있습니다.

기본적인 사용 커맨드 문법은 다음과 같습니다.

ufw allow/deny from [외부 IP] to any port [서버 포트]

3306 포트는 MySQL의 접속 포트입니다. 원격으로 DB에 접속하려는 외부 접속 IP를 제한해서 MySQL로 무단 접속하는 것을 차단할 수 있습니다.

$> ufw allow from 192.168.0.11 to any port 3306
Rule added
$> ufw status
Status: active

To                         Action      From
--                         ------      ----
3306                       ALLOW       192.168.0.11

접속 허용(ALLOW)과 접속 거부(DENY)

접속을 허용하는 것은 "allow", 접속을 차단하는 것은 "deny"로 규칙 커맨드를 사용합니다.

기본 정책을 차단으로 설정했을 경우 "allow"로 허용 규칙을 추가해서 필요한 서비스 접속만 가능하도록 합니다.

기본 정책을 거부로 했어도 "deny"로 규칙을 추가할 경우가 있습니다.

예를 들어 서브넷 마스크로 IP 범위를 허용했지만 특정 IP는 외부 사용자용으로 허용한 IP여서 보안상 서버에 접속하는 것을 차단할 필요가 있습니다. 이럴 때 허용 규칙을 먼저 추가한 후, 특정 IP만 차단하는 차단 규칙을 추가해서 등록하면 접근 제어를 정확하게 할 수 있습니다.

허용과 차단 규칙을 모두 작성할 때는 순서에 주의해야 합니다.

IP를 접속 허용 규칙에 추가

특정 IP에서 서버로 연결하는 모든 연결을 허용하고 싶을 때 "ufw allow from IP주소" 포맷으로 규칙을 추가합니다.

$> ufw allow from 192.168.0.11
Rule added

추가한 규칙이 방화벽에 등록되었는지 "status" 커맨드로 확인합니다.

$> ufw status
Status: active

To                         Action      From
--                         ------      ----
Anywhere                   ALLOW       192.168.0.11

Anywhere는 To와 From 컬럼에 모두 나올 수 있으며, "전체"를 의미합니다. 즉 102.168.0.11 IP에서 오는 모든 트래픽은 전체를 허용(ALLOW) 한다는 규칙이 됩니다.

IP 범위를 허용하려면 다음처럼 서브넷 마스크로 IP 범위를 허용/거부 대상으로 설정할 수 있습니다.

ufw allow from 192.168.0.0/24

192.168.0.0/24 는 192.168.0.0 ~ 192.168.0.255 범위의 IP가 추가하는 방화벽 규칙의 영향을 받게됩니다.

프로그램 파일로 방화벽 규칙 추가

UFW는 프로그램 단위로 방화벽 규칙을 설정할 수 있습니다. 윈도우 운영체제의 프로그램 실행 파일 단위 방화벽 관리 기능과 동일합니다.

SSH를 방화벽 허용 규칙에 추가해보겠습니다. 규칙이 추가되면 IPv4, IPv6 규칙 두 개가 생성됩니다.

$> ufw allow ssh
Rule added
Rule added (v6)
$> sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)

규칙을 삭제할 때도 프로그램/서비스 이름으로 삭제할 수 있습니다.

ufw delete allow ssh

UFW에서 사용하는 서비스 이름은 아무거나 쓸 수 있는 것은 아니며, 잘 알려진 몇몇 서비스들만 이름이 등록되어 있고, 그 외에는 미리 작성해서 저장한 프로필을 통해 이름으로 UFW 방화벽 규칙의 프로그램 이름으로 사용하게 됩니다.

UFW를 설치하면 미리 작성 된 몇 개의 프로필이 있으므로 이 파일을 참조해서 새 프로그램 이름을 프로필로 등록할 수 있습니다. 사전 작성된 프로필들은 다음 경로에서 확인할 수 있습니다.

/etc/ufw/applications.d

사전 등록된 프로필 중에는 nginx가 있으며, 등록된 프로필을 사용해서 다음처럼 UFW 방화벽 허용 규칙을 추가할 수 있습니다.

$> ufw allow 'Nginx Full'
Rule added
Rule added (v6)
$> sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
CUPS                       ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
CUPS (v6)                  ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)

윈도우 방화벽처럼 방화벽 규칙 추가를 할 수 있는 프로그램 목록을 확인하려면 "app list" 커맨드로 확인할 수 있습니다. 현재 호스트에 패키지로 설치한 프로그램 목록을 출력합니다.

$> ufw app list
Available applications:
  CUPS
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
  Postfix
  Postfix SMTPS
  Postfix Submission

웹 서버 패키지는 HTTP(80), HTTPS(443)를 구분해서 설치하거나 두 포트를 모두 방화벽 규칙에 추가(Full) 할 수 있으므로 구분해서 사용할 수 있습니다.

Nginx는 Nginx Full, Nginx HTTP, Nginx HTTPS로 구분을 하고, 아파치 웹서버는 Apache, Apache Secure, Apache Full로 구분을 합니다.

Nginx Full, Apache Full 로 방화벽 규칙을 설정하는 것을 권장합니다.

ICMP 프로토콜 차단

처음 UFW 방화벽이 설치되면 기본 설정으로 핑테스트(ICMP)가 개방되어 있습니다. 핑테스트는 호스트의 존재를 확인하는 좋은 수단이지만, 해킹 시도를 위해 해당 호스트가 존재하는지를 확인하는 용도로도 악용됩니다.

이미 안정화된 서비스를 유지하고 있어서 핑테스트를 할 필요가 없거나 개발용 서버같은 호스트들은 직접 서버의 상태를 확인할 방법이 여러가지 있기 때문에 굳이 핑테스트를 켤 필요가 없습니다.

ICMP 프로토콜의 모든 타입을 차단하려면 UFW 설정 파일을 수정해야 합니다.

/etc/ufw/before.rules 파일을 텍스트 편집기에서 연 후 다음 행들을 찾습니다.

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

끝 부분의 ACCEPT를 DROP으로 변경한 후 저장합니다.

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j DROP
-A ufw-before-input -p icmp --icmp-type time-exceeded -j DROP
-A ufw-before-input -p icmp --icmp-type parameter-problem -j DROP
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP

UFW 버전에 따라 행 수는 약간 다를 수 있습니다. INPUT 관련 행들만 수정하면 됩니다.

핑테스트가 차단되면 다른 호스트에서 핑을 보냈을 때 시간이 만료되어 핑테스트 반응을 얻지 못하게 됩니다.

UFW 규칙 적용

방화벽 규칙을 추가/변경 후에는 방화벽을 재로딩해야 변경한 규칙이 적용됩니다. UFW 방화벽을 재로딩하는 커맨드는 다음과 같습니다.

ufw reload

UFW 방화벽 규칙 삭제

방화벽 규칙 삭제는 delete 커맨드로 삭제합니다. 커맨드 뒤에 추가했던 규칙을 작성하면 해당 규칙이 삭제됩니다.

ufw delete [방화벽규칙]

앞서 추가했던 443 포트 접속을 허용하는 방화벽 규칙을 삭제할 때는 다음과 같이 작성합니다. 추가했던 규칙을 delete 커맨드 뒤에 그대로 작성하면 됩니다.

ufw delete allow 443/tcp

방화벽 규칙을 삭제하는 방법은 두 가지가 있습니다.

  • 추가한 규칙을 기준으로 삭제
  • 규칙 목록의 번호를 기준으로 삭제

UFW는 방화벽에 규칙을 추가할 때 IPv4와 IPv6 규칙을 모두 추가합니다. 규칙 기반으로 삭제하면 추가했던 규칙들이 모두 삭제됩니다. 추가한 방화벽 규칙을 개별적으로 삭제하거나, 일부만 삭제하고 나머지 규칙을 유지하려면 목록의 번호를 기준으로 삭제해야 합니다.

먼저 방화벽 규칙의 일련 번호를 확인합니다. 왼쪽 끝의 1부터 시작하는 번호가 일련 번호입니다. 일련 번호는 고유한 숫자가 아니며, 방화벽 규칙이 추가되거나 삭제될 때마다 변경됩니다. 따라서 방화벽 규칙을 삭제하기전 삭제하려는 일련 번호가 몇 번인지 status 명령어로 확인한 후 삭제해야 합니다.

ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] Anywhere                   ALLOW IN    192.168.0.11
[ 2] 3306                       ALLOW IN    Anywhere
[ 3] 3306 (v6)                  ALLOW IN    Anywhere (v6)

방화벽 규칙을 추가하면 IPv4와 IPv6가 각각 규칙으로 추가됩니다. 포트 3306 허용 규칙 중 IPv6 규칙인 3번만 삭제하려면 다음과 같이 커맨드를 실행합니다.

$> sudo ufw delete 3
Deleting:
 allow 3306
Proceed with operation (y|n)? y
Rule deleted (v6)
$> sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
Anywhere                   ALLOW       192.168.0.11
3306                       ALLOW       Anywhere

프로그램으로 등록한 규칙은 마찬가지로 추가했던 프로그램 추가 규칙 그대로를 작성하면 삭제됩니다. SSH 프로그램 이름으로 접속 허용한 방화벽 규칙은 다음과 같이 삭제합니다.

$> ufw delete allow ssh
Rule deleted
Rule deleted (v6)
$>

UFW 방화벽 초기화

방화벽을 설치 초기 상태로 초기화 할 때는 "reset" 커맨드를 사용합니다. 실제 서비스 중인 서버의 방화벽을 초기화 할 때는 보안 위협에 노출되므로 신중하게 결정해야 합니다.

$> sudo ufw reset
Resetting all rules to installed defaults. This may disrupt existing ssh
connections. Proceed with operation (y|n)? y
Backing up 'user.rules' to '/etc/ufw/user.rules.20240206_162158'
Backing up 'before.rules' to '/etc/ufw/before.rules.20240206_162158'
Backing up 'after.rules' to '/etc/ufw/after.rules.20240206_162158'
Backing up 'user6.rules' to '/etc/ufw/user6.rules.20240206_162158'
Backing up 'before6.rules' to '/etc/ufw/before6.rules.20240206_162158'
Backing up 'after6.rules' to '/etc/ufw/after6.rules.20240206_162158'
$>

초기화 명령을 실행하면 "초기화를 하면 현재 연결된 SSH 연결이 끊어질 수 있다"는중요한 경고 메시지가 표시되고 초기화를 정말로 할지를 확인합니다.

중요한 메시지입니다.

원격 접속 상태에서 초기화를 하면, 방화벽의 기본 정책이 거부일 경우 SSH 원격 접속이 끊어지면서 다시 원격 접속을 할 수 없는 상태가 될 수 있습니다. 이 때 로컬 터미널 접속을 해서 방화벽을 재구성 할 수 없는 가상 호스팅 환경일 경우 서버에 아얘 접속할 수 없게될 수도 있습니다.

UFW 방화벽 로깅 관리

방화벽은 여러가지 선택이 가능하지만 한가지는 공통으로 반드시 사용해야 하는게 있는데 로그를 남기는 것입니다.

방화벽을 사용하는데 있어서 로깅은 무엇보다도 중요합니다.

방화벽에 어떤 접속 시도가 있고, 어떤 해킹 시도가 있는지 알아야 대응을 할 수 있고, 방화벽 규칙을 꾸준히 업데이트 할 수 있습니다.

FTP 포트인 21번 포트로 로그인 무작위 대입 트래픽이 장시간 발생한다면, 21번 포트로 접속을 시도하는 특정 IP을 거부(DENY) 설정을 해서 부정 접속 시도 자체를 원천 차단해야 합니다.

방화벽 로깅을 켜는 커맨드는 다음과 같습니다.

ufw logging on

로깅을 끌 때는 on을 off로 바꾸면 됩니다.

ufw logging off

UFW 로그 파일은 "/var/log/ufw.log" 파일에 저장됩니다. 이벤트가 많이 발생하면 방화벽 로그 파일도 같이 커지게 되므로 방화벽 로그 파일은 자주 모니터링을 해야 합니다.

기본 설정으로 UFW 방화벽 로그 파일은 일주일 단위로 파일이 새롭게 생성되며, 오래된 파일은 gzip으로 압축을 해서 보관합니다.

장기간 방화벽 로그를 방치하면 디스크 공간을 많이 차지하게 되므로 주기적으로 관리를 해야 합니다.

-rw-r-----   1 syslog        adm               961703  2월  6 23:44 ufw.log
-rw-r-----   1 syslog        adm              2077587  2월  3 23:59 ufw.log.1
-rw-r-----   1 syslog        adm               151139  1월 27 23:59 ufw.log.2.gz
-rw-r-----   1 syslog        adm               162070  1월 20 23:59 ufw.log.3.gz
-rw-r-----   1 syslog        adm               151177  1월 13 23:59 ufw.log.4.gz

UFW 방화벽 로그는 기본 값으로 시스템 로그에 함께 로그가 남게 됨니다.

  • /var/log/syslog
  • /var/log/kern.log

syslog 파일을 확인하면 다음처럼 UFW 로그들이 다른 시스템 로그들과 함께 남겨집니다. kern.log 파일에도 같은 로그가 남습니다.

Feb  6 23:33:20 apost kernel: [950568.352862] [UFW BLOCK] IN=wlan0 OUT= MAC=01:00:5e:00:00:01:58:86:94:3c:05:1b:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0xC0 TTL=1 ID=63086 PROTO=2
Feb  6 23:33:21 apost kernel: [950568.967254] [UFW BLOCK] IN=wlan0 OUT= MAC=01:00:5e:00:00:fb:20:2b:20:64:c1:53:08:00 SRC=192.168.0.12 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=61216 PROTO=2
Feb  6 23:34:21 apost kernel: [950628.770555] [UFW BLOCK] IN=wlan0 OUT= MAC=dc:a6:32:ef:d0:42:58:86:94:3c:05:1b:08:00 SRC=91.92.251.164 DST=192.168.0.10 LEN=44 TOS=0x00 PREC=0x00 TTL=234 ID=40608 PROTO=TCP SPT=10000 DPT=22 WINDOW=1024 RES=0x00 SYN URGP=0
Feb  6 23:35:20 apost kernel: [950688.367055] [UFW BLOCK] IN=wlan0 OUT= MAC=01:00:5e:00:00:01:58:86:94:3c:05:1b:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=28 TOS=0x00 PREC=0xC0 TTL=1 ID=516 PROTO=2
Feb  6 23:35:23 apost kernel: [950691.440145] [UFW BLOCK] IN=wlan0 OUT= MAC=01:00:5e:00:00:fb:20:2b:20:64:c1:53:08:00 SRC=192.168.0.12 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=61219 PROTO=2

중복 로그를 차단하려면 rsyslog 데몬의 방화벽 설정 파일을 수정해야 합니다. 다음 파일을 텍스트 편집기에서 엽니다. UFW 방화벽 로그 관련 설정 파일입니다.

/etc/rsyslog.d/20-ufw.conf

설정 파일 내용은 다음과 같습니다.

# Log kernel generated UFW log messages to file
:msg,contains,"[UFW " /var/log/ufw.log

# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
#& stop

영문으로 자세하게 설명이 되어있지만 간단하게 설정 파일 맨 끝 줄의 #을 삭제하면 "/var/log/ufw.log", "/var/log/kern.log" 파일에 UFW 방화벽 로그가 남지 않게 됩니다.

"#& stop"에서 맨 앞의 #을 지운 후 파일을 저장하고 편집기를 빠져나옵니다. 이제 rsyslog 데몬을 재 실행해서 변경된 환경 설정이 반영되도록 합니다.

sudo systemctl restart rsyslog