<https://happist.com/573574/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%B0%A9%ED%99%94%EB%B2%BD-%EA%B0%95%ED%99%94%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%9A%B0%EB%B6%84%ED%88%AC-iptables-%EC%84%A4%EC%A0%95%EB%B2%95-ddos-%EB%B0%A9%EC%96%B4#HTTPHTTPS_heoyong>
<https://tdoodle.tistory.com/entry/IPtables%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-DDoS-%EB%B0%A9%EC%96%B4-%EA%B6%81%EA%B7%B9%EC%9D%98-%EA%B0%80%EC%9D%B4%EB%93%9C>
<https://linuxstory1.tistory.com/entry/iptables-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%B0%8F-%EC%98%B5%EC%85%98-%EB%AA%85%EB%A0%B9%EC%96%B4>
## 기본 정책 
<https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rpg2003a&logNo=221179743333> 

DDOS, CC 방어 기본

## iptables 명령어(command)
#-A (–-append) : 새로운 규칙을 추가
#-C (–check) : 패킷을 테스트
#-D (–delete) : 규칙을 삭제
#-F (–flush) : chain 으로 부터 규칙을 모두 삭제
#-I (–Insert) : 새로운 규칙을 삽입
#-L (–list) : 규칙을 출력
#-N (–new) : 새로운 chain을 만듬
#-P (–policy) : 기본정책을 변경
#-R (–replace) : 새로운 규칙으로 교체
#-X (–delete-chain) : chain 을 삭제
#-Z (–zero) : 모든 chain의 패킷과 바이트 카운터 값을 0으로 만듬

## 매치(match)
#iptables에서 패킷을 처리할 때 만족해야 하는 조건을 가리킵니다.
#즉, 이 조건을 만족시키는 패킷들만 규칙을 적용합니다.
#-s (-–source) : 출발지 IP주소나 네트워크와의 매칭 (지정하지 않을시 any)
#-d (-–destination) : 목적지 IP주소나 네트워크와의 매칭 (지정하지 않을시 any)
#-p (-–protocol) : 특정 프로토콜과의 매칭
#-i (-–in-interface) : 입력 인터페이스
#-o (-–out-interface) : 출력 인터페이스
#–state : 연결상태와의 매칭
#–comment : 커널 메모리 내의 규칙과 연계되는 최대 256바이트 주석
#-y (–syn) : SYN 패킷을 허용하지 않음
#-f(–fragment) : 두번째 이후의 조가게 대해서 규칙을 명시한다.
#-t (–table) : 처리될 테이블
#-j (–jump) : 규칙에 맞는 패킷을 어떻게 처리할것인가를 명시한다.
#-m (–match) : 특정 모듈과의 매치
#--deport: 목적지 포트 --dport [서비스번호] 로 입력
#--sport: 출발지 포트 입력방법은 상동

## 타겟(target)
# iptalbes에서 패킷이 규칙과 일치할 때 동작을 취하는 타겟을 지원합니다.
#ACCEPT : 패킷을 받아들임.
#DROP : 패킷을 버림 (패킷전송이 없었던 것 처럼)
#REJECT : 패킷을 버리고 이와 동시에 적절한 응답 패킷을 전송
#LOG : 패킷을 syslog에 기록
#RETURN : 호출 체인 내에서 패킷 처리를 지속함

# 삭제 iptables -D INPUT -s 211.202.2.100/32 -j ACCEPT

#!/bin/bash

# Filter 테이블은 -t (-table) 옵션을 사용하지 않으면 규칙이 사용하는 가장 일반적으로 사용되는 기본 테이블입니다.
# sport - 출발지 dpoer - 목적지

# 기본설정 모두 드랍
-P INPUT DROP #서버로 들어오는 패킷 제어
-P FORWARD DROP # 브릿지 방화벽, VPN 등등
-P OUTPUT ACCEPT # 외부 나가는 패킷 제어

