.htaccess Rules สำหรับ WordPress

ไฟล์ .htaccess เป็น Configuration File ของ Apache Web Server ที่ควบคุมพฤติกรรมของเว็บในหลายด้าน ตั้งแต่ URL Rewriting, Security Headers ไปจนถึงการป้องกันการโจมตีเบื้องต้น WordPress ใช้ .htaccess สำหรับระบบ Permalink เป็นค่าเริ่มต้น แต่เราสามารถเพิ่ม Rules ความปลอดภัยได้อีกมาก

สำรองข้อมูลก่อนแก้ไขเสมอ: ก่อนแก้ไข .htaccess ให้ดาวน์โหลดไฟล์ปัจจุบันสำรองไว้ก่อน ถ้า Syntax ผิดเว็บจะขึ้น Error 500 ทันที

1. WordPress Default Rules (Permalink)

WordPress สร้าง Rules ชุดนี้ให้อัตโนมัติเมื่อตั้งค่า Permalink ในระบบ ควรมีอยู่เสมอ:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

2. ป้องกัน wp-config.php

wp-config.php เก็บข้อมูลสำคัญมากที่สุดของ WordPress ได้แก่ Database credentials, Secret Keys และ Debug settings การป้องกันไม่ให้เข้าถึงจากภายนอกเป็นสิ่งบังคับ:

<files wp-config.php>
  order allow,deny
  deny from all
</files>

3. ป้องกัน .htaccess ตัวเอง

ป้องกันไม่ให้ใครอ่าน .htaccess จาก URL ตรงๆ (ซึ่งจะเปิดเผย Rules Security ทั้งหมด):

<files .htaccess>
  order allow,deny
  deny from all
</files>

4. ปิด XML-RPC

xmlrpc.php เป็น API เก่าของ WordPress ที่มักถูกโจมตีแบบ Brute Force และ DDoS Amplification ถ้าไม่ได้ใช้ JetPack หรือ Remote Publishing ควรปิดทันที:

<files xmlrpc.php>
  order deny,allow
  deny from all
</files>

ข้อควรระวัง: ถ้าใช้ JetPack, Caching Plugin หรือ Mobile App ที่ Connect ผ่าน XML-RPC การปิดจะทำให้ Plugin เหล่านั้นไม่ทำงาน ตรวจสอบก่อนปิด

5. ป้องกัน Directory Browsing

ถ้าโฟลเดอร์ไม่มีไฟล์ index.html/php Apache จะแสดงรายการไฟล์ทั้งหมดในโฟลเดอร์นั้น ซึ่งเป็นข้อมูลที่แฮกเกอร์ใช้วางแผนโจมตีได้:

Options -Indexes

5.5. เปิด GZIP Compression

GZIP ลดขนาดไฟล์ HTML, CSS, JavaScript ได้ 60–80% ช่วยให้หน้าโหลดเร็วขึ้นอย่างเห็นได้ชัด โดยเฉพาะบนเครือข่ายมือถือ ใช้คำสั่งนี้เพื่อเปิดใช้งาน:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml
  AddOutputFilterByType DEFLATE text/css text/javascript
  AddOutputFilterByType DEFLATE application/javascript application/x-javascript
  AddOutputFilterByType DEFLATE application/json application/xml
  AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>

ทดสอบ GZIP: ใช้เครื่องมือออนไลน์อย่าง GTmetrix หรือ Google PageSpeed Insights วิ่งตรวจสอบว่า GZIP ทำงานแล้วหรือยัง คะแนน Performance จะเพิ่มขึ้นหลังเปิดใช้งาน

5.6. Browser Caching ด้วย Cache-Control Headers

บอกให้ Browser เก็บ Cache ไฟล์ Static เช่น รูปภาพ, CSS, JS ไว้ในเครื่อง เพื่อลดเวลาโหลดในการเข้าครั้งถัดไป:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType application/x-javascript "access plus 1 month"
  ExpiresByType text/html "access plus 1 day"
