ชุดกฎ iptables มาตรฐานที่ปลอดภัยสำหรับเว็บเซิร์ฟเวอร์ HTTP พื้นฐาน


15

ฉันพยายามรวบรวมสคริปต์ iptables เซิร์ฟเวอร์พื้นฐานที่จะทำงานกับเว็บไซต์ส่วนใหญ่ที่ใช้เว็บเซิร์ฟเวอร์พื้นฐานโดยใช้ HTTP (S) และ SSH (พอร์ต 80, 443, & 22) ท้ายที่สุด VPS ส่วนใหญ่ต้องการกฎพอร์ตเริ่มต้นเหล่านี้เท่านั้นและสามารถเพิ่มเมลหรือพอร์ตเกมในภายหลังได้ตามต้องการ

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

*filter

#  Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allows all outbound traffic
#  You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allows SSH connections (only 4 attempts by an IP every 3 minutes, drop the rest)
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

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

วิธีที่ปลอดภัยที่สุดในการเปิดพอร์ตพื้นฐานที่จำเป็นสำหรับเว็บเซิร์ฟเวอร์คืออะไร?

Update: cyberciti.biz มีอีกสคริปต์ iptablesที่ดูค่อนข้างดี

นอกจากนี้แทนที่จะใช้ Denyhosts หรือ fail2ban คุณสามารถใช้iptables ตัวเองเพื่อป้องกันความพยายามในการทำซ้ำที่ไม่ดีที่ SSH


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

จุดดีเนื่องจาก VPS ส่วนใหญ่อยู่ใน VM กับคนอื่น ๆ ที่สามารถเข้าถึงได้จาก LAN ฉันจะบอกว่าการไม่ไว้ใจพวกเขาจะเป็นจุดเริ่มต้นที่ชาญฉลาด หากคุณมี VPS เพิ่มเติมคุณสามารถเพิ่มกฎในภายหลังเพื่อเข้าถึง (เช่นเว็บเซิร์ฟเวอร์ไปยังฐานข้อมูล)
Xeoncross

1
คำเตือน: หากคุณรันสคริปต์ cyberciti.biz ที่กล่าวถึงและmodprobeไม่ได้ติดตั้ง (หรือมีข้อผิดพลาดอื่น ๆ ก่อนที่คุณจะเปิดพอร์ต 22) คุณจะล็อคตัวเองออกจากเซิร์ฟเวอร์
EoghanM

คำตอบ:


14

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