# 관리자 아이피 (출발지 아이피 주소로(-s) 통과 (-j) )
iptables -A INPUT -s 1.212.55.18 -j ACCEPT
iptables -A INPUT -s 115.88.69.98 -j ACCEPT
iptables -A INPUT -s 59.22.201.116 -j ACCEPT

# TCP 포트 22번을 SSH 접속을 위해 허용 
# 원격 접속을 위해 먼저 설정합니다 
# -m tcp (tcp 포트를 tcp포트와 매치하기)는 생략해도 가능 한듯 보인다 다 적어 준 부분
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

# 로컬호스트(loopback) 접속 허용
# 일반적으로 많은 소프트웨어들이 localhost 어댑터와 통신이 되어야 하기때문에 필요
-A INPUT -i lo -j ACCEPT "OK"

# established and related 접속을 허용 
# 일반적으로 네트워크 트래픽은 양방으로 흘러야 한다 때문

에 established and related 접속 허용 
#NEW : 이전에 없던 패킷의 새로운 첫 연결 요청이 Client PC로부터 들어오는 패킷을 의미한다.
#ESTABLISHED : NEW 상태를 거친 이후의 패킷 / 새로운 연결 요청에 관한 그 후의 패킷들이 오고가는 상태를 의미한다.
#RELATED : 새로운 연결 요청이지만, 기존의 연결과 관련된 패킷을 의미한다. (FTP 데이터 전송, ICMP 에러 전송 등)
#INVALID : 이전 상태 중에 어떠한 것도 적용되지 않으면 패킷의 상태를 INVALID로 표시합니다. (결론: 비정상적인 접근)
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT "OK"

# 1초동안 80포트에 똑같은 IP가 10번 이상의 SYN가 들어오면 드랍시킨다. (즉, 정상적인 요청이 아닌 웹서비스 공격으로 간주하여 요청패킷을 폐기시켜 응답하지 않도록 한다.) 
-A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP
-A INPUT -p tcp --dport 443 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP

# Apache 서비스 허용 
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# NEW state 는 호스트 시스템에 의해 시작되지 않은 수신 연결의 첫 번째 패킷인 수신 패킷을 나타냅니다. 예는 TCP 연결의 SYN 패킷입니다. 
# 그러나 패킷은 SYN 패킷이 아닐 수도 있으며 여전히 NEW로 간주됩니다.
-A INPUT -m state --state NEW -m tcp -p tcp -m multiport --sports 80,443 -j ACCEPT

#FTP 서비스 허용
-A INPUT -p tcp --dport 21 -j ACCEPT
# 1024 이상의 나머지 포트
-A INPUT -p tcp --dport 1024:65535 -j ACCEPT

#DNS 클라이언트 서비스 허용
-A INPUT -p tcp --dport 53 -j ACCEPT
-A INPUT -p udp --dport 53 -j ACCEPT

#STMP 메일발송 서비스 허용
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 465 -j ACCEPT

#핑 허용
-A INPUT -p icmp -j ACCEPT "OK"

#디도스 방어 시작

#mangle 테이블은 패킷과 헤더 정보를 수정하거나 표시하는 데 사용

#Block Invalid Packets(이 규칙은 SYN 패킷이 아니며 설정된 TCP 연결에 속하지 않는 모든 패킷을 차단합니다.)
iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP

#Block New Packets That Are Not SYN(SYN이 아닌 새 패킷 차단)
iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

#Block Uncommon MSS Values(흔하지 않은 MSS 값 차단)
iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

#Block Packets With Bogus TCP Flags(가짜 TCP 플래그가있는 패킷 차단)
#가짜 TCP 플래그(합법적인 패킷이 사용하지 않는 TCP 플래그)를 사용하는 패킷을 차단
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

#Block Packets From Private Subnets (Spoofing)(개인 서브넷의 패킷 차단 (스푸핑))
iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP 
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP 
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP 
iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP 
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP

#Drop ICMP (you usually don’t need this protocol)(모든 ICMP 패킷이 삭제)
# ICMP는 호스트가 아직 살아 있는지를 핑 (ping)하는 데에만 사용됩니다. 일반적으로 필요하지 않음
iptables -t mangle -A PREROUTING -p icmp -j DROP

