เคล็ดลับและเทคนิค iptables [ปิด]


60

ฉันแน่ใจว่า Linux sysadmins ค่อนข้างคุ้นเคยกับiptablesอินเตอร์เฟส userland กับnetfilterเฟรมเวิร์กการกรองแพ็คเก็ต

ตอนนี้ "คำถาม" นี้มีขึ้นเพื่อเป็นCommunity Wikiสำหรับการรวบรวมiptablesปัญญาส่วนต่างๆ ไม่มีอะไรที่ธรรมดาเกินไปหรือคลุมเครือเกินไป iptablesโพสต์สิ่งที่คุณรู้ว่าจะช่วยคนอื่นให้มากที่สุดของ

คำตอบ:


26

การใช้รายการที่อนุญาตและบัญชีดำกับ iptables

#!/bin/bash

WHITELIST=/whitelist.txt
BLACKLIST=/blacklist.txt

#THIS WILL CLEAR ALL EXISTING RULES!
echo 'Clearing all rules'
iptables -F

#
## Whitelist
#

for x in `grep -v ^# $WHITELIST | awk '{print $1}'`; do
        echo "Permitting $x..."
        $IPTABLES -A INPUT -t filter -s $x -j ACCEPT
done

#
## Blacklist
#

for x in `grep -v ^# $BLACKLIST | awk '{print $1}'`; do
        echo "Denying $x..."
        $IPTABLES -A INPUT -t filter -s $x -j DROP
done

สคริปต์เพื่อเปิดพอร์ต

#!/bin/bash
ALLOWEDTCP="80 3128 3784"
ALLOWEDUDP="3128 3784"

#
## Permitted Ports
#

for port in $ALLOWEDTCP; do
       echo "Accepting port TCP $port..."
       $IPTABLES -A INPUT -t filter -p tcp --dport $port -j ACCEPT
done

for port in $ALLOWEDUDP; do
        echo "Accepting port UDP $port..."
        $IPTABLES -A INPUT -t filter -p udp --dport $port -j ACCEPT
done

การปิดกั้นพอร์ตสแกน

# Attempt to block portscans
# Anyone who tried to portscan us is locked out for an entire day.
iptables -A INPUT   -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP

# Once the day has passed, remove them from the portscan list
iptables -A INPUT   -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove

# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

แพ็คเก็ตปลอมแปลง / ไม่ถูกต้อง

# Reject spoofed packets
# These adresses are mostly used for LAN's, so if these would come to a WAN-only server, drop them.
iptables -A INPUT -s 10.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP

#Multicast-adresses.
iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP

# Drop all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP

บล็อกการโจมตี Smurf

# Stop smurf attacks
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m icmp -j DROP

# Drop excessive RST packets to avoid smurf attacks
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

บล็อก ICMP (aka ping)

# Don't allow pings through
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP

4
พิจารณาการเพิ่มความคิดเห็นในความคิดเห็น "spoofed" เพื่อให้ผู้ใช้ที่มีประสบการณ์น้อยรู้ว่าเหตุใดที่อยู่ของแหล่งที่มาจึงถูกพิจารณาว่าเป็น spoofed (... เมื่อมาถึงอินเทอร์เฟซ wan)
3molo

1
โทรดี :-) เสร็จสิ้น
Bart De Vos

รอ. Block ICMP (aka ping) ไม่ทำซ้ำซ้อนกับ Block smurf สายโจมตี: iptables -A INPUT -p icmp -m icmp -j DROP?
Stann

2
เรื่องสคริปต์ที่อนุญาต: มีiptablesบรรทัดที่ 8 จาก$IPTABLESนั้นในภายหลัง มันเพียงพอสำหรับการใช้iptablesทุกที่หรือไม่? ไม่อย่างนั้นฉันคิดว่าคุณจะต้องมอบหมายอะไรแบบนี้IPTABLES=/sbin/iptablesใช่ไหม
UpTheCreek

1
ฉันจะไม่ปิดกั้นการสแกนพอร์ตด้วยวิธีนั้น มีบางอย่างที่จะยอมรับการเชื่อมต่อ tcp / udp และค้นหาแพ็กเก็ตที่เกี่ยวข้องหลายรายการแทน tcp เป็นเรื่องง่ายเพียงแค่ค้นหาเพื่อสร้างพอร์ตเหล่านั้น ผู้อื่นสามารถทดสอบสิ่งนี้ได้ด้วยแพ็กเก็ตปลอมแปลงและบล็อกสิ่งที่คุณไม่ได้อยู่ในรายการที่อนุญาตเช่นเกตเวย์ของคุณ
แอรอน

25

เพิ่มประสิทธิภาพการใช้ netfilter ipset

หากคุณเขียนกฎที่คล้ายกันจำนวนมากโดยพิจารณาจาก IP, พอร์ตหรือทั้งสองอย่างipsetให้ลองใช้เพื่อเพิ่มประสิทธิภาพการทำงานของ netfilter

ตัวอย่างเช่น:

iptables -s 192.168.1.11 -j ACCEPT
iptables -s 192.168.1.27 -j ACCEPT
iptables -s 192.168.1.44 -j ACCEPT
... hundreds of similar rules ...
iptables -s 192.168.251.177 -j ACCEPT

ซึ่งหมายความว่าแพ็กเก็ตที่มีแหล่งที่อยู่ 192.168.251.177 จะต้องสำรวจกฎนับร้อยก่อนจึงจะสามารถรับการตัดสินของ ACCEPT ได้

แน่นอนว่าผู้ดูแลระบบที่มีประสบการณ์จะแบ่งกฎด้วยซับเน็ต แต่นั่นก็ยังหมายถึงกฎหลายร้อย

ipset ช่วยเหลือ!

ก่อนกำหนดipmapประเภทชุด IP :

ipset -N Allowed_Hosts ipmap --network 192.168.0.0/16

จากนั้นเติมด้วยที่อยู่:

for ip in $LIST_OF_ALLOWED_IP; do ipset -A Allowed_Hosts $ip; done

สุดท้ายให้แทนที่กฎ iptables หลายร้อยรายการด้านบนด้วยกฎเดียว

iptables -m set --match-set Allowed_Hosts src -j ACCEPT

เมื่อแพ็กเก็ตมาถึง netfilter จะทำการค้นหาบิตแมปที่รวดเร็วมากสำหรับแหล่งที่มาของแพ็คเก็ต (src) IP กับAllowed_Hostsชุด IP แพ็กเก็ตทั้งหมดที่มาจาก 192.168.0.0/16 จะได้รับหนึ่งกฎ และเชื่อฉันไหมว่าการค้นหาบิตแมปเป็นลำดับอย่างน้อยสองลำดับของขนาดที่เร็วกว่าการตรวจสอบกฎ iptables หลายร้อยรายการ

ipsetไม่ จำกัด เฉพาะที่อยู่ IP นอกจากนี้ยังสามารถจับคู่ตามพอร์ต, IP-port tuple, ที่อยู่เครือข่าย / ซับเน็ต, IP-MAC tuple และอื่น ๆ และสามารถจับคู่เกณฑ์เหล่านั้นเป็นแหล่งที่มาหรือปลายทางหรือทั้งสองอย่างผสมกัน (ในกรณีของ tuples)

