diff --git a/OpenLiteSpeed_htaccess_Module_Documentation.md b/OpenLiteSpeed_htaccess_Module_Documentation.md new file mode 100644 index 000000000..b0c1dd2a8 --- /dev/null +++ b/OpenLiteSpeed_htaccess_Module_Documentation.md @@ -0,0 +1,2791 @@ +# CyberPanel OpenLiteSpeed Module - Complete Usage Guide + +**Version:** 2.2.0 +**Last Updated:** December 28, 2025 +**Status:** Production Ready + +--- + +## Table of Contents + +1. [Getting Started](#getting-started) +2. [Header Directives](#1-header-directives) +3. [Request Header Directives](#2-request-header-directives) +4. [Environment Variables](#3-environment-variables) +5. [Access Control](#4-access-control) +6. [Redirect Directives](#5-redirect-directives) +7. [Error Documents](#6-error-documents) +8. [FilesMatch Directives](#7-filesmatch-directives) +9. [Expires Directives](#8-expires-directives) +10. [PHP Directives](#9-php-directives) +11. [Brute Force Protection](#10-brute-force-protection) +12. [CyberPanel Integration](#cyberpanel-integration) +13. [Real-World Examples](#real-world-examples) +14. [Troubleshooting](#troubleshooting) + +--- + +## Getting Started + +### What is This Module? + +The CyberPanel OpenLiteSpeed Module brings Apache .htaccess compatibility to OpenLiteSpeed servers. It allows you to use familiar Apache directives without switching web servers. + +### Quick Start + +1. **Module is pre-installed** on CyberPanel servers +2. **Create .htaccess** in your website's public_html directory +3. **Add directives** from this guide +4. **Test** using curl or browser + +### Basic .htaccess Example + +```apache +# Security headers +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" + +# Enable brute force protection +BruteForceProtection On +``` + +--- + +## 1. Header Directives + +### What Are HTTP Headers? + +HTTP headers are metadata sent with web responses. They control browser behavior, caching, security, and more. + +### Supported Operations + +| Operation | Purpose | Syntax | +|-----------|---------|--------| +| **set** | Set header (replaces existing) | `Header set Name "Value"` | +| **unset** | Remove header | `Header unset Name` | +| **append** | Append to existing header | `Header append Name "Value"` | +| **merge** | Add if not present | `Header merge Name "Value"` | +| **add** | Always add (allows duplicates) | `Header add Name "Value"` | + +### How to Use + +#### Basic Security Headers + +**What it does:** Protects against clickjacking, XSS, and MIME sniffing. + +```apache +# Prevent site from being embedded in iframe (clickjacking protection) +Header set X-Frame-Options "SAMEORIGIN" + +# Prevent MIME type sniffing +Header set X-Content-Type-Options "nosniff" + +# Enable XSS filter in browsers +Header set X-XSS-Protection "1; mode=block" + +# Control referrer information +Header set Referrer-Policy "strict-origin-when-cross-origin" + +# Restrict browser features +Header set Permissions-Policy "geolocation=(), microphone=(), camera=()" +``` + +**Testing:** +```bash +curl -I https://yourdomain.com | grep -E "X-Frame|X-Content|X-XSS" +``` + +#### Cache Control Headers + +**What it does:** Controls how browsers cache your content. + +```apache +# Cache for 1 year (static assets) +Header set Cache-Control "max-age=31536000, public, immutable" + +# No caching (dynamic content) +Header set Cache-Control "no-cache, no-store, must-revalidate" +Header set Pragma "no-cache" +Header set Expires "0" + +# Cache for 1 hour +Header set Cache-Control "max-age=3600, public" +``` + +**Testing:** +```bash +curl -I https://yourdomain.com/style.css | grep Cache-Control +``` + +#### CORS Headers + +**What it does:** Allows cross-origin requests (needed for APIs, fonts, n8n, etc.). + +```apache +# Allow all origins +Header set Access-Control-Allow-Origin "*" + +# Allow specific origin +Header set Access-Control-Allow-Origin "https://app.example.com" + +# Allow specific methods +Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" + +# Allow specific headers +Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" + +# Allow credentials +Header set Access-Control-Allow-Credentials "true" + +# Preflight cache duration +Header set Access-Control-Max-Age "86400" +``` + +**Testing:** +```bash +curl -I -H "Origin: https://example.com" https://yourdomain.com/api +``` + +#### Remove Server Identification + +**What it does:** Hides server information from attackers. + +```apache +Header unset Server +Header unset X-Powered-By +Header unset X-LiteSpeed-Tag +``` + +**Testing:** +```bash +curl -I https://yourdomain.com | grep -E "Server|X-Powered" +# Should return nothing +``` + +### CyberPanel Integration + +#### Via File Manager + +1. Log into **CyberPanel** +2. Go to **File Manager** +3. Navigate to `/home/yourdomain.com/public_html` +4. Create or edit `.htaccess` +5. Add header directives +6. Save and test + +#### Via SSH + +```bash +# Navigate to website directory +cd /home/yourdomain.com/public_html + +# Edit .htaccess +nano .htaccess + +# Add your headers +Header set X-Frame-Options "SAMEORIGIN" + +# Save (Ctrl+X, Y, Enter) + +# Test +curl -I https://yourdomain.com | grep X-Frame +``` + +### Common Use Cases + +#### WordPress Security Headers + +```apache +# WordPress-specific security +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" +Header set X-XSS-Protection "1; mode=block" +Header set Referrer-Policy "strict-origin-when-cross-origin" +Header unset X-Powered-By + +# Disable XML-RPC header +Header unset X-Pingback +``` + +#### n8n CORS Configuration + +```apache +# Allow n8n webhooks +Header set Access-Control-Allow-Origin "https://your-n8n-instance.com" +Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" +Header set Access-Control-Allow-Headers "Content-Type, Authorization" +Header set Access-Control-Allow-Credentials "true" +``` + +#### API Response Headers + +```apache +# JSON API headers +Header set Content-Type "application/json; charset=utf-8" +Header set X-Content-Type-Options "nosniff" +Header set Access-Control-Allow-Origin "*" +Header set Cache-Control "no-cache, no-store, must-revalidate" +``` + +--- + +## 2. Request Header Directives + +### What Are Request Headers? + +Request headers are sent FROM the client TO the server. This feature lets you modify or add headers before they reach your PHP application. + +### How It Works + +Since OpenLiteSpeed's LSIAPI doesn't support direct request header modification, these are implemented as **environment variables** accessible in PHP via `$_SERVER`. + +### Supported Operations + +| Operation | Syntax | Result | +|-----------|--------|--------| +| **set** | `RequestHeader set Name "Value"` | `$_SERVER['HTTP_NAME']` | +| **unset** | `RequestHeader unset Name` | Header removed | + +### How to Use + +#### SSL/HTTPS Detection (Behind Proxy) + +**What it does:** Tells your application the request came via HTTPS (when behind Cloudflare, nginx proxy, etc.). + +```apache +# Set HTTPS protocol headers +RequestHeader set X-Forwarded-Proto "https" +RequestHeader set X-Forwarded-SSL "on" +RequestHeader set X-Real-IP "%{REMOTE_ADDR}e" +``` + +**PHP Usage:** +```php + +``` + +#### Application Environment Identification + +**What it does:** Tags requests with environment information. + +```apache +# Identify environment +RequestHeader set X-Environment "production" +RequestHeader set X-Server-Location "us-east-1" +RequestHeader set X-Request-Start "%{REQUEST_TIME}e" +``` + +**PHP Usage:** +```php + +``` + +#### Custom Backend Headers + +**What it does:** Passes custom information to your application. + +```apache +# Custom application headers +RequestHeader set X-API-Version "v2" +RequestHeader set X-Feature-Flags "new-ui,beta-features" +RequestHeader set X-Client-Type "web" +``` + +**PHP Usage:** +```php + +``` + +### CyberPanel Integration + +#### For WordPress Behind Cloudflare + +```apache +# In /home/yourdomain.com/public_html/.htaccess +RequestHeader set X-Forwarded-Proto "https" +RequestHeader set X-Forwarded-SSL "on" + +# WordPress will now correctly detect HTTPS +``` + +**Verify in WordPress:** +```php +// Add to wp-config.php if needed +if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $_SERVER['HTTPS'] = 'on'; +} +``` + +### Common Use Cases + +#### Cloudflare + WordPress + +```apache +RequestHeader set X-Forwarded-Proto "https" +RequestHeader set X-Forwarded-SSL "on" +RequestHeader set X-Real-IP "%{REMOTE_ADDR}e" +``` + +#### Laravel Behind Load Balancer + +```apache +RequestHeader set X-Forwarded-Proto "https" +RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}e" +``` + +--- + +## 3. Environment Variables + +### What Are Environment Variables? + +Environment variables are key-value pairs accessible in your PHP application. They're useful for configuration, feature flags, and conditional logic. + +### Supported Directives + +| Directive | Purpose | Syntax | +|-----------|---------|--------| +| **SetEnv** | Set static variable | `SetEnv NAME value` | +| **SetEnvIf** | Conditional set (case-sensitive) | `SetEnvIf attribute regex VAR=value` | +| **SetEnvIfNoCase** | Conditional set (case-insensitive) | `SetEnvIfNoCase attribute regex VAR=value` | +| **BrowserMatch** | Detect browser | `BrowserMatch regex VAR=value` | + +### How to Use + +#### Static Configuration Variables + +**What it does:** Sets application configuration accessible in PHP. + +```apache +# Application settings +SetEnv APPLICATION_ENV production +SetEnv DB_HOST localhost +SetEnv DB_NAME myapp_db +SetEnv API_ENDPOINT https://api.example.com +SetEnv FEATURE_FLAG_NEW_UI enabled +SetEnv DEBUG_MODE off +``` + +**PHP Usage:** +```php + +``` + +#### Conditional Variables (SetEnvIf) + +**What it does:** Sets variables based on request properties. + +##### Supported Conditions + +- `Request_URI` - URL path +- `Request_Method` - HTTP method (GET, POST, etc.) +- `User-Agent` - Browser/client identifier +- `Host` - Domain name +- `Referer` - Referrer URL +- `Query_String` - URL parameters +- `Remote_Addr` - Client IP address + +**Examples:** + +```apache +# Detect API requests +SetEnvIf Request_URI "^/api/" IS_API_REQUEST=1 + +# Detect POST requests +SetEnvIf Request_Method "POST" IS_POST_REQUEST=1 + +# Detect specific domain +SetEnvIf Host "^beta\." IS_BETA_SITE=1 + +# Detect search queries +SetEnvIf Query_String "search=" HAS_SEARCH=1 + +# Detect local development +SetEnvIf Remote_Addr "^127\.0\.0\.1$" IS_LOCAL=1 +``` + +**PHP Usage:** +```php + +``` + +#### Browser Detection + +**What it does:** Identifies the user's browser for compatibility handling. + +```apache +# Case-insensitive browser detection +SetEnvIfNoCase User-Agent "mobile|android|iphone|ipad" IS_MOBILE=1 +SetEnvIfNoCase User-Agent "bot|crawler|spider|scraper" IS_BOT=1 +SetEnvIfNoCase User-Agent "MSIE|Trident" IS_IE=1 + +# Specific browser matching +BrowserMatch "Chrome" IS_CHROME=1 +BrowserMatch "Firefox" IS_FIREFOX=1 +BrowserMatch "Safari" IS_SAFARI=1 +BrowserMatch "Edge" IS_EDGE=1 +``` + +**PHP Usage:** +```php +Please use a modern browser'; +} +?> +``` + +### CyberPanel Integration + +#### Environment-Specific Configuration + +```apache +# In /home/yourdomain.com/public_html/.htaccess + +# Production settings +SetEnv APPLICATION_ENV production +SetEnv DEBUG_MODE off +SetEnv CACHE_ENABLED on + +# Database connection +SetEnv DB_HOST localhost +SetEnv DB_NAME wp_database + +# Feature flags +SetEnv ENABLE_CDN on +SetEnv ENABLE_CACHE on +``` + +**WordPress Usage (wp-config.php):** +```php + +``` + +### Common Use Cases + +#### Mobile Detection + Redirect + +```apache +# Detect mobile users +SetEnvIfNoCase User-Agent "mobile|android|iphone" IS_MOBILE=1 + +# Redirect mobile to subdomain (using PHP) +``` + +**PHP redirect:** +```php + +``` + +#### API Rate Limiting Preparation + +```apache +# Tag API requests +SetEnvIf Request_URI "^/api/" IS_API=1 +SetEnvIf Request_Method "POST" IS_POST=1 +``` + +**PHP rate limiting:** +```php + +``` + +--- + +## 4. Access Control + +### What is Access Control? + +Access control restricts who can access your website based on IP addresses. Perfect for staging sites, admin panels, or development environments. + +### Directives + +| Directive | Syntax | Description | +|-----------|--------|-------------| +| **Order** | `Order deny,allow` or `Order allow,deny` | Set evaluation order | +| **Allow** | `Allow from IP/CIDR` | Allow specific IP | +| **Deny** | `Deny from IP/CIDR` | Deny specific IP | + +### Supported IP Formats + +- **Single IP:** `192.168.1.100` +- **CIDR Range:** `192.168.1.0/24` (entire subnet) +- **Large Ranges:** `10.0.0.0/8` (entire class) +- **IPv6:** `2001:db8::/32` +- **Wildcard:** `all` (everyone) + +### How Order Works + +#### Order deny,allow + +1. Check **Deny** list first +2. Then check **Allow** list +3. **Allow overrides Deny** +4. Default: **DENY** if not in either list + +```apache +Order deny,allow +Deny from all +Allow from 192.168.1.100 +# Result: Only 192.168.1.100 can access +``` + +#### Order allow,deny + +1. Check **Allow** list first +2. Then check **Deny** list +3. **Deny overrides Allow** +4. Default: **ALLOW** if not in either list + +```apache +Order allow,deny +Allow from all +Deny from 192.168.1.100 +# Result: Everyone except 192.168.1.100 can access +``` + +### How to Use + +#### Block All Except Specific IPs (Recommended for Staging) + +```apache +# Only allow office IP and VPN +Order deny,allow +Deny from all +Allow from 203.0.113.50 # Office IP +Allow from 192.168.1.0/24 # Office LAN +Allow from 10.8.0.0/24 # VPN range +``` + +**Use case:** Development/staging sites, admin areas + +**Testing:** +```bash +# From allowed IP +curl https://staging.example.com +# Should work + +# From other IP +curl https://staging.example.com +# Should get 403 Forbidden +``` + +#### Allow All Except Specific IPs + +```apache +# Block known attackers +Order allow,deny +Allow from all +Deny from 198.51.100.50 # Banned IP +Deny from 203.0.113.0/24 # Banned subnet +``` + +**Use case:** Blocking spam IPs, attack sources + +#### Protect Admin Directory + +```apache +# In /home/yourdomain.com/public_html/admin/.htaccess +Order deny,allow +Deny from all +Allow from 192.168.1.0/24 # Office network +Allow from 203.0.113.100 # Your home IP +``` + +**Use case:** WordPress wp-admin protection + +### CyberPanel Integration + +#### Protect Staging Site + +1. Create subdomain `staging.yourdomain.com` in CyberPanel +2. Navigate to `/home/staging.yourdomain.com/public_html` +3. Create `.htaccess`: + +```apache +# Staging site - Office only +Order deny,allow +Deny from all +Allow from YOUR.OFFICE.IP.HERE +Allow from YOUR.HOME.IP.HERE +``` + +4. Test: +```bash +# Get your IP +curl ifconfig.me + +# Test access +curl -I https://staging.yourdomain.com +# Should see 403 if not allowed +``` + +#### Protect WordPress Admin + +```apache +# In /home/yourdomain.com/public_html/wp-admin/.htaccess +Order deny,allow +Deny from all +Allow from 203.0.113.50 # Your IP +``` + +**Important:** This creates TWO layers of protection: +1. IP restriction (from .htaccess) +2. Login authentication (from WordPress) + +#### Protect CyberPanel Access + +```apache +# In /usr/local/CyberCP/public/.htaccess (if web accessible) +Order deny,allow +Deny from all +Allow from 127.0.0.1 # localhost +Allow from 192.168.1.0/24 # Your network +``` + +### Common Use Cases + +#### Development Environment + +```apache +# Dev site - developers only +Order deny,allow +Deny from all +Allow from 192.168.1.0/24 # Office LAN +Allow from 10.8.0.0/24 # VPN +Allow from 203.0.113.50 # Lead developer home +``` + +#### Geographic Restriction + +```apache +# Block specific countries (you need to maintain IP list) +Order allow,deny +Allow from all +Deny from 198.51.100.0/24 # Country X subnet +Deny from 203.0.113.0/24 # Country Y subnet +``` + +#### API Endpoint Protection + +```apache +# In /home/yourdomain.com/public_html/api/.htaccess +Order deny,allow +Deny from all +Allow from 10.0.0.0/8 # Internal network +Allow from 172.16.0.0/12 # Private network +``` + +### Troubleshooting + +**Problem:** Getting 403 even from allowed IP + +**Solution:** +1. Check your actual IP: `curl ifconfig.me` +2. Verify CIDR: `192.168.1.0/24` covers `192.168.1.1` to `192.168.1.254` +3. Check logs: `tail -f /usr/local/lsws/logs/error.log` + +**Problem:** Access control not working + +**Solution:** +1. Verify module loaded: `ls -la /usr/local/lsws/modules/cyberpanel_ols.so` +2. Check .htaccess permissions: `chmod 644 .htaccess` +3. Restart OpenLiteSpeed: `/usr/local/lsws/bin/lswsctrl restart` + +--- + +## 5. Redirect Directives + +### What Are Redirects? + +Redirects tell browsers to go to a different URL. Essential for SEO, site migrations, and URL structure changes. + +### Directives + +| Directive | Syntax | Use Case | +|-----------|--------|----------| +| **Redirect** | `Redirect [code] /old /new` | Simple path redirects | +| **RedirectMatch** | `RedirectMatch [code] regex target` | Pattern-based redirects | + +### Status Codes + +| Code | Name | When to Use | +|------|------|-------------| +| **301** | Permanent | SEO-friendly, URL has moved forever | +| **302** | Temporary | URL temporarily moved, may change back | +| **303** | See Other | Redirect after POST (form submission) | +| **410** | Gone | Resource permanently deleted | + +### How to Use + +#### Simple Redirects + +**What it does:** Redirects one path to another. + +```apache +# Old page to new page +Redirect 301 /old-page.html /new-page.html + +# Old directory to new directory +Redirect 301 /old-blog /blog + +# Use keywords instead of codes +Redirect permanent /old-url /new-url +Redirect temp /maintenance /coming-soon +``` + +**Testing:** +```bash +curl -I https://yourdomain.com/old-page.html +# Should show: HTTP/1.1 301 Moved Permanently +# Location: https://yourdomain.com/new-page.html +``` + +#### Force HTTPS + +**What it does:** Redirects HTTP to HTTPS. + +```apache +# Redirect HTTP to HTTPS +Redirect 301 / https://yourdomain.com/ +``` + +**Better Alternative (checks if already HTTPS):** +```apache +SetEnvIf Request_URI ".*" IS_HTTP=1 +# Use with PHP to avoid redirect loop +``` + +**PHP solution:** +```php + +``` + +#### Force WWW or Non-WWW + +**What it does:** Standardizes domain format for SEO. + +```apache +# Force www +Redirect 301 / https://www.yourdomain.com/ + +# Force non-www (use RedirectMatch) +RedirectMatch 301 ^(.*)$ https://yourdomain.com$1 +``` + +#### Pattern-Based Redirects (RedirectMatch) + +**What it does:** Uses regex to match and redirect URLs. + +```apache +# Blog restructuring +RedirectMatch 301 ^/blog/(.*)$ /news/$1 +# /blog/post-1 → /news/post-1 + +# Product ID migration +RedirectMatch 301 ^/product-([0-9]+)$ /item/$1 +# /product-123 → /item/123 + +# Year/month/title to title +RedirectMatch 301 ^/blog/([0-9]{4})/([0-9]{2})/(.*)$ /articles/$3 +# /blog/2024/12/my-post → /articles/my-post + +# Category reorganization +RedirectMatch 301 ^/category/(.*)$ /topics/$1 +``` + +**Testing:** +```bash +curl -I https://yourdomain.com/blog/my-post +# Should redirect to /news/my-post +``` + +### CyberPanel Integration + +#### Site Migration (Old Domain to New) + +```apache +# In old site's .htaccess +Redirect 301 / https://new-domain.com/ +``` + +**Steps:** +1. Keep old domain active in CyberPanel +2. Add redirect to `/home/old-domain.com/public_html/.htaccess` +3. Monitor traffic migration +4. After 6 months, can delete old domain + +#### WordPress Permalink Change + +**Scenario:** Changed permalinks from `/?p=123` to `/blog/post-title` + +```apache +# WordPress handles this automatically, but for custom: +RedirectMatch 301 ^/\?p=([0-9]+)$ /blog/post-$1 +``` + +#### E-commerce URL Update + +```apache +# Old: /products/view/123 +# New: /shop/product-123 + +RedirectMatch 301 ^/products/view/([0-9]+)$ /shop/product-$1 +``` + +### Common Use Cases + +#### Complete Site Redesign + +```apache +# Redirect old structure to new +RedirectMatch 301 ^/about-us$ /about +RedirectMatch 301 ^/contact-us$ /contact +RedirectMatch 301 ^/services/(.*)$ /solutions/$1 +RedirectMatch 301 ^/blog/(.*)$ /news/$1 +``` + +#### Affiliate Link Management + +```apache +# Short URLs for affiliate links +Redirect 302 /go/amazon https://amazon.com/your-affiliate-link +Redirect 302 /go/product https://example.com/long-url-here +``` + +#### Seasonal Campaigns + +```apache +# Temporary campaign redirect +Redirect 302 /sale /christmas-sale-2025 +Redirect 302 /promo /black-friday +``` + +#### Remove .html Extensions (SEO) + +```apache +# Old: /page.html +# New: /page + +RedirectMatch 301 ^/(.*)/index\.html$ /$1/ +RedirectMatch 301 ^/(.*)[^/]\.html$ /$1 +``` + +### Troubleshooting + +**Problem:** Redirect loop + +**Solution:** Check for conflicting rules: +```apache +# BAD - Creates loop +Redirect 301 / https://example.com/ +Redirect 301 / https://www.example.com/ + +# GOOD - Use one or the other +Redirect 301 / https://www.example.com/ +``` + +**Problem:** Redirect not working + +**Solution:** +1. Clear browser cache (redirects are cached!) +2. Test with curl: `curl -I https://yoursite.com/old-page` +3. Check .htaccess syntax +4. Restart OpenLiteSpeed + +--- + +## 6. Error Documents + +### What Are Error Documents? + +Custom error pages shown when errors occur (404 Not Found, 500 Internal Server Error, etc.). + +### Supported Error Codes + +| Code | Error | When It Happens | +|------|-------|-----------------| +| **400** | Bad Request | Malformed request | +| **401** | Unauthorized | Authentication required | +| **403** | Forbidden | Access denied | +| **404** | Not Found | Page doesn't exist | +| **500** | Internal Server Error | Server-side error | +| **502** | Bad Gateway | Proxy/backend error | +| **503** | Service Unavailable | Server overloaded/maintenance | + +### Syntax + +```apache +ErrorDocument +``` + +### How to Use + +#### HTML Error Pages + +**What it does:** Shows custom-designed error pages. + +```apache +# Custom error pages +ErrorDocument 404 /errors/404.html +ErrorDocument 500 /errors/500.html +ErrorDocument 403 /errors/403.html +ErrorDocument 503 /errors/maintenance.html +``` + +**Create error pages:** + +```bash +mkdir -p /home/yourdomain.com/public_html/errors +``` + +**404.html example:** +```html + + + + Page Not Found + + + +

