firewalld가 기본 방화벽으로 등장한 이후로(아마 CentOS 7에서였을 것으로 생각됩니다. 2011년에 소개되었습니다.), 저는 어떤 비용이든 iptables로 돌아가는 것을 삶의 목표로 삼아왔습니다. 이에는 두 가지 이유가 있었습니다. 첫째, 당시 사용 가능한 문서들은 서버가 IP 수준까지 어떻게 보호되고 있는지 제대로 보여주지 않는 단순한 규칙을 사용했습니다. 둘째이자 주된 이유는, 저는 오랜 기간 동안 iptables와 함께한 경험이 있었으며, 솔직히 iptables를 계속 사용하는 것이 더 편했습니다. 공개 또는 내부를 막론하고 배포한 모든 서버에는 iptables 방화벽 규칙 집합을 사용했습니다. 해당 서버에 맞는 기본 규칙 집합을 간단히 조정하고 배포하는 것이 쉬웠습니다. CentOS 7, CentOS 8 및 이제 Rocky Linux 8에서 이를 수행하려면 이 절차를 사용해야 했습니다.
그렇다면 이 문서를 작성하는 이유는 무엇일까요? 첫째, 대부분의 firewalld 참조 자료들의 한계를 해결하고, 둘째로, 더 세부적인 방화벽 규칙을 모방하기 위해 firewalld 사용 방법을 찾아내기 위함입니다.
물론, 초보자들이 Rocky Linux의 기본 방화벽을 이해하는 데 도움이 되기도 합니다.
매뉴얼 페이지에 따르면, "firewalld는 네트워크/방화벽 존을 정의하여 네트워크 연결 또는 인터페이스의 신뢰 수준을 지원하는 동적으로 관리되는 방화벽을 제공합니다. IPv4, IPv6 방화벽 설정 및 이더넷 브리지를 지원하며 런타임 및 영구 구성 옵션을 분리합니다. 또한 서비스 또는 응용 프로그램용 인터페이스를 지원하여 방화벽 규칙을 직접 추가할 수 있습니다."
재미있는 사실: firewalld는 실제로 Rocky Linux에서 netfilter와 nftables 커널 하위 시스템의 프론트 엔드입니다.
이 가이드는 iptables 방화벽에서 firewalld 방화벽으로 규칙을 적용하는 데 초점을 맞추고 있습니다. 방화벽에 대한 처음 단계라면, 이 문서가 도움이 될 수 있습니다. 두 문서를 읽어 firewalld를 최대한 활용해보세요.
그러나 만약 이 서버에 우리 조직에 할당된 IP 블록만 액세스할 수 있는 이너넷이 있는 경우는 어떻게 될까요? 이제 "internal" 존을 이 규칙에 적용해야 할까요? 솔직히 말해서, 저는 관리자 사용자의 IP (서버에 SSH로 접근을 허용하는 IP)를 다루는 존을 만들기를 원합니다. 사실 말하자면, 나만의 모든 존을 추가하는 것이 좋겠지만, 그렇게 하면 말도 안 될 수 있습니다.
저희는 지금까지 --permanent 플래그를 많이 사용했습니다. 테스트할 때는 --permanent 플래그 없이 규칙을 추가한 다음, 예상대로 작동하는지 테스트한 후 firewall-cmd --runtime-to-permanent을 사용하여 규칙을 적용하고, firewall-cmd --reload를 실행하기 전에 실제 규칙을 추가하는 것이 좋습니다. 위험이 적다면 (다시 말해, 자체적으로 잠금 걸릴 위험이 없다면), 여기서처럼 --permanent 플래그를 추가할 수 있습니다.
이 존을 실제로 사용하기 전에 방화벽을 재로드해야 합니다:
firewall-cmd --reload
!!! !!!
사용자 정의 존에 대한 참고 사항: 특정 소스 IP 또는 인터페이스만 포함하고 프로토콜 또는 서비스를 포함하지 않는 신뢰할 수 있는 존을 추가해야 할 경우, "trusted" 존을 이미 다른 용도로 사용했기 때문에 제대로 작동하지 않는 경우 등, 이를 위해 사용자 정의 존을 추가할 수 있습니다. 그러나 이때 "default" 대신 "ACCEPT" (목표에 따라 REJECT 또는 DROP도 사용 가능)로 존의 대상을 변경해야 합니다. 다음은 LXD 머신에서 브리지 인터페이스 (이 경우 lxdbr0)를 사용하는 예제입니다. 다음은 LXD 머신에서 브리지 인터페이스 (이 경우 lxdbr0)를 사용하는 예제입니다.
먼저 영역을 추가하고 사용할 수 있도록 다시 로드합니다.
```
firewall-cmd --new-zone=bridge --permanent
firewall-cmd --reload
```
다음으로 존의 대상을 "default"에서 "ACCEPT"로 변경한 다음 인터페이스를 할당하고 방화벽을 재로드합니다:
```
firewall-cmd --zone=bridge --set-target=ACCEPT --permanent
firewall-cmd --zone=bridge --add-interface=lxdbr0 --permanent
firewall-cmd --reload
```
이는 방화벽에 다음을 알려줍니다.
1. 존의 대상을 ACCEPT로 변경합니다.
2. 브리지 인터페이스 "lxdbr0"을 존에 추가합니다.
3. 방화벽 재로드합니다.
이는 브리지 인터페이스에서 모든 트래픽을 허용한다는 것을 의미합니다.
더 나아가기 전에, 존을 나열하는 방법을 살펴보아야 합니다. iptables -L에서 제공되는 표 형식 출력과 달리, 하나의 열과 헤더가 포함된 단일 열이 출력됩니다. 존을 나열하려면 다음 명령을 사용합니다: firewall-cmd --zone=[zone_name] --list-all. 이렇게 하면 새로 만든 "admin" 존을 나열하는 결과는 다음과 같습니다:
이전 지침에 따라 "trusted" 존에 IP를 추가한 경우, 이제 해당 존에서 IP를 제거해야 합니다. --permanent 플래그를 사용하는 데 관한 우리의 참고 사항을 기억하세요. 여기서는 실제로 규칙을 적용하기 전에 제대로 테스트하기 위해 이 플래그를 사용하지 않는 것이 좋습니다:
그런 다음 테스트합니다. 최종 두 단계를 실행하기 전에 다른 존에서 ssh를 통해 접근할 수 있는지 확인하십시오. (아래의 경고 참조!) 다른 변경 사항을 가하지 않았다면, "public" 존에는 여전히 ssh가 허용되어 있을 것입니다.
만족하셨다면, 런타임 규칙을 영구 규칙으로 이동합니다:
firewall-cmd --runtime-to-permanent
그리고 다시 로드합니다:
firewall-cmd --reload
주의
원격 서버 또는 VPS에서 작업 중이라면 마지막 명령을 실행하지 마세요! 원격 서버에서 ssh 서비스를 제거하지 마세요. 다른 방법으로 쉘에 접근할 수 있는 경우에만 이 작업을 수행하세요. (아래 참조).
방화벽으로부터 SSH 서비스 접근을 차단할 경우, 방화벽을 통한 SSH 접근 방법이 없는 상태가 될 수 있으며, 이 경우 최악의 경우 서버를 직접 고치거나 지원팀에 문의하거나 제어판을 통해 OS를 재설치해야 할 수 있습니다 (서버가 물리적 또는 가상인지에 따라 다릅니다).
상기한 IP (위에서는 192.168.1.122)를 사용하여 root 또는 sudo 권한이 있는 사용자로 SSH합니다 (root 사용자를 여기서 사용하는 이유는 해당 호스트에서 실행해야 하는 명령을 위해 사용됩니다. sudo 사용자를 사용하는 경우, 연결 후 sudo -s를 기억하세요).
연결한 후, tail /var/log/secure을 실행하면 다음과 같이 비슷한 출력이 표시됩니다:
원격 서버 또는 VPS에서 작업하는 경우, 언제나 같은 IP를 사용하지 않는 인터넷 연결이 있는 경우, SSH 서비스를 자신의 인터넷 서비스 제공업체 또는 지역의 IP 주소 범위에 열어두는 것이 좋습니다. 이렇게 하면 자체 방화벽에 의해 잠금이 걸릴 위험을 줄일 수 있습니다.
많은 ISP들은 전용 IP 주소에 대해 추가 요금을 부과하며, 제공하지 않는 경우도 있으므로 신중하게 고려해야 합니다.
여기서 제시된 예제는 자체 개인 네트워크의 IP를 사용하여 로컬 서버에 접근하는 것으로 가정합니다.
신입자들을 위해 말씀드리면, ICMP는 오류 보고를 위해 설계된 데이터 전송 프로토콜입니다. 기본적으로 머신과 연결하는 데 문제가 발생했을 때 알려줍니다.
실제로 우리는 ICMP를 로컬 IP(이 경우 192.168.1.0/24)에 대해 열어두는 것이 좋을 것입니다. 하지만 "public" 및 "admin" 존은 기본적으로 ICMP가 켜져 있으므로 첫 번째로 "public" 및 "admin" 존에서 해당 네트워크 주소로의 ICMP를 제한하는 것이 좋습니다.
다시 말하지만, 이는 데모 목적으로 제공된 것입니다. 관리 사용자가 서버에 대한 ICMP를 할당받아야 하는 것은 당연하며, LAN 네트워크 IP의 구성원이기 때문에 아마도 할당받을 것입니다.
이 모든 것은 좋지만, 예를 들어 Nextcloud 서비스를 http/https로 실행하고 신뢰된 네트워크만 해당 서비스에 액세스하도록 하려면 어떻게 해야 할까요? 이는 일반적인 상황입니다! 이러한 상황은 항상 발생하며, 실제로 공개적으로 트래픽을 허용하되 실제로 액세스해야 하는 사용자를 고려하지 않는 것은 큰 보안 취약점입니다.
이전에 사용한 "trusted" 존 정보를 사용할 수 없습니다. 그것은 테스트를 위한 것이었습니다. 최소한 우리의 LAN IP 블록이 "trusted"에 추가된 것으로 가정해야 합니다. 이렇게 보일 것입니다:
이 부분의 스크립트는 표준 FTP 포트(20 및 21)와 몇 가지 추가적인 패시브 포트를 다룹니다. 이러한 종류의 규칙은 일반적으로 VSFTPD와 같은 ftp 서버에서 필요합니다. 일반적으로 이러한 규칙은 고객으로부터의 ftp 연결을 허용하기 위해 공개적으로 공개적인 웹 서버에 적용됩니다.
firewalld에는 ftp-data 서비스(포트 20)가 없습니다. 여기에 나열된 7000에서 7500 포트는 패시브 FTP 연결을 위한 것입니다. 다시 말하지만, firewalld에서는 이를 직접 처리할 방법이 없습니다. SFTP로 전환하여 여기서 포트 허용 규칙을 단순화할 수 있으며, 현재에는 추천되는 방법일 수도 있습니다.
그러나 여기서 우리는 iptables 규칙을 firewalld로 변환하는 것을 보여주려고 합니다. 이러한 문제를 해결하기 위해 다음과 같이 진행할 수 있습니다.
먼저, 웹 서비스를 호스트하는 존에 ftp 서비스를 추가합니다. 이 예제에서는 "public"일 것으로 예상됩니다:
웹 서버를 다루면 거의 항상 데이터베이스도 다루게 됩니다. 데이터베이스에 대한 액세스는 다른 서비스에 적용한 것과 동일한 주의가 필요합니다. 액세스가 전 세계에서 필요하지 않다면 "public" 이외의 다른 곳에 규칙을 적용하세요. 또 하나의 고려사항은 귀사가 액세스를 제공해야 하는지 여부입니다. 이 또한 귀사의 환경에 따라 다를 수 있습니다. 저는 이전에 일한 곳에서 고객들을 위해 호스팅된 웹 서버를 운영했습니다. 많은 고객이 워드프레스 사이트를 사용했고, 그 중 아무도 MariaDB에 대한 프런트엔드 액세스를 필요로 하거나 요청하지 않았습니다. 고객이 더 많은 액세스를 필요로 할 경우, 고객의 웹 서버를 위해 LXD 컨테이너를 생성하고 고객이 원하는대로 방화벽을 구성하고 서버에서 발생하는 일에 대해 책임을 넘겨줬습니다. 그래도 공개 서버인 경우, phpmyadmin 또는 MariaDB에 대한 기타 프런트엔드 액세스를 제공해야 할 수 있습니다. 이 경우 데이터베이스의 암호 요구 사항을 고려하고 기본값이 아닌 데이터베이스 사용자로 설정해야 합니다. 나에게 있어서 암호 길이가 암호를 만들 때 주요 고려 사항입니다.
물론 암호 보안은 다른 문서에서 다루어야 할 주제이므로 여기서는 데이터베이스 액세스에 대한 iptables 라인이 다음과 같다고 가정합니다:
iptables -A INPUT -p tcp -m tcp --dport=3600 -j ACCEPT
이 경우 firewalld 변환을 위해 서비스를 "public" 영역에 추가하기만 하면 됩니다.
공개적으로 알려진 웹 서버에서는 덜 흔할 수 있지만, 내부 리소스로 더 흔할 수 있습니다. 동일한 보안 고려 사항이 적용됩니다. 신뢰된 네트워크에 서버가 있으면(우리의 예에서는 192.168.1.0/24) 아마 모두에게 액세스할 필요가 없을 수 있습니다. Postgresql에는 보다 상세한 액세스 권한을 다루기 위한 액세스 목록이 있습니다. 우리의 firewalld 규칙은 다음과 같이 보일 것입니다:
사설 또는 공개 DNS 서버를 운영한다는 것은 이 서비스를 보호하기 위해 작성하는 규칙에 주의해야 한다는 것을 의미합니다. 사설 DNS 서버가 있다면 이러한 iptables 규칙과 같을 수 있습니다(대부분의 DNS 서비스는 UDP 대신 TCP를 사용합니다. 그러나 항상 그렇지 않을 수 있습니다):
기본적으로 firewalld는 모든 사용 가능한 인터페이스에서 수신대기하도록 설정되어 있습니다. 여러 인터페이스가 있는 bare-metal 서버의 경우 해당 인터페이스를 해당 네트워크를 바라보도록 존에 할당해야 할 필요가 있을 것입니다.
우리의 예제에서는 인터페이스를 추가하지 않았습니다. 실험용으로 LXD 컨테이너를 사용하고 있기 때문에 사용 가능한 인터페이스가 하나뿐입니다. 작업할 인터페이스는 하나뿐입니다. 예를 들어, "public" 존이 Ethernet 포트 enp3s0을 사용하도록 구성되어야 하며 해당 포트에 공개 IP가 있습니다. 그리고 "trusted" 및 "admin" 존은 LAN 인터페이스에 위치할 것입니다.
Rocky Linux에서는 firewalld가 권장되고 포함되어 있으므로 firewalld가 어떻게 동작하는지 이해하는 것이 좋습니다. firewalld를 사용하여 서비스를 적용하는 문서에 포함된 간단한 규칙들은 종종 서버가 사용되는 용도를 고려하지 않으며 해당 서비스를 세계에 공개적으로 허용하는 것 외에 다른 옵션을 제공하지 않습니다. 이는 보안 결함을 가지게 됩니다.
이러한 지침을 볼 때, 서버가 사용되는 용도와 해당 서비스가 전 세계에 공개적으로 허용되어야 하는지 여부를 고려하세요. 그렇지 않으면 위에서 설명한 대로 더 많은 세분화된 규칙을 사용하는 것을 고려하십시오. 작성자는 여전히 firewalld로 전환하는 것이 100% 편하지는 않지만 향후 문서에서 firewalld를 사용할 가능성이 높습니다.
작성한 문서와 결과를 실험하는 과정이 저에게 매우 도움이 되었습니다. 다른 누군가에게도 도움이 될 것입니다. 이것은 firewalld에 대한 완벽한 가이드가 아니라 시작점으로 생각하시기 바랍니다.
Author: Steven Spencer
Contributors: wsoyinka, Antoine Le Morvan, Ezequiel Bruni