정리하는 공간
리눅스) 방화벽(firewalld, iptables) 본문
firewalld
Zone 개념을 제공하는 방화벽 데몬으로 firewall-cmd, firewall-config 명령어를 사용한다.
GUI 버전에선 firewall-config 패키지를 사용하지만 CORE 버전에선 firewall-cmd 패키지로 사용한다.
이유는 자원을 최소화하고, GUI 버전에서 사용하는 firewall-config는 디테일한 설정을 할 수 없다.
서버 운영에 있어 대다수의 클라이언트 요청에 빠르게 응답하기 위해 firewall-cmd 명령어를 사용한다.
firewalld zone 개념
서버에 들어오고 나가는 트래픽을 어떻게 제어할지 목적에 맞는 zone들이 존재하는데, 서비스를 사용 목적에 맞게
zone을 지정하고, 들어오고 나가는 트래픽들을 차단, 혹은 허용할 수 있다.
환경설정 파일은 아래와 같다.
/etc/firewalld/firewalld.conf
drop 존
들어오는 패킷은 모두 버려지고, 이에 대한 응답 메시지도 없으며, 단지 내부에서 외부로 나갔다 들어오는 것만 허용
block 존
drop과 뜻은 같지만, 버려진 패킷에 대한 응답 메시지를 보낸다.
public 존 (기본 zone으로 사용)
서비스를 제공하는 특별한 포트로의 연결만 허용하고, 그 외 포트로의 연결은 모두 거부된다.
external 존
매스커레이드가 적용되는 외부 라우터를 위해 사용하고, 외부에서 들어오는 특정 패킷만 내부로 들어오게 할 수 있고
내부에서 외부로 내 보낼 수도 있다.
매스커레이드란 사설 네트워크가 공인 네트워크로 내보내지고 다시 사설네트워크로 들어오는 것을 가능하게 해준다.
DMZ 존
내부 네트워크로의 접근은 제한적으로 허용하지만, 공개된 네트워크의 접속은 특정 포트로 허용한다.
internal 존
내부 네트워크를 위해 사용되고, 선택된 열견만을 접속 허용한다.
Tip : iptables는 체인, 규칙, 타겟 등의 설정으로 여러 단계를 거쳐야하지만, firewalld는 정해진 존에 넣기만 하면 되는
간편한 장점을 가지고 있다.
firewall-cmd 명령어
firewall-cmd --get-zones
지원하는 존 축력
firewall-cmd --get-active-zones
활성화 된 존 출력
firewall-cmd --get-defualt-zone
존 설정 시 기본 값 출력
firewall-cmd --list-all-zones
모든 존 정보 확인
firewall --cmd -get-zone-of-interfaces=eno33
특정 인터페이스에 적용되어 있는 존정보 확인
firewall-cmd --zone=public --list-interfaces
현재 특정존이 적용되어 있는 인터페이스 확인(위와 반대)
firewall-cmd --zone=public --list-all
현재 특정 존에 대한 모든 정보확인
firewall-cmd --get-service
적용 가능한 모든 서비스 목록 출력
/usr/lib/firewalld/services 디렉터리
/etc/firewalld/services 디렉터리에도 지원하는 서비스 가 .xml 형식으로 들어있다.
특정 존을 다른 인터페이스에 연결하고 싶을 때
firewall-cmd --zone=public --add-interface=eno44
eno44 인터페이스를 퍼블릭 존에 지정
설정 되어 있는 인터페이스를 다른 존으로 연결할 때
firewall-cmd --zone=home --change-interface=eno33
지정된 eno33 인터페이스를 홈 존에서 삭제할 때
firewall-cmd --zone=home --remove-interface=eno33
Tip
재부팅 시 기본 적용된 존 정보면 남아있고, 설정한 인터페이스(추가, 제거)들은 삭제된다
영구적으로 해당 인터페이스에 해당 포트를 적용하고 싶을 때
ls /etc/sysconfig/network-scripts
현재 사용 중인 인터페이스 카드의 정보를 담은 파일 경로
GUI 모드의 경우 '뒤에 것', CORE 모드의 경우 '앞에 것'
vi /etc/sysconfig/network-scripts/ifcfg-유선_연결_1
해당 파일의 설정 값을 변경한다.
하단에 ZONE=public (drop, dmz 등 원하는 존 설정)
변경 사항을 적용하기 위해
systemctl restart NetworkManager 입력
Tip
설정 값을 변경할 때 2개의 파일 중 아이피 주소 값이 기록되어 있는 파일이 우선권이 된다.
기본 존 변경하는 방법
firewall-cmd --set-default-zone=home
또는 위의 방법처럼 설정 값을 변경해 주면 된다.
vi /etc/firewalld/firewalld.conf
DefaultZone=home
firewall-cmd --reload
특정 서비스 허용, 차단하는 방법
firewall-cmd --add-service=http
firewall-cmd --zone=pbublic --add-service=https
firewall-cmd --zone=pbublic --add-service={smtp,ftp,dns}
Tip
서비스를 추가, 제거하면 재부팅 후 설정 값이 초기화 된다고 했다. 이럴 땐 영구적 --permanent 를 이용한다.
firewall-cmd --permanent --add-service=http
설정 변경된 내용은 /etc/firewalld/zones/public.xml 이 파일에 기록된다.
firewall-cmd --zone=pbublic --add-port=8080/tcp
firewall-cmd --query-port=8080/tcp
yes, no로 맞는지 출력
firewall-cmd --zone=pbublic --add-port=21-23/tcp
21-23 포트에 지정 추가
마스커레이드와 포트포워드 [external 존]
마스커레이드는 사설 네트워크-공인 네트워크-사설 네트워크를 가능하게 해준다 (일반적인 공유기)
external 존으로 변경하면 마스커레이드를 추가할 수 있다.
포트포워드는 외부에서 사설 네트워크로 들어올때 트래픽이 전달되지 않는데, 이걸 가능하게 하는 것이다.
우선은 이렇게만 알고 있자......
다이렉트 인터페이스 (디테일한 패킷 필터링을 할 수 있다)
특정한 서비스나 애플리케이션을 위해 실행 중인 firewalld에 새로운 체인이나 규칙을 생성, 삭제할 수 있는 기능
firewall-cmd --direct --get-all-rules
firewall-cmd --direct –add-rule ipv4 filter input 0 –p tcp –dport 9000 –j ACCEPT
firewalld 요약
firewall-cmd --zone-public --add-service=LDAP
firewall-cmd --permanet --zone-public --add-service=LDAP
firewalld 요약
firewall-cmd --zone=public --add-service=LDAP
firewall-cmd --permanet --zone=public --add-service=LDAP
우선 이 2개만이라도 꼭 기억해보자..
stateful 방화벽, iptable
stateful 방화벽이란
방화벽을 통과한 패킷에 대해 연결 상태를 관찰해서 기억해 두었다가 다음 접속 시 보안을 허용하는 개념이다.
이 설정을 위해선 zone 개념만으론 디테일하게 할 수 없어 iptables 개념을 잘 알아두어야 한다.
tip
iptables는 firewalld와 호환이 되지 않기 때문에 firewalld를 사용 중이라면 disable설정을 해주도록 한다.
(systemctl stop firewalld -> systemctl disable firewalld)
iptable의 테이블(tables) 개념
iptabes는 firewalld가 사용하는 zone 개념이 아닌 tables 개념을 사용한다.
tables에는 filter, nat, manle 3가지가 있고, 각각 여러 체인(규칙 그룹)이 존재하며
filter의 tables에는 INPUT, OUTPUT, FORWARD 규칙이 있다.
각 규칙에 맞게 들어오는 트래픽마다 허용과 차단이 정해진다.
Tip
체인의 규칙은 순차적으로 이루어지기 때문에
만들 때는 범위가 작은 것 부터 큰 것 순으로 꼭 이루어져야 한다. (그렇지 않을 시 오류 발생)
tables
filter
방화벽의 가장 핵심적인 테이블로 특정 룰에 따라 패킷을 차단, 허용하는 규칙의 체인이 존재
nat
패킷을 필터링하는 기능은 없고, 네트워크의 주소만 변환하는 테이블
mangle
패킷의 TTL이나 TOS값을 변경하거나 매칭할 때 사용 (잘 사용되진 않는다)
chain
filter tables에서는 미리 정의된 3가지 chain이 존재한다. 어떤 트래픽을 허용하고 차단할지 규칙이 정해져 있다.
Tip
모든 체인은 여러 개의 규칙과 한 개의 정책으로 이루어져 있다.
INPUT
해당 서버로 패킷이 들어올 때 차단, 허용하는 규칙
(nat에서는 패킷이 들어올 때 사설에서 공인, 공인에서 사설로 바꾸는 규칙)
OUTPUT
패킷들이 외부로 나가기 직전 나가도 되는지의 차단, 허용 규칙
(nat에서는 패킷이 나갈 때 공인ip로 변경되느냐의 규칙)
FORWARD
해당 서버를 거쳐 그 속의 서버까지 패킷을 전할지의 차단 허용 규칙
(본래 목적지가 자신이 아니면 패킷은 버려지는데, 중계역할을 해주는 셈이다)
PREROUTION
DNAT(목적지 NAT)
내부에서 외부로 갔다가 다시 내부로 들어오는 트래픽
POSTROUTING
SNAT(출발지 NAT)
내부에서 외부로 나가는 트래픽
iptables 사용형식
iptables [-t tableaud] [명령어] [매칭옵션] [타겟]
match
--sorce (-s)
출발지 IP주소나 네트워크와의 매칭
--destination (-d)
목적지 iP주소나 네트워크와의 매칭
--mac-source
mac 출발지 주소와의 매칭
--mac-destination
mac 도착지 주소와의 매칭
--sport
출발지 포트
--dport
도착지 포트
--protocol (-p)
특정 프로토콜과의 매칭
--in-interface (-i)
입력 인터페이스, INPUT 일때 사용
--out-interface (-o)
출력 인터페이스, OUTPUT 일때 사용
--state
연결 상태와의 매칭
--srting
애플리케이션 계층 데이터 바이트 순서와의 매칭
--comment
커널 메모리 내의 규칙과 연계되는 최대 256바이트 주석
--syn (-y)
FIN, SYN, RST, ACK 패킷을 조사해서 SYN만 체크된 패킷
tip
클라이언트가 서버에 '처음' 접속하면 무조건 4개 패킷 중 SYN만 1로 체크되어 온다.
이때의 최초 접속을 허용, 차단 할지의 매칭을 하는 것이다.
[3 shake hands]
Client > Server : TCP SYN
Server > Client : TCP SYN ACK
Client > Server : TCP ACK
클라이언트가 서버에 접속하면 위의 과정이 일어난다.
--fragement (-f)
두 번째 이후의 조각에 대해서 규칙을 명시
--table (-t)
처리될 테이블
--jump (-j)
규칙에 맞는 패킷을 어떻게 처리할 것인가를 명시
--match (-m)
특정 모듈과의 매치
tip
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ESTABLISHED(연결확립) : 연결 확립된 상태를 허용해서 패킷을 주고 받겠다는 뜻
RELATED : 연결 확립상태와 동시에 현 서버와 관련된 트래픽을 허용하겠다.
(ex, www.naver.com -> mail.naver.com)
[연결 추적 기능]
프로토콜이 tcp여야만 추적이 가능하다.
NEW : 새로운 연결을 요청하는 패킷, 예, HTTP 요청
ESTABLISHED : 기존 연결의 일부인 패킷들을 허용, 차단하는 것. 연결확립.
RELATED : 기존 연결에 속하지만 새로운 연결을 요청하는 패킷,
--tcp-flags
tcp헤더 내에 flag 비트를 검사해서 뒤에 설정한 값과 비교하여 차단, 허용
tip
iptables -A INPUT -p tcp --tcp-falgs ACK,FIN FIN -j DROP
ACK, FIN을 확인해서 fin이 있으면 DROP시키겠다.
이유는 ACK가 있어야 접속 중인 상태기 때문에 ACK가 없이 종료를 뜻하는 FIN이 있으면 이상한 패킷인거다.
--icmp-type
핑에 대한 접근통제를 할 때 차단, 허용
포스트 캐닝
외부에서 해당 서버로 침투할 때 특정 어플리케이션에 해당되는 트래픽 포트가 열려있는지 확인
타겟
ACCEPT
패킷을 받아들이겠다.
DROP
응답 메세지 없이 패킷을 버린다.
REJECT
패킷을 버리고 이와 동시에 적절한 응답 패킷을 전송한다.
tip
서비스에 접속하려는 사용자의 액세스를 거부하고 connection refused라는 오류 메시지를 보여주는 반면 drop은 보내지 않는다. 여기서 사용자의 목적이 불순하면 REJECT의 메시지로 방화벽이 설치되어 있다는 것을 알 수 있어 공격해 올 수도 있다.
LOG
매칭되는 트레픽이 도착했다 하면 기록하라 (언제 어디서 이런 서비스가 발생했다.)
패킷 정보를 syslog에 기록한다
명령어
-F (--flush)
이전 설정된 규칙을 모두 비움.
-A (--append)
해당체인의 마지막에 새로운 규칙을 추가한다.
-D (--delete)
규칙을 삭제한다.
-C (--check)
패킷을 테스트한다.
-R (--replace)
새로운 규칙으로 교체한다.
규칙을 추가할 때 범위에 따라 순서가 중요한데, 중간에 규칙을 추가, 변경하고 싶을 때 많이 사용
-I (--insert)
해당체인의 처음에 새로운 규칙을 삽입한다.
-L (--list)
규칙을 출력한다. 규칙을 보기 쉽게 넘버 부여
-F (--flush)
chain으로부터 규칙을 모두 삭제한다.
-Z (--zero)
모든 chain의 패킷과 바이트 카운터 값을 0으로 만든다.
-N (--new)
새로운 chain을 만든다.
-X (--delete-chain)
hain을 삭제한다.
-P (--policy)
기본정책을 변경한다.
기본동작
패킷에 대한 동작은 순차적으로 위에서부터 차례대로 각 규칙에 대해 검사하고
그 규칙과 일치하는 패켓에 대하여 타겟에 지정한 ACCEPT, DROP, REJECT를 수행한다.
INPUT 체인에 빈도율이 잦은 트래픽을 가장 마지막에 넣으면 과부하가 걸린다.
tip
1-100까지 규칙이 있다고 가정하자
패킷은 순차적으로 진행하기 때문에 1부터 100까지 하나하나 검사하고 다음 차례로 넘어간다.
여기서 ESTABLISHED, RELATED의 경우 접속을 확립하고 관련 짓는 모듈이라 1번으로 지정을 하는데
100번에 둔다고 치면, 제대로 정책이 제대로 수행되지 않을 수 있다.
즉, 패킷이 체인의 모든 규칙과 매치하지 않아 바닥에 도달하면 정해진 기본정책이 수행되기 때문이다.
예제
INPUT 체인에 로컬호스트 인터페이스에 들어오는 모든 패킷을 허용 추가
iptables -A INPUT -i lo -j ACCEPT
INPUT 체인에 state 모듈과 매치되는 연결상태가 ESTABLISHED, RELATED인 패킷에 대해 허용 추가
(NEW,ESTABLISHED,RELATED,INVALID)
[1번 트래픽]
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
INPUT 체인에 프로토콜이 TCP이며 state 모듈과 매치되고, 연결 상태가 NEW이며 목적지 포트가 22번인 패킷에 대해 허용 추가
[1번 트랙픽]
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
P.S
[3번 트래픽]
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
[https 방화벽설정]
iptables -A INPUT -p tcp -m state --state NEW --dport 443 -j ACCEPT
핑을 주고받을 수 있도록한다.
service iptables save 설정값을 적용하기 위해선 꼭 저장을 해준다.
'리눅스 기초' 카테고리의 다른 글
리눅스) SELinux (0) | 2022.05.12 |
---|---|
리눅스) 웹 서버(아파치, html, perl, python) userdir (0) | 2022.05.12 |
리눅스) 리눅스 시스템의 부팅4(grub2) (0) | 2022.05.12 |
리눅스) 리눅스 시스템의 부팅3 (데몬 프로세스) (0) | 2022.05.12 |
리눅스) 리눅스 시스템의 부팅(2. init, systemd, systemctl, journalctl (0) | 2022.05.12 |