และในที่สุดipsetคุณสามารถใส่ที่อยู่ IP โดยอัตโนมัติในบัญชีดำ / บัญชีขาว บัญชีดำ / บัญชีขาวเหล่านี้สามารถ 'อายุ' ได้ดังนั้นการลบที่อยู่ IP โดยอัตโนมัติหลังจากผ่านเวลาที่กำหนดได้

โปรดดูรายละเอียดเพิ่มเติมในipsetหน้า man man

หมายเหตุสำคัญมาก:

Linux distros บางตัวอาจไม่รองรับการใช้งาน 'นอกกรอบ' ipset(เช่น Ubuntu 10.04 มีปัญหานี้) ในระบบเหล่านี้วิธีหนึ่งคือการติดตั้งipsetจากซอร์สโค้ด

ให้ดาวน์โหลดipsetแหล่งข้อมูลจากเว็บไซต์ของตนแทน: http://ipset.netfilter.org/install.html

หรือถ้าคุณใช้xtables-addonsipset จะรวมอยู่ในแหล่งที่มา: http://xtables-addons.sourceforge.net/


3
น่าเสียดายจริงๆที่ไม่รองรับ Debian และ Ubuntu เป็นค่าเริ่มต้น ฉันคิดว่าคุณกำลังจะแสดงรายการ distros ที่ไม่แน่นอน: /
UpTheCreek

@UpTheCreek ฉันได้แก้ไขคำตอบของฉันแล้ว ... 'โน้ตพิเศษ' มีผลบังคับใช้ในระหว่างที่โพสต์คำตอบ แต่ไม่สามารถใช้งานได้อีกต่อไป
pepoluan


16

บล็อกการโจมตี TCP ที่รู้จักกันดี

เพิ่มกฎต่อไปนี้โดยเฉพาะอย่างยิ่งใน -t raw -A PREROUTING

-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP

การโจมตีที่ถูกบล็อกคือตามลำดับ:

  • การโจมตี SYN-FIN
  • การโจมตี SYN-RST
  • การโจมตี X-Mas
  • สแกน nmap FIN
  • การโจมตีของ NULL
  • การโจมตี ALLflags

(อย่าลังเลที่จะแก้ไขชื่อของการโจมตีด้านบน)


4
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROPจะถูกลบออกในขณะที่-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROPจะจับทุกแพ็คเก็ตมันสามารถป้องกัน

4
ตามsecurity.stackexchange.com/questions/4603/... "ไม่จำเป็นต้องทิ้งแพ็กเก็ตที่ไม่ถูกต้องหรือผิดรูปแบบการโจมตีทั้งหมดนี้เป็นเวลาสิบปีแล้วเคอร์เนล Linux devs นั้นทันสมัยกว่าคุณมากเกี่ยวกับแพ็กเก็ตประเภทใดที่ใช้ได้และไม่เป็นเช่นนั้น" บางคนอาจเถียงกันคุณจะรู้ได้อย่างไรว่าข้อบกพร่องในอนาคตจะอยู่ในตัวจัดการ TCP และไม่อยู่ในตัวแยกวิเคราะห์ TCP ของ iptables ได้อย่างไร "
แมตต์

1
@VlastimilBurian ในทางทฤษฎีพวกเขาไม่ต้องการอีกต่อไป แต่การเพิ่มกฎเหล่านี้ไม่ทำให้เครือข่ายช้าลงหรือเพิ่มภาระของ CPU ดังนั้นฉันไม่เห็นเหตุผลที่จะไม่เพิ่มพวกเขาและลืมพวกเขา😊
pepoluan

7

เปิดใช้งาน NAT

  1. echo 1 > /proc/sys/net/ipv4/ip_forward
  2. /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

ขั้นตอนที่ 1 ตั้งค่าพารามิเตอร์เคอร์เนลเพื่ออนุญาตสำหรับการส่งต่อ ip ขั้นตอนที่ 2 ตั้งค่ากฎ iptables ที่เปิดใช้งาน NAT บนอินเตอร์เฟส eth0


4
สิ่งนั้นจะไม่คงอยู่ตลอดการรีบูตใช่หรือไม่ /etc/sysctl.conf net.ipv4.ip_forward = 1คุณจำเป็นต้องแก้ไข (สมมติว่า Red Hat หรืออนุพันธ์)
Aaron Copley

6

บล็อกการโจมตี ICMP

เพิ่มกฎต่อไปนี้โดยเฉพาะอย่างยิ่งใน -t raw -A PREROUTING

-p icmp -m u32 ! --u32 "4&0x3FFF=0"   -j DROP
-p icmp -m length --length 1492:65535 -j DROP