</IfModule>

รูปภาพตั้ง Cache 1 ปีได้อย่างปลอดภัย เพราะมักเปลี่ยนน้อย ส่วน HTML ตั้ง 1 วันเพื่อให้ Bot และผู้เยี่ยมชมเห็นเนื้อหาใหม่ทุกวัน

6. ป้องกัน Hotlinking รูปภาพ

Hotlinking คือการที่เว็บอื่นนำ URL รูปภาพของคุณไปใช้โดยตรง ทำให้ Bandwidth ของคุณถูกใช้โดยไม่ได้รับประโยชน์ Block ได้ด้วย:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yoursite\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|svg)$ - [F,NC,L]

แทนที่ yoursite.com ด้วยโดเมนของคุณ

7. Redirect HTTP → HTTPS

บังคับให้ทุก Request ใช้ HTTPS เสมอ ป้องกัน Downgrade Attack:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

AsiaGB Hosting มี Let's Encrypt SSL ให้ฟรี และสามารถตั้ง Force HTTPS ได้ผ่าน DirectAdmin → SSL Certificates โดยไม่ต้องแก้ .htaccess เอง

7.5. บล็อก Bad Bots และ IP ที่ Abuse

Bot บางตัวไม่ใช่ Search Engine แต่คือ Scraper, Vulnerability Scanner หรือ Spam Bot ที่กิน Resource ของเซิร์ฟเวอร์โดยเปล่าประโยชน์ สามารถ Block ด้วย User-Agent หรือ IP Range ได้:

<IfModule mod_rewrite.c>
RewriteEngine On
# Block known bad scrapers and vulnerability scanners
RewriteCond %{HTTP_USER_AGENT} (masscan|nikto|sqlmap|havij|netsparker) [NC]
RewriteRule .* - [F,L]
</IfModule>

บล็อก IP เดียวหรือ Range ที่โจมตี:

<RequireAll>
  Require all granted
  Require not ip 185.220.101.0/24
</RequireAll>

ข้อควรระวัง: การบล็อก SEO Bot อย่าง Ahrefs หรือ Semrush อาจทำให้ไม่ปรากฏในฐานข้อมูล Backlink ของเครื่องมือเหล่านั้น บล็อกเฉพาะ Bot ที่สร้างปัญหา Load จริงๆ เท่านั้น

7.6. ป้องกัน wp-login.php จาก Brute Force

หน้า Login ของ WordPress คือเป้าหมายหลักของการโจมตีแบบ Brute Force จำกัดการเข้าถึงจาก IP ที่อนุญาตได้โดยตรง หรือบังคับให้ต้องผ่าน Basic Auth ก่อน:

# จำกัด wp-login.php เฉพาะ IP ที่กำหนด (แทนที่ YOUR.IP.HERE ด้วย IP จริง)
<Files wp-login.php>
  Order Deny,Allow
  Deny from all
  Allow from YOUR.IP.HERE
</Files>

ถ้ามี IP แบบ Dynamic (เปลี่ยนทุกครั้ง) ให้ใช้ Plugin อย่าง Limit Login Attempts Reloaded แทนการ Block IP ใน .htaccess

อีกวิธีหนึ่งคือเปลี่ยน URL หน้า Login ด้วย Plugin เช่น WPS Hide Login ทำให้ Bot หาหน้า Login ไม่เจอตั้งแต่แรก ลด Brute Force Attack ได้มากกว่า 90%

8. ซ่อน Server Signature

ซ่อน Version ของ Apache และ PHP เพื่อไม่ให้แฮกเกอร์รู้ว่าใช้ Software เวอร์ชันที่มีช่องโหว่หรือไม่:

ServerSignature Off
Header unset X-Powered-By
Header always unset X-Powered-By

9. Security Headers เพิ่มเติม