404 - Page Not Found

+

The page you're looking for doesn't exist.

+ Go to Homepage + + +``` + +**Testing:** +```bash +curl https://yourdomain.com/nonexistent-page +# Should show your custom 404 page +``` + +#### Inline Messages + +**What it does:** Shows simple text message. + +```apache +ErrorDocument 403 "Access Denied - Contact Administrator" +ErrorDocument 404 "Page Not Found - Please check the URL" +``` + +#### WordPress-Friendly Error Pages + +**What it does:** Routes errors through WordPress. + +```apache +# Let WordPress handle 404s +ErrorDocument 404 /index.php?error=404 +``` + +**WordPress theme (404.php):** +```php + +

Page Not Found

+

Sorry, this page doesn't exist.

+ +``` + +### CyberPanel Integration + +#### Setup Custom Error Pages + +**Step 1:** Create error directory +```bash +cd /home/yourdomain.com/public_html +mkdir errors +cd errors +``` + +**Step 2:** Create error page files +```bash +nano 404.html +# Add custom HTML +# Save (Ctrl+X, Y, Enter) + +nano 500.html +# Add custom HTML +# Save +``` + +**Step 3:** Configure .htaccess +```apache +# In /home/yourdomain.com/public_html/.htaccess +ErrorDocument 404 /errors/404.html +ErrorDocument 500 /errors/500.html +ErrorDocument 403 /errors/403.html +``` + +**Step 4:** Test +```bash +curl https://yourdomain.com/test-404 +``` + +#### Maintenance Page + +```apache +# During maintenance +ErrorDocument 503 /maintenance.html +``` + +**maintenance.html:** +```html + + + + Maintenance + + + + +