กฎข้อแรกบล็อกแพ็คเก็ต ICMP ทั้งหมดที่มี "แฟรกเมนต์แฟรกเมนต์" ไม่ใช่ 0 (ICMP ไม่ควรมีการแตกแฟรกเมนต์

กฎที่สองบล็อกแพ็คเก็ต ICMP ที่ไม่มีการจัดเรียงขนาดใหญ่


นั่นจะไม่ทำลายเส้นทาง MTU Discovery หรือไม่
แมตต์

@ ตัวเลขไม่ได้เนื่องจากการค้นพบ Path MTU ใช้แพ็กเก็ตที่มีขนาดใหญ่เท่ากับขนาดของข้อมูลอีเทอร์เน็ตคือ 1500 ไบต์ซึ่ง 8 ไบต์จะถูกใช้โดยส่วนหัว IP และส่วนหัว ICMP
pepoluan

ขอบคุณสำหรับการชี้แจง แต่ 1492-64k? ทำไมมันไม่ 1500-65k ฉันสามารถเข้าใจ 1492 สำหรับ PPPoE แต่อีเธอร์เน็ตตรง
แมตต์

ยังใช้งานได้หรือไม่
LinuxSecurityFreak

@VlastimilBurian ฉันจะตอบว่าใช่ ยังคงมีความต้องการแพ็คเก็ต ICMP ขนาดใหญ่
pepoluan

4

ใช้FireHOL - iptables wrapper ที่สะดวก

ฉันพบว่ามันใช้งานง่ายกว่าคำสั่ง iptables โดยตรง โดยเฉพาะอย่างยิ่งสำหรับผู้ที่มีประสบการณ์ในอดีตกับไฟร์วอลล์อื่น ๆ :

FireHOL เป็นเครื่องกำเนิดไฟฟ้าไฟร์วอลล์ iptables ที่ผลิตไฟร์วอลล์กรองแพ็คเก็ต iptables stateful บน Linux โฮสต์และเราเตอร์ที่มีจำนวนของเครือข่ายอินเตอร์เฟซจำนวนเส้นทางใด ๆ จำนวนบริการที่ให้บริการใด ๆ จำนวนความซับซ้อนใด ๆ ระหว่างการเปลี่ยนแปลงของบริการ (รวมถึงบวกและลบ การแสดงออก)


2
ฉันชอบ Shorewall ซึ่งได้รับการพัฒนาอย่างแข็งขันรองรับ IPv4 และ IPv6 และสามารถสร้างไฟร์วอลล์สำหรับระบบ iptables อื่น ๆ
BillThor

4

(จากไฟล์ iptables_tricks.txt ของฉันคอมไพล์ใหม่จากหลาย ๆ ที่: P)

ทำให้ iptables รอ 15 วินาทีระหว่างการเชื่อมต่อใหม่จาก IP เดียวกันบนพอร์ต 22 (SSH):

 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT

1
เหมือนกัน แต่ด้วยการนับความพยายาม:-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 --rttl --name SSH -j DROP
alexm

3

IPTABLES tutorials วิดีโอ

ตอนที่ 1 http://www.youtube.com/watch?v=ldB8kDEtTZA&feature=player_embedded

ตอนที่ 2 http://www.youtube.com/watch?v=aDaEXxRHeXY&feature=related

ตอนสุดท้าย

http://www.youtube.com/watch?v=JojqHKcSxpo&feature=player_embedded

จะเป็นการเริ่มต้นที่ดีสำหรับมือใหม่


บทช่วยสอนที่ดีมาก
Stann

3

ตรวจสอบชุด IP แล้ว

มีคำตอบที่กล่าวถึงชุด IP แล้ว อย่างไรก็ตามมันค่อนข้างเป็นมิติเดียวที่จะมุ่งเน้นไปที่ประสิทธิภาพที่เพิ่มขึ้นตามกฎดั้งเดิมและความจริงที่ว่าชุด IP ช่วยลดปัญหาที่เรามีกับที่อยู่ IP ส่วนบุคคลจำนวนมากที่ไม่สามารถแสดงได้อย่างง่ายดายในฐานะซับเน็ตในสัญกรณ์ CIDR

สัญลักษณ์ที่ใช้ด้านล่าง

สำหรับipsetผมจะใช้สัญกรณ์อ่านโดยและเขียนโดยipset restoreipset save

ตามลําดับสำหรับiptables(และip6tables) กฎผมจะใช้สัญกรณ์เป็นอ่านโดยและเขียนโดยiptables-restore iptables-saveทำให้สั้นลงและทำให้ฉันสามารถเน้นกฎIPv4-only (prefixed -4) หรือ IPv6-only (prefixed -6) ที่เป็นไปได้

ในตัวอย่างเราจะเบี่ยงเบนการไหลของแพ็กเก็ตไปเป็นสายโซ่อื่น เชนจะถือว่ามีอยู่ ณ จุดนั้นดังนั้นบรรทัดในการสร้างเชนส์จะไม่ถูกสร้างขึ้น (หรือเป็นชื่อตารางที่กล่าวถึงหรือคำสั่งCOMMIT-ted เมื่อสิ้นสุด)

ชุด IP ขั้นสูง

ชุด IP สามารถทำได้มากกว่าที่กล่าวไว้ในคำตอบอื่น ๆและคุณควรอ่านเอกสารชุด IP ( ipset(8)) พร้อมด้วยiptables-extensions(8)นอกเหนือจากรายการสั้น ๆ นี้ที่นี่

ตัวอย่างเช่นฉันจะมุ่งเน้นไปที่ชุดของสามประเภท: hash:ip, hash:netและlist:set, แต่มีมากกว่านั้นและพวกเขาทั้งหมดมีกรณีการใช้ที่ถูกต้อง

เช่นคุณสามารถตรงกับหมายเลขพอร์ตไม่ได้เป็นเพียงที่อยู่ IP

การบันทึกและกู้คืนชุด IP เช่นเดียวกับiptables-saveและiptables-restore

คุณสามารถสร้างการประกาศชุด IP เป็นกลุ่มและนำเข้าได้โดยการส่งไปipset restoreยัง ipset -exist restoreหากคุณต้องการที่จะทำให้คำสั่งของคุณมีความยืดหยุ่นมากขึ้นกับรายการที่มีอยู่แล้วให้ใช้

หากกฎของคุณอยู่ในไฟล์ที่เรียกว่าdefault.setคุณจะใช้:

ipset -exist restore < default.set

ไฟล์เช่นนั้นสามารถมีรายการที่จะcreateตั้งค่าและไปยังaddรายการต่างๆ แต่โดยทั่วไปคำสั่งส่วนใหญ่จากบรรทัดคำสั่งดูเหมือนจะมีรุ่นที่สอดคล้องกันในไฟล์ ตัวอย่าง (การสร้างชุดเซิร์ฟเวอร์ DNS):

create dns4 hash:ip family inet
create dns6 hash:ip family inet6
# Google DNS servers
add dns4 8.8.8.8
add dns4 8.8.4.4
add dns6 2001:4860:4860::8888
add dns6 2001:4860:4860::8844

ที่นี่หนึ่งชุดถูกสร้างขึ้นสำหรับ IPv4 ( dns4) และอีกชุดสำหรับ IPv6 ( dns6)

หมดเวลากับชุด IP

หมดเวลาในชุด IP สามารถตั้งเป็นค่าเริ่มต้นต่อชุดและต่อรายการ สิ่งนี้มีประโยชน์มากสำหรับสถานการณ์ที่คุณต้องการบล็อกใครบางคนชั่วคราว (เช่นสำหรับการสแกนพอร์ตหรือพยายามบังคับเซิร์ฟเวอร์ SSH ของคุณ)

วิธีการทำงานดังต่อไปนี้ (ค่าเริ่มต้นระหว่างการสร้างชุด IP):

create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800

เราจะกลับไปที่ชุดเฉพาะเหล่านี้ด้านล่างและเหตุผลว่าทำไมพวกเขาถึงตั้งค่าแบบที่พวกเขาเป็น

หากคุณต้องการตั้งค่าการหมดเวลาสำหรับที่อยู่ IP เฉพาะคุณสามารถพูดได้ว่า:

add ssh_dynblock4 1.2.3.4 timeout 7200

หากต้องการบล็อก IP 1.2.3.4 เป็นเวลาสองชั่วโมงแทนการตั้งค่าเริ่มต้นครึ่งชั่วโมง

หากคุณต้องดูสิ่งipset save ssh_dynblock4นั้นหลังจากผ่านไปครู่หนึ่งคุณจะเห็นบางสิ่งบางอย่างตามแนวของ:

create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800
add ssh_dynblock4 1.2.3.4 timeout 6954

คำเตือนหมดเวลา

  • หมดเวลาเป็นคุณสมบัติในชุดที่กำหนด หากไม่ได้สร้างชุดที่มีการสนับสนุนการหมดเวลาคุณจะได้รับข้อผิดพลาด (เช่นKernel error received: Unknown error -1)
  • หมดเวลาจะได้รับในไม่กี่วินาที ตัวอย่างเช่นใช้นิพจน์ทางคณิตศาสตร์ของ Bash เพื่อรับจากนาทีเป็นวินาที เช่น:sudo ipset add ssh_dynblock4 1.2.3.4 timeout $((120*60))

การตรวจสอบว่ามีรายการอยู่ในชุด IP ที่กำหนดหรือไม่

ภายในสคริปต์ของคุณจะเป็นประโยชน์ในการดูว่ามีรายการอยู่แล้ว สิ่งนี้สามารถทำได้โดยipset testที่คืนค่าศูนย์ถ้ารายการมีอยู่และไม่เป็นศูนย์ ดังนั้นการตรวจสอบตามปกติสามารถนำไปใช้ในสคริปต์:

if ipset test dns4 8.8.8.8; then
  echo "Google DNS is in the set"
fi

อย่างไรก็ตามในหลายกรณีคุณจะต้องการใช้-existสวิตช์ipsetเพื่อไม่ให้บ่นเกี่ยวกับรายการที่มีอยู่

การเติมชุด IP จากiptablesกฎ

ในความคิดของฉันนี้เป็นหนึ่งในคุณสมบัตินักฆ่าของชุด IP ไม่เพียง แต่คุณสามารถจับคู่กับรายการของชุด IP คุณยังสามารถเพิ่มรายการใหม่ไปยังชุด IP ที่มีอยู่

ตัวอย่างเช่นในคำตอบของคำถามนี้คุณมี:

-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT

... ด้วยความตั้งใจที่จะ จำกัด การเชื่อมต่ออัตราพยายาม SSH (พอร์ต TCP 22) โมดูลที่ใช้recentติดตามความพยายามเชื่อมต่อล่าสุด อย่างไรก็ตามแทนที่จะเป็นstateโมดูลฉันชอบconntrackโมดูลมากกว่า

# Say on your input chain of the filter table you have
   -A INPUT -i eth+ -p tcp --dport ssh -j SSH
# Then inside the SSH chain you can
# 1. create an entry in the recent list on new connections
   -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
# 2. check whether 3 connection attempts were made within 2 minutes
#    and if so add or update an entry in the ssh_dynblock4 IP set
-4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist
-6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist
# 3. last but not least reject the packets if the source IP is in our
#    IP set
-4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT
-6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT

ในกรณีนี้ฉันกำลังเปลี่ยนทิศทางการไหลไปยังSSHสายโซ่ดังกล่าวซึ่งฉันไม่ต้องทำซ้ำตัวเองด้วย-p tcp --dport sshสำหรับกฎทุกข้อ

หากต้องการย้ำ:

  • -m setทำให้iptablesทราบว่าเราใช้สวิตช์จากsetโมดูล (ซึ่งจัดการชุด IP)
  • --match-set ssh_dynblock4 srcบอกiptablesให้ตรงกับที่อยู่ต้นทาง ( src) กับชุดชื่อ ( ssh_dynblock4)
    • สิ่งนี้สอดคล้องกับsudo ipset test ssh_dynblock4 $IP(ที่$IPมีที่อยู่ IP ต้นทางสำหรับแพ็คเก็ต)
  • -j SET --add-set ssh_dynblock4 src --existเพิ่มหรือปรับปรุงแหล่งที่มา ( srcที่อยู่) ssh_dynblock4จากแพ็คเก็ตลงไปในชุด หากมีรายการอยู่ ( --exist) รายการนั้นจะได้รับการอัปเดต
    • สิ่งนี้สอดคล้องกับsudo ipset -exist add ssh_dynblock4 $IP(ที่$IPมีที่อยู่ IP ต้นทางสำหรับแพ็คเก็ต)

หากคุณต้องการที่จะตรงกับที่อยู่เป้าหมาย / ปลายทางแทนคุณต้องการใช้แทนdst srcศึกษาคู่มือสำหรับตัวเลือกเพิ่มเติม

ชุดเซต

ชุด IP สามารถมีชุดอื่น ๆ ตอนนี้ถ้าคุณติดตามบทความจนถึงที่นี่คุณจะสงสัยว่าเป็นไปได้หรือไม่ที่จะรวมชุดต่างๆ และแน่นอนมันเป็น สำหรับชุด IP จากด้านบนเราสามารถสร้างชุดข้อต่อสองชุดssh_dynblockและssh_loggedonตามลำดับเพื่อให้มีชุด IPv4-only และ IPv6-only เท่านั้น:

create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800
# Sets of sets
create ssh_loggedon  list:set
create ssh_dynblock  list:set
# Populate the sets of sets
add ssh_loggedon ssh_loggedon4
add ssh_loggedon ssh_loggedon6
add ssh_dynblock ssh_dynblock4
add ssh_dynblock ssh_dynblock6

และคำถามต่อไปที่ควรปรากฏในใจของคุณคือสิ่งนี้ช่วยให้เราสามารถจับคู่และจัดการชุด IP ในรูปแบบที่ไม่เชื่อเรื่องพระเจ้าได้หรือไม่

และคำตอบก็คือดังก้อง: ใช่! (อนิจจานี่ไม่ใช่เอกสารครั้งสุดท้ายที่ฉันตรวจสอบอย่างชัดเจน)

ดังนั้นกฎจากส่วนก่อนหน้านี้สามารถเขียนใหม่เพื่ออ่าน:

-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT

ซึ่งกระชับกว่านี้มาก และใช่นี่คือการลองและทดสอบและใช้งานได้อย่างมีเสน่ห์

รวบรวมทุกอย่างเข้าด้วยกัน: การป้องกันกำลังดุร้ายของ SSH

บนเซิร์ฟเวอร์ของฉันฉันมีสคริปต์ทำงานเป็นcronงานที่ใช้ชื่อโฮสต์จำนวนมากและแก้ไขที่อยู่ IP จากนั้นป้อนลงในชุด IP สำหรับ "โฮสต์ที่เชื่อถือได้" แนวคิดก็คือโฮสต์ที่เชื่อถือได้จะพยายามเข้าสู่เซิร์ฟเวอร์มากขึ้นและไม่จำเป็นต้องถูกบล็อกออกนานเท่าที่คนอื่น ๆ

ในทางกลับกันฉันมีทั้งประเทศที่ถูกบล็อกไม่ให้เชื่อมต่อกับเซิร์ฟเวอร์ SSH ของฉันด้วยข้อยกเว้น (ที่เป็นไปได้) ของโฮสต์ที่เชื่อถือได้ (เช่นลำดับของกฎสำคัญ)

อย่างไรก็ตามนั่นเป็นแบบฝึกหัดสำหรับผู้อ่าน ที่นี่ฉันต้องการเพิ่มโซลูชันที่เรียบร้อยที่จะใช้ชุดที่มีอยู่ในssh_loggedonชุดเพื่ออนุญาตการเชื่อมต่อที่ตามมาพยายามส่งผ่านและไม่ต้องมีการตรวจสอบข้อเท็จจริงเช่นเดียวกับแพ็กเก็ตอื่น ๆ

สิ่งสำคัญคือต้องจดจำการหมดเวลาเริ่มต้นของ 90 นาทีssh_loggedonและ 30 นาทีssh_dynblockเมื่อดูiptablesกฎต่อไปนี้:

-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m set --match-set ssh_loggedon src -j ACCEPT
-A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT

ถึงตอนนี้คุณควรถามตัวคุณเองว่าการเชื่อมต่อที่อยู่ IP สิ้นสุดลงในชุดssh_loggedonย่อยอย่างไร อ่านต่อ ...

โบนัส: เพิ่ม IP ที่คุณลงชื่อเข้าใช้ด้วยระหว่างการเข้าสู่ระบบ SSH

หากคุณทดลองsshrcและกับเพื่อน ๆ คุณจะได้เรียนรู้ข้อบกพร่องของมัน แต่ PAM มาเพื่อช่วยเหลือ โมดูลที่ชื่อpam_exec.soช่วยให้เราสามารถเรียกใช้สคริปต์ระหว่างการเข้าสู่ระบบ SSH ที่จุดที่เรารู้ว่าผู้ใช้เป็นที่ยอมรับ

ใน/etc/pam.d/sshdด้านล่างpam_envและpam_selinuxรายการเพิ่มบรรทัดต่อไปนี้:

session    optional     pam_exec.so stdout /path/to/your/script

และตรวจสอบให้แน่ใจว่าเวอร์ชันของสคริปต์ของคุณ ( /path/to/your/scriptด้านบน) มีอยู่และสามารถใช้งานได้

PAM ใช้ตัวแปรสภาพแวดล้อมเพื่อสื่อสารสิ่งที่เกิดขึ้นเพื่อให้คุณสามารถใช้สคริปต์อย่างง่ายเช่นนี้:

#!/bin/bash
# When called via pam_exec.so ...
SETNAME=ssh_loggedon
if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then
    [[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4"
    ipset -exist add $SETNAME "$PAM_RHOST"
fi

น่าเสียดายที่ipsetยูทิลิตีดูเหมือนจะไม่มีตัวกรอง netfilter ในตัว ดังนั้นเราจำเป็นต้องแยกแยะระหว่างชุด IPv4 และ IPv6 IP เมื่อเพิ่มรายการของเรา มิฉะนั้นipsetจะถือว่าเราต้องการเพิ่มอีกชุดหนึ่งให้กับชุดของชุดแทนที่จะเป็น IP และแน่นอนว่าไม่น่าจะมีชุดชื่อหลังจาก IP :)

ดังนั้นเราจึงตรวจสอบ:ที่อยู่ IP และต่อท้าย6ชื่อชุดในกรณีดังกล่าวและ4อื่น ๆ

ตอนจบ.


2

GUI ที่สามารถใช้ในการกำหนดค่า iptables ก็คือFirewall Builder ช่วยให้ผู้ใช้สร้างองค์ประกอบกฎเป็นวัตถุในฐานข้อมูลแล้วลากและวางวัตถุเหล่านี้ลงในตัวแก้ไขกฎเพื่อสร้างนโยบายไฟร์วอลล์ที่ต้องการ แอ็พพลิเคชันจะสร้างไฟล์สคริปต์พร้อมกับคำสั่ง iptables ทั้งหมดที่จำเป็นในการใช้กฎ

แตกต่างจากโซลูชัน GUI iptables GUI อื่นที่คุณสามารถจัดการการกำหนดค่า iptables ได้ครั้งละหนึ่งตัวเท่านั้นด้วย Firewall Builder คุณสามารถจัดการการกำหนดค่า iptables จำนวนมากได้จากแอปพลิเคชันเดียว ตัวสร้างไฟร์วอลล์ทำงานบน Linux, Windows และ Mac OS X มานานกว่า 10 ปีและมีผู้ใช้งานนับพันรายทั่วโลก

การเปิดเผยข้อมูลแบบเต็ม - ฉันเป็นผู้ร่วมก่อตั้ง NetCitadel ซึ่งเป็น บริษัท ที่พัฒนาตัวสร้างไฟร์วอลล์


1

ล็อกการเชื่อมต่อขาออกด้วย uid

iptables -A OUTPUT -m state --state NEW -m tcp -p tcp -m limit --limit 5/m -j LOG --log-uid --log-prefix="outgoing connection: "

พอร์ต / การส่งต่อการเชื่อมต่อ:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.1.7:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT

1
ฉันชอบNFLOGเป้าหมาย จะช่วยให้คำนำหน้าสายยาวและ daemon โหมดผู้ใช้สามารถเข้าสู่ระบบฐานข้อมูลเช่นกัน
0xC0000022L

1

จับคู่ชื่อหลาย ๆ อินเทอร์เฟซกับไวด์การ์ด

ตัวอย่าง: คุณมีeth0 และ eth1ต้องการอนุญาตการรับส่งข้อมูลระหว่างกันหรือไม่

iptables -A FORWARD -i eth+ -o eth+ -j ACCEPT

ฉันเคยใช้สิ่งนี้ในอดีตเพื่อจับคู่veth<something>อินเตอร์เฟสที่สร้างและตั้งชื่อโดย LXC แบบไดนามิก veth+ดังนั้นผมจึงสามารถจับคู่ทั้งหมดในครั้งเดียวด้วย

ฉันยังจงใจชื่ออินเตอร์เฟซบางส่วนเพื่อให้ตรงกับ_<something>_+


1

บล็อกค่า MSS ที่ผิดปกติ

iptables -t mangle -A PREROUTING -p tcp \
-m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

SYNPROXY เป้าหมายสำหรับการป้องกัน DDos

วัตถุประสงค์ของเป้าหมายนี้คือการตรวจสอบว่าโฮสต์ที่ส่งแพ็กเก็ต SYN สร้างการเชื่อมต่อหรือไม่ทำอะไรหลังจากเริ่มการเชื่อมต่อ SYN ถ้ามันไม่ทำอะไรเลยมันจะทิ้งแพ็กเก็ตโดยใช้ความพยายามเพียงเล็กน้อย

ตั้งค่าแพ็กเก็ตซิงค์เป็นตารางติดตามการเชื่อมต่อในตารางข้อมูลดิบ

iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 --syn -j CT --notrack

เปิดใช้งาน synproxy สำหรับเซิร์ฟเวอร์ http:

iptables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate INVALID,UNTRACKED \
-j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

ทรัพยากร: SYNPROXY กำหนดเป้าหมายจากบล็อก RHEL


1

การ จำกัด ที่อยู่ IP ทั้งหมดให้กับโควต้าแบนด์วิดท์ขาออกด้วยชุด IP

คุณอาจกำหนดค่าเซิร์ฟเวอร์ของคุณเพื่ออนุญาตการใช้แบนด์วิดท์ IP แต่ละ 15GiByte แต่ละรายการต่อเดือนโดยหวังว่าจะสะท้อนหรือหลีกเลี่ยงการโจมตีการใช้แบนด์วิดท์อาจเป็นโควต้าแบนด์วิดท์ตามมิเตอร์ของคุณที่ ISP ของคุณ สามารถทำได้ดังต่อไปนี้:

ขั้นแรกสร้างชุด IP สำหรับ IPv4 และ IPv6:

ipset create IP_QUOTA_SET_OUT hash:ip timeout 345600 counters
ipset create IP_QUOTA_SET_OUT_INET6 hash:ip timeout 345600 counters family inet6

ตอนนี้เพิ่มกฎ iptables ของคุณ บรรทัดแรกจะเพิ่ม IP ลงในชุดหากยังไม่มี บรรทัดที่สองจะไม่ตรงกันหากไบต์ที่ถ่ายโอนสำหรับ IP ในชุดมากกว่าจำนวนที่ระบุ จากนั้นจะทำเหมือนกันสำหรับ IPv6

iptables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT dst -j SET --add-set IP_QUOTA_SET_OUT dst --timeout 345600
iptables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT dst --bytes-gt 16106127360 -j DROP

ip6tables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT_INET6 src -j SET --add-set IP_QUOTA_SET_OUT_INET6 src --timeout 345600
ip6tables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT_INET6 src --bytes-gt 16106127360 -j DROP

วิธีนี้จะป้องกันการโจมตีเช่นผู้ใช้ที่ร้องขอไฟล์ขนาดใหญ่จากเว็บเซิร์ฟเวอร์ของคุณเป็นเวลานานหรือจากบริการใด ๆ สำหรับเรื่องนั้น สามารถทำเช่นเดียวกันสำหรับห่วงโซ่การป้อนข้อมูล


0

สิ่งที่ฉันทำส่วนใหญ่เป็นเพราะไม่รู้วิธีแก้ปัญหาที่สง่างามมากขึ้นของฉันคือการตรวจสอบบันทึก Nginx ของฉันด้วยตนเองทุก 4 ชั่วโมงและเซิร์ฟเวอร์อีเมลบันทึกทุก 2 นาทีเพื่อเข้าถึง IP ของแต่ละบุคคลมากเกินไป ฉันรันสคริปต์สองสามตัวด้วยกันที่:

  1. ตรวจสอบaccess.logและแสดงรายการ IP 10 อันดับแรกที่จัดโดยจำนวนครั้งที่พวกเขามีต่อเซิร์ฟเวอร์
  2. ดัมพ์ผลลัพธ์ลงในล็อกไฟล์
  3. ให้สคริปต์อื่นดูที่ไฟล์บันทึกนั้นและห้าม IP ใด ๆ ที่มีการเข้าชมเซิร์ฟเวอร์มากกว่า X จำนวนครั้งในช่วง X ชั่วโมงที่ผ่านมา
  4. บันทึกของฉัน iptables.save

นี่คือสิ่งที่ดูเหมือนว่า:

autoBanIPs_mail.sh
#!/bin/bash

# This script checks the last 2 minutes of log entries to see if any 
# IP has made over 99 connections

now=$(date +"%m_%d_%Y")

/root/bin/checkBadIPs_mail.sh > /home/ipChecker/ipcheckMAIL_$now.txt
cat /home/ipChecker/ipcheckMAIL_$now.txt | \
    grep " \\(\\([9][9]\\)\\|\\([0-9][0-9][0-9]\\+\\)\\) " | \
    awk '{print $2}' > /home/ipChecker/badMailIPs_$now.sh
sed -i "s/^/\/usr\/local\/sbin\/blockIP /g" /home/ipChecker/badMailIPs_$now.sh
/bin/bash /home/ipChecker/badMailIPs_$now.sh
cat /home/ipChecker/ipcheckMAIL_$now.txt >> /home/ipChecker/ipcheckMAIL_$now.log
rm /home/ipChecker/ipcheckMAIL_$now.txt
rm /home/ipChecker/badMailIPs_$now.sh
checkBadIPs_mail.sh

สิ่งหนึ่งที่สำคัญมากที่ควรทราบไว้ที่นี่คือคุณต้องตั้งค่ารายการที่ปลอดภัยหรือคุณจะเริ่มการบล็อก IP ของแท้จำนวนมากจากเซิร์ฟเวอร์ที่คุณเพิ่งได้รับอีเมลจำนวนมากจากหรือในกรณีของบันทึกอื่น ๆ เพิ่งเข้าสู่เซิร์ฟเวอร์ของคุณบ่อยครั้งด้วยเหตุผลที่ชอบด้วยกฎหมาย บัญชีขาวของฉันถูกสร้างไว้ในสคริปต์นี้โดยเพิ่ม grep pipes ทันทีหลังจาก| grep ']' | ที่ดูเหมือนอะไรอย่างนี้"grep -v 127.0 |" .
คุณต้องใช้เวลาในการสอนเซิร์ฟเวอร์ของคุณว่า IP ที่มีปริมาณการใช้งานสูงนั้นถูกต้องหรือไม่ สำหรับฉันนี่หมายความว่าฉันต้องใช้เวลาหนึ่งสัปดาห์หรือมากกว่านั้นเพื่อตรวจสอบบันทึกของฉันด้วยตนเองทุกสองสามชั่วโมงค้นหา ip ที่มีปริมาณการใช้งานสูงใน iplocation.net จากนั้นเพิ่มที่ถูกต้องเช่น amazon, box.com หรือแม้แต่บ้าน / สำนักงานของฉัน ช่วง IP ของรายการที่อนุญาตนี้ หากคุณไม่ทำเช่นนั้นคุณจะถูกบล็อกจากเซิร์ฟเวอร์ของคุณเองหรือคุณจะเริ่มบล็อกอีเมล / เว็บเซิร์ฟเวอร์ที่ถูกต้องและทำให้เกิดการหยุดชะงักของอีเมลหรือการรับส่งข้อมูล

cat /var/log/mail.log | awk \
    -v d1="$(date --date="-2 min" "+%b %_d %H:%M")" \
    -v d2="$(date "+%b %_d %H:%M")" \
    '$0 > d1 && $0 < d2 || $0 ~ d2' | \
    grep '\[' | grep '\]' | \
    grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v 127.0 | \
    awk '{print $1}' | sort | uniq -c | sort -n | tail -10
BlockIP
#!/bin/bash
sudo iptables -I INPUT -s $1 -j DROP
sudo bash -c "iptables-save > /etc/network/iptables.save"

อีกครั้งฉันรู้ว่ามันเป็นน้ำมันดิบเป็นนรกและอาจมีโปรโตคอลที่มีประสิทธิภาพดีสะอาดที่ทำทั้งหมดนี้ แต่ฉันไม่ทราบเกี่ยวกับมันและสิ่งนี้ได้ไปหนึ่งหรือสองปีในขณะนี้และทำให้คนเลวที่อ่าว สิ่งหนึ่งที่ฉันอยากจะแนะนำอย่างจริงจังมากคือคุณมีพร็อกซีหรือเซิร์ฟเวอร์อื่น ๆ ที่คุณสามารถใช้เพื่อเข้าถึงเซิร์ฟเวอร์หลักของคุณ .. เหตุผลก็คือถ้าคุณกำลังพัฒนาเว็บไซต์หนึ่งวันจากสีฟ้าและคุณ ping ตัวคุณเอง 2000 ครั้งใน 5 ชั่วโมงสำหรับการทดสอบบางอย่างคุณอาจถูกบล็อกโดยไม่มีทางกลับยกเว้นพร็อกซี

คุณเห็นได้ว่าในcheckBadIPs.shฉันใส่ grep -v 127.0 และในไฟล์จริงของฉันฉันมีกฎการเพิกเฉยต่อช่วง IP ของฉันเองและช่วง IP อื่น ๆ ที่เชื่อถือได้ แต่บางครั้ง IP ของคุณเปลี่ยนไปคุณลืมอัปเดตแล้วคุณถูกล็อค ออกจากเซิร์ฟเวอร์ของคุณเอง

อย่างไรก็ตามหวังว่าจะช่วยได้

UPDATE

ฉันเปลี่ยนสิ่งต่าง ๆ เล็กน้อยเพื่อให้ตอนนี้แทนที่จะตรวจสอบทุกสองสามชั่วโมงฉันมีบันทึกการตรวจสอบทุก 2 นาทีส่วนใหญ่บันทึก ssh auth ของฉันและบันทึกอีเมลเมื่อพวกเขาถูกทุบ :(

ฉันตั้งค่าสคริปต์เฉพาะสำหรับไฟล์บันทึกแต่ละไฟล์แม้ว่าจะง่ายพอจากสคริปต์คู่มือที่ฉันใช้เองเมื่อต้องการตรวจสอบบันทึก ดูเหมือนว่านี้:

#!/bin/bash

log=$1 time=$2

cat /var/log/${log} | awk \
    -v d1="$(date --date="-${time} min" "+%b %_d %H:%M")" \
    -v d2="$(date "+%b %_d %H:%M")" \
    '$0 > d1 && $0 < d2 || $0 ~ d2' | \
    grep '\[' | grep '\]' | \
    grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
    sort | uniq -c | sort -n | tail -10

ต้องใช้อินพุต 2 ตัวเมื่อเรียกใช้ไฟล์บันทึกที่คุณต้องการสแกนและย้อนกลับไปในอดีตที่คุณต้องการสแกน

ดังนั้นถ้าฉันต้องการตรวจสอบ mail.log สำหรับจำนวน ip บอกว่า 75 นาทีในอดีตฉันจะเรียกใช้:

$ sudo script.sh mail.log 75

บิตอย่างรวดเร็วของ googling พบฉันนี้ซึ่งดูเหมือนว่าจะทำในสิ่งที่ผมอธิบายไว้ข้างต้น: cyberciti.biz/faq/iptables-connection-limits-howto
unc0nnected

1
ดี! ฉันจะใช้ipsetแทนการขยายของ iptables chain แต่ความคิดนั้นยอดเยี่ยมและฉันคิดว่าฉันจะใช้มันกับเซิร์ฟเวอร์ที่ใช้งานจริงของฉัน ขอบคุณสำหรับการแบ่งปัน!
pepoluan

2
ฉันเพิ่งอ่านเกี่ยวกับ ipset เป็นครั้งแรกในวันอื่น ๆ และดีใจที่ได้เรียนรู้เกี่ยวกับสิ่งที่มันทำ .. ฉันกลัวเล็กน้อยที่จะใช้มันเพียงเพราะฉันอาจโคลนในตอนแรกและปิดเซิร์ฟเวอร์ลง แต่มันอยู่ในรายการสิ่งที่ฉันต้องเรียนรู้ที่นี่ ที่ถูกกล่าวว่าห่วงโซ่ iptable ของฉันน่าจะประมาณ 30-40 รายการและได้รับ 1 ใหม่ทุกวันหรือสองครั้งดังนั้นจึงไม่อยู่ในจุดที่ฉันกังวลมากเกินไป
unc0nnected

คุณถือว่า fail2ban แล้วหรือยัง
ลูกไก่

0

ฉันเห็นด้วยกับความคิดเห็นเกี่ยวกับ ipsets และการตั้งค่าสถานะ tcp แต่ยังคงมีหลายสิ่งที่ขาดหายไป:

ใช้การจับคู่ geoip xtables-addons แทน ipsets สำหรับรายการประเทศ อัปเดตข้อมูล geoip เป็นประจำ (อย่างน้อยหนึ่งครั้งต่อเดือน) ข้อมูลเป็นแบบไดนามิกมากขึ้นที่รายการ ipset ที่ใช้ไฟและลืม

พิจารณาการติดตามสถานะการเชื่อมต่อด้วยแฟล็ก tcp ตัวอย่างเช่น tcp RST หรือ ACK เหมาะสมสำหรับการเชื่อมต่อที่สร้างไว้แล้วเท่านั้น SYN เหมาะสมสำหรับการเชื่อมต่อใหม่และที่เกี่ยวข้องเท่านั้น SYN สำหรับการเชื่อมต่อที่สร้างไว้หมายความว่า SYN + ACK ของคุณสูญหายหรือพยายามแฮ็กและควรรีเซ็ตเนื่องจากการเชื่อมต่อทั้งสองด้านไม่เห็นด้วยตามที่ระบุ

แม้ว่าไม่มี SYN + RST และ FIN + RST เป็นชุดค่าผสมที่ผิดกฎหมายตอนนี้ SYN + FIN สามารถใช้ได้ภายใต้ TCP fast-open (ตัวเลือก TCP 34) โดยเฉพาะอย่างยิ่งสำหรับ DNS แพ็คเก็ต SYN แม้จะเปิดอย่างรวดเร็วก็ไม่ควรแยกส่วน ฉันไม่พิจารณากฎที่มีธง PSH และ URG ว่ามีประโยชน์ อย่าสับสนสถานะการติดตามการเชื่อมต่อกับสถานะ TCP: การตอบสนอง RST ไปยังแพ็กเก็ต SYN ได้รับการจัดตั้งขึ้นเพื่อวัตถุประสงค์ในการติดตาม

SYNPROXY สำหรับแพ็คเก็ตที่ส่งต่อและไม่เพิ่มสิ่งใด ๆ สำหรับการจัดส่งในพื้นที่นอกเหนือจากการสนับสนุน syncookie

แพ็คเก็ตข้อผิดพลาด ICMP จะอยู่ในสถานะที่เกี่ยวข้องและมีความยาว 48: 576 เสมอหากถูกต้อง ความยาว 84: 1280 สำหรับ IPv6 อื่น ๆ ทั้งหมดควรถูกละเว้น เนื่องจากขนาดสูงสุดของพวกเขาคือ MTU ขั้นต่ำจึงไม่ควรมีการแยกส่วน คำขอ ICMP (ส่ง Ping เวลาประทับ ฯลฯ ) จะเป็นเรื่องใหม่เสมอและจะมีการตอบกลับ ดร็อปแพ็กเก็ต ICMP ในสถานะอื่น

เช่นเดียวกับตัวอย่าง SSH ที่มีรายการล่าสุดและยอมรับเฉพาะแพ็กเก็ต SYN ที่ตามมาเท่านั้นควรทำเช่นเดียวกันสำหรับ SMTP และคล้ายกับ“ greylisting” บนที่อยู่ IP ที่อยู่คนเดียว

ในตารางตัวกรองกฎแรก (หรือที่สองถ้ายอมรับแพ็กเก็ตสถานะที่กำหนดไว้ก่อน) ในอินพุตและเอาท์พุตเชนควรยอมรับทุกอย่างบนอินเตอร์เฟสลูปแบ็ค คุณควรเชื่อถือแพ็กเก็ตภายในของคุณเอง หากคุณทำไม่ได้แสดงว่าคุณมีปัญหาใหญ่กว่าโซลูชันไฟร์วอลล์

สุดท้ายอย่าคัดลอกกฎโดยเด็ดขาดเว้นแต่คุณจะเข้าใจจริงๆ รายการกฎที่คล้ายกันจำนวนมากทำเช่นนั้นและส่วนใหญ่แล้วผลที่ได้นั้นน่าหัวเราะ


-2
#!/bin/bash
# The following iptables/ip6tables configurations have
# been kindly shared with us from ArckWiki. There are
# a few additions apart from what has been defined.
#
#=================Flush current definitions==============
    iptables -F
    ip6tables -F
    iptables -X
    ip6tables -X

#
#=================Chains=================================
#
#----Define chains for opened ports
    iptables -N TCP
    ip6tables -N TCP
    iptables -N UDP
    ip6tables -N UDP

#
#----Setting up the filter table for NAT
#   iptables -N fw-interfaces
#   ip6tables -N fw-interfaces
#   iptables -N fw-open
#   ip6tables -N fw-open

#
#================Default Chain reactions=================
#
#----Default FORWARD reaction
    iptables -P FORWARD DROP
    ip6tables -P FORWARD DROP

#
#----Default OUTPUT reaction
    iptables -P OUTPUT ACCEPT
    ip6tables -P OUTPUT ACCEPT

#
#----Shellshock
    iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
    ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP

#
#----Default INPUT reaction
    iptables -P INPUT DROP
    ip6tables -P INPUT DROP
#
#----Drop spoofing packets
    iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -i wlan0 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -i wlan1 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -s 10.0.0.0/8 -j DROP
    iptables -A INPUT -s 169.254.0.0/16 -j DROP
    iptables -A INPUT -s 172.16.0.0/12 -j DROP
    iptables -A INPUT -s 224.0.0.0/4 -j DROP
    iptables -A INPUT -d 224.0.0.0/4 -j DROP
    iptables -A INPUT -s 240.0.0.0/5 -j DROP
    iptables -A INPUT -d 240.0.0.0/5 -j DROP
    iptables -A INPUT -s 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 239.255.255.0/24 -j DROP
    iptables -A INPUT -d 255.255.255.255 -j DROP

#
#================Ping rate limiting globally=============
    iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 30/min --limit-burst 8 -j ACCEPT
    ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 --match limit --limit-burst 8 -j ACCEPT
    iptables -A INPUT -p icmp --icmp-type 8 -j DROP
    ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 -j DROP

#
#----flooding RST packets, smurf attack Rejection
    iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

#
#----Bogus packet DROP
    iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP

#
#================RELATED,ESTABLISHED reaction============
    iptables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    ip6tables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#
#================unfetered loopback======================
    iptables -A INPUT -i lo -j ACCEPT
    ip6tables -A INPUT -i lo -j ACCEPT

#
#================INVALID catagory of packets=============
    iptables -A INPUT -p 41 -j ACCEPT
    iptables -A INPUT --match conntrack --ctstate INVALID -j DROP
    ip6tables -A INPUT --match conntrack --ctstate INVALID -j DROP

#
#================IPv6 reactions and definitions==========
    ip6tables -A INPUT -s fe80::/10 -p icmpv6 -j ACCEPT
    ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/10 -j ACCEPT
    ip6tables -t raw -A PREROUTING --match rpfilter -j ACCEPT
    ip6tables -t raw -A PREROUTING -j DROP
#
#=======Acceptable INVALIDs and a curteous response======
    iptables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
    ip6tables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
    iptables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP
    ip6tables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP

#
#================Defining the TCP and UDP chains
#
#########################################################
#            Notes for port open definitions            #
# It is important to note that this should be config-   #
# ured differently if you're providing any routing      #
# activity for any purpose. it is up to you to actively #
# define what suites your needs to get the job done.    #
# In this example, I'm exempting IPv6 from being able   #
# to interact with SSH protocols for two reasons. The   #
# first is because it is generally easier and more com- #
# for internal networks to be deployed with IPv4. The   #
# second reason is, IPv6 can be deployed globally.      #
#########################################################
#
#----SSH configured for eth0
    iptables -A TCP -i eth0 -p tcp --dport ssh -j ACCEPT

#!---Blocking SSH interactions in IPv6
    ip6tables -A TCP -p tcp --dport ssh -j DROP

#!---Leave commented for end service device
#   iptables -A TCP -p tcp --dport 80 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 80 -j ACCEPT
#   iptables -A TCP -p tcp --dport 443 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 443 -j ACCEPT
#
#!---Uncomment for remote service to this device
#   iptables -A TCP -p tcp --dport 22 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 22 -j ACCEPT
#
#!---Uncomment if you're providing routing services
#   iptables -A UDP -p udp 53 -j ACCEPT
#   ip6tables -A UDP -p udp 53 -j ACCEPT
#
#=================Tricking port scanners=================
#
#----SYN scans
    iptables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
    ip6tables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
    iptables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP
    ip6tables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP

#
#----UDP scans
    iptables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
    ip6tables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
    iptables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP
    ip6tables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP

#
#----For SMURF attack protection
    iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
    iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
    iptables -A INPUT -p icmp -m limit --limit 2/second --limit-burst 2 -j ACCEPT
    ip6tables -A INPUT -p icmpv6 -m limit --limit 2/second --limit-burst 2 -j ACCEPT

#
#----Ending all other undefined connections
    iptables -A INPUT -j DROP
    ip6tables -A INPUT -j DROP

#
#=======Defining the IN_SSH chain for bruteforce of SSH==
#
#!---I've elected to keep IPv6 out of this realm for
#!---ease of use
    iptables -N IN_SSH
    iptables -A INPUT -p tcp --dport ssh --match conntrack --ctstate NEW -j IN_SSH
    iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP
    iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP
    iptables -A IN_SSH --match recent --name sshbf --set -j ACCEPT
    iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH

#
#==================Setting up a NAT gateway==============
#
#########################################################
#                                                       #
# I commented this half out because it's not something  #
# that will apply to all setups. Make note of all par-  #
# tinate interfaces and what exactly is going on.       #
#                                                       #
#########################################################
#
#----Setting up the FORWARD chain
#   iptables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#   ip6tables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#
#
#----Defining the fw-interfaces/open chains for FORWARD
#   iptables -A FORWARD -j fw-interfaces
#   ip6tables -A FORWARD -j fw-interfaces
#   iptables -A FORWARD -j fw-open
#   ip6tables -A FORWARD -j fw-open
#   iptables -A FORWARD -j DROP # Should be REJECT. But, fuck them
#   ip6tables -A FORWARD -j DROP
#   iptables -P FORWARD DROP
#   ip6tables -P FORWARD DROP
#
#
#----Setting up the nat table
#   iptables -A fw-interfaces -i ### -j ACCEPT
#   ip6tables -A fw-interfaces -i ### -j ACCEPT
#   iptables -t nat -A POSTROUTING -s w.x.y.z/S -o ppp0 -j MASQUERADE
#   ip6tables -t nat -A POSTROUTING -s fe::/10 -o ppp0 -j MASQUERADE
#----The above lines should be repeated specifically for EACH interface
#
#----Setting up the PREROUTING chain
#
#######################################################
#                             #
# The PREROUTING chain will redirect either port      #
# targets to be redirected. This can also redirect    #
# traffic inbound to your network from the gateway    #
# to this machine. This can be useful if you're using #
# a honeypot or have any service within your network  #
# that you want to be pointed to a specific device.   #
#                             #
#######################################################
#
#----SSH honeypot server
#   iptables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
#   ip6tables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
#----With intuition, you can configure the above to also direct specific
#----requests to other devices providing those services. The bellow will
#----be for a squid server
#   iptables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
#   ip6tables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
#   iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
#   ip6tables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
#
#===============Declare configurations=================
    iptables -nvL
    ip6tables -nvL

1
ด้วยเสียงตะโกนทั้งหมดฉันไม่สามารถเข้าใจข้อความโพสต์ของคุณ
Deer Hunter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.