ในยุคดิจิทัลปัจจุบัน เซิร์ฟเวอร์เว็บไซต์ของเรามักถูกรบกวนจากบอทที่ไม่พึงประสงค์ เช่น บอทที่ใช้สำหรับการจำหน่ายข้อมูล (scraping) หรือบอทที่มีจุดประสงค์เพื่อค้นหาช่องโหว่ด้านความปลอดภัย (security scanning) User-Agent Blocking เป็นเทคนิคที่สำคัญในการป้องกันการเข้าถึงที่ไม่ต้องการและลดความเสี่ยงด้านความปลอดภัยของเว็บไซต์ได้อย่างมีประสิทธิภาพ
Nginx เป็นเว็บเซิร์ฟเวอร์ที่มีความสามารถในการจัดการและกรองข้อมูลจากลูกค้า (client) ได้อย่างดีเยี่ยม ด้วยความสามารถในการระบุและปิดกั้น User-Agent ที่ไม่ต้องการ เราสามารถปกป้องเว็บไซต์และลดความเสี่ยงจากการโจมตี (attack) ได้อย่างมีประสิทธิภาพ บทความนี้จะอธิบายวิธีการป้องกันและตั้งค่า User-Agent Blocking ใน Nginx แบบครบถ้วน
User-Agent คืออะไร และเหตุใดจึงต้องปิดกั้น
User-Agent เป็นข้อมูลส่วนหัว (HTTP header) ที่บ่งบอกข้อมูลเกี่ยวกับเบราว์เซอร์หรือแอปพลิเคชันที่กำลังส่งคำขอ (request) ไปยังเซิร์ฟเวอร์ User-Agent จะประกอบไปด้วยข้อมูล เช่น ชื่อเบราว์เซอร์ เวอร์ชัน ระบบปฏิบัติการ และอื่น ๆ ตัวอย่างเช่น:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
เหตุผลสำคัญในการปิดกั้น User-Agent ที่ไม่พึงประสงค์มีดังนี้:
- ป้องกันการ Scraping: บอทที่ใช้เพื่อดึงข้อมูลจากเว็บไซต์ของเรามักจะเปิดเผย User-Agent เฉพาะตัว
- ลดภาระงาน (Load): บอทที่ไม่พึงประสงค์อาจสร้างความเสี่ยงต่อประสิทธิภาพของเซิร์ฟเวอร์
- เพิ่มความปลอดภัย: บอทที่สแกนช่องโหว่ (vulnerability scanning) มักใช้ User-Agent เฉพาะตัว
- ป้องกันการโจมตี DDoS: บางการโจมตี DDoS อาจใช้ User-Agent เพื่อซ่อนตัวตัวเอง
การระบุบอทที่ไม่พึงประสงค์ผ่าน User-Agent
วิธีการระบุบอทที่ไม่พึงประสงค์นั้นสามารถทำได้โดยการบันทึกข้อมูล User-Agent และวิเคราะห์ลวดลายของมัน บอทส่วนใหญ่มักเปิดเผย User-Agent ของพวกเขาอย่างชัดเจน ดังเช่น:
curl/7.x.x— เครื่องมือ curl ที่ใช้เพื่อส่งคำขอ HTTPwget/1.x— เครื่องมือ wget สำหรับดาวน์โหลดไฟล์python-requests— ไลบรารี Python ที่ใช้ทำบอทMJ12bot, AhrefsBot— บอทที่ใช้เพื่อ SEO scanningSqlMap, Nikto— เครื่องมือที่ใช้ในการทดสอบช่องโหว่Empty User-Agent— การร้องขอที่ไม่มี User-Agent มักเป็นสัญญาณที่น่าสงสัย
สามารถดูบันทึก (log) เซิร์ฟเวอร์ Nginx และตรวจสอบ User-Agent ที่ส่งคำขอมาหา:
tail -f /var/log/nginx/access.log | grep -oP '(?<="[^"]*" )[^"]*'
ปิดกั้น User-Agent เฉพาะตัวด้วย if Directive
วิธีพื้นฐานในการปิดกั้น User-Agent คือการใช้ if directive ใน Nginx configuration ตัวอย่างด้านล่างจะแสดงวิธีปิดกั้น User-Agent บางตัว:
server {
listen 80;
server_name example.com;
# ปิดกั้น curl
if ($http_user_agent ~* curl) {
return 403;
}
# ปิดกั้น wget
if ($http_user_agent ~* wget) {
return 403;
}
# ปิดกั้น python-requests
if ($http_user_agent ~* python-requests) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
ในตัวอย่างข้างต้น:
$http_user_agent— ตัวแปร Nginx ที่เก็บค่า User-Agent จากการร้องขอ~*— ตัวดำเนินการเปรียบเทียบที่ไม่คำนึงถึงขนาดตัวอักษร (case-insensitive)return 403— ส่งการตอบสนอง HTTP 403 (Forbidden)
การใช้ map เพื่อปิดกั้น User-Agent ที่มีประสิทธิภาพ
การใช้ if directive หลายครั้งนั้นอาจทำให้ประสิทธิภาพลดลง วิธีที่ดีกว่าคือการใช้ map block เพื่อจัดการ User-Agent หลายตัวพร้อมกัน:
http {
map $http_user_agent $block_user_agent {
default 0;
~*curl 1;
~*wget 1;
~*python-requests 1;
~*MJ12bot 1;
~*AhrefsBot 1;
~*SqlMap 1;
~*Nikto 1;
~*nmap 1;
~*masscan 1;
}
server {
listen 80;
server_name example.com;
if ($block_user_agent) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
วิธีนี้มีข้อดี:
- ประสิทธิภาพดีกว่า: ใช้การเปรียบเทียบแบบเดียวแทนที่จะใช้หลาย
ifstatement - ง่ายต่อการจัดการ: สามารถเพิ่มหรือลบ User-Agent ได้อย่างง่ายดาย
- อ่านรหัสได้ชัดเจน: ทำให้ configuration ดูเป็นระเบียบเรียบร้อย
ปิดกั้น User-Agent ที่ว่างเปล่า
User-Agent ที่ว่างเปล่า (empty User-Agent) มักเป็นสัญญาณที่น่าสงสัย และอาจบ่งชี้ถึงการโจมตี เราสามารถปิดกั้นได้ดังนี้:
http {
map $http_user_agent $block_empty_ua {
default 0;
"" 1;
}
server {
listen 80;
server_name example.com;
if ($block_empty_ua) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
อีกวิธีหนึ่งคือการตรวจจับ User-Agent ว่างเปล่าอย่างชัดเจน:
server {
listen 80;
server_name example.com;
if ($http_user_agent = "") {
return 403;
}
location / {
proxy_pass http://backend;
}
}
อนุญาตเฉพาะบอทที่เชื่อถือได้ เช่น Googlebot และ Bingbot
บางครั้งเราต้องการอนุญาตเฉพาะบอทที่เชื่อถือได้เท่านั้น เช่น Googlebot และ Bingbot ซึ่งมีประโยชน์สำหรับการทำให้เว็บไซต์ปรากฏในผลลัพธ์การค้นหา (SEO):
http {
map $http_user_agent $allow_user_agent {
default 0;
~*Googlebot 1;
~*Bingbot 1;
~*Slurp 1;
~*DuckDuckBot 1;
~*Baidu 1;
}
server {
listen 80;
server_name example.com;
if ($allow_user_agent = 0) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
วิธีการข้างต้นนั้นเข้มงวดมาก และอาจปิดกั้นบอทที่ดีบางตัว วิธีที่สมดุลกว่าคือการปิดกั้นเฉพาะบอทที่ไม่พึงประสงค์แทน:
http {
map $http_user_agent $block_bad_bot {
default 0;
~*curl 1;
~*wget 1;
~*python 1;
~*SqlMap 1;
~*Nikto 1;
"" 1;
}
server {
listen 80;
server_name example.com;
if ($block_bad_bot) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
บันทึก (Log) การร้องขอที่ถูกปิดกั้น
เพื่อตรวจสอบ User-Agent ที่ถูกปิดกั้นและวิเคราะห์รูปแบบการโจมตี สำคัญที่เราต้องบันทึกข้อมูลของ User-Agent:
http {
log_format blocked_bots '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/blocked_bots.log blocked_bots if=$block_bad_bot;
location / {
proxy_pass http://backend;
}
}
}
หรือสามารถบันทึกทุกการร้องขอไปที่ access.log เดียวกันและวิเคราะห์ในภายหลัง:
grep ' 403 ' /var/log/nginx/access.log | tail -20
grep ' 403 ' /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn
การรวม User-Agent Blocking กับ Rate Limiting
นอกเหนือจากการปิดกั้น User-Agent แล้ว เราสามารถรวม Rate Limiting เพื่อป้องกันการทำให้เซิร์ฟเวอร์โอเวอร์โหลด (overload):
http {
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=strict:10m rate=1r/s;
map $http_user_agent $block_bad_bot {
default 0;
~*curl 1;
~*wget 1;
~*python 1;
~*SqlMap 1;
~*Nikto 1;
"" 1;
}
server {
listen 80;
server_name example.com;
if ($block_bad_bot) {
return 403;
}
location / {
limit_req zone=general burst=20 nodelay;
proxy_pass http://backend;
}
location /api/ {
limit_req zone=strict burst=5 nodelay;
proxy_pass http://backend;
}
}
}
Regular Expression สำหรับการจับคู่ User-Agent
Nginx ใช้ Regular Expression (regex) เพื่อจับคู่ User-Agent ได้อย่างยืดหยุ่น มีตัวดำเนินการสำคัญดังนี้:
~— Regex matching (case-sensitive)~*— Regex matching (case-insensitive)!~— Regex NOT matching (case-sensitive)!~*— Regex NOT matching (case-insensitive)
ตัวอย่างการใช้ regex สำหรับ User-Agent:
http {
map $http_user_agent $block_bad_bot {
default 0;
~*^curl 1;
~*^wget 1;
~*python|requests|urllib 1;
~*bot(?!s) 1;
~*nmap|masscan|sqlmap|nikto 1;
^$ 1;
}
server {
listen 80;
server_name example.com;
if ($block_bad_bot) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
ทดสอบ User-Agent Blocking ด้วย curl
เราสามารถทดสอบการตั้งค่า User-Agent Blocking ด้วยเครื่องมือ curl ได้อย่างง่ายดาย:
curl -A "curl/7.68.0" http://example.com
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" http://example.com
curl -H "User-Agent:" http://example.com
curl -I -A "curl/7.68.0" http://example.com
curl -v -A "curl/7.68.0" http://example.com
ผลลัพธ์ที่คาดหวัง:
- ถ้าปิดกั้นได้สำเร็จ จะได้รับการตอบสนอง
HTTP 403 Forbidden - ถ้าอนุญาต จะได้รับการตอบสนอง
HTTP 200 OK
การบำรุงรักษาและอัพเดต Blocklist
ในการจัดการ User-Agent Blocking ให้มีประสิทธิภาพ จำเป็นต้องทำการบำรุงรักษาและอัพเดต blocklist เป็นระยะ ๆ:
1. บันทึกและวิเคราะห์บอทใหม่
grep ' 403 ' /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn | head -20
2. สร้าง Blocklist แยกต่างหาก
แนะนำให้สร้างไฟล์แยกต่างหากสำหรับ Blocklist เพื่อให้ง่ายต่อการจัดการ:
map $http_user_agent $block_bad_bot {
default 0;
~*curl 1;
~*wget 1;
~*python 1;
~*MJ12bot 1;
~*AhrefsBot 1;
~*SqlMap 1;
~*Nikto 1;
~*nmap 1;
~*masscan 1;
"" 1;
}
3. ทดสอบก่อนทำการ Reload
sudo nginx -t
sudo systemctl reload nginx
4. ใช้ GeoIP หรือ IP-based blocking เพิ่มเติม
สำหรับการป้องกันที่ครอบคลุมมากขึ้น สามารถรวม GeoIP blocking หรือ IP-based blocking กับ User-Agent Blocking:
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $block_country {
default 0;
KP 1;
IR 1;
}
map $http_user_agent $block_bad_bot {
default 0;
~*curl 1;
~*wget 1;
"" 1;
}
server {
listen 80;
server_name example.com;
if ($block_country = 1) {
return 403;
}
if ($block_bad_bot) {
return 403;
}
location / {
proxy_pass http://backend;
}
}
}
สรุป
User-Agent Blocking เป็นเทคนิคที่สำคัญในการป้องกันเว็บไซต์จากการโจมตีและการรบกวนจากบอทที่ไม่พึงประสงค์ ด้วยการใช้ Nginx configuration อย่างถูกต้อง เราสามารถ:
- ปิดกั้น User-Agent ที่ไม่พึงประสงค์ได้อย่างมีประสิทธิภาพ
- อนุญาตเฉพาะบอทที่เชื่อถือได้เท่านั้น
- บันทึกและวิเคราะห์การโจมตี
- รวม User-Agent Blocking กับ Rate Limiting และการป้องกันอื่น ๆ
- บำรุงรักษา Blocklist ให้อัดทันต่อข้อมูลใหม่
การตั้งค่า User-Agent Blocking ที่ดีจะช่วยลดภาระงานของเซิร์ฟเวอร์ เพิ่มความปลอดภัย และปกป้องข้อมูลของเว็บไซต์อย่างมีประสิทธิภาพ
แนะนำบริการ DE
หากท่านกำลังมองหาบริการ Cloud Infrastructure ที่เชื่อถือได้ เพื่อตั้งใจจัดเก็บและจัดการเว็บไซต์ของท่าน Dot Enterprise Co., Ltd. (DE) มีบริการที่เหมาะสมสำหรับความต้องการของท่าน:
- Cloud VPS — บริการเซิร์ฟเวอร์เสมือนจริงที่มีความยืดหยุ่นสูง สามารถปรับแต่ง Nginx configuration ได้อย่างเต็มที่ เหมาะสำหรับเว็บไซต์ที่มีความต้องการเฉพาะ
- Cloud Hosting — บริการ Hosting ที่มีการจัดการแบบแมนเนจด์ (Managed) ซึ่งรวมถึงการป้องกันความปลอดภัยและการบำรุงรักษาเซิร์ฟเวอร์ตั้งแต่ต้น
บริการของ DE พร้อมให้บริการด้วยประสิทธิภาพและความเชื่อถือได้สูง เพื่อให้เว็บไซต์ของท่านสามารถป้องกันตัวเองจากการโจมตีและบอทที่ไม่พึงประสงค์ได้อย่างมีประสิทธิภาพ ลองติดต่อทีมของ DE วันนี้เพื่อรับการให้คำปรึกษาและอัพเดตข้อมูลเพิ่มเติม