We'll be right back!

+

Our site is undergoing maintenance.

+

Expected completion: 2 hours

+ + +``` + +**Trigger maintenance mode:** +```bash +# Temporarily disable PHP +mv index.php index.php.bak +# Site will show 503 +``` + +### Common Use Cases + +#### Professional 404 Page with Search + +**404.html:** +```html + + + + Page Not Found + + +

404 - Page Not Found

+

Try searching:

+
+ + +
+

Return to Homepage

+ + +``` + +#### Branded Error Pages + +```apache +ErrorDocument 400 /errors/400.html +ErrorDocument 401 /errors/401.html +ErrorDocument 403 /errors/403.html +ErrorDocument 404 /errors/404.html +ErrorDocument 500 /errors/500.html +ErrorDocument 502 /errors/502.html +ErrorDocument 503 /errors/503.html +``` + +Each page styled with your brand colors, logo, navigation. + +--- + +## 7. FilesMatch Directives + +### What is FilesMatch? + +FilesMatch applies directives only to files matching a regex pattern. Perfect for caching strategies, security headers per file type. + +### Syntax + +```apache + + # Directives here apply only to matching files + Header set Name "Value" + +``` + +### Common File Patterns + +| Pattern | Matches | +|---------|---------| +| `\.(jpg\|png\|gif)$` | Images | +| `\.(css\|js)$` | Stylesheets and JavaScript | +| `\.(woff2?\|ttf\|eot)$` | Fonts | +| `\.(pdf\|doc\|docx)$` | Documents | +| `\.(html\|php)$` | Dynamic pages | +| `\.json$` | JSON files | + +### How to Use + +#### Cache Static Assets (Performance Boost) + +**What it does:** Tells browsers to cache images/fonts for a long time. + +```apache +# Images - Cache for 1 year + + Header set Cache-Control "max-age=31536000, public, immutable" + Header unset ETag + Header unset Last-Modified + + +# Fonts - Cache for 1 year + + Header set Cache-Control "max-age=31536000, public, immutable" + Header set Access-Control-Allow-Origin "*" + + +# CSS/JS - Cache for 1 week (you update these more often) + + Header set Cache-Control "max-age=604800, public" + +``` + +**Testing:** +```bash +curl -I https://yourdomain.com/logo.png | grep Cache-Control +# Should show: Cache-Control: max-age=31536000, public, immutable +``` + +**Performance Impact:** +- First visit: Downloads all files +- Return visits: Loads from browser cache (instant!) +- Page load time: -50% to -80% + +#### Security Headers for HTML/PHP + +**What it does:** Applies security headers only to pages (not images). + +```apache + + Header set X-Frame-Options "SAMEORIGIN" + Header set X-Content-Type-Options "nosniff" + Header set X-XSS-Protection "1; mode=block" + Header set Referrer-Policy "strict-origin-when-cross-origin" + +``` + +#### Prevent Caching of Dynamic Content + +**What it does:** Ensures dynamic pages are never cached. + +```apache + + Header set Cache-Control "no-cache, no-store, must-revalidate" + Header set Pragma "no-cache" + Header set Expires "0" + +``` + +#### CORS for Fonts (Fix Font Loading) + +**What it does:** Allows fonts to load from CDN or different domain. + +```apache + + Header set Access-Control-Allow-Origin "*" + +``` + +**Use case:** Fixes "Font from origin has been blocked by CORS policy" errors. + +#### Download Headers for Files + +**What it does:** Forces download instead of displaying in browser. + +```apache + + Header set Content-Disposition "attachment" + Header set X-Content-Type-Options "nosniff" + +``` + +### CyberPanel Integration + +#### WordPress Performance Optimization + +```apache +# In /home/yourdomain.com/public_html/.htaccess + +# Cache WordPress static assets + + Header set Cache-Control "max-age=31536000, public, immutable" + + +# Cache CSS/JS (with version strings in WordPress) + + Header set Cache-Control "max-age=2592000, public" + + +# Don't cache WordPress admin + + Header set Cache-Control "no-cache, no-store, must-revalidate" + +``` + +**Result:** PageSpeed score +20-30 points + +#### WooCommerce Security + +```apache +# Protect sensitive files + + Order deny,allow + Deny from all + + +# JSON API security + + Header set X-Content-Type-Options "nosniff" + Header set Content-Type "application/json; charset=utf-8" + +``` + +### Common Use Cases + +#### Complete Caching Strategy + +```apache +# Aggressive caching for static assets (1 year) + + Header set Cache-Control "max-age=31536000, public, immutable" + Header unset ETag + + +# Moderate caching for CSS/JS (1 month) + + Header set Cache-Control "max-age=2592000, public" + + +# Short caching for HTML (1 hour) + + Header set Cache-Control "max-age=3600, public" + + +# No caching for dynamic content + + Header set Cache-Control "no-cache, must-revalidate" + +``` + +#### Media Library Protection + +```apache +# Prevent hotlinking (bandwidth theft) + + SetEnvIf Referer "^https://yourdomain\.com" local_ref + SetEnvIf Referer "^$" local_ref + Order deny,allow + Deny from all + Allow from env=local_ref + +``` + +--- + +## 8. Expires Directives + +### What is mod_expires? + +Alternative syntax for setting cache expiration. More concise than Cache-Control headers. + +### Directives + +```apache +ExpiresActive On +ExpiresByType mime-type base+seconds +``` + +### Time Bases + +- **A** = Access time (when user requests file) +- **M** = Modification time (when file was last modified) + +### Common Durations + +| Duration | Seconds | Example | +|----------|---------|---------| +| 1 minute | 60 | `A60` | +| 1 hour | 3600 | `A3600` | +| 1 day | 86400 | `A86400` | +| 1 week | 604800 | `A604800` | +| 1 month | 2592000 | `A2592000` | +| 1 year | 31557600 | `A31557600` | + +### How to Use + +#### Complete Expiration Strategy + +```apache +# Enable module +ExpiresActive On + +# Images - 1 year +ExpiresByType image/jpeg A31557600 +ExpiresByType image/png A31557600 +ExpiresByType image/gif A31557600 +ExpiresByType image/webp A31557600 +ExpiresByType image/svg+xml A31557600 +ExpiresByType image/x-icon A31557600 + +# CSS and JavaScript - 1 month +ExpiresByType text/css A2592000 +ExpiresByType application/javascript A2592000 +ExpiresByType application/x-javascript A2592000 +ExpiresByType text/javascript A2592000 + +# Fonts - 1 year +ExpiresByType font/ttf A31557600 +ExpiresByType font/woff A31557600 +ExpiresByType font/woff2 A31557600 +ExpiresByType application/font-woff A31557600 +ExpiresByType application/font-woff2 A31557600 + +# HTML - no cache +ExpiresByType text/html A0 + +# PDF - 1 month +ExpiresByType application/pdf A2592000 + +# JSON/XML - 1 hour +ExpiresByType application/json A3600 +ExpiresByType application/xml A3600 +``` + +**Testing:** +```bash +curl -I https://yourdomain.com/image.jpg | grep -E "Expires|Cache-Control" +``` + +### CyberPanel Integration + +#### WordPress Caching + +```apache +# In /home/yourdomain.com/public_html/.htaccess + +ExpiresActive On + +# WordPress uploads (images in wp-content/uploads) +ExpiresByType image/jpeg A31557600 +ExpiresByType image/png A31557600 +ExpiresByType image/gif A31557600 + +# WordPress theme assets +ExpiresByType text/css A2592000 +ExpiresByType application/javascript A2592000 + +# WordPress HTML (dynamic, don't cache) +ExpiresByType text/html A0 +``` + +### FilesMatch vs Expires + +**Use FilesMatch when:** +- Need multiple headers per file type +- Need complex regex patterns +- Want more control + +**Use Expires when:** +- Only setting cache expiration +- Want concise syntax +- Working with MIME types + +**Both together:** +```apache +ExpiresActive On + + + ExpiresByType image/jpeg A31557600 + Header set Cache-Control "public, immutable" + Header unset ETag + +``` + +--- + +## 9. PHP Directives + +### What Are PHP Directives? + +Change PHP configuration per-directory without editing php.ini. + +### Directives + +| Directive | Syntax | Purpose | +|-----------|--------|---------| +| **php_value** | `php_value name value` | Set numeric/string values | +| **php_flag** | `php_flag name on/off` | Set boolean (on/off) values | + +### Requirements + +- Must use **LSPHP** (not PHP-FPM) +- Must be **PHP_INI_ALL** or **PHP_INI_PERDIR** directive +- CyberPanel uses LSPHP by default ✅ + +### How to Use + +#### Memory and Execution Limits + +**What it does:** Allows scripts to use more memory/time. + +```apache +# Increase memory (default 128M) +php_value memory_limit 256M + +# Increase execution time (default 30s) +php_value max_execution_time 300 + +# Increase input time (default 60s) +php_value max_input_time 300 + +# Increase max input variables (default 1000) +php_value max_input_vars 5000 +``` + +**Use case:** WordPress imports, WooCommerce bulk operations, data processing. + +**Testing:** +```php + +``` + +#### Upload Limits + +**What it does:** Allows larger file uploads. + +```apache +# Allow 100MB uploads (default 2M) +php_value upload_max_filesize 100M +php_value post_max_size 100M + +# Increase max file uploads (default 20) +php_value max_file_uploads 50 +``` + +**Use case:** Media uploads, plugin/theme installation, backup uploads. + +**Testing:** +```php + +``` + +#### Error Handling + +**What it does:** Controls error display and logging. + +```apache +# Production (hide errors) +php_flag display_errors off +php_flag log_errors on +php_value error_log /home/yourdomain.com/logs/php_errors.log + +# Development (show errors) +php_flag display_errors on +php_value error_reporting 32767 +``` + +**Use case:** Debugging vs production security. + +#### Session Configuration + +**What it does:** Configures PHP sessions. + +```apache +# Session lifetime (1 hour) +php_value session.gc_maxlifetime 3600 + +# Session cookie (close browser = logout) +php_value session.cookie_lifetime 0 + +# Session security +php_flag session.cookie_httponly on +php_flag session.cookie_secure on +php_value session.cookie_samesite Strict +``` + +**Use case:** Login session duration, security. + +#### Timezone + +**What it does:** Sets server timezone. + +```apache +php_value date.timezone "America/New_York" +php_value date.timezone "Europe/London" +php_value date.timezone "Asia/Tokyo" +``` + +**Use case:** Correct timestamps in logs, posts, events. + +**Testing:** +```php + +``` + +### CyberPanel Integration + +#### WordPress Performance Tuning + +```apache +# In /home/yourdomain.com/public_html/.htaccess + +# WordPress recommended settings +php_value memory_limit 256M +php_value max_execution_time 300 +php_value max_input_time 300 +php_value max_input_vars 5000 +php_value upload_max_filesize 64M +php_value post_max_size 64M + +# Production error handling +php_flag display_errors off +php_flag log_errors on +php_value error_log /home/yourdomain.com/logs/php_errors.log + +# Session security +php_flag session.cookie_httponly on +php_flag session.cookie_secure on +``` + +#### WooCommerce Optimization + +```apache +# WooCommerce needs more resources +php_value memory_limit 512M +php_value max_execution_time 600 +php_value max_input_vars 10000 +php_value upload_max_filesize 128M +php_value post_max_size 128M +``` + +#### Development vs Production + +**Development .htaccess:** +```apache +php_flag display_errors on +php_value error_reporting 32767 +php_flag display_startup_errors on +php_value memory_limit 512M +``` + +**Production .htaccess:** +```apache +php_flag display_errors off +php_flag log_errors on +php_value error_log /home/yourdomain.com/logs/php_errors.log +php_value memory_limit 256M +``` + +### Common Use Cases + +#### Fix "Memory Exhausted" Error + +```apache +php_value memory_limit 512M +``` + +#### Fix "Maximum Execution Time Exceeded" + +```apache +php_value max_execution_time 300 +``` + +#### Fix "Upload Failed" (File Too Large) + +```apache +php_value upload_max_filesize 100M +php_value post_max_size 100M +``` + +#### Fix "Maximum Input Vars Exceeded" (WordPress Theme Options) + +```apache +php_value max_input_vars 10000 +``` + +### Supported Directives + +Most PHP ini settings can be changed: + +**✅ Supported:** +- memory_limit +- max_execution_time +- max_input_time +- max_input_vars +- upload_max_filesize +- post_max_size +- display_errors +- log_errors +- error_log +- error_reporting +- session.* (all session directives) +- date.timezone +- default_charset +- output_buffering + +**❌ Not Supported:** +- enable_dl (PHP_INI_SYSTEM only) +- safe_mode (deprecated) +- open_basedir (security setting) + +--- + +## 10. Brute Force Protection + +### What is Brute Force Protection? + +Built-in WordPress login protection. Limits POST requests to wp-login.php and xmlrpc.php to stop password guessing attacks. + +### Quick Start + +```apache +BruteForceProtection On +``` + +That's it! Default settings: 10 attempts per 5 minutes. + +### How It Works + +1. Tracks POST requests to `/wp-login.php` and `/xmlrpc.php` +2. Counts requests per IP address +3. Uses time-window quota system (e.g., 10 requests per 300 seconds) +4. When quota exhausted, applies action (block, log, or throttle) +5. Quota resets after time window expires + +### Phase 1 Directives (Basic) + +| Directive | Values | Default | Description | +|-----------|--------|---------|-------------| +| **BruteForceProtection** | On/Off | Off | Enable protection | +| **BruteForceAllowedAttempts** | 1-1000 | 10 | Max POST requests per window | +| **BruteForceWindow** | 60-86400 | 300 | Time window (seconds) | +| **BruteForceAction** | block/log/throttle | block | Action when limit exceeded | + +### Phase 2 Directives (Advanced) + +| Directive | Values | Default | Description | +|-----------|--------|---------|-------------| +| **BruteForceXForwardedFor** | On/Off | Off | Use X-Forwarded-For for real IP | +| **BruteForceWhitelist** | IP list | (empty) | Bypass protection for these IPs | +| **BruteForceProtectPath** | path | (none) | Additional paths to protect | + +### Actions Explained + +#### block (Recommended) + +**What it does:** Immediately returns 403 Forbidden. + +```apache +BruteForceAction block +``` + +**Response:** +``` +HTTP/1.1 403 Forbidden +Content-Type: text/html + + +403 Forbidden + +

