前幾天終於把限制請求「數量」的部分講完了,但光是限制數量是不夠的,最好還能限制每個請求的大小,否則攻擊者只要發一些 body 很肥很肥的無用請求,一樣可以把伺服器癱瘓掉
值得慶幸的是,不管你前面擋的是 Nginx、Apache、IIS 還是其他 Web server,他們都已經幫你設好一個不錯的預設值,只要在修改設定時不要不小心改掉就好了~
考慮以下這個設定檔,如果我想把所有 server(大多時候會同時聽 80 跟 443 port)可接受的 body 大小都設定成 100KB,那只需要在 http
底下加一行 client_max_body_size 100k
就好了,非常簡單吧~而且就如剛剛說的,就算你不刻意設定,client_max_body_size
屬性的預設值也是 1MB,對於一般應用來說也是非常合理的範圍
http {
# 請求的 body 最大就是 100KB
client_max_body_size 100K;
upstream backend {
server 192.0.0.1:8000;
server 192.0.0.2:8000;
server 192.0.0.3:8000;
}
server {
listen 80;
location /api {
proxy_pass http://backend;
}
}
}
設定套用上去之後,如果有人嘗試送超過 100KB 的請求,那 Nginx 就會直接拒絕,並且回給他 413 Request Entity Too Large
的錯誤,這樣 client 看到就會知道請求的 body 太肥了。而且這樣有一個好處就是 Nginx 後面的 API server 完全不會意識到有人送了這個太肥的請求,畢竟一開始就被 Nginx 擋掉了,等於是加上一層防護罩的概念
但有一種情況是這樣:因為有些 Server 需要讓使用者上傳檔案,而 100KB 對上傳的頭貼、影片來說顯然是不夠的,所以對於那些上傳檔案的 API 要特別把限制調高,這時也可以針對不同 location 做不同的設定
http {
# 預設值 100KB
client_max_body_size 100K;
server {
# 上傳大頭貼最高可以到 5MB
location /api/upload/avatar {
client_max_body_size 5M;
proxy_pass http://backend;
}
# 上傳影片最高可以到 20MB
location /api/upload/video {
client_max_body_size 20M;
proxy_pass http://backend;
}
# 其他 API 就是預設值 100KB
location /api {
proxy_pass http://backend;
}
}
}
如此一來大部分 API 還是維持 100KB 的限制,而上傳大頭貼、影片的兩個 API 則是調整到 5MB、20MB,因為這兩個 API 的資源消耗比較多,所以記得要搭配前幾天講的 rate limit 進行使用,才不會被惡意攻擊者不斷上傳一堆影片
關於「流量限制」的部分就到今天結束,這幾天講的這些方法雖然可以有效擋住短時間的流量攻擊,但對於大規模、長時間的 DDOS 攻擊還是沒辦法完全擋住,畢竟請求來自四面八方,三不五時還會更換 IP,所以真的遇到的話也只能請專業的公司協助了
另外這邊也想補充一下,除了 max body size 之外,Nginx 在很多屬性上(像是 buffer 大小、connection pool 大小、timeout)都給了很不錯的預設值。所以就算你只是把 Nginx 擋在 API server 前面做轉發,不做多餘的調整,也能為 server 帶來基本的防護力哦~
如果對於這幾天的內容若有什麼問題都歡迎在下方留言,如果都沒問題的話,明天就要開始講 HTTP Headers 相關的設定了~