[LINUX] IPTABLES 활용, 최적화 -IPset,firehol
많은 조직과 기업이 네트워크 보안을 강화하기 위해 다양한 방법을 모색하고 있습니다. 이를 위해 iptables, ipset, firehol과 같은 오픈소스툴을 유용하게 활용될 수 있습니다.
이러한 도구들을 어떻게 활용하여 네트워크 보안을 높일 수 있는지에 대해 살펴보겠습니다.
IPTABLES 명령어 및 활용
리눅스 시스템에서 네트워크 트래픽을 관리하고 보안 정책을 설정하는 데 사용되는 오픈소스 방화벽 소프트웨어입니다.
주로 방화벽 기능을 수행하며, 패킷 필터링, NAT(Network Address Translation), 포트 포워딩 등의 기능을 제공합니다.
자세한 내용은 이전 게시글을 참고하시면 더욱 좋습니다.
Linux iptables – 스마일서브 IDCHOWTO닷컴
우선 IPtables 기본명령어에 대해 몇가지 알아보겠습니다.
기본 명령어 알아보기
-
- 실행, 종료 재실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[실행]
systemctl start iptables.service
[종료]
systemctl stop iptables.service
[재시작]
systemctl restart iptables.service
[상태 확인]
systemctl status iptables
[설정파일만 적용(재시작X)]
systemctl reload iptables.service
|
cs |
-
- 적용 된 룰셋 확인 명령어
1
2
|
# iptables -nL
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp –– 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
|
cs |
iptables- 상태에서 TAB키를 두번 누르면 사용할 수 있는 명령어 목록이 표시됩니다.
-
- 룰셋 내보내기,덮어쓰기
1
2
3
4
|
//현재 적용된 룰셋을 파일에 저장함
# iptables-save > 설정파일 경로 //설정파일 룰셋을 현재 룰셋에 적용함
# iptables-restore** < 설정파일 경로
|
cs |
-
- OS별 iptables 설정 파일 default 경로
1
2
|
[Ubuntu] /etc/iptables/rules.v4
[Redhat] /etc/sysconfig/iptables
|
cs |
-
- 적용된 룰셋 전체 삭제 (파일삭제 X)
1
|
# iptables -F
|
cs |
iptables -F를 하면 아래와 같이 현재 적용되어 있는 룰셋만 삭제되는데요.
iptables-restore했던 파일 내용도 함께 사라지는 것은 아닙니다.
IPtables 룰셋을 활용하여 포트 차단 또는 허용 하기
iptables에 다양한 룰셋을 적용하여 보겠습니다.
룰셋을 적용하는 방법에는 두가지가 있습니다.
먼저 shell창에서 룰셋 적용하는 방법에 대해 몇가지 알아보겠습니다.
shell창에서 룰셋 적용하는 방법
-
-
특정 포트를 모든 IP 허용하기.
-
1
2
|
iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport [number] ACCEPT
iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport 443 -j ACCEPT //443번 포트를 모든IP에서 접근할 수 있습니다.
|
cs |
-
-
특정 포트 대역(range). 모든 IP 허용
-
1
2
3
|
iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport [number:number] -j ACCEPT
ex )iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport 50001:50005 -j ACCEPT
//범위에 있는 50001번~50005번 포트가 모든IP에서 접근할 수 있습니다.
|
cs |
-
-
특정 포트 IP대역 허용
-
1
2
3
4
5
6
|
iptables -A INPUT -s 192.168.0.0/16 -p tcp -m state –state NEW -m tcp –dport 3306 -j ACCEPT
# iptables -nL //룰셋 적용 확인.
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp — 192.168.0.0/16 0.0.0.0/0 tcp dpt:3306
|
cs |
-
특정 대역 및 특정아이피 접속 로그 저장
-
-
10번방문 시 로그가 1번 찍히게 끔 설정
-
1
2
3
|
-A INPUT -s [IP] -m statistic –mode nth –every [접속 횟수] –packet [로그저장 횟수] -j LOG –log-prefix “[문구 설정]”
-A INPUT -s 115.68.xx.xxx -m statistic –mode nth –every 10 –packet 1 -j LOG –log-prefix “VDI_TEST:”
//115.68.xx.xxx 아이피에서 10번 방문하면 로그가 1번 기록되게 설정됩니다.
|
cs |
1
2
3
4
5
6
|
iptables -vnL
//접속 카운트 수 확인 가능
/var/log/message 로그 확인
Sep 25 16:51:42 iwinv-web kernel: TEST_IDCHOWTO:IN=eth0 OUT= MAC=[mac address] SRC=115.68.xx.xxx DST=115.68.xx.xxx LEN=52 TOS=0x02 PREC=0x00 TTL=122 ID=3784 DF PROTO=TCP SPT=52649 DPT=443 WINDOW=64860 RES=0x00 CWR ECE SYN URGP=0
Sep 25 16:51:42 iwinv-web kernel: TEST_IDCHOWTO:IN=eth0 OUT= MAC=[mac address] SRC=115.68.xx.xxx DST=115.68.xx.xxx LEN=52 TOS=0x02 PREC=0x00 TTL=122 ID=3784 DF PROTO=TCP SPT=52649 DPT=443 WINDOW=64860 RES=0x00 CWR ECE SYN URGP=0
|
cs |
설정파일에서 변경하기
!!! 수정 전 백업 필수! 수정 전 백업 필수!!!
!!! 수정 전 백업 필수! 수정 전 백업 필수!!!!
OS설치 후 iptables 파일 초기 설정입니다.
vi로 파일을 열어 수정할 수 있습니다.
!!! 수정 전 백업 필수! 수정 전 백업 필수!!!
!!! 수정 전 백업 필수! 수정 전 백업 필수!!!!
1
2
|
cp -arp /etc/sysconfig/iptables /etc/sysconfig/iptables_ori //백업파일 이름은 자유롭게 설정
vi /etc/sysconfig/iptables
|
cs |
shell에서 등록하는 명령어와 유사하여 1가지만 적용 테스트를 해보겠습니다.
-
- 80번 포트 모든 IP 접근 허용
1
2
3
4
5
6
|
*filter
..
-A INPUT -p tcp -m state –state NEW -m tcp –dport 80 -j ACCEPT //추가
#-A INPUT -p tcp -m state –state NEW -m tcp –dport [포트] -j ACCEPT
..
COMMIT
|
cs |
적용을 위해 서비스 재시작 후 룰셋이 적용되었는지 확인해봅니다.
1
2
|
service iptables restart //재시작
iptables -nL //룰셋 리스트 확인
|
cs |
정상적으로 적용되는 것을 확인할 수 있습니다.
이제 위 shell에서 등록했던 내용들을 conf파일에 저장해봅시다. (restart했을 시 다시 룰셋 적용 필요)
1
2
|
iptables-save > /etc/sysconfig/iptables (저장하기)
vi /etc/sysconfig/iptables (저장되었는지 확인)
|
cs |
외부에서 방화벽 적용 테스트를 할경우 nmap명령어를 활용할 수 있습니다.
💡 linux 에서 사용하는 nmap 명령어입니다. nmap [확인할 서버IP] -p[포트번호] 아래와 같이 상태 확인을 할 수 있습니다. [ 질의 서버 > 확인 서버 ]의 방화벽 통신 확인을 합니다. [STATE 종류] filtered → 방화벽으로 제한됨. open → 해당 SERVICE 활성화 및 접근가능 closed → 해당 SERVICE 비활성화 및 접근가능. |
IPset 명령어 및 사용
IPset이란?
아래 사이트에 자세한 설명을 찾을 수 있었는데요. 설명이 자세하게 나와있어 번역하여 가져와봤습니다.
IPset Linux 커널 내부의 프레임워크로, ipset 유틸리티로 관리할 수 있습니다.
유형에 따라 IP 세트는 IP 주소, 네트워크, (TCP/UDP) 포트 번호, MAC 주소, 인터페이스 이름 또는 이들의 조합을 어떤 방식으로든 저장할 수 있으므로 항목을 세트와 일치시킬 때 매우 빠른 속도를 보장합니다.
여러 개의 IP 주소 또는 포트 번호를 저장하고 한 번에 iptables의 컬렉션과 일치시킵니다 . 성능 저하 없이 IP 주소 또는 포트에 대한 iptables규칙을 동적으로 업데이트합니다 . 하나의 단일 iptables규칙으로 복잡한 IP 주소 및 포트 기반 규칙 세트를 표현하고 IPset속도의 이점을 누리세요.
룰셋..예를들면 영수증이라고 생각하시면 될 것 같습니다. 내용이 많으면 많을수록 모든 내용을 읽는데 오래걸리기 마련입니다.
iptables도 동일합니다. 정책 설정 파일을 위에서부터 한줄 한줄 읽어나가기 떄문에 많은 룰셋이 구동 될 경우 성능에 영향을 받습니다.
이러한 이유로 서버 최적화를 목표를 두고 계시다면 IPset을 함께 활용하여 서버 운영 쾌적화에 도움을 줄 수 있습니다.
IPset 룰셋이 적용된다면 이렇게 적용됩니다.
△ 예시 사진입니다.
IPset활용 방법
ipset 명령어 사용 시 아래 에러가 나오는 경우 설치를 진행해주시면 됩니다.
1
2
3
4
5
6
|
-bash: ipset: command not found
IPset 설치
dnf install -y ipset
|
cs |
활용 예시로 22번포트로 ssh접근하는 ip리스트를 기록하게 해보겠습니다.
1
2
3
4
5
6
7
|
[ipset생성]
# ipset create [ipset명] iphash
ipset create ssh-access iphash
[iptables 룰셋입력]
# iptables -I INPUT -p tcp –dport [portnumber] -m state –state NEW -j SET –add-set [ipset명] src
iptables -I INPUT -p tcp –dport 22 -m state –state NEW -j SET –add-set ssh-access src
|
cs |
1
2
3
4
5
6
7
|
ipset list [ipset명]
ipset list ssh-access
iptables -nL //룰셋이 들어가있는지 확인
Chain INPUT (policy ACCEPT)
target prot opt source destination
SET tcp –– 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW add-set ssh-access src
|
cs |
ipset list 명령어를 할용하여 리스트를 확인할 수 있습니다.
ssh접근을 각각 다른 두개의 클라이언트에서 시도 후 확인해보았습니다.
정상적으로 리스트확인이 완료된 것을 확인할 수 있었습니다.
IPset을 활용하여 간단하게 접근 IP리스트를 제작하거나
아니면 IPset에 직접 IP리스트를 제작하여 차단 또는 허용할 수 있습니다.
firehol 적용 및 업데이트 cron설정
firehol이란?
종류별의 IP차단리스트들을 제공해주고 업데이트해주는 사이트입니다.
특징)
- 사용자 편의성: FireHOL Level 1은 사용자가 쉽게 사용할 수 있도록 설계되어 있습니다. 이는 구성 파일이나 스크립트를 통해 쉽게 적용하고 관리할 수 있다는 것을 의미합니다.
- 신뢰할 수 있는 IP 주소 목록: FireHOL Level 1은 신뢰할 수 있는 소스로부터 수집한 IP 주소 목록을 기반으로 구성됩니다. 이는 악성 활동이나 공격으로부터 시스템을 보호하기 위한 것입니다.
- 보안 강화: FireHOL Level 1은 네트워크 보안을 강화하기 위한 다양한 정책과 규칙을 포함하고 있습니다. 이는 사용자의 시스템이나 네트워크를 다양한 공격으로부터 보호하는 데 도움이 됩니다.
- 지속적인 업데이트: FireHOL Level 1은 주기적으로 업데이트되어 최신 보안 이슈에 대응합니다. 이는 사용자가 항상 최신 보안 기능을 유지할 수 있도록 도와줍니다.
출처 : FireHOL IP Lists | IP Blacklists | IP Reputation Feeds
Firehol IPList 적용 및 업데이트
firehol은 다양한 IP리스트들을 제공합니다. Firehol데몬을 설치하여 구동하는 방법도 있으나 더 간단하게 cron설정을 활용하여 보겠습니다.
적용 List : firehol_level1
|
아래 링크를 curl로 다운받고, IPset을 업데이트하는 스크립트를 작성하여 적용해보겠습니다.
https://raw.githubusercontent.com/ktsaou/blocklist-ipsets/master/firehol_level1.netset
스크립트 작성
아래 스크립트 내용을 저장합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/bin/bash
# 파일 다운로드
curl -o /tmp/firehol_level1.netset https://raw.githubusercontent.com/ktsaou/blocklist-ipsets/master/firehol_level1.netset
# ipset 생성
ipset create my_ipset2 hash:net //초기생성 후 주석처리해도됩니다.
ipset flush my_ipset2
# 파일을 읽어서 ipset에 추가
for i in $(cat /tmp/firehol_level1.netset |egrep -v “^#|^$”)
do
ipset add my_ipset2 $i
done
# 임시 파일 삭제
rm /tmp/firehol_level1.netset
|
cs |
실행권한 부여
1
|
chmod +x firehol_ipset.sh
|
cs |
스크립트 실행 시 파일이 다운로드 되며 my_ipset2에 IP목록이 업데이트됩니다.
1
2
3
4
|
# sh /root/script/firehol_ipset.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 32270 100 32270 0 0 118k 0 –:–:– –:–:– –:–:– 118k
|
cs |
스크립트 정상 확인
ipset에 적용되었는지 확인합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# ipset -L
Name: firehol_level1
Type: hash:ip
Revision: 4
Header: family inet hashsize 4096 maxelem 65536
Size in memory: 120
References: 0
Number of entries: 0
Members:
Name: my_ipset2
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 59832
References: 0
Number of entries: 1993
Members:
103.215.80.0/22
192.161.56.0/24
196.20.60.0/22
103.76.48.0/23
202.61.112.0/23
103.251.46.0/24
125.169.0.0/16
120.64.0.0/16
103.143.248.0/23
192.206.102.0/24
192.251.201.0/24
195.22.149.0/24
200.189.44.0/22
206.72.160.0/19
89.41.189.0/24
103.51.124.0/22
45.148.120.0/23
….
|
cs |
cron등록
/etc/crontab에 스크립트가 실행되도록 설정해둡니다.
1
2
3
|
0 0 * * * * root /root/script/firehol_ipset.sh
systemctl restart crond
|
cs |
iptables 등록
다음으로 IPtables에 ipset을 등록해줍니다.
1
2
3
4
5
6
7
8
9
10
11
|
# iptables -I INPUT -m set –match-set my_ipset2 src -j DROP //룰셋에 있는 IP차단
# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all — 0.0.0.0/0 0.0.0.0/0 match-set my_ipset2 src
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
|
cs |
리스트에 있는 것을 차단시키는 것으로 설정이 완료된 것을 볼 수 있습니다.
iptables 로그 별도 관리
log-prefix가 설정되어있으면 기본적으로 /var/log/messages(syslog)에 기록되나 이를 변경할 수 있습니다.
별도 iptables.log파일을 만들어 해당파일에 쌓이게끔 해보겠습니다.
iptables 확인
1
2
3
|
iptables -nL
target prot opt source destination
LOG all — 115.68.xxx.xx 0.0.0.0/0 LOG flags 0 level 4 prefix “TEST:”
|
cs |
rsyslog설정
log-prefix에서 설정하여 TEST:~로 로그가 쌓이게 끔 설정하여 로그에 ‘TEST:’가 포함되어 있을 경우 기록되게끔 설정해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[로그파일생성]
touch /var/log/iptables.log
[설정파일 구문 추가]
vi /etc/rsyslog.conf
:msg, contains, “TEST:” /var/log/iptables.log //추가
[데몬재실행]
systemctl restart rsyslog
|
cs |
로그확인
정상적으로 로그가 쌓이는 것을 확인할 수 있습니다.
1
2
3
4
5
6
|
[확인]
cat /var/log/iptables.log
Feb 26 13:37:40 hagorud99-238771 kernel: TEST:IN=eth0 OUT= MAC=fa:16:3e:cb:9f:22:fa:16:3e:fc:00:e3:08:00 SRC=115.68.xxx.xx DST=10.101.0.36 LEN=60 TOS=0x00 PREC=0x00 TTL=124 ID=36316 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=31
Feb 26 13:37:45 hagorud99-238771 kernel: TEST:IN=eth0 OUT= MAC=fa:16:3e:cb:9f:22:fa:16:3e:fc:00:e3:08:00 SRC=115.68.xxx.xx DST=10.101.0.36 LEN=60 TOS=0x00 PREC=0x00 TTL=124 ID=36317 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=32
Feb 26 13:37:50 hagorud99-238771 kernel: TEST:IN=eth0 OUT= MAC=fa:16:3e:cb:9f:22:fa:16:3e:fc:00:e3:08:00 SRC=115.68.xxx.xx DST=10.101.0.36 LEN=60 TOS=0x00 PREC=0x00 TTL=124 ID=36318 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=33
|
cs |
이렇게 다양한 방법으로 IPtables, IPset을 활용하여 서버 방화벽으로 보안강화를 하는 몇가지 방법을 안내드렸습니다.
감사합니다.