Access Denied

+

Too many login attempts. Please try again later.

+ + +``` + +**Use case:** Production sites, maximum security. + +#### log (Monitoring) + +**What it does:** Allows request but logs to error.log. + +```apache +BruteForceAction log +``` + +**Use case:** Testing, monitoring before enabling blocking. + +**Check logs:** +```bash +grep BruteForce /usr/local/lsws/logs/error.log +``` + +#### throttle (New in v2.2.0) + +**What it does:** Applies progressive delays before responding. + +```apache +BruteForceAction throttle +``` + +**Throttle levels:** + +| Over-Limit Attempts | Level | Delay | HTTP Response | +|---------------------|-------|-------|---------------| +| 1-2 | Soft | 2 seconds | 429 Too Many Requests | +| 3-5 | Medium | 5 seconds | 429 Too Many Requests | +| 6+ | Hard | 15 seconds | 429 Too Many Requests | + +**Response includes:** +``` +HTTP/1.1 429 Too Many Requests +Retry-After: 15 +``` + +**Use case:** Slows down attackers while allowing legitimate users who forgot password. + +### How to Use + +#### Basic Protection (Small Site) + +```apache +# Simple protection +BruteForceProtection On +``` + +**Result:** Default 10 attempts per 5 minutes, then block. + +#### Strict Protection (High Security) + +```apache +# Only 3 attempts per 15 minutes +BruteForceProtection On +BruteForceAllowedAttempts 3 +BruteForceWindow 900 +BruteForceAction block +``` + +**Result:** Very strict, good for high-value targets. + +#### Moderate Protection with Throttle (Recommended) + +```apache +# 5 attempts per 5 minutes, then progressive throttle +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +``` + +**Result:** Legitimate users can still login (slowly), attackers waste time. + +#### Behind Cloudflare/Proxy + +**Problem:** All requests appear to come from proxy IP. + +**Solution:** Use X-Forwarded-For to get real client IP. + +```apache +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +BruteForceXForwardedFor On +``` + +**Important:** Only enable if behind trusted proxy (Cloudflare, nginx). + +#### With IP Whitelist + +**What it does:** Allows unlimited attempts from trusted IPs. + +```apache +BruteForceProtection On +BruteForceAllowedAttempts 3 +BruteForceWindow 900 +BruteForceAction block +BruteForceWhitelist 203.0.113.50, 192.168.1.0/24, 10.0.0.0/8 +``` + +**Use case:** Whitelist office IP, admin home IP, VPN range. + +#### Protect Custom Login Pages + +```apache +# Protect custom endpoints +BruteForceProtection On +BruteForceProtectPath /admin/login +BruteForceProtectPath /api/auth +BruteForceProtectPath /members/signin +``` + +**Default protected:** `/wp-login.php` and `/xmlrpc.php` + +### CyberPanel Integration + +#### WordPress Security Setup + +**Step 1:** Navigate to website .htaccess +```bash +cd /home/yourdomain.com/public_html +nano .htaccess +``` + +**Step 2:** Add protection +```apache +# At top of .htaccess +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +``` + +**Step 3:** Save and test +```bash +# Try multiple wrong passwords +# After 5 attempts, should get throttled +``` + +**Step 4:** Monitor logs +```bash +tail -f /usr/local/lsws/logs/error.log | grep BruteForce +``` + +#### WooCommerce + WordPress + +```apache +# Protect both WordPress and WooCommerce login +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction block +BruteForceProtectPath /my-account/ +BruteForceProtectPath /checkout/ +``` + +#### Multi-Site WordPress + +```apache +# Apply to all subsites +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +BruteForceXForwardedFor On +``` + +### Shared Memory Storage + +**Location:** `/dev/shm/ols/` + +```bash +ls -la /dev/shm/ols/ +# BFProt.shm - Stores IP quota data +# BFProt.lock - Synchronization lock +``` + +**Persistence:** Data survives OpenLiteSpeed restarts (stored in tmpfs). + +**Reset/Clear:** +```bash +# Clear all quota data +rm -f /dev/shm/ols/BFProt.* +/usr/local/lsws/bin/lswsctrl restart +``` + +**Use case:** Accidentally locked out, need to reset. + +### Monitoring and Logs + +#### View Brute Force Events + +```bash +grep BruteForce /usr/local/lsws/logs/error.log +``` + +**Sample log entries:** + +``` +[INFO] [BruteForce] Initialized: 10 attempts per 300s window, action: throttle +[WARN] [BruteForce] Warning: 192.168.1.50 has 2 attempts remaining for /wp-login.php +[NOTICE] [BruteForce] Blocked 192.168.1.50 - quota exhausted for /wp-login.php (10 attempts in 300s) +[NOTICE] [BruteForce] Throttling 192.168.1.50 (medium level, 5000ms delay) for /wp-login.php +``` + +#### Real-Time Monitoring + +```bash +# Watch in real-time +tail -f /usr/local/lsws/logs/error.log | grep BruteForce + +# Count blocked IPs today +grep "BruteForce.*Blocked" /usr/local/lsws/logs/error.log | grep "$(date +%Y-%m-%d)" | wc -l +``` + +#### Check Specific IP + +```bash +grep "BruteForce.*192.168.1.50" /usr/local/lsws/logs/error.log +``` + +### Testing Brute Force Protection + +#### Manual Test + +```bash +# Try multiple wrong passwords +for i in {1..15}; do + curl -X POST https://yourdomain.com/wp-login.php \ + -d "log=admin&pwd=wrong$i&wp-submit=Log+In" \ + -I | grep "HTTP" + sleep 1 +done + +# After BruteForceAllowedAttempts, should see: +# HTTP/1.1 403 Forbidden (if action=block) +# HTTP/1.1 429 Too Many Requests (if action=throttle) +``` + +#### Check Logs + +```bash +grep BruteForce /usr/local/lsws/logs/error.log | tail -20 +``` + +### Common Use Cases + +#### Production WordPress + +```apache +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction block +``` + +#### Behind Cloudflare + +```apache +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +BruteForceXForwardedFor On +``` + +#### Enterprise with Whitelist + +```apache +BruteForceProtection On +BruteForceAllowedAttempts 3 +BruteForceWindow 900 +BruteForceAction block +BruteForceXForwardedFor On +BruteForceWhitelist 10.0.0.0/8, 192.168.1.0/24, 203.0.113.100 +BruteForceProtectPath /admin/ +BruteForceProtectPath /api/login +``` + +### Troubleshooting + +**Problem:** Legitimate users getting blocked + +**Solution:** +```apache +# Increase allowed attempts +BruteForceAllowedAttempts 10 + +# Or use throttle instead of block +BruteForceAction throttle + +# Or whitelist their IP +BruteForceWhitelist 203.0.113.50 +``` + +**Problem:** Protection not working + +**Solution:** +```bash +# Check module loaded +ls -la /usr/local/lsws/modules/cyberpanel_ols.so + +# Check .htaccess syntax +cat /home/yourdomain.com/public_html/.htaccess | grep BruteForce + +# Check logs +grep BruteForce /usr/local/lsws/logs/error.log + +# Restart OpenLiteSpeed +/usr/local/lsws/bin/lswsctrl restart +``` + +**Problem:** Shared memory errors + +**Solution:** +```bash +# Create directory if missing +mkdir -p /dev/shm/ols + +# Set permissions +chmod 755 /dev/shm/ols + +# Restart +/usr/local/lsws/bin/lswsctrl restart +``` + +--- + +## CyberPanel Integration + +### Accessing Website Files + +#### Via CyberPanel File Manager + +1. Log into **CyberPanel** (https://yourserver:8090) +2. Click **File Manager** +3. Navigate to `/home/yourdomain.com/public_html` +4. Create or edit `.htaccess` +5. Add directives from this guide +6. Click **Save** + +#### Via SSH + +```bash +# Log in via SSH +ssh root@yourserver + +# Navigate to website +cd /home/yourdomain.com/public_html + +# Edit .htaccess +nano .htaccess + +# Add directives +# Save: Ctrl+X, Y, Enter +``` + +#### Via FTP (FileZilla) + +1. Connect via FTP +2. Navigate to `/home/yourdomain.com/public_html` +3. Download `.htaccess` +4. Edit locally +5. Upload back + +### Creating New Website + +1. **Create Website** in CyberPanel +2. **Navigate to directory:** + ```bash + cd /home/newsite.com/public_html + ``` +3. **Create .htaccess:** + ```bash + nano .htaccess + ``` +4. **Add base configuration:** + ```apache + # Security headers + Header set X-Frame-Options "SAMEORIGIN" + Header set X-Content-Type-Options "nosniff" + + # Brute force protection + BruteForceProtection On + + # Cache static assets + + Header set Cache-Control "max-age=31536000, public" + + ``` + +### WordPress on CyberPanel + +#### Complete WordPress .htaccess + +```apache +# Security Headers +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" +Header set X-XSS-Protection "1; mode=block" +Header unset X-Powered-By + +# Brute Force Protection +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle + +# Performance - Cache Static Assets + + Header set Cache-Control "max-age=31536000, public, immutable" + + + + Header set Cache-Control "max-age=2592000, public" + + +# PHP Configuration +php_value memory_limit 256M +php_value upload_max_filesize 64M +php_value post_max_size 64M +php_value max_execution_time 300 +php_flag display_errors off + +# WordPress Rewrite Rules (leave as-is) +# BEGIN WordPress + +RewriteEngine On +RewriteBase / +RewriteRule ^index\.php$ - [L] +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule . /index.php [L] + +# END WordPress +``` + +### Staging Environment + +```apache +# Staging site - restrict access +Order deny,allow +Deny from all +Allow from YOUR.OFFICE.IP +Allow from YOUR.HOME.IP + +# No search engine indexing +Header set X-Robots-Tag "noindex, nofollow" + +# Show errors (development) +php_flag display_errors on +php_value error_reporting 32767 +``` + +### Testing After Configuration + +```bash +# Test headers +curl -I https://yourdomain.com | grep -E "X-Frame|Cache-Control|X-Content" + +# Test specific file +curl -I https://yourdomain.com/wp-content/uploads/2024/12/image.jpg | grep Cache + +# Test PHP settings +echo '' > /home/yourdomain.com/public_html/info.php +curl https://yourdomain.com/info.php | grep memory_limit + +# Clean up +rm /home/yourdomain.com/public_html/info.php +``` + +--- + +## Real-World Examples + +### Example 1: High-Performance WordPress + +```apache +# Security +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" +Header set X-XSS-Protection "1; mode=block" +Header set Referrer-Policy "strict-origin-when-cross-origin" +Header unset Server +Header unset X-Powered-By + +# Brute Force Protection +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +BruteForceXForwardedFor On + +# Aggressive Caching + + Header set Cache-Control "max-age=31536000, public, immutable" + Header unset ETag + + + + Header set Cache-Control "max-age=31536000, public, immutable" + Header set Access-Control-Allow-Origin "*" + + + + Header set Cache-Control "max-age=2592000, public" + + +# PHP Optimization +php_value memory_limit 256M +php_value max_execution_time 300 +php_value upload_max_filesize 64M +php_value post_max_size 64M +php_flag display_errors off +php_flag log_errors on +``` + +### Example 2: WooCommerce E-commerce + +```apache +# Security Headers +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" +Header set X-XSS-Protection "1; mode=block" + +# Strict Brute Force Protection +BruteForceProtection On +BruteForceAllowedAttempts 3 +BruteForceWindow 900 +BruteForceAction block +BruteForceProtectPath /my-account/ +BruteForceProtectPath /checkout/ + +# Product Image Caching + + Header set Cache-Control "max-age=31536000, public, immutable" + + +# Don't Cache Checkout/Cart + + Header set Cache-Control "no-cache, no-store, must-revalidate" + + +# PHP for WooCommerce +php_value memory_limit 512M +php_value max_execution_time 600 +php_value max_input_vars 10000 +php_value upload_max_filesize 128M +php_value post_max_size 128M +``` + +### Example 3: API Server + +```apache +# CORS for API +Header set Access-Control-Allow-Origin "*" +Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" +Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-API-Key" +Header set Access-Control-Max-Age "86400" + +# JSON Response Headers + + Header set Content-Type "application/json; charset=utf-8" + Header set X-Content-Type-Options "nosniff" + Header set Cache-Control "no-cache, must-revalidate" + + +# API Rate Limiting +BruteForceProtection On +BruteForceAllowedAttempts 100 +BruteForceWindow 60 +BruteForceAction throttle +BruteForceProtectPath /api/ + +# Environment +SetEnv API_VERSION v2 +SetEnv API_ENVIRONMENT production +``` + +### Example 4: Static Site with CDN + +```apache +# Aggressive Caching +ExpiresActive On +ExpiresByType image/jpeg A31557600 +ExpiresByType image/png A31557600 +ExpiresByType image/gif A31557600 +ExpiresByType text/css A31557600 +ExpiresByType application/javascript A31557600 +ExpiresByType text/html A3600 + +# CORS for CDN +Header set Access-Control-Allow-Origin "*" + +# Security Headers +Header set X-Frame-Options "SAMEORIGIN" +Header set X-Content-Type-Options "nosniff" +Header set Content-Security-Policy "default-src 'self' https://cdn.example.com" + +# Remove Server Info +Header unset Server +Header unset X-Powered-By +``` + +### Example 5: Multi-Environment Setup + +**Production (.htaccess):** +```apache +SetEnv APPLICATION_ENV production +php_flag display_errors off +php_flag log_errors on +BruteForceProtection On +BruteForceAction block +Header set X-Robots-Tag "index, follow" +``` + +**Staging (staging.example.com/.htaccess):** +```apache +SetEnv APPLICATION_ENV staging +php_flag display_errors on +BruteForceProtection On +BruteForceAction log +Header set X-Robots-Tag "noindex, nofollow" + +# IP Restriction +Order deny,allow +Deny from all +Allow from 203.0.113.50 +``` + +**Development (dev.example.com/.htaccess):** +```apache +SetEnv APPLICATION_ENV development +php_flag display_errors on +php_value error_reporting 32767 +BruteForceProtection Off +Header set X-Robots-Tag "noindex, nofollow" +``` + +--- + +## Troubleshooting + +### Common Issues + +#### 1. Directives Not Working + +**Symptoms:** Headers not appearing, PHP settings not applied. + +**Solutions:** + +```bash +# Check module is installed +ls -la /usr/local/lsws/modules/cyberpanel_ols.so +# Should show 147KB file + +# Check module is loaded in config +grep cyberpanel_ols /usr/local/lsws/conf/httpd_config.conf +# Should show: module cyberpanel_ols { + +# Restart OpenLiteSpeed +/usr/local/lsws/bin/lswsctrl restart + +# Check logs for errors +tail -50 /usr/local/lsws/logs/error.log +``` + +#### 2. .htaccess File Permissions + +**Symptoms:** 500 Internal Server Error + +**Solutions:** + +```bash +# Set correct permissions +chmod 644 /home/yourdomain.com/public_html/.htaccess + +# Set correct ownership +chown nobody:nogroup /home/yourdomain.com/public_html/.htaccess + +# Verify +ls -la /home/yourdomain.com/public_html/.htaccess +# Should show: -rw-r--r-- nobody nogroup +``` + +#### 3. Headers Not Showing + +**Symptoms:** `curl -I` doesn't show custom headers + +**Solutions:** + +```bash +# Clear browser cache +# Some headers are cached aggressively + +# Test with curl (bypasses cache) +curl -I https://yourdomain.com + +# Test specific file +curl -I https://yourdomain.com/test.jpg + +# Check if file exists +ls -la /home/yourdomain.com/public_html/test.jpg + +# Verify .htaccess syntax +cat /home/yourdomain.com/public_html/.htaccess +``` + +#### 4. PHP Directives Not Applied + +**Symptoms:** `phpinfo()` shows old values + +**Solutions:** + +```bash +# Verify using LSPHP (not PHP-FPM) +# CyberPanel uses LSPHP by default + +# Check if directive is allowed +# Some directives are PHP_INI_SYSTEM only + +# Create test file +echo '' > /home/yourdomain.com/public_html/info.php + +# Check value +curl https://yourdomain.com/info.php | grep memory_limit + +# Delete test file +rm /home/yourdomain.com/public_html/info.php +``` + +#### 5. Brute Force Protection Not Triggering + +**Symptoms:** Can submit unlimited login attempts + +**Solutions:** + +```bash +# Check shared memory directory +ls -la /dev/shm/ols/ +# Should show BFProt.shm and BFProt.lock + +# Create if missing +mkdir -p /dev/shm/ols +chmod 755 /dev/shm/ols + +# Check .htaccess syntax +grep BruteForce /home/yourdomain.com/public_html/.htaccess + +# Must be POST request to protected path +curl -X POST https://yourdomain.com/wp-login.php -d "log=test&pwd=test" + +# Check logs +grep BruteForce /usr/local/lsws/logs/error.log + +# Restart +/usr/local/lsws/bin/lswsctrl restart +``` + +#### 6. Access Control Allowing All + +**Symptoms:** IP restrictions not working + +**Solutions:** + +```bash +# Verify your actual IP +curl ifconfig.me + +# Check CIDR syntax +# 192.168.1.0/24 = 192.168.1.1 to 192.168.1.254 +# 10.0.0.0/8 = 10.0.0.0 to 10.255.255.255 + +# Check logs for access decisions +grep "cyberpanel_access" /usr/local/lsws/logs/error.log + +# Test with curl from different IP +curl -I https://yourdomain.com +# Should get 403 if not allowed +``` + +#### 7. Redirect Loop + +**Symptoms:** ERR_TOO_MANY_REDIRECTS + +**Solutions:** + +```bash +# Check for conflicting redirects +grep Redirect /home/yourdomain.com/public_html/.htaccess + +# Common mistake: +# BAD: Both redirects active +# Redirect 301 / https://example.com/ +# Redirect 301 / https://www.example.com/ + +# GOOD: Only one +Redirect 301 / https://www.example.com/ + +# Check WordPress settings +# wp-admin > Settings > General +# WordPress Address and Site Address must match +``` + +### Getting Help + +#### Enable Debug Logging + +```bash +# Edit OpenLiteSpeed config +nano /usr/local/lsws/conf/httpd_config.conf + +# Change Log Level to DEBUG +# Restart +/usr/local/lsws/bin/lswsctrl restart + +# Monitor logs +tail -f /usr/local/lsws/logs/error.log +``` + +#### Collect Information + +```bash +# Module version +ls -lh /usr/local/lsws/modules/cyberpanel_ols.so + +# OpenLiteSpeed version +/usr/local/lsws/bin/openlitespeed -v + +# Check .htaccess +cat /home/yourdomain.com/public_html/.htaccess + +# Recent logs +tail -100 /usr/local/lsws/logs/error.log + +# Test headers +curl -I https://yourdomain.com +``` + +#### Report Issue + +When reporting issues, include: + +1. **What you're trying to do** (which feature) +2. **.htaccess content** (sanitized) +3. **Expected behavior** vs **actual behavior** +4. **Error logs** (last 50 lines) +5. **Test results** (curl output) +6. **Module version** and **OpenLiteSpeed version** + +--- + +## Performance Optimization + +### Best Practices + +1. **Minimize .htaccess size** - Only include necessary directives +2. **Use FilesMatch carefully** - Each pattern adds regex overhead +3. **Prefer block over throttle** - Throttle holds connections longer +4. **Whitelist known IPs** - Skips brute force checks entirely +5. **Set long cache times** - Reduce server load + +### Benchmarks + +| Metric | Value | +|--------|-------| +| Overhead per request | < 1ms | +| Memory per cached .htaccess | ~2KB | +| Memory per tracked IP (brute force) | ~64 bytes | +| Cache invalidation | mtime-based (instant) | + +### Optimization Examples + +**Before (Slow):** +```apache +# Every request checks all patterns +Header set X-Custom "Value" +Header set X-Another "Value" +Header set X-More "Value" + + + Header set Cache-Control "max-age=3600" + +``` + +**After (Fast):** +```apache +# Only static assets checked + + Header set Cache-Control "max-age=31536000, public, immutable" + +``` + +--- + +## Appendix + +### Quick Reference + +#### Headers +```apache +Header set Name "Value" +Header unset Name +Header append Name "Value" +``` + +#### Access Control +```apache +Order deny,allow +Deny from all +Allow from 192.168.1.0/24 +``` + +#### Redirects +```apache +Redirect 301 /old /new +RedirectMatch 301 ^/blog/(.*)$ /news/$1 +``` + +#### PHP +```apache +php_value memory_limit 256M +php_flag display_errors off +``` + +#### Brute Force +```apache +BruteForceProtection On +BruteForceAllowedAttempts 5 +BruteForceWindow 300 +BruteForceAction throttle +``` + +### Common MIME Types + +``` +image/jpeg, image/png, image/gif, image/webp, image/svg+xml +text/css, text/html, text/javascript, text/plain +application/javascript, application/json, application/xml, application/pdf +font/ttf, font/woff, font/woff2 +``` + +### Time Duration Reference + +``` +1 minute = 60 +5 minutes = 300 +15 minutes = 900 +1 hour = 3600 +1 day = 86400 +1 week = 604800 +1 month = 2592000 +1 year = 31557600 +``` + +### IP CIDR Cheat Sheet + +``` +/32 = 1 IP (255.255.255.255) +/24 = 256 IPs (255.255.255.0) +/16 = 65,536 IPs (255.255.0.0) +/8 = 16,777,216 IPs (255.0.0.0) +``` + +--- + +## Support + +- **GitHub:** [github.com/usmannasir/cyberpanel_ols](https://github.com/usmannasir/cyberpanel_ols) +- **Community:** [community.cyberpanel.net](https://community.cyberpanel.net) + +--- + +**Document Version:** 1.0 +**Module Version:** 2.2.0 +**Last Updated:** December 28, 2025 + +--- + +*Thank you for using the CyberPanel OpenLiteSpeed Module!* diff --git a/install/OpenLiteSpeed_htaccess_Module_Documentation.md b/install/OpenLiteSpeed_htaccess_Module_Documentation.md deleted file mode 100644 index e69de29bb..000000000