PC 상단에 공유기가 있다면 외부에서 들어오는 요청을 공유기 방화벽이 막아주기 때문에 그나마 안심인데, 인터넷 선을 직결시키는 조건이라면 방화벽을 필수적으로 설정해야 할 것입니다. 특히 서버로 활용한다면요.

우분투에서 밀고 있는 UFW 방화벽은 iptables가 복잡하다는 의견을 반영해서 만든 프로그램이라고 하는데, 초보자인 저는 UFW도 낯설게 느껴지네요.ㅠㅠ

 

UFW에 대해서 검색해보면 ①포트 기준으로 관리하는 법, ②서비스 기준으로 관리하는 법, ③IP주소/서브넷 기준으로 관리하는 법을 순서대로 소개하는 경우가 많은데, 우분투 공식 문서(UFW 항목)에서도 이 순서대로 소개하다보니 우분투 코리아 위키를 비롯한 대부분의 문서들이 같은 흐름을 취하는 경향이 있는 것 같습니다.

원조 방화벽인 iptables가 포트 기반으로 차단/허용하는 방식이니까 UFW 문서도 포트 기반 설정을 먼저 설명하는 게 이해가 되긴 합니다. 하지만 개별 패키지들(예 : ssh, Apache2, Nginx 등)의 설정파일에서 포트를 바꿨을 때 방화벽 포트도 수동으로 바꿔야 한다는 점이 저는 부담스러웠습니다.

 

만약 서비스명으로 UFW에 차단/허용을 등록해 놓으면 /etc/ssh/sshd.conf 파일, /etc/apache2/ports.conf 파일, /etc/nginx/sites-enabled/ 등등 개별 패키지 설정 파일에서 포트를 바꿨을 때 UFW에서 자동으로 인식하고 바뀌지 않을까요?

서비스명으로 우선 UFW에 등록하고 부족한 부분을 포트 기준으로 관리하는 식으로 대응하면 관리가 수월하지 않을까 싶어서 한 번 시도해 봤습니다.

 

의식의 흐름에 따른 UFW 설정 과정. 설명해 볼게요. ^^

 

1. UFW 상태 확인, UFW 켜기

UFW 상태 확인 명령어sudo ufw status 입니다.

우분투를 처음 설치하면 UFW 방화벽이 내려가 있는 게 기본 설정입니다.

 

sudo ufw enable

이라고 입력해서 UFW를 켭니다. (UFW 끄는 명령어sudo ufw disable)

스샷의 경고에서 확인할 수 있듯이, 원격 접속 상태에서 UFW 켰을 때 SSH포트를 안 열고 재부팅하면 망하는 겁니다(접속 불가).

UFW 상태 확인 명령어(sudo ufw status verbose)를 쳐보면... 들어오는 패킷은 전부 거부(deny) / 나가는 패킷은 전부 허용(allow) / 라우팅은 disabled 상태인 것을 알 수 있습니다(기본값). 개별 포트 허용은 하나도 안 되어 있네요.

기본값을 기준으로 한다면 들어오는 패킷 중에서 원하는 부분만 개방하는 식으로 설정하면 수월하겠군요!

 

▼ 만약 UFW 설정이 꼬였다면 언제든지 초기화 명령을 입력해서 처음부터 다시 설정 가능합니다.

UFW 설정 초기화 명령어sudo ufw reset 입니다.

초기 상태로 돌아가니까, 모든 설정이 지워지면서 UFW는 비활성화 되겠죠?

 

2. 서비스 이름으로 UFW 허용 목록 등록하기

각설하고, SSH 서비스부터 허용해야 불상사를 막을 수 있겠네요.

UFW 허용 서비스 등록 명령어는 "sudo ufw allow 서비스명 comment '메모'" 형식입니다(comment는 주석 기능으로, 선택사항임. 작은따옴표는 comment에 띄어쓰기를 넣어 구성했다면 반드시 입력.).

만약 UFW 기본 설정이 들어오는 패킷 전부 허용(allow)이라면 UFW 거부 서비스 등록 명령어(sudo ufw deny 서비스명)를 입력해야겠죠?

 

sudo ufw allow ssh comment 'ssh'

입력 후에 sufo ufw status 로 확인해보니, 서비스명으로 등록되지 않고 포트로 등록됐네요??

 

미심쩍어서 https://help.ubuntu.com/community/UFW 에 나온 우분투 서비스 목록 확인 명령어(less /etc/services)를 입력해봤는데...

 

▲ systemd에 실제로 등록된 서비스의 설정파일에서 제어하는 포트가 아닌, /etc/services 파일에 적혀있는 서비스명에 매칭된 포트를 UFW에 등록하는 식으로 처리하는 것 같네요.

