การตั้งค่า Apache VirtualHost สามารถกำหนดให้บล็อกการเข้าถึง URL บางรายการได้ โดยไม่จำเป็นต้องปิดเว็บไซต์ทั้งหมด เหมาะสำหรับผู้ดูแลระบบที่ต้องการซ่อนหน้าแรก ป้องกันผู้ใช้เข้าถึงหน้าตั้งค่า หรือจำกัดการเข้าถึง URL ที่ไม่ต้องการเปิดเผยต่อสาธารณะ
บทความนี้อธิบายการใช้ RewriteRule เพื่อบล็อกหน้าแรกและ URL ที่กำหนด โดยใช้ Apache บน CentOS Stream 9 และโดเมนตัวอย่าง cam.test.com ซึ่งทำ Reverse Proxy ไปยัง go2rtc ที่ 127.0.0.1:1984
1. หลักการทำงานของ RewriteRule
Apache สามารถใช้ mod_rewrite ตรวจสอบ URL ที่ผู้ใช้ร้องขอ แล้วกำหนดให้ปฏิเสธการเข้าถึงด้วยสถานะ HTTP 403 Forbidden
RewriteEngine On
RewriteRule ^/config\.html$ - [F,L,NC]
ความหมายของคำสั่ง:
RewriteEngine Onเปิดใช้งานระบบ URL Rewrite^/config\.html$ตรวจสอบ path/config.htmlเท่านั้น-หมายถึงไม่ต้องเปลี่ยน URL ปลายทางFปฏิเสธการเข้าถึงด้วย HTTP 403 ForbiddenLหยุดประมวลผลกฎ Rewrite ในรอบนั้นNCไม่แยกแยะตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
2. วิธีบล็อกเฉพาะหน้าแรกของเว็บไซต์
หากต้องการบล็อกเฉพาะหน้าแรกของเว็บไซต์ https://cam.test.com/ ให้เพิ่มกฎต่อไปนี้ภายใน <VirtualHost *:443>
RewriteEngine On
# Block homepage only
RewriteRule ^/$ - [F,L]
เมื่อผู้ใช้เปิดหน้าแรก จะได้รับสถานะ 403 Forbidden แต่ URL อื่นยังสามารถใช้งานได้ตามปกติ หากไม่ได้กำหนดกฎบล็อกเพิ่มเติมและบริการปลายทางรองรับ URL เหล่านั้น
3. วิธีบล็อก URL บางหน้า
หากต้องการบล็อกหน้าตั้งค่า เช่น /config.html ให้เพิ่มกฎดังนี้
RewriteEngine On
# Block configuration page
RewriteRule ^/config\.html$ - [F,L,NC]
หากต้องการบล็อกหลายหน้า สามารถเพิ่มกฎแยกแต่ละ URL ได้
RewriteEngine On
# Block configuration page
RewriteRule ^/config\.html$ - [F,L,NC]
# Block admin page
RewriteRule ^/admin\.html$ - [F,L,NC]
# Block status page
RewriteRule ^/status\.html$ - [F,L,NC]
3.1 การบล็อก URL ที่มี Query String
Query String คือข้อมูลที่อยู่หลังเครื่องหมาย ? ใน URL มักใช้ส่งค่าพารามิเตอร์ให้เว็บไซต์ เช่น หมายเลขกล้องหรือรหัสรายการ
ตัวอย่าง URL:
https://cam.test.com/admin.html?cam=44
https://cam.test.com/admin.html?cam=99
https://cam.test.com/admin.html?user=test
หากกำหนดกฎดังนี้
# Block admin page
RewriteRule ^/admin\.html$ - [F,L,NC]
URL ทั้งสามรายการข้างต้นจะถูกบล็อกทั้งหมด เพราะ RewriteRule ในระดับ VirtualHost จะจับคู่กับ path ของ URL โดยไม่รวม Query String ตามค่าเริ่มต้น
ตัวอย่างผลลัพธ์:
| URL | ผลลัพธ์ |
|---|---|
/admin.html | ถูกบล็อก |
/admin.html?cam=44 | ถูกบล็อก |
/admin.html?cam=99 | ถูกบล็อก |
/admin.html?user=test | ถูกบล็อก |
/admin.php?cam=44 | ไม่ถูกบล็อกด้วยกฎนี้ |
/admin.html/other | ไม่ถูกบล็อกด้วยกฎนี้ |
ดังนั้น หากต้องการบล็อกหน้า admin.html ทุกกรณี โดยไม่สนใจค่าพารามิเตอร์ที่ส่งเข้ามา ไม่จำเป็นต้องเขียนกฎแยกสำหรับ cam=44, cam=99 หรือค่าอื่น ๆ
ข้อควรระวัง: หากต้องการบล็อกเฉพาะบางค่าของ Query String เช่น บล็อกเฉพาะ cam=44 แต่อนุญาต cam=99 จะต้องเขียนกฎเพิ่มเติมโดยใช้ RewriteCond ตรวจสอบ %{QUERY_STRING}
ตัวอย่างการบล็อกเฉพาะ cam=44 บนหน้า admin.html:
RewriteCond %{QUERY_STRING} (^|&)cam=44(&|$)
RewriteRule ^/admin\.html$ - [F,L,NC]
กฎนี้จะบล็อก admin.html?cam=44 และ URL ที่มีพารามิเตอร์ cam=44 ร่วมกับพารามิเตอร์อื่น แต่ไม่บล็อก admin.html?cam=99 ด้วยเงื่อนไขนี้เพียงอย่างเดียว
4. ตัวอย่างโค้ด VirtualHost ฉบับเต็ม
ตัวอย่างนี้ใช้กับโดเมน cam.test.com ซึ่งทำ Reverse Proxy ไปยัง go2rtc ผ่านพอร์ต 1984 โดยบล็อกหน้าแรกและหน้า config.html รวมถึง admin.html แต่คงการตั้งค่า WebSocket และ Proxy เดิมไว้
<VirtualHost *:443>
ServerName cam.test.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/ip-default.crt
SSLCertificateKeyFile /etc/pki/tls/private/ip-default.key
# Reverse Proxy Configuration
ProxyRequests Off
ProxyPreserveHost On
# URL Rewrite
RewriteEngine On
# Block homepage
RewriteRule ^/$ - [F,L]
# Block go2rtc configuration page
RewriteRule ^/config\.html$ - [F,L,NC]
# Block admin page, including all query strings
RewriteRule ^/admin\.html$ - [F,L,NC]
# Block status page
# RewriteRule ^/status\.html$ - [F,L,NC]
# WebSocket Proxy
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:1984/$1 [P,L]
# HTTP Reverse Proxy
ProxyPass / http://127.0.0.1:1984/ retry=0 timeout=30
ProxyPassReverse / http://127.0.0.1:1984/
</VirtualHost>
หากต้องการบล็อกหน้าอื่น ให้เพิ่ม RewriteRule ก่อนส่วน WebSocket Proxy และ ProxyPass เช่น
RewriteRule ^/settings\.html$ - [F,L,NC]
5. วิธีตรวจสอบและนำการตั้งค่าไปใช้
ตรวจสอบไวยากรณ์ของ Apache ก่อน
sudo httpd -t
หากแสดงผล Syntax OK ให้รีโหลด Apache
sudo systemctl reload httpd
ทดสอบหน้าแรก
curl -I https://cam.test.com/
ทดสอบหน้า config
curl -I https://cam.test.com/config.html
ทดสอบหน้า admin ที่มี Query String
curl -I "https://cam.test.com/admin.html?cam=44"
หากบล็อกสำเร็จ ควรได้รับสถานะ 403 Forbidden ทั้งสามรายการ
หากต้องการตรวจสอบเฉพาะรหัส HTTP สามารถใช้คำสั่ง
curl -s -o /dev/null -w "%{http_code}\n" \
"https://cam.test.com/admin.html?cam=44"
ผลลัพธ์ที่คาดหวัง:
403
6. ตัวอย่างผลลัพธ์หลังบล็อก URL
| URL | ผลลัพธ์ที่คาดหวัง |
|---|---|
https://cam.test.com/ | 403 Forbidden |
https://cam.test.com/config.html | 403 Forbidden |
https://cam.test.com/admin.html | 403 Forbidden |
https://cam.test.com/admin.html?cam=44 | 403 Forbidden |
https://cam.test.com/admin.html?cam=99 | 403 Forbidden |
https://cam.test.com/stream.html | ส่งต่อไปยัง go2rtc หากมีหน้าดังกล่าว |
| WebSocket | ทำงานตามกฎ Proxy เดิม |
ผลลัพธ์ของ URL ที่ไม่ได้บล็อกยังขึ้นอยู่กับการตั้งค่าของบริการปลายทางด้วย
7. ข้อควรระวังเกี่ยวกับ HTTP และ HTTPS
หากกำหนดกฎไว้ภายใน <VirtualHost *:443> กฎดังกล่าวจะทำงานกับคำขอที่เข้าสู่ VirtualHost สำหรับ HTTPS เท่านั้น
หากมี VirtualHost พอร์ต 80 แยกต่างหาก คำขอผ่าน HTTP เช่น http://cam.test.com/ จะไม่ถูกบล็อกด้วยกฎในพอร์ต 443 โดยอัตโนมัติ
สามารถจัดการได้สองแนวทาง:
- ตั้งค่า HTTP ให้เปลี่ยนเส้นทางไป HTTPS แล้วใช้กฎบล็อกใน VirtualHost พอร์ต 443
- เพิ่มกฎบล็อกเดียวกันใน VirtualHost พอร์ต 80 หากต้องการบล็อก HTTP โดยตรง
นอกจากนี้ ควรตรวจสอบว่าไม่ได้เปิดพอร์ต 1984 ให้เข้าถึงจากอินเทอร์เน็ตโดยตรง หากต้องการให้ผู้ใช้เข้าถึง go2rtc ผ่าน Apache Reverse Proxy เท่านั้น
การบล็อก URL ด้วย Apache เป็นการจำกัดการเข้าถึงผ่านเส้นทางที่กำหนด ไม่ใช่การปิดระบบยืนยันตัวตนหรือการรักษาความปลอดภัยของ go2rtc ทั้งหมด หากหน้าดังกล่าวมีข้อมูลสำคัญ ควรจำกัดการเข้าถึงที่บริการต้นทางหรือเครือข่ายเพิ่มเติมด้วย
สรุป
การใช้ RewriteRule ช่วยให้ผู้ดูแลระบบควบคุมการเข้าถึง URL ได้อย่างตรงจุด โดยไม่จำเป็นต้องปิด VirtualHost ทั้งหมด
- บล็อกหน้าแรก ใช้
RewriteRule ^/$ - [F,L] - บล็อกหน้าเฉพาะ ใช้
RewriteRule ^/ชื่อไฟล์\.html$ - [F,L,NC] - บล็อกหน้าและทุก Query String ที่ตามมา ใช้กฎจับคู่ path ตามปกติ ไม่ต้องระบุพารามิเตอร์แยก
- บล็อกเฉพาะค่าพารามิเตอร์ ใช้
RewriteCond %{QUERY_STRING}ร่วมกับRewriteRule - ตรวจสอบด้วย
sudo httpd -tก่อนใช้sudo systemctl reload httpd
หมายเหตุ: cam.test.com เป็นโดเมนตัวอย่าง ควรเปลี่ยนเป็นโดเมนจริงของเว็บไซต์เมื่อนำการตั้งค่าไปใช้งาน และตรวจสอบให้ใบรับรอง SSL ตรงกับโดเมนดังกล่าว