ฉันใช้อันนี้เพียงมอบหมายงานที่มีค่าเล็กน้อยเท่านั้นที่จะต้องทำเพื่อให้มันใช้งานได้

  #!/bin/bash +x

  # first author: marcos de vera
  # second: joan marc riera

  ip=/sbin/iptables
  mriera="xx.xx.xx.xx"
  nsancho="yy.yy.yy.yy"
  admins="$mriera $nsancho "
  sshers=""
  mysqlrs="zz.zz.zz.zz/23"
  snmprs="uu.uu.uu.uu"
  tcpservices="80 443 22"
  udpservices=""

  # Firewall script for servername

  echo -n ">> Applying iptables rules... "

  ## flushing...
  $ip -F
  $ip -X
  $ip -Z
  $ip -t nat -F

  # default: DROP!
  $ip -P INPUT DROP
  $ip -P OUTPUT DROP
  $ip -P FORWARD DROP

  # filtering...

  # localhost: free pass!
  $ip -A INPUT -i lo -j ACCEPT
  $ip -A OUTPUT -o lo -j ACCEPT

  # administration ips: free pass!
  for admin in $admins ; do
      $ip -A INPUT -s $admin -j ACCEPT
      $ip -A OUTPUT -d $admin -j ACCEPT
  done

  # allow ssh access to sshers
  for ssher in $sshers ; do
      $ip -A INPUT -s $ssher -p tcp -m tcp --dport 22 -j ACCEPT
      $ip -A OUTPUT -d $ssher -p tcp -m tcp --sport 22 -j ACCEPT
  done

  # allow access to mysql port to iReport on sugar

  for mysql in $mysqlrs ; do
      $ip -A INPUT -s $mysql -p tcp -m tcp --dport 3306 -j ACCEPT
      $ip -A OUTPUT -d $mysql -p tcp -m tcp --sport 3306 -j ACCEPT
      $ip -A INPUT -s $mysql -p udp -m udp --dport 3306 -j ACCEPT
      $ip -A OUTPUT -d $mysql -p udp -m udp --sport 3306 -j ACCEPT
  done


  # allowed services
  for service in $tcpservices ; do
      $ip -A INPUT -p tcp -m tcp --dport $service -j ACCEPT
      $ip -A OUTPUT -p tcp -m tcp --sport $service -m state --state RELATED,ESTABLISHED -j ACCEPT
  done
  for service in $udpservices ; do
      $ip -A INPUT -p udp -m udp --dport $service -j ACCEPT
      $ip -A OUTPUT -p udp -m udp --sport $service -m state --state RELATED,ESTABLISHED -j ACCEPT
  done

  $ip -A INPUT -j LOG --log-level 4
  # VAS and VGP
  #88 tcp udp
  #389 tcp ldap queries , udp ldap ping
  #464 tcp upd kerberos
  #3268 tcp global catalog access
  for dc in ip.ip.ip.ip ; do # our dc servers for some ldap auth
      vas=88
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $vas -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $vas -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $vas -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $vas -j ACCEPT
      ldap=389
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $ldap -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $ldap -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $ldap -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $ldap -j ACCEPT
      kpasswd=464
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $kpasswd -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $kpasswd -j ACCEPT
      $ip -A INPUT -s $dc -p udp -m udp --dport $kpasswd -j ACCEPT
      $ip -A OUTPUT -d $dc -p udp -m udp --dport $kpasswd -j ACCEPT
      gca=3268
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $gca -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $gca -j ACCEPT
      vgp=445
      $ip -A INPUT -s $dc -p tcp -m tcp --dport $vgp -j ACCEPT
      $ip -A OUTPUT -d $dc -p tcp -m tcp --dport $vgp -j ACCEPT
  done


  # allow the machine to browse the internet
  $ip -A INPUT -p tcp -m tcp --sport 80 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
  $ip -A INPUT -p tcp -m tcp --sport 443 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT

  $ip -A INPUT -p tcp -m tcp --sport 8080 -m state --state RELATED,ESTABLISHED -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT


  # don't forget the dns...
  $ip -A INPUT -p udp -m udp --sport 53 -j ACCEPT
  $ip -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
  $ip -A INPUT -p tcp -m tcp --sport 53 -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 53 -j ACCEPT

  # ... neither the ntp... (hora.rediris.es)
  #$ip -A INPUT -s 130.206.3.166 -p udp -m udp --dport 123 -j ACCEPT
  #$ip -A OUTPUT -d 130.206.3.166 -p udp -m udp --sport 123 -j ACCEPT

  $ip -A INPUT -p udp -m udp --dport 123 -j ACCEPT
  $ip -A OUTPUT -p udp -m udp --sport 123 -j ACCEPT


  # and last but not least, the snmp access
  for monitor in $snmprs ; do
      $ip -A INPUT -s $monitor -p tcp -m tcp --sport 161 -j ACCEPT   # monitoring service
      $ip -A OUTPUT -d $monitor -p tcp -m tcp --dport 161 -j ACCEPT  # monitoring service
  end
  # outgoing SMTP
  $ip -A INPUT -p tcp -m tcp --sport 25 -j ACCEPT
  $ip -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT


  # temporary backup if we change from DROP to ACCEPT policies
  $ip -A INPUT -p tcp -m tcp --dport 1:1024 -j DROP
  $ip -A INPUT -p udp -m udp --dport 1:1024 -j DROP


  echo "OK. Check rules with iptables -L -n"

  # end :)

ฉันใช้มันมาระยะหนึ่งแล้วและการปรับเปลี่ยนใด ๆ จะได้รับการชื่นชมอย่างมากหากทำให้การบริหารจัดการง่ายขึ้น


เครื่องมือยอดนิยมใด ๆ ที่ใช้ SNMP (161) ผ่าน TCP หรือไม่ ฉันคิดว่ากฎเหล่านี้ควรเป็น UDP / 161
kubanczyk

1

มันดูค่อนข้างดี แต่คุณสามารถลดสิ่งต่าง ๆ ลงได้เล็กน้อย แฟล็ก -s เป็น IP ต้นทางหรือชื่อโดเมนและคุณเพิ่ม "-s 198.23.12.32" หรือที่อยู่ IP ของคุณคืออนุญาตให้ SSH จาก IP ต้นทางของคุณเท่านั้น คุณยังสามารถเลือกช่วงของ IP ต้นทางได้โดยใช้รูปแบบCIDR

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

คุณสามารถผูกfail2banกับ iptables สำหรับ pseudo-IDS fail2ban จะสแกนไฟล์บันทึกของคุณและสามารถบล็อก IP หากพวกเขาพยายามบังคับให้เข้าสู่ระบบของคุณ ตัวอย่างเช่นหากที่อยู่ IP ไม่สามารถลงชื่อเข้าใช้ SSH ได้ 5 ครั้งคุณสามารถล็อคเอาไว้ได้ทั้งวัน นอกจากนี้ยังทำงานบน FTP และอื่น ๆ อีกมากมาย (รวมถึงบ็อตที่ไม่ดีต่อ Apache) ฉันใช้มันในเซิร์ฟเวอร์ของฉันทั้งหมดเพื่อมอบการเสริมแรงบางอย่างจากการโจมตีที่ดุร้าย