예를 들어 Nginx에서 서버블록 설정 파일로 webdav용 포트를 하나 열었는데 해당 포트를 /etc/services에 등록하지 않았다!! 그러면 /etc/services에 webdav 라는 서비스명과 webdav용 포트가 없기 때문에 UFW에 webdav라는 서비스명으로 포트를 등록하는 것이 불가능한 겁니다.

(참고로 /etc/services에 포트와 서비스가 존재하는지를 빠르게 확인하려면 "less /etc/services | grep 포트명(또는 서비스명)" 형식으로 명령어를 입력해보면 됩니다.)

 

▲ 서비스 이름으로 UFW 등록을 시도하더라도 실제로 기록되는 것은 "포트/프로토콜"의 형태이고(스샷 참고), UFW에서 서비스명이 안 보이기 때문에 /etc/services 파일의 포트/프로토콜 리스트의 변화를 자동으로 감지+반영하지 못할 것 같았습니다.

실제로 테스트해보니 추측이 맞더군요. UFW 허용 목록을 제외한 각종 설정에서 SSH 포트를 바꿔봤는데 UFW에서 알아채지 못하고 22번 포트만 연 채로 기다림;;; 당연히 원격 접속 불가. 수동으로 UFW에서 다른 포트를 등록 → sshd.conf 파일에서 포트 변경 후 SSH 서비스 재시작 → 22번 포트 삭제하는 과정을 거쳐야 했지요.

그렇다고 /etc/services 에 있는 서비스명과 우리가 실제적으로 많이 쓰는 sudo service --status-all | grep '+'(또는 systemctl list-units --type=service) 라는 서비스 목록 확인 명령어에서 나오는 서비스 이름이 일치하는 것도 아니고.

 

결국 UFW 허용목록 등록을 서비스 이름으로 하는 것은 유의미한 편의성이 없는 방식이라는 결론을 내렸습니다. /etc/services 파일을 적극적으로 이용할 줄 아는 분들께만 편리할 것 같습니다.

 

3. 포트/프로토콜 형식으로 UFW 허용 목록 등록하기

어차피 포트/프로토콜 형식으로 전환되어 등록된다면 사람이 수동으로 포트/프로토콜 형식의 허용 목록을 등록/삭제하는 방식이 효과적이지 않겠습니까? 우분투 공식 문서(UFW 항목)에서 제일 앞쪽에서 소개하는 방식이니 권장한다고 받아들여도 될 것 같고요.

 

우분투가 듣고 있는(LISTEN) 포트들을 확인하는 명령어(sudo netstat -atulpvn)로 프로그램 이름, 포트, 프로토콜을 확인.

UFW 허용 포트 등록 명령어(sudo ufw allow 포트/프로토콜 comment '메모')를 입력하면 즉시 등록됩니다.

(만약 UFW 기본 설정이 들어오는 패킷 전부 허용(allow)이면 거부 등록 명령어(sudo ufw deny 포트/프로토콜)를 입력해야겠죠?)

TCP, UDP 상관 없이 허용하려면 프로토콜을 빼면 되겠지요? (스샷 참고)

등록 명령에 allow 라고 적었지만 정확하게 쓰면 allow in 입니다(스샷에서 sudo ufw allow verbose 출력 결과 참고).

 

UFW 상태 조회 결과를 통해 확인할 수 있듯이, 군더더기가 없습니다. 추천할만 합니다.

단, 포트 내역 바뀔 때마다 수동으로 반영해줘야 한다는 점만 주의하면 되겠습니다.

 

 

포트는 하나씩만 지정할 수 있는 것이 아닙니다.

sudo ufw allow 시작포트:종료포트/tcp

형식으로 입력하면 해당 범위의 포트를 개방할 수 있습니다(프로토콜은 선택사항). FTP(vsftpd) 세팅할 때 유용하게 쓸 수 있을 것으로 예상합니다.

 

4. App List로 UFW 허용 목록 등록하기

UFW로 구글링하다 보면 ufw allow 'nginx full' 이라고 입력하면 80포트와 443포트가 한꺼번에 열린다고 적은 글들이 종종 나올 겁니다. nginx full이 어디에서 나왔냐면...

 

▼ sudo ufw app list 라고 입력했을 때 "사용 가능한 프로그램" 목록에 뜹니다. 이 목록을 보고

sudo ufw allow 'App List명' 형식으로 입력하면 허용 목록에 등록됩니다.

(sudo ufw allow 는 만능 명령어인 것 같네요. 다 받아먹고 알아서 처리함.)

 

