Giới hạn HTTP request method với Nginx

Giới hạn HTTP request method với Nginx
4.3 (86.67%) 3 votes

Theo nguyên tắt bảo mật, bạn chỉ nên mở những gì bạn cần và biết rõ về nó, còn lại hay đóng. Hay nói cách khác hãy đóng hết tất cả các cánh cửa ra vào của hệ thống, chỉ mở những các cửa mà mình chắc chắn dùng.

Nguyên tắt này có thể áp dụng cho việc cấu hình tưởng lửa layer 3, 4 như chỉ mở các port cần thiết trên hệ thống máy chủ, hay giới hạn chỉ cho phép những IP từ những người dùng nội bộ truy cập và SSH .v.v. Bài viết này sẽ hướng dẫn cách giới hạn HTTP request method  – chỉ cho phép một số request method thông dụng nhằm tăng cường tính báo mật cho hệ thống web server với Nginx.

GET, POST – Các HTTP request method thông dụng

Trong bài viết Bảo mật web server Apache với ModSecurity – Phần 1 tôi đã giới thiệu về các HTTP request method thông dụng bao gồm GET, POST, HEAD,DELETE, PUT . Một website thông thường chỉ dùng GET và POST (trừ trường hợp một số website API thì dùng khá nhiều request method). Hãy quan sát và tìm hiểu website của bạn, nếu không thuộc vào trường hợp đặt biệt như website chuyên chạy API, bạn hoàn toàn có thể giới hạn request method để nâng cao tính bảo mật cho website mình.

gioi han http request method nginx

Tấn công với sử dụng hình thức HTTP HEAD

Dưới đây là một trường hợp cụ thể, khách hàng của tôi bị tấn công DOS sửa dụng HTTP request method là HEAD. Thông tin log như sau:

85.143.24.70 - - [25/Apr/2016:04:34:56 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://www.topsiteminecraft.com/site/pinterest.com/search?q=walmart stores" "BeamMachine/0.5 (dead link remover of www.beammachine.net)"
120.52.72.20 - - [25/Apr/2016:04:34:57 +0700] "GET /?&time=0.05536&query=!@$ HTTP/1.1" 301 5 "https://play.google.com/store/search?q=medical insurance" "Cityreview Robot (+http://www.cityreview.org/crawler/)"
85.143.24.70 - - [25/Apr/2016:04:34:57 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://www.topsiteminecraft.com/site/pinterest.com/search?q=walmart stores" "BeamMachine/0.5 (dead link remover of www.beammachine.net)"
120.52.72.68 - - [25/Apr/2016:04:34:57 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.1" 403 0 "https://developers.google.com/speed/pagespeed/insights/?url=yahoo google" "Digger/1.0 JDK/1.3.0rc3"
120.52.72.20 - - [25/Apr/2016:04:34:57 +0700] "GET /?&time=0.05536&query=!@$ HTTP/1.1" 301 5 "https://play.google.com/store/search?q=medical insurance" "Cityreview Robot (+http://www.cityreview.org/crawler/)"
120.52.72.68 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.1" 403 0 "https://developers.google.com/speed/pagespeed/insights/?url=yahoo google" "Digger/1.0 JDK/1.3.0rc3"
203.195.172.147 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://filehippo.com/search?q=sports" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5"
120.52.72.20 - - [25/Apr/2016:04:34:58 +0700] "GET /?&time=0.05536&query=!@$ HTTP/1.1" 301 5 "https://play.google.com/store/search?q=medical insurance" "Cityreview Robot (+http://www.cityreview.org/crawler/)"
203.195.172.147 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://filehippo.com/search?q=sports" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5"
203.195.172.147 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://filehippo.com/search?q=sports" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5"
200.86.136.196 - - [25/Apr/2016:04:34:58 +0700] "HEAD //?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://www.google.com/translate?u=paid to" "EARTHCOM.info/1.x [www.earthcom.info]"
120.52.72.68 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.1" 403 0 "https://developers.google.com/speed/pagespeed/insights/?url=yahoo google" "Digger/1.0 JDK/1.3.0rc3"
120.52.72.20 - - [25/Apr/2016:04:34:58 +0700] "GET /?&time=0.05536&query=!@$ HTTP/1.1" 301 5 "https://play.google.com/store/search?q=medical insurance" "Cityreview Robot (+http://www.cityreview.org/crawler/)"
203.195.172.147 - - [25/Apr/2016:04:34:58 +0700] "HEAD /?&time=0.05536&query=!@$##@%$#^&%$&%$&%$^#!@&%#$!%%#$^ HTTP/1.0" 403 0 "http://filehippo.com/search?q=sports" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5"

Nhìn đoạn log trên, có thể bạn sẽ có nhiều ý tưởng cho việc viết các rule WAF (web application firewall) để chặn hình thức tấn công trên. Ở đây tôi chỉ đề cập đến việc chặn bằng cách giới hạn request method, chỉ cho phép GET và POST, còn lại chặn tất cả bằng cách cấu hình web server Nginx.

Giới hạn HTTP request method với Nginx, chỉ cho phép GET và POST

Nginx cung cấp condition if và biến $request_method cho phép chúng ta kiểm soát request method. Sử dụng đoạn cấu hình sau để giới hạn request method, chỉ cho hpesp GET và POST

if ( $request_method !~ ^(GET|POST)$ ) {
return 403;
}

Đoạn cấu hình trên có thể khai báo trong location / hoặc location đặt biệt nào mà bạn cần chỉ định. Status code return tôi để 403, bạn có thể chọn 404, 405 tùy ý. Tất nhiên 405 chính xác hơn!

Chặn một request method nào đó, ví dụ như HEAD

Nếu bạn chỉ chắc chắn rằng website của tôi không sử dụng HEAD, còn lại không biết có sửa dụng request method khác hay không. Bạn có thể lựa chọn phương án chỉ chặn 1 request method nào đó với cấu hình sau:

if ($request_method = "HEAD") {
return 403;
}

Đoạn cấu hình trên chặn tất cả các request với request method là HEAD.

Kiểm tra bằng cách gởi request với method là HEAD đến website mà bạn cấu hình:

Buis-MacBook-Air:~ buitanviet$ curl -I http://websitecuaban.com
HTTP/1.1 403 Forbidden
Server: nginx
Date: Mon, 25 Apr 2016 04:52:48 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 162
Connection: keep-alive

Chúc các bạn thành công.

Thêm bình luận