Rails 如何用 Rack::Attack 對付駭客 hacking
WriterShelf™ is a unique multiple pen name blogging and forum platform. Protect relationships and your privacy. Take your writing in new directions. ** Join WriterShelf**
WriterShelf™ is an open writing platform. The views, information and opinions in this article are those of the author.
Article info
This article is part of:
分類於:
標籤:
日期:
創作於:2019/02/18,最後更新於:2020/07/27。
合計:4237字
Like
or Dislike
About the Author
很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯
More to explore
如果你有看過你的 web server log,你一定會很驚訝,怎麼會有那麼多的奇怪要求,他們有時會來要求一些不存在的網頁,有時十秒內要求同一個網頁幾十次甚至上百次,還有很多要來讀 /adm 的,這些在我看來,都應該是要被認為是 hacker 的行為,他們很討厭,想要用這些笨方法來試出你網頁的漏洞,看你是不是沒做好基本的保護,目的應該不外乎炫耀、偷網站的資料,或是,植入木馬,不管他們有沒有成功,這些「夭壽鬼」至少佔用了你付錢買的頻寬及讓你的 server 負擔加重,至少讓你的網站反應變慢,真的很討厭,我們有沒有辦法對付他們呢?
先來看看有多少夭壽鬼
最簡單的方法就是看你的 rails server log,它通常就在你的 /log 裡,只是你要一條一條的看,很累啊,當你發現一些可疑的網站時,你可以用:
grep -B 3 -A 2 "夭壽鬼ip" 你的server.log
來更簡單的查出到底這個 ip 來做了什麼,加一個
-c
,你就可以知道這個夭壽鬼來了幾次,你一定會很驚訝,怎麼那麼多啊!查 log 總是麻煩,我覺得一定要裝的工具就是:logwatch,這是個老工具了,如果你還沒裝,強烈建議,網站上很多參考,如果你是用最流行了 ubuntu,以下的這篇文章寫得不錯:
執行了 logwatch 後,你就可以在報告的 httpd 那部分,看到到底有那些來搞亂的 http 要求,你可能不看還好,看了以後一定昏倒,怎麼有那麼多的夭壽鬼啊,如果你還順便看了一下 ssh,你會更昏倒,這世界怎麼有那麼多夭壽鬼,真希望有個方法對付他們,可惜的是,沒有一個一勞永逸的方法,但是 Rails 有一個還不錯的 gem 可以幫你只擋一部分,就是 Rack:Attack,我們接下來就來看看,怎麼用 Rack::Attack 來做一些基本的防禦。
Rack::Attack
這個 gem 使用很簡單,下面就是它的官網連結:
GitHub
各位一定乖乖的好好的看官方正式說明啦,不能只依靠這篇文章,我可不要付那麼大的責任啊,我這篇只是「輔助」,雖然,這是我認我我寫的比較好懂,貼近使用目的⋯⋯
要對付夭壽鬼駭客,當然就要先認識那些是夭壽鬼,Rack::Attack 基本上只能
而且,你要擋得很小心,不要把你可愛的顧客給擋掉了,也不要擋掉你可能很需要的 google 機器人,那麼,我們來看看有那些是有可能的夭壽鬼呢?
這是我目前有想到的,也許還有其他要擋的,也歡迎大家提出分享。 接下來,我們就來安裝 Rack::Attack 吧。
安裝 Rack::Attack
加入 gem: 就跟其他的 gem 一樣,在 gem file 中加入 gem 'rack-attack',再執行:bundle,你就可以看到 Installing rack-attack x.x.x 的訊息,然後你要在 config/application.rb 中加入一行:config.middleware.use Rack::Attack,這樣,你就裝好 Rack::Attack 了。
使用 Rack::Attack
要使用 Rack::Attack,只要在 config/initializers,加入 Rack::Attak 的設定檔,檔案的名稱是 rack_attack.rb,如同我一向的慣例,放碼!畢竟,碼說話最清楚了!
我已經把說明加上了,所以程式碼應該很容易讀了,但是也有一些要注意的:
cache 一定要設好
Rack::Attack 的 Throttle,allow2ban 以及 fail2ban 這些功能是要使用 Rails cache 的,所以 cache 一定要設定好,我如同已經介紹過的 Rails Cache 文章,單一 server 的網站就用 file store 就好啦,簡單又快速,很多台 server 的大網站,也應該不用看這篇了,防止駭客要做的工作,絕不只是裝這一個 gem,這只能算是基本啦,還沒有看過我的 Rails Cache 文章的人,如果還不熟 rails cache ,不嫌棄可以看看:
Scrivinor 思書: 紅寶鐵軌客
Scrivinor 思書: 紅寶鐵軌客
再來,我們沒有介紹:safelisting 跟 track,這兩個都是不錯的功能,可以設定在 rack_attack.rb 中,寫在越上面,就越有優先權,所以你如果有一些 ip 是永遠都不想被擋的,可以用 saftlisting 加在最前面,另外, 你也可以用 Rack::Attack 的 track 功能來追蹤一些用戶的使用狀況,這些設定都很簡單,我這裡就不說明了,你可以看一下官網,或是以下這篇文章(也是 Rack::Attack 的作者寫的):
還有是有關登入限制的設定,如何管制登入失敗又一直再試的討厭鬼這部分,我們使用的是 blocklist + allow2ban,你如果覺得太麻煩了,可以只用 blocklist 或是 throttle,官網上都有範例,只是,只用 blocklist 或是 throttle 的話,你會發現,被擋下來的 ip 只要在執行幾個正常的網頁,或是等一下,就又可以繼續搞怪了,我不喜歡,但也許合乎你的要求,就看你的需求了。
不能在 Proxy 後運作:如果你的網站是架在 proxy 後(如 Cloudflare),你可以參考以下這篇文章,這篇文章也介紹了更進一步有效防止 DDoS 的方法。
BigBinary Blog
再來,就是關於如何設定客製化回應中的 HTTP 狀態碼,這是一個有趣的問題, 基本上,四字頭都是客戶端有問題,五字頭都是伺服器端有問題,看你要回什麼,回四字頭就是告訴討厭鬼,你被抓到了,回五字頭就是裝不知道,看你自己的選擇,我喜歡四字頭就是了。
把討厭鬼留下紀錄
你當然可以不留下任何記錄,不過我是認為這樣太大膽了,如果你有任何設定錯誤,把不該擋下來的也擋下來,那就有可能會造成用戶抱怨或是流量流失,要把紀錄那些討厭鬼被擋下來也很簡單,Rack::Attack 是使用 ActiveSupport::Notifications,如果你對它不熟悉,以下這篇教學真的很棒,我相信你一看就懂:#249 Notifications in Rails 3 - RailsCasts: Short Ruby on Rails screencasts containing tips, tricks and tutorials. Great for both novice and experienced web developers.
你可以將紀錄寫到資料庫中,但是我覺得先記在 server log 中就好,畢竟,寫資料到資料庫中,還是要花資源,還是一樣,以下是如何將討厭鬼在 server log 中紀錄,放碼出來:
Rack::Attack 顧名思義,就是是一個 Rack 上的服務,Rack::Attack 會將 Rack 的 Request 包起來再加上以下這些資訊:
玩一下,應該就很清楚什麼是什麼了。 Rack 的 Request 說明在這:Class: Rack::Request — Documentation for rack。
有一點比較怪的是,當用
Rack::Attack.blocklist()
來擋特定的 IP 時,payload 會是空的,也就是說 ip, env, header 等等都不會傳進來,所以你有用到blocklist()
,你在必須要在紀錄時,先檢查一下 method 是不是 undefined,可以用payload.try(:env).present?
我們把討厭鬼記錄下來的目的,我認為最主要的就是防止誤判,最簡的的檢查方法就是用 grep 來掃出我們要的 log 資料:
在 server 上,打入以上第 01 行就可以知道到底有幾個要求被擋下來,如果有,再用第 02 行去細看,如果你是 copy paste 我的碼,你就可以把 pentesters 換成 allow2ban 或是 max_req,這樣就知道各個被擋的數字跟是誰了,想看個幾天應該就知道有沒有誤判了。 下面這篇有更多簡單的 log 讀取方法:
對抗 DDoS 的 404 Not Found
DDoS 就是討厭鬼開始亂讀你的伺服器網址,這包含了存在與不存在的網址,如果你有注意到你的 log 中出現一大堆的 Routing Error,很有可能就是 DDoS 的徵兆,討厭鬼開始亂讀不存在的網址了,在它被 Rack::Attack 擋下來前(也可能討厭鬼沒讀超過門檻,沒擋到),我們要怎麼辦呢?這你就要想想了,看你的需求,一般有以下幾個方法:
這三種裡面我覺得第三個回應 404 最好,第一個不理它絕不是一個正確的答案,反正也不用做任何事,所以我們就不討論了,以下我們來看看二跟三的做法:
把不存在的網址導引到一個特定頁面:
這寫法很簡單,就在你的 routes.rb 最底下加上以下這行:
這是用到了 route 的鬼牌功能,因為這個 match 是在 routes.rb 的最下面,所以就是前面所有的路徑都沒有配對到,這時,
*nopath
前面的*
鬼牌就會擋下任何路徑要求,轉到 applicatoin controller 的 nopath_action,還會把路徑經由 params[:nopath] 傳來,接下來要做什麼就看你了,可以顯示一個討厭鬼的畫面,也可以連到主頁,不過,這有個實務上的小問題,對搜尋引擎來說,這並不正確,他應該是 404 不存在! Rails guide 的說明:Rails Routing from the Outside In — Ruby on Rails Guides:照標準,就回應 404:網頁不存在「Not Found」
我覺得這個方法最好,因為事實上就是「找不到」,所以最合網站規矩與標準,上面也提到搜尋引擎的考量,搜尋引擎,特別是 google,很喜歡來找不存在的網址,google 也建議,找不到就回應 404 ,有興趣的可以讀讀:
你當然可以用前面導引的方法來寫,但是以下這個寫法更簡單,就在你的 routes.rb 最底下加上以下這行:
這個寫法很酷,其中的
[404, {}, ["xxx"]]
其實就是 Rack response 的[status, {headers}, [body]]
,所以你就可以很簡單快速的寫一個文字或網頁回應,上面的例子就是一個簡單的文字回應,你也可以寫成:[404, {'Content-Type' => 'text/html; charset=utf-8'}, ["<div><b>Not Found....</b></div>"]]
,這樣就是一個 html 網頁了。結語:
實務上,你會很驚訝的發現,真的有很多討厭鬼,我裝上的第一個 12 小時,就攔截成功上千個討厭鬼,感覺真不錯,我相信,應該有很多網站,每天的討厭鬼數目都是以千來記的,上萬也不稀奇,所以,裝 Rack::Attack 是一個很有價值的投資,想想你可以省下多少頻寬與提高伺服器效率,真是一個簡單好用很棒的寶石。
為什麼不用 Linux 的 fail2ban 就好?
看到這,如果你對 Linux 的 fail2ban 熟悉,我想你一定會問,那為什麼不用 fail2ban 就好?其實我一開始有一樣的想法,只是後來我發現我不大會用 fail2ban,fail2ban 的觀念很簡單,但是在設定上,對我來說,真的有些難搞,不過我相信,如果能用 fail2ban,效率應該會比用 Rack::Attack 好,畢竟它是在 app server 前,但是,後來我還是決定用 Rack::Attack 的主要原因有:
不過,就算用了 Rack::Attack,你還是應該要裝好 Fail2ban,除了 httpd 那部分可以靠 Rack::Attack,其他都要好好的保護好,不然,光 web server 保護了,討厭鬼從 SSH 進來,死得更慘。 下面這篇就是怎麼用 Fail2Ban 的一篇不錯的文章:用 Fail2Ban 防範暴力破解 (SSH、vsftp、dovecot、sendmail): Fail2Ban 可以用來防護 Linux Server 上的 SSH、vsftp、dovecot…等服務… 。
如果還是想用 Fail2Ban,這兩篇不錯: 如何配置 fail2ban 来保护 Apache 服务器, How To Protect an Apache Server with Fail2Ban on Ubuntu 14.04。
防止討厭鬼是一條不歸路,還有很多 tools (例如:mod_security 等),也希望這是拋磚引玉,大家可以分享一些好用的工具或服務。
就寫到這了,希望大家使用愉快。