Link Search Menu Expand Document

7. DoS 拒絕服務攻擊

7-1 什麽是 DoS 拒絕服務攻擊

想像你今天開一間書店,惡意的對手找了跑腿100人在你的店門口只看不買,這一種攻擊就叫做 DoS 拒絕服務攻擊。不像前幾章,駭客的目的是竊取資料或是修改資料,DoS 攻擊的目的是讓你做不成生意,讓你的網站無法服務正常用戶。

攻擊的手法就是暴力,只要不斷地發送 HTTP 請求讓伺服器忙不過來即可。用瀏覽器不斷重新整理太慢了,讓我們安裝一個 wrk,這是一個量測 HTTP 伺服器效能的壓力測試工具:

執行 brew install wrk

執行 wrk -t12 -c400 -d30s http://localhost:3000/products

這會在 30 秒內,同時平行發送 12 個 HTTP 請求,並保持 400 個 HTTP 連線不中斷的速度,進行 http://localhost:3000/products 的壓力測試。

Running 30s test @ http://localhost:3000/products
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   468.83ms  168.30ms 888.55ms   63.89%
    Req/Sec     3.12      3.07    10.00     65.31%
  50 requests in 30.06s, 1.30MB read
  Socket errors: connect 0, read 319, write 0, timeout 14
  Non-2xx or 3xx responses: 4
Requests/sec:      1.66
Transfer/sec:     44.25KB

本機跑的 rails server 超不耐打的,這個網站基本上是廢了,你用瀏覽器已經無法正常瀏覽 http://localhost:3000 了。

強烈警告,對自己的網站打叫做”壓力測試”,對別人的網站打可是”干擾他人網路正常功能”,是犯法的行為。請不要以身試法。

7-2 如何防禦?

DoS 其實是不太好防禦的攻擊,因為並不是因為網站有什麽漏洞造成的。大方向只能想辦法去辨識攻擊方的樣態,然後進行封鎖。實務上需要臨場反應,碰到了見招拆招。

封鎖攻擊方的 IP 網路地址是最基本的手法,問題就出在樣態可能很多種,例如 DDoS (分佈式DoS)就是利用很多臺中毒的電腦,同時進行攻擊,那麽來源 IP 就很多,防禦方就不容易判斷哪一些是正常用戶流量、哪一些是惡意的。

在 Rails 中,可以安裝 rack-attack gem,這可以設定當特定 IP 位址就某一段時間記憶體取太多次的話,自動進行封鎖:

不過困難點在於太多次是多少次,設太低會阻擋到正常用戶,例如有些公司組織很可能是很多人共享同一個 IP 位址來上網的,透過 VPN 科學上網的話,來源 IP 也是很多人共享的。但是設太高又沒效果。

編輯 Gemfile

+  gem 'rack-attack'

執行 bundle

編輯 config/application.rb

+     config.middleware.use Rack::Attack

新增 config/initializers/rack-attack.rb

class Rack::Attack

  throttle('req/ip', :limit => 180, :period => 1.minutes) do |req|
    req.ip
  end

  ### Prevent Brute-Force Login Attacks ###

  # The most common brute-force login attack is a brute-force password
  # attack where an attacker simply tries a large number of emails and
  # passwords to see if any credentials match.
  #
  # Another common method of attack is to use a swarm of computers with
  # different IPs to try brute-forcing a password for a specific account.

  # Throttle POST requests to /login by IP address
  #
  # Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}"
  throttle('logins/ip', :limit => 5, :period => 20.seconds) do |req|
    if req.path == '/users/sign_in' && req.post?
      req.ip
    end
  end

  # Throttle POST requests to /login by email param
  #
  # Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{req.email}"
  #
  # Note: This creates a problem where a malicious user could intentionally
  # throttle logins for another user and force their login requests to be
  # denied, but that's not very common and shouldn't happen to you. (Knock
  # on wood!)
  throttle("logins/email", :limit => 5, :period => 20.seconds) do |req|
    if req.path == '/users/sign_in' && req.post?
      # return the email if present, nil otherwise
      req.params['email'].presence
    end
  end

end

重啟伺服器。以上設定包括:

  1. 一分鐘內,一個 IP 位址只能存取 180 次
  2. 針對 /users/sign_in 這個登入網址,20 秒內只能嘗試登入 5 次
  3. 針對 /users/sign_in 這個網址,同一 email 在 20 秒內只能嘗試登入 5 次

另外可以做的事情就是,改進網站效能:假如你有一個頁面效能很爛,需要跑好幾秒,這麽這就是網站 DoS 的弱點,因為駭客只要去打這個頁面就有最好的攻擊效果。

如果真的面臨大量的 DDoS 攻擊,就不是 Rails 應用層級可以處理得了,必須購買專門的網路防火牆,例如 CloudflareGoogle Cloud ArmorAWS Shield百度安全雲盾DDoS高防IP等等雲服務商的產品。


Copyright © 2010-2022 Wen-Tien Chang All Rights Reserved.