Aturan-set iptables aman dan standar untuk server web HTTP dasar

15

Saya telah mencoba untuk menyusun skrip iptables server dasar yang akan berfungsi untuk sebagian besar situs hanya menjalankan server web dasar menggunakan HTTP (S) dan SSH (port 80, 443, & 22). Lagi pula, sebagian besar VPS hanya membutuhkan aturan port awal ini dan dapat menambahkan port mail atau game nanti sesuai kebutuhan.

Sejauh ini saya memiliki ruleset berikut dan saya bertanya-tanya apakah ada yang tahu tentang skrip yang lebih baik atau perbaikan apa pun yang dapat ditambahkan.

*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 adalah salah satu bagian paling penting dari pengamanan kotak Anda (juga lihat fail2ban) namun ada banyak orang seperti saya yang kesulitan memahami segala sesuatu yang membuat firewall dasar aman untuk server kami.

Apa cara paling aman untuk hanya membuka port dasar yang diperlukan untuk server web?

Pembaruan: cyberciti.biz memiliki skrip iptables lain yang terlihat cukup bagus.

Selain itu, daripada menggunakan Denyhosts atau fail2ban, Anda dapat menggunakan iptables sendiri untuk memblokir upaya berulang yang buruk di SSH .

Xeoncross
sumber
Anda mengatakan itu VPS. Saya menganggap itu memiliki IP LAN juga kan? Apakah Anda mempercayai setiap mesin di subnet Anda? Seberapa paranoid Anda ingin berada di sini, Anda bisa menggunakan pemfilteran OUTPUT untuk lebih mengamankan mesin Anda. Beri tahu saya dan saya bisa menanggapi dengan apa yang saya sarankan Anda gunakan.
hobodave
Poin baiknya, mengingat bahwa sebagian besar VPS berada dalam VM dengan yang lainnya dapat diakses dari LAN, saya akan mengatakan bahwa tidak memercayai mereka akan menjadi tempat awal yang cerdas. Jika Anda memiliki VPS tambahan maka Anda dapat menambahkan aturan nanti untuk mengaksesnya (mis. Server web ke basis data).
Xeoncross
1
PERINGATAN: jika Anda menjalankan skrip cyberciti.biz yang disebutkan dan modprobetidak diinstal (atau ada kesalahan lain sebelum Anda membuka port 22), Anda akan mengunci diri dari server.
EoghanM

Jawaban:

14

Cara paling aman untuk bekerja dengan iptables adalah menutup semuanya dan hanya membuka apa yang Anda butuhkan. Saya agak terganggu, jadi saya selalu mencoba untuk menjadi malas mungkin, jadi saya tidak membuat kesalahan yang dapat menyebabkan server menjadi tidak aman.

Saya menggunakan ini, hanya sedikit penugasan varible harus dilakukan untuk membuatnya bekerja.

  #!/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 :)

Saya telah menggunakannya untuk beberapa waktu, dan segala jenis modifikasi akan sangat dihargai jika membuatnya lebih mudah untuk diadministrasikan.

marc.riera
sumber
Apakah ada alat populer yang menggunakan SNMP (161) melalui TCP? Saya pikir aturan ini harus UDP / 161.
kubanczyk
1

Ini terlihat cukup bagus, tetapi Anda bisa sedikit memperketat. Bendera -s adalah IP sumber atau nama domain, dan Anda menambahkan "-s 198.23.12.32" atau apa pun alamat IP Anda hanya mengizinkan SSH dari IP sumber Anda. Anda juga dapat memilih rentang IP sumber dengan menggunakan notasi gaya CIDR .

Anda harus berhati-hati saat mencatat panggilan yang ditolak. Alamat IP server Anda akan dipindai oleh bot, skrip kiddies, dll, dan file log bisa menjadi agak besar dengan cepat. Kecuali Anda mencoba mendiagnosis masalah tertentu yang menurut Anda mungkin terkait dengan seseorang yang mencoba membobol firewall Anda, saya akan menghapus opsi ini.

Anda juga bisa mengikat fail2ban ke iptables untuk pseudo-IDS. fail2ban akan memindai file log Anda dan dapat memblokir IP jika mereka mencoba memaksa masuk ke sistem Anda. Misalnya, jika alamat IP tertentu gagal masuk ke SSH 5 kali, Anda dapat mengunci mereka sepanjang hari. Ini juga berfungsi pada FTP dan banyak lainnya (termasuk bot buruk yang menabrak Apache). Saya menggunakannya di semua server saya untuk memberikan beberapa bantal tambahan dari serangan brute-force.