다만 App List로 등록하는 게 만능이 아닐 수 있습니다. 예를 들어 Nginx Full은 80포트, 443포트 TCP 프로토콜만 허용한다고 나오는데, Nginx 서버블록 파일에서 80, 443포트 이외의 포트를 Listen 하라고 적은 경우에는 Nginx Full이 스스로 Listen 상태를 인지하고 대응하지 못합니다(예 : webdav 구축을 위해 8888포트 Listen. 하지만 Nginx Full은 알아차리지 못함). 포트 추가/변경은 Nginx 서버블록 파일에서 빈번하게 일어날 수 있기 때문에, App List를 이용한 방식은 한계 시점이 의외로 빨리 다가올 수 있습니다. 결국 포트로 허용 목록 추가할 상황이 오는 거죠. 그래서 이 방식도 비추천합니다.

(글을 써나갈수록 포트로 허용 짱짱맨~ 하게 되네요. 원래 이러려는 의도는 없었는데...)

 

그런데 스샷을 보니 80포트, 443포트, Nginx Full로 허용한 포트(80,443)이 중복되었네요. 좋을 게 없는 상황이라고 생각합니다. 이따 지우는 방법을 설명하면서 지우겠습니다.

 

5. 처리 순번 확인. 중간에 UFW 규칙 끼워넣기

모든 방화벽은 순서대로 처리됩니다. UFW도 예외는 아닙니다.

 

UFW 처리 순서 확인 명령어(sudo ufw status numbered)를 입력하면 순번이 보입니다. 이 순서대로 방화벽이 처리되는 겁니다. sudo ufw status verbose라고 입력했을 때와는 화면 구성이 다르죠?

 

방화벽 규칙이 순서대로 처리된다는 것을 인지하는 것은 중요합니다.

만약 123.123.123.123 IP가 홈페이지(80포트)에 접근하는 것을 차단하고 싶어서 sudo ufw deny from 123.123.123.123 이라고 입력했다! 그러면 아래 스샷처럼 UFW 순서가 구성될 겁니다.

 

▲ ipv4 쪽에서는 제일 마지막(5번)에 123.123.123.123 IP를 차단하는 구성이 추가됐죠?

이 경우, 123.123.123.123 IP가 80포트로 접근해올 경우 2번 규칙이 먼저 요청을 허용해버리기 때문에 5번 규칙은 발동하지 못합니다. 5번은 존재의 가치가 없어진 것이죠.

 

만약 1번에 123.123.123.123 IP를 거부하는 규칙을 끼워넣는다면? 80포트 허용 전에 거부 규칙이 발동하니까 해당 IP는 홈페이지로 접근하지 못하겠죠!

 

▼ UFW 규칙 끼워넣기 사례

▲ 원하는 순번에 UFW 규칙을 끼워넣는 방식은 어렵지 않습니다. ufw 구성 명령을 입력하면서 ufw와 deny(또는 allow) 사이에 insert 원하는 순번 형식으로 적어주면 됩니다.

기존에 해당 위치에 존재하던 규칙은 뒤로 밀립니다. 22번 포트 허용 규칙이 1번에 있었는데 2번으로 밀렸네요.

 

기존 규칙의 순서를 바꾸는 방법이 있는지는 모르겠습니다. 저는 규칙을 지우고 원하는 위치에 다시 작성&삽입하는 식으로 대처하려고요.

 

6. UFW로 IP(IP대역) 차단하기

바로 위 스크린 샷에서 단일 IP 차단 명령어가 나왔네요. 다시 한 번 텍스트로 정리를 해보면...

sudo ufw insert 순번 deny from IP주소 comment '설명'

순번은 22포트(SSH), 80포트(http), 443포트(https)보다 앞쪽 순번으로 정해야 차단 효과가 나오겠죠?

 

IP들의 범위를 정해서 차단하는 방법도 생각해볼 수 있을 겁니다.

192.168.0.25부터 192.168.0.29까지. 이렇게 좁은 범위를 지정하는 것도 가능하긴 한데, 일반적으로는 특정 대역을 차단하는 식으로 처리하는 경우가 많지 않나 싶습니다.

 

 

예를 들면

31.184.238. 로 시작하는 대역 전체(31.184.238.0 부터 31.184.238.255 까지)

5.188. 로 시작하는 대역 전체(5.188.0.0 부터 5.188.255.255 까지)

178. 로 시작하는 대역 전체(178.0.0.0 부터 178.255.255.255 까지)

 

