วิธีบล็อก URL เฉพาะหน้าแรกและบางหน้าใน Apache VirtualHost บน CentOS Stream 9


การตั้งค่า 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 Forbidden
  • L หยุดประมวลผลกฎ 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.html403 Forbidden
https://cam.test.com/admin.html403 Forbidden
https://cam.test.com/admin.html?cam=44403 Forbidden
https://cam.test.com/admin.html?cam=99403 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 โดยอัตโนมัติ

สามารถจัดการได้สองแนวทาง:

  1. ตั้งค่า HTTP ให้เปลี่ยนเส้นทางไป HTTPS แล้วใช้กฎบล็อกใน VirtualHost พอร์ต 443
  2. เพิ่มกฎบล็อกเดียวกันใน 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 ตรงกับโดเมนดังกล่าว

, ,