เพิ่ม HTTP Security Headers ที่ป้องกันการโจมตีระดับ Browser:

<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set X-XSS-Protection "1; mode=block"
</IfModule>

10. ปิดการรัน PHP ใน wp-content/uploads/

ช่องโหว่ที่แฮกเกอร์นิยมใช้คือการอัพโหลดไฟล์ PHP ปลอมเป็นรูปภาพแล้วสั่งรันผ่าน URL ตรงๆ วิธีป้องกันที่ดีที่สุดคือสร้างไฟล์ .htaccess ใหม่ภายในโฟลเดอร์ wp-content/uploads/ โดยเฉพาะ:

# สร้างไฟล์ .htaccess ใหม่ใน wp-content/uploads/
<FilesMatch "\.php$">
  Order Allow,Deny
  Deny from all
</FilesMatch>

เมื่อมีไฟล์ PHP หลุดเข้าไปในโฟลเดอร์ upload ก็ไม่สามารถสั่งรันได้ Browser จะได้รับ Error 403 Forbidden แทน นี่คือการป้องกันการโจมตีด้วย Shell Upload ได้อย่างสมบูรณ์

แนะนำอย่างยิ่ง: Rule เดียวนี้สามารถป้องกันการโจมตีประเภท PHP Shell Upload ได้ทั้งหมด ไม่ต้องใช้ Plugin ใดๆ ใช้เวลาตั้งค่าไม่ถึง 1 นาที แต่ป้องกันการแฮ็กระดับที่ Plugin Security ส่วนใหญ่ไม่สามารถทำได้

10.5. Custom Error Pages สำหรับ WordPress

การกำหนด Error Pages แบบ Custom ช่วยให้ผู้ใช้ได้รับประสบการณ์ที่ดีกว่าหน้า Error เริ่มต้นของ Apache และยังป้องกันไม่ให้ข้อมูล Server รั่วไหลด้วย:

# Custom Error Pages
ErrorDocument 400 /400.html
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

สร้างไฟล์ HTML สำหรับแต่ละ Error Code ที่ Root ของเว็บ หน้าเหล่านี้ควรมีลิงก์กลับหน้าแรกและ Navigation ปกติเพื่อให้ผู้ใช้หาทางออกได้

สำหรับ WordPress เฉพาะ 404 สามารถตั้งผ่าน Theme ได้ด้วย โดยสร้างไฟล์ 404.php ในโฟลเดอร์ Theme ซึ่งจะถูกใช้แทนหน้า WordPress 404 เริ่มต้นโดยอัตโนมัติ

11. สรุปลำดับความสำคัญของ Rules ที่ต้องมี

ถ้ายังไม่เคยปรับ .htaccess มาก่อน ควรเพิ่ม Rules ตามลำดับความสำคัญดังนี้ ทำทีละขั้นและทดสอบหลังเพิ่มแต่ละ Rule:

ลำดับ Rule ความสำคัญ ผลที่ได้รับ
1 Force HTTPS สูงมาก ป้องกัน Downgrade Attack, SEO ดีขึ้น
2 ปกป้อง wp-config.php + .htaccess สูงมาก ป้องกันข้อมูล Database รั่วไหล
3 ปิด XML-RPC สูง ป้องกัน Brute Force + DDoS Amplification
4 ปิด Directory Browsing สูง ซ่อนโครงสร้างไฟล์จากแฮกเกอร์
5 Security Headers สูง ป้องกัน XSS, Clickjacking, MIME Sniffing
6 GZIP + Browser Cache กลาง เว็บโหลดเร็วขึ้น, PageSpeed สูงขึ้น
7 ป้องกัน Hotlinking กลาง ลด Bandwidth ที่ถูกใช้โดยไม่ได้รับประโยชน์

12. วิธีทดสอบว่า .htaccess ทำงานถูกต้อง