ฉันใช้ DenyHosts จริง ๆ เพราะมันช่วยประหยัด 15MB หรือมากกว่า fail2ban อย่างไรก็ตาม fail2ban นั้นมีประสิทธิภาพมากกว่าและทำงานได้กับหลาย ๆ แอปพลิเคชั่น (ไม่ใช่แค่ SSH อย่าง DenyHosts) เนื่องจากผู้โจมตีถูกแบนฉันควรยังกังวลเกี่ยวกับไฟล์บันทึกที่บรรจุอย่างรวดเร็วหรือไม่ มีวิธีการหมุนไฟล์เมื่อถึงขนาดเต็มหรือไม่? หากฉันปิดการใช้งานการเข้าสู่ระบบใน fail2ban Denyhosts / Fail2ban จะยังคงมีรายการบันทึกที่จะสแกนหรือไม่ นอกจากนี้ตัวเลือกแหล่งข้อมูลจะดีสำหรับบางคน - แต่เนื่องจากฉันตั้งเป้าหมายว่าจะมีกฎชุดเริ่มต้นที่เหมือนกับตัวฉันที่เคลื่อนไหวไปมามากมายไม่สามารถใช้ตัวเลือกนั้นได้
Xeoncross

@ Xeoncross: DenyHosts เป็นกองไอโอ ฉันให้มันทำงานบนเครื่องหนึ่งที่พยายามบุกรุกจากจีนตลอดเวลา ในช่วงเวลาไม่กี่เดือน /etc/hosts.deny มี IP ไม่กี่พันตัวในเวลานี้ทำให้ sshd ใช้ทรัพยากรหมดในกล่องทำให้มีความเร็วถึง 60+ บนเครื่องซีพียูเดี่ยว ฉันเปลี่ยนเป็นล้มเหลว 2 แบนและไม่เคยมองย้อนกลับไป
hobodave

@hododave ฉันเพิ่งเริ่มต้นกับ DenyHosts ดังนั้นฉันจะเก็บความคิดนี้เป็นสิ่งแรกที่จะเปลี่ยนเมื่อสิ่งนี้กลายเป็นปัญหา
Xeoncross

1
@Xeoncross หากคุณต้องการหมุนบันทึก iptables คุณสามารถเขียนสคริปต์ logrotate.d ของคุณเองได้ ลองดูที่ /etc/logrotate.d แล้วก็คัดลอกอันใหม่และเปลี่ยนชื่อไฟล์บันทึกและมันจะถูกหมุนด้วยไฟล์บันทึกอื่น ๆ หน้าคนสำหรับ logrotate อธิบายตัวเลือกต่าง ๆ
Alan Ivey

1

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

สำหรับเซิร์ฟเวอร์ HTTP พื้นฐานคุณต้องการเปิดการเข้าถึงขาเข้าสู่พอร์ต 80 และพอร์ต 443 หากคุณใช้ HTTPS การเข้าถึงขาเข้า SSH จากที่อยู่ที่ จำกัด ไม่กี่แห่งเป็นที่ต้องการ คุณอาจต้องการล็อคการเข้าถึงขาออกเช่นกัน เปิดไฟร์วอลล์เพื่อเซิร์ฟเวอร์และบริการที่จำเป็นเท่านั้น ควรเปิด NTP และ DNS รวมถึงแชนเนลเพื่อดึงโปรแกรมแก้ไข


1

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

BillThor เริ่มพูดถึงสิ่งนี้ข้างต้น แต่ฉันแค่ตอบด้วยตัวอย่างเฉพาะ หนึ่งในสิ่งที่ดีเกี่ยวกับ iptables คือมันสามารถจดจำสถานะการเชื่อมต่อได้ซึ่งอาจส่งผลกระทบต่อประสิทธิภาพการทำงานบนไซต์ที่ถูกค้ามนุษย์อย่างหนัก แต่คุณสามารถเปลี่ยนการเข้าถึงขาเข้าของคุณบน http / https เพื่ออนุญาตการตอบกลับเฉพาะการเชื่อมต่อที่กำหนด ผู้ใช้จากการเข้าถึงขาออกได้ทั้งหมด จากนั้นกฎขาออกของคุณจะมีส่วนคำสั่งที่เกี่ยวข้องที่สร้างขึ้นซึ่งจะป้องกันไม่ให้โฮสต์ทั้งหมดของการโจมตีเสริมและชะลอตัวลงที่ต้องใช้เวทีรองเพื่อใช้ประโยชน์จากกล่องซึ่งเป็นเรื่องธรรมดามาก

ในที่สุดฉันจะบอกว่ามันเป็นการดีกว่าที่จะกำหนดนโยบาย iptables ของคุณ -P DROP แทนที่จะมี REJECT ต่อท้ายในตอนท้าย มันเป็นเรื่องของการตั้งค่าส่วนใหญ่ แต่สามารถลดข้อผิดพลาดเมื่อผนวกกับกฎที่มีอยู่แทนการแทรกหรือล้าง / รีเซ็ต


ดังนั้นฉันควรเปลี่ยน-A INPUT -j REJECTเป็น-A INPUT -P DROP?
Xeoncross
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.