#Drop fragments in all chains(단편화 된 패킷을 차단. 일반적으로 UDP는 필요하지 않으며 UDP 단편화를 완화)
iptables -t mangle -A PREROUTING -f -j DROP

# 일반 에 합쳐진다
#Limit connections per source IP (연결이 100 개 이상인 호스트의 연결을 거부)
iptables -A INPUT -p tcp -m connlimit --connlimit-above 100 -j REJECT --reject-with tcp-reset

#Limit RST packets(들어오는 TCP RST 패킷을 제한하여 TCP RST 플러드를 완화)
iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT 
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP

#Limit new TCP connections per second per source IP(클라이언트가 초당 설정할 수있는 새로운 TCP 연결을 제한)
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT 
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP

#Use SYNPROXY on all ports (disables connection limiting rule)
#모든 포트에서 SYNPROXY 사용(연결 제한 규칙 비활성화)
#SSH brute-force protection
#SSH 무차별 대입 보호
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set 
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

#Protection against port scanning(포트 스캐닝으로부터 보호)
/sbin/iptables -N port-scanning 
/sbin/iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN 
/sbin/iptables -A port-scanning -j DROP

# 저장 (수동입력은 리스타트 해야 적용됨, 명령줄 입력은 save 해야 입력됨)
# centos7 기본적으로 파이어월 설치되어있음 아이피 끄고 아이피 테이블 설치 해야 함

# 파이어월 상태 확인
firewall-cmd --state
# 파이어월 정지
$ systemctl stop firewalld
# 파이어월 자동 재시작 정지
$ systemctl mask firewalld

# 아이피 테이블 설치
$ yum install iptables-services
# 부팅시 자동으로 실행 되도록
$ systemctl enable iptables
# 이거 최초 해줘야 실행 되는듯 최초 실행시 그냥 건너띄어 봐야 할 듯
$ sudo service iptables save
# 아이피 테이블 시작
$ sudo service iptables start

# 정책 보기
$ iptables -L -v 
# 상태 보기
$ sudo service iptables status

#저장
# 1. 콘솔에서 적용
service iptables save -> service iptables restart

# 2. iptables 직접 수정
service iptables restart -> service iptables save

#재부팅(설정 후 해줘야 적용)

# 이거 하면 안됨 다 날라감 이건 명령어줄로 적용 시키는것

# 집 아이피 최 상단에 적용 해놔야 안전
iptables -A INPUT -s 1.212.55.18 -j ACCEPT
iptables -A INPUT -s 59.22.201.116 -j ACCEPT

iptables -I INPUT 8 -p tcp --sport 80 --dport 1024:65535 -j ACCEPT
iptables -I INPUT 8 -p tcp -m tcp --sport 443 --dport 1024:65535 -j ACCEPT
iptables -I INPUT 8 -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT

iptables -D INPUT -p tcp --sport 80 --dport 1024:65535 -j ACCEPT
iptables -D INPUT -p tcp -m tcp --sport 443 --dport 1024:65535 -j ACCEPT
iptables -D INPUT -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT
iptables -D INPUT -p tcp --dport 1024:65535 -j ACCEPT

iptables -I INPUT 1 -p tcp --dport 5666 -j ACCEPT
iptables -I INPUT 8 -p tcp --dport 1024:65535 -j ACCEPT

iptables -D INPUT -p tcp --dport 5666 -j ACCEPT

# iptables-config
IPTABLES_SAVE_ON_RESTART="yes"
IPTABLES_SAVE_ON_STOP=" yes"

# iptables 설정 변경 값 저장 및 서비스 재시작 (chkconfig iptables on = 시작프로그램 등록)
service iptables save chkconfig iptables on
열린포트 확인
netstat -tnlp

# 열려 있어야 하는 포트 목록
21
22
25
80
443
444
445
446
447
448
449
450
3306

# 나머지는 장애 확인시 오픈