Alan Ivey
sumber
Saya benar-benar menggunakan DenyHosts karena menghemat 15MB atau lebih dari fail2ban. Namun, fail2ban lebih kuat dan berfungsi dengan banyak aplikasi (bukan hanya SSH seperti DenyHosts). Mengingat penyerang dilarang, haruskah saya masih khawatir tentang file log yang diisi hingga cepat? Apakah ada cara untuk memutar file ketika sudah penuh? Jika saya menonaktifkan login di fail2ban apakah Denyhosts / Fail2ban masih memiliki entri log untuk dipindai? Juga, opsi sumber akan bagus untuk beberapa orang - tetapi karena saya bertujuan untuk menetapkan aturan standar orang-orang seperti saya yang sering berpindah-pindah tidak dapat menggunakan opsi itu.
Xeoncross
@Xeoncross: DenyHosts adalah imo tumpukan mengepul. Saya menjalankannya pada satu mesin yang terus-menerus mendapat upaya intrusi dari Cina. Selama periode beberapa bulan /etc/hosts.deny tumbuh memiliki beberapa ribu IP di dalamnya, yang pada saat itu menyebabkan sshd menghabiskan sumber daya di dalam kotak, meningkatkan beban hingga 60+ pada satu mesin CPU. Saya beralih ke fail2ban dan tidak pernah melihat ke belakang.
hobodave
@Hobodave Saya baru saja mulai dengan DenyHosts jadi saya akan menjaga pikiran ini sebagai hal pertama yang beralih ketika ini menjadi masalah.
Xeoncross
1
@ Xeoncross jika Anda ingin memutar log iptables, Anda dapat menulis skrip logrotate.d Anda sendiri untuk itu. Lihatlah /etc/logrotate.d dan salin yang lain dan ubah nama file log dan itu akan diputar dengan file log lainnya. Halaman manual untuk logrotate menjelaskan berbagai opsi.
Alan Ivey
1

Lihatlah Shorewall. Konfigurasi default antarmuka tunggal akan menjadi titik awal yang baik. Mudah dikonfigurasikan, dan memiliki makro untuk hal-hal seperti SSH dan akses Web. Dapat dikonfigurasikan untuk mengunci server ke level yang diinginkan ketika firewall dimatikan. Dengan Shorewall-lite, Anda dapat menjalankan pembangunan firewall di server lain. Logging mudah dikonfigurasi ke level yang diinginkan.

Untuk server HTTP dasar Anda ingin membuka akses masuk ke port 80 dan port 443 jika Anda menggunakan HTTPS. Akses masuk SSH dari beberapa alamat terbatas biasanya diinginkan. Anda mungkin ingin mengunci akses keluar juga. Buka firewall hanya untuk server dan layanan yang diperlukan. NTP dan DNS harus dibuka, serta saluran untuk mengambil tambalan.

BillThor
sumber
1

Saya akan mengatakan ini adalah firewall yang cukup bagus, kecuali bahwa itu diarahkan untuk menghentikan lalu lintas masuk, dan tidak berfokus pada lalu lintas keluar atau keluar. Dalam banyak kasus, sama pentingnya untuk fokus pada koneksi keluar dari kotak seperti yang masuk. Dalam kasus yang disayangkan bahwa mesin tersebut benar-benar dieksploitasi, alangkah baiknya jika dapat mencegah mengunduh root kit tambahan, atau menyambung ke komando dan mengendalikan node, atau apa pun.

BillThor mulai membicarakan hal ini di atas, tetapi saya hanya menjawab dengan contoh-contoh spesifik. Salah satu hal yang menyenangkan tentang iptables adalah ia dapat mengingat status koneksi, ini dapat memiliki implikasi kinerja pada situs-situs yang sangat banyak diperdagangkan, tetapi Anda dapat mengubah akses masuk Anda di http / https untuk hanya membolehkan balasan pada koneksi yang telah dibuat misalnya, atau secara khusus membatasi orang-orang tertentu yang tidak terjangkau pengguna dari memiliki akses keluar sama sekali. Maka aturan keluar Anda akan memiliki klausa TERKAIT, DIDIRIKAN yang akan mencegah seluruh host serangan tambahan dan memperlambat yang membutuhkan tahap sekunder untuk benar-benar mengeksploitasi kotak, yang sangat umum.

Akhirnya, saya akan mengatakan bahwa lebih baik untuk menetapkan kebijakan iptables Anda -P DROP daripada menambahkan TOLAK di akhir. Sebagian besar masalah preferensi, tetapi dapat mengurangi kesalahan saat menambahkan ke rantai dengan aturan yang ada alih-alih menyisipkan atau membilas / mengatur ulang.

MattyB
sumber
Jadi saya harus berubah -A INPUT -j REJECTmenjadi -A INPUT -P DROP?
Xeoncross