엔진엑스(Nginx)에서 IP 대역을 차단하는 방법처럼 UFW도 IP주소와 CIDR의 조합으로 IP대역 차단 규칙을 적을 수 있다고 합니다. 우분투 Help 문서에는 "Allow by Subnet"이라는 항목으로 (툭 던지듯이) 간단하게 소개하고 있는데, 우리가 "3회 공격 누적시 대역 전체 차단" 이렇게 스스로 기준을 세워놓고 대처하는 경우라면 의외로 대역 차단 기능 자주 쓰게 될 겁니다. 그래서 위에서 예를 든 정도는 CIDR로 변환했을 때 어떻게 되는지 정리해두면 좋을 겁니다.

 

31.184.238.0/24

5.188.0.0/16

178.0.0.0/8

 

https://www.ipaddressguide.com/cidr

▲ CIDR 계산기 주소(IPv4).

https://www.ipaddressguide.com/ipv6-cidr

▲ IPv6 CIDR 블록 계산기 주소

 

직접 계산하는 것이 복잡해서 CIDR 계산기를 이용해봤는데, 규칙이 보이나요?

이 IP+CIDR 조합을 UFW IP차단 명령에 대입하면 IP대역 차단이 되는 겁니다.

 

▲ 포트/프로토콜 차단은 "목적" 카테고리에 분류되어 있는데, IP 차단은 "출발" 카테고리에 분류되어 있네요.

 

7. UFW 등록 항목 삭제하기

sudo ufw delete 순번

ipv4나 ipv6 중 하나만 설정된 규칙은 순번으로 삭제하는 방법이 간편합니다.

 

sudo ufw delete 규칙 등록시 사용했던 명령어

처럼 입력해도 삭제가 됩니다. 특히 이 방식은 ipv4, ipv6 조건이 동시에 등록되어 있을 때 한번에 지워주므로 편리합니다.

 

8. UFW 룰 백업

사용자가 등록한 UFW 룰은 /etc/ufw/user.rules 과 /etc/ufw/user6.rules 에 저장됩니다. 각각 ipv4, ipv6 설정이고요.

그래서 /etc/ufw/ 디렉토리를 복사해두면 백업이 될 것 같고...

 

▲ PC 포맷 후 UFW 룰을 복원할 때 user.rules 파일과 user6.rules 파일을 덮어씌우는 방식으로 처리하는 게 꺼려진다면 파일 내용 중에서 ### RULES ### 블라블라 ### END RULES ### 까지를 복사+붙여넣기하면 될 것 같습니다.

 

9. UFW로 PING 요청 거부 설정하기

UFW는 PING 요청 허용이 기본값이라고 합니다. PING 요청은 네트워크 문제를 진단할 수 있기에 유용하지만, 때로는 공격의 빌미가 될 수 있기 때문에 요청을 거부하기를 원하는 분도 있을 수 있다고 봅니다.

 

▲ /etc/ufw/before.rules 파일을 열고 ok icmp codes for INPUT 항목을 찾아 전체를 주석처리(#)하거나, ACCEPT를 DROP으로 바꾸면 PING 요청이 거부된다고 합니다. 저장 후 빠져나온 다음 재부팅하면 적용되는 것을 확인했습니다.

 

저는 웬만하면 PING 요청 거부를 하지 않을 생각입니다. :-)

 

10. 팁 : 개방을 추천하는 포트들

- 80 : Apache/Nginx 등 웹서버 프로그램을 쓴다면...

- 443 : 웹서버에서 SSL을 쓴다면...

- 22 : SSH로 원격 접속을 한다면... (변경했다면 변경한 포트를 개방할 것.)

- 3389 : 그놈, XFCE 같은 GUI 인터페이스로 원격 접속을 한다면...

- 1022 : 우분투 메이저 판올림(예 : 16.04 → 18.04.1)할 때 개방하라고 요구할 겁니다. 미리 설정해두면 좋습니다.

 

- 기타 본인이 서비스하는 프로그램들이 요구하는 포트들(FTP, WebDAV, 메일, 등등...)

 

11. 팁 : gufw 써보세요

▲ 인터페이스 괜찮은 것 같아요.

sudo apt install gufw

 

 

※ 참고한 글들

https://happist.com/561474/우분투-18-04로-서버-운영-ufw로-방화벽-설정/

https://extrememanual.net/12019

https://webdir.tistory.com/206

https://help.ubuntu.com/community/UFW

https://wiki.ubuntu-kr.org/index.php/UFWHowToKo

https://medium.com/@jasonrigden/a-guide-to-the-uncomplicated-firewall-ufw-for-linux-570c3774d7f4

 

 

▲ World of Dance South Korea Qualifier 2016 Expression Crew

한국의 춤은 아름답습니다.

반응형