หลังเพิ่ม Rule ใหม่ควรทดสอบทันทีว่าเว็บยังทำงานปกติและ Rule ที่เพิ่มเข้ามามีผลจริง มีวิธีทดสอบหลายแบบตามประเภทของ Rule:

ทดสอบ HTTPS Redirect

เปิด Browser และพิมพ์ http:// นำหน้าโดเมน (ไม่ใช่ https) แล้วดูว่า URL เปลี่ยนเป็น https:// อัตโนมัติหรือไม่ หรือใช้ Tool เช่น curl -I http://yourdomain.com แล้วดู Status Code ต้องได้ 301

ทดสอบการปิด Directory Browsing

ลองเข้า URL ที่เป็นโฟลเดอร์ที่ไม่มีไฟล์ Index เช่น https://yourdomain.com/wp-content/ ถ้า Rule ทำงานถูกต้องจะได้ Error 403 Forbidden แทนรายการไฟล์

ทดสอบ Security Headers

ใช้เว็บ securityheaders.com ตรวจสอบว่า HTTP Headers ที่ตั้งใน .htaccess ส่งออกมาจริง โดยใส่ URL เว็บแล้วกด Scan จะเห็น Grade และ Headers ที่มี/ขาดหายไป เว็บที่ตั้งครบควรได้ Grade A หรือ A+

ทดสอบ GZIP Compression

ใช้ GTmetrix หรือ Google PageSpeed Insights วิ่งตรวจสอบเว็บ จะมี Section บอกว่า Enable text compression แล้วหรือยัง ถ้า GZIP ทำงานจะไม่เห็น Warning นี้

ทดสอบ Hotlink Protection

เปิด Browser อื่นหรือ Private Mode แล้วพยายามเปิด URL รูปภาพตรงๆ จากโดเมนอื่น (เช่นใส่ใน HTML ของเว็บ Test) ถ้า Rule ทำงานถูกต้องรูปจะไม่โหลดหรือได้ Error 403

สิ่งที่ต้องระวังหลังแก้ .htaccess: ล้าง Browser Cache และ CDN Cache เสมอก่อนทดสอบ เพราะ Request ที่ Cache ไว้อาจไม่ผ่าน .htaccess อีกครั้ง ทำให้เห็นผลผิดพลาดได้

13. ข้อผิดพลาดที่พบบ่อยเมื่อแก้ .htaccess

แม้แต่ผู้ดูแลระบบที่มีประสบการณ์ก็ยังเจอข้อผิดพลาดเหล่านี้ รู้ไว้จะช่วยแก้ปัญหาได้เร็วขึ้น:

เคล็ดลับสำหรับการ Debug .htaccess คือเพิ่มทีละ Rule แล้วทดสอบทันที แทนที่จะเพิ่มหลาย Rule พร้อมกัน เมื่อเกิดปัญหาจะได้รู้ทันทีว่า Rule ไหนเป็นต้นเหตุ

14. ตัวอย่าง .htaccess WordPress ฉบับสมบูรณ์

รวมทุก Rules ด้านบนในไฟล์เดียว (แทนที่ yoursite.com ด้วยโดเมนจริง):

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

# Security: Protect wp-config.php
<files wp-config.php>
  order allow,deny
  deny from all
</files>

# Security: Protect .htaccess
<files .htaccess>
  order allow,deny
  deny from all
</files>

# Security: Block XML-RPC
<files xmlrpc.php>
  order deny,allow
  deny from all
</files>

# Disable Directory Browsing
Options -Indexes

# Force HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Security Headers
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  ServerSignature Off
  Header unset X-Powered-By
</IfModule>

Hosting WordPress พร้อม SSL ฟรี บน Apache ที่เชื่อถือได้

AsiaGB Hosting ใช้ Apache + DirectAdmin รองรับ .htaccess เต็มรูปแบบ พร้อม SSL ฟรีและ Backup อัตโนมัติ เริ่มต้น 500 บาท/ปี

ดูแพ็กเกจ Hosting →