Uploaded by Nguyễn Hoàng Lân

Cau hinh IPtables nang cao

advertisement
Phần này sẽ trình bày qua ví dụ cụ thể và chỉ hướng dẫn các bạn lọc packet vào. Các packet
“forward” và “output” tương tự.
Giả sử như máy chủ phục vụ Web kết nối mạng trực tiếp vào Internet qua card mạng eth0, địa
chỉ IP là 1.2.3.4. Cần lập cấu hình tường lửa cho Iptables đáp ứng các yêu cầu sau:
- Cổng TCP 80 (chạy apache) mở cho mọi người truy cập web
- Cổng 21 (chạy proftpd) chỉ mở cho webmaster (dùng để upload file lên public_html)
- Cổng 22 (chạy openssh) chỉ mở cho admin (cung cấp shell `root` cho admin để nâng cấp &
patch lỗi cho server khi cần)
- Cổng UDP 53 (chạy tinydns) để phục vụ tên miền (đây chỉ là ví dụ)
- Chỉ chấp nhận ICMP PING tới với code=0×08, các loại packet còn lại đều bị từ chối.
Bước 1: thiết lập các tham số cho nhân
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 0 > /proc/sys/net/ipv4/tcp_window_scaling
echo 0 > /proc/sys/net/ipv4/tcp_sack
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 0 > /proc/sys/net/ipv4/conf/eth0/accept_source_route
tcp_syncookies=1  bật chức năng chống DoS SYN qua syncookie của Linux
tcp_fin_timeout=10  đặt thời gian timeout cho quá trình đóng kết nối TCP là 10 giây
tcp_keepalive_time=1800  đặt thời gian giữ kết nối TCP là 1800 giây
…
Các tham số khác bạn có thể xem chi tiết trong tài liệu đi kèm của nhân Linux.
Bước 2: nạp các môđun cần thiết cho Iptables
Để sử dụng Iptables, bạn cần phải nạp trước các môđun cần thiết. Ví dụ nếu bạn muốn dùng
chức năng LOG trong Iptables, bạn phải nạp môđun ipt_LOG vào trước bằng lệnh # modprobe
ipt_LOG.
MODULES=”ip_tables iptable_filter ipt_LOG ipt_limit ipt_REJECT ipt_state
for i in $MODULES; do
/sbin/modprobe $MODULES
done
Bước 3: nguyên tắc đặt luật là “drop trước, accept sau”
Đây là nguyên tắc mà bạn nên tuân theo. Đầu tiên hãy đóng hết các cổng, sau đó mở dần
cách cổng cần thiết. Cách này tránh cho bạn gặp sai sót trong khi đặt luật cho Iptables.
iptables -P INPUT DROP thả packet trước
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT giữ các kết nối hiện tại
và chấp nhận các kết nối có liên quan
iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT chấp nhận các gói vào looback từ IP 127.0.0.1
iptables -A INPUT -i lo -s 1.2.3.4 -j ACCEPT và 1.2.3.4
BANNED_IP=”10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 224.0.0.0/4 240.0.0.0/5″
for i in $BANNED_IP; do
iptables -A INPUT -i eth0 -s $i -j DROP thả các gói dữ liệu đến từ các IP nằm trong danh sách
cấm BANNER_IP
done
Bước 4: lọc ICMP vào và chặn ngập lụt PING
LOG của Iptables sẽ được ghi vào file /var/log/firewall.log. Bạn phải sửa lại cấu hình cho
SYSLOG như sau:
# vi /etc/syslog.conf
kern.=debug /var/log/firewall.log
# /etc/rc.d/init.d/syslogd restart
Đối với các gói ICMP đến, chúng ta sẽ đẩy qua chain CHECK_PINGFLOOD để kiểm tra xem hiện
tại đamg bị ngập lụt PING hay không, sau đó mới cho phép gói vào. Nếu đang bị ngập lụt
PING, môđun LOG sẽ tiến hành ghi nhật kí ở mức giới hạn –limit $LOG_LIMIT và –limit-burst
$LOG_LIMIT_BURST, các gói PING ngập lụt sẽ bị thả hết.
LOG_LEVEL=”debug”
LOG_LIMIT=3/m
LOG_LIMIT_BURST=1
PING_LIMIT=500/s
PING_LIMIT_BURST=100
iptables -A CHECK_PINGFLOOD -m limit –limit $PING_LIMIT –limit-burst $PING_LIMIT_BURST
-j RETURN
iptables -A CHECK_PINGFLOOD -m limit –limit $LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j
LOG –log-level $LOG_LEVEL –log-prefix “fp=PINGFLOOD:warning a=DROP ”
iptables -A CHECK_PINGFLOOD -j DROP
iptables -A INPUT -i eth0 -p icmp –icmp-type echo-request -j CHECK_PINGFLOOD
iptables -A INPUT -i eth0 -p icmp –icmp-type echo-request -j ACCEPT
Bước 5: reject quét cổng TCP và UDP
Ở đây bạn tạo sẵn chain reject quét cổng, chúng ta sẽ đẩy vào chain INPUT sau. Đối với gói
TCP, chúng ta reject bằng gói TCP với cờ SYN=1 còn đối với gói UDP, chúng ta sẽ reject bằng
gói ICMP `port-unreachable`
iptables-N REJECT_PORTSCAN
iptables-A REJECT_PORTSCAN -p tcp -m limit –limit $LOG_LIMIT –limit-burst
$LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=PORTSCAN:tcp a=REJECT
”
iptables-A REJECT_PORTSCAN -p udp -m limit –limit $LOG_LIMIT –limit-burst
$LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=PORTSCAN:udp a=REJECT
”
iptables-A REJECT_PORTSCAN -p tcp -j REJECT –reject-with tcp-reset
iptables-A REJECT_PORTSCAN -p udp -j REJECT –reject-with icmp-port-unreachable
Bước 6: phát hiện quét cổng bằng Nmap
iptables-N DETECT_NMAP
iptables-A DETECT_NMAP -p tcp –tcp-flags ALL FIN,URG,PSH -m limit –limit $LOG_LIMIT –
limit-burst $LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:XMAS
a=DROP ”
iptables-A DETECT_NMAP -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -m limit –limit
$LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix
“fp=NMAP:XMAS-PSH a=DROP ”
iptables-A DETECT_NMAP -p tcp –tcp-flags ALL ALL -m limit –limit $LOG_LIMIT –limit-burst
$LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:XMAS-ALL a=DROP
”
iptables-A DETECT_NMAP -p tcp –tcp-flags ALL FIN -m limit –limit $LOG_LIMIT –limit-burst
$LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:FIN a=DROP ”
iptables-A DETECT_NMAP -p tcp –tcp-flags SYN,RST SYN,RST -m limit –limit $LOG_LIMIT –
limit-burst $LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:SYN-RST
a=DROP ”
iptables-A DETECT_NMAP -p tcp –tcp-flags SYN,FIN SYN,FIN -m limit –limit $LOG_LIMIT –
limit-burst $LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:SYN-FIN
a=DROP ”
iptables-A DETECT_NMAP -p tcp –tcp-flags ALL NONE -m limit –limit $LOG_LIMIT –limit-burst
$LOG_LIMIT_BURST -j LOG –log-level $LOG_LEVEL –log-prefix “fp=NMAP:NULL a=DROP ”
iptables-A DETECT_NMAP -j DROP
iptables-A INPUT -i eth0 -p tcp ! –syn -m state –state NEW -j DETECT_NMAP
Đối với các gói TCP đến eth0 mở kết nối nhưng không đặt SYN=1 chúng ta sẽ chuyển sang
chain DETECT_NMAP. Đây là những gói không hợp lệ và hầu như là quét cổng bằng nmap hoặc
kênh ngầm. Chain DETECT_NMAP sẽ phát hiện ra hầu hết các kiểu quét của Nmap và tiến
hành ghi nhật kí ở mức –limit $LOG_LIMIT và –limit-burst $LOG_LIMIT_BURST. Ví dụ để kiểm
tra quét XMAS, bạn dùng tùy chọn –tcp-flags ALL FIN,URG,PSH nghĩa là 3 cờ FIN, URG và PSH
được bật, các cờ khác đều bị tắt. Các gói qua chain DETECT_NMAP sau đó sẽ bị DROP hết.
Bước 7: chặn ngập lụt SYN
Gói mở TCP với cờ SYN được set 1 là hợp lệ nhưng không ngoại trừ khả năng là các gói SYN
dùng để ngập lụt. Vì vậy, ở dây bạn đẩy các gói SYN còn lại qua chain CHECK_SYNFLOOD để
kiểm tra ngập lụt SYN như sau:
iptables-N CHECK_SYNFLOOD
iptables-A CHECK_SYNFLOOD -m limit –limit $SYN_LIMIT –limit-burst $SYN_LIMIT_BURST -j
RETURN
iptables-A CHECK_SYNFLOOD -m limit –limit $LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j
LOG –log-level $LOG_LEVEL –log-prefix “fp=SYNFLOOD:warning a=DROP ”
iptables-A CHECK_SYNFLOOD -j DROP
iptables-A INPUT -i eth0 -p tcp –syn -j CHECK_SYNFLOOD
Bước 8: giới hạn truy cập SSH cho admin
SSH_IP=”1.1.1.1″
iptables -N SSH_ACCEPT
iptables -A SSH_ACCEPT -m state –state NEW -j LOG –log-level $LOG_LEVEL –log-prefix
“fp=SSH:admina=ACCEPT ”
iptables -A SSH_ACCEPT -j ACCEPT
iptables -N SSH_DENIED
iptables -A SSH_DENIED -m limit –limit $LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j LOG –
log-level $LOG_LEVEL –log-prefix “fp=SSH:attempt a=REJECT ”
iptables -A SSH_DENIED -p tcp -j REJECT –reject-with tcp-reset
for i in $SSH_IP; do
iptables -A INPUT -i eth0 -p tcp -s $i –dport 22 -j SSH_ACCEPT
done
iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -j SSH_DENIED
Bước 9: giới hạn FTP cho web-master
FTP_IP=”2.2.2.2″
iptables -N FTP_ACCEPT
iptables -A FTP_ACCEPT -m state –state NEW -j LOG –log-level $LOG_LEVEL –log-prefix
“fp=FTP:webmaster a=ACCEPT ”
iptables -A FTP_ACCEPT -j ACCEPT
iptables -N FTP_DENIED
iptables -A FTP_DENIED -m limit –limit $LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j LOG –
log-level $LOG_LEVEL –log-prefix “fp=FTP:attempt a=REJECT ”
iptables -A FTP_DENIED -p tcp -j REJECT –reject-with tcp-reset
for i in $FTP_IP; do
iptables -A INPUT -i eth0 -p tcp -s $i –dport 21 -j FTP_ACCEPT
done
iptables -A INPUT -i eth0 -p tcp –dport 21 -m state –state NEW -j FTP_DENIED
Bước 10: lọc TCP vào
iptables -N TCP_INCOMING
iptables -A TCP_INCOMING -p tcp –dport 80 -j ACCEPT
iptables -A TCP_INCOMING -p tcp -j REJECT_PORTSCAN
iptables -A INPUT -i eth0 -p tcp -j TCP_INCOMING
Bước 11: lọc UDP vào và chặn ngập lụt UDP
iptables -N CHECK_UDPFLOOD
iptables -A CHECK_UDPFLOOD -m limit –limit $UDP_LIMIT –limit-burst $UDP_LIMIT_BURST -j
RETURN
iptables -A CHECK_UDPFLOOD -m limit –limit $LOG_LIMIT –limit-burst $LOG_LIMIT_BURST -j
LOG –log-level $LOG_LEVEL –log-prefix “fp=UDPFLOOD:warning a=DROP ”
iptables -A CHECK_UDPFLOOD -j DROP
iptables -A INPUT -i eth0 -p udp -j CHECK_UDPFLOOD
iptables -N UDP_INCOMING
iptables -A UDP_INCOMING -p udp –dport 53 -j ACCEPT
iptables -A UDP_INCOMING -p udp -j REJECT_PORTSCAN
iptables -A INPUT -i eth0 -p udp -j UDP_INCOMING
Để hạn chế khả năng bị DoS và tăng cường tốc độ cho máy chủ phục vụ web, bạn có thể dùng
cách tải cân bằng (load-balacing) như sau:
Cách 1: chạy nhiều máy chủ phục vụ web trên các địa chỉ IP Internet khác nhau. Ví dụ, ngoài
máy chủ phục vụ web hiện tại 1.2.3.4, bạn có thể đầu tư thêm các máy chủ phục vụ web mới
1.2.3.2, 1.2.3.3, 1.2.3.4, 1.2.3.5. Điểm yếu của cách này là tốn nhiều địa chỉ IP Internet.
Cách 2: đặt các máy chủ phục vụ web trong một mạng DMZ. Cách này tiết kiệm được nhiều
địa chỉ IP nhưng bù lại bạn gateway Iptables 1.2.3.4 – 192.168.0.254 có thể load nặng hơn
trước và yêu cầu bạn đầu tư tiền cho đường truyền mạng từ gateway ra Internet.
Bạn dùng DNAT trên gateway 1.2.3.4 để chuyển tiếp các gói dữ liệu từ client đến một trong
các máy chủ phục vụ web trong mạng DMZ hoặc mạng LAN như sau:
# iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j DNAT –to-destination
192.168.0.1-192.168.0.4
Download