SiamCafe.net Blog
Cybersecurity

WordPress Block Theme Log Management ELK

wordpress block theme log management elk
WordPress Block Theme Log Management ELK | SiamCafe Blog
2025-08-10· อ. บอม — SiamCafe.net· 8,722 คำ

WordPress Block Theme คืออะไร

WordPress Block Theme เป็นวิวัฒนาการใหม่ของระบบ Theme ที่ใช้ Full Site Editing (FSE) ทั้งหมด แทนที่จะเขียน PHP Template Files อย่าง header.php, footer.php, single.php ตอนนี้ใช้ HTML Files ที่ประกอบด้วย Block Markup ในโฟลเดอร์ templates/ และ parts/ ร่วมกับ theme.json สำหรับกำหนด Style, Colors, Typography และ Layout Settings

เมื่อ WordPress Site มีขนาดใหญ่ขึ้นและมี Traffic สูง การจัดการ Log อย่างเป็นระบบกลายเป็นสิ่งจำเป็น ELK Stack (Elasticsearch, Logstash, Kibana) เป็นโซลูชันมาตรฐานสำหรับ Centralized Log Management ที่ช่วยรวบรวม วิเคราะห์ และ Visualize Log จาก WordPress Server ทั้งหมดในที่เดียว

โครงสร้าง WordPress Block Theme

# โครงสร้าง Block Theme
my-block-theme/
├── style.css # Theme Metadata
├── theme.json # Global Styles & Settings
├── templates/ # Full Page Templates
│ ├── index.html
│ ├── single.html
│ ├── page.html
│ ├── archive.html
│ ├── 404.html
│ └── search.html
├── parts/ # Reusable Template Parts
│ ├── header.html
│ ├── footer.html
│ └── sidebar.html
├── patterns/ # Block Patterns
│ ├── hero.php
│ └── cta.php
└── assets/
 ├── fonts/
 └── images/

---
# theme.json — Global Configuration
{
 "$schema": "https://schemas.wp.org/wp/6.5/theme.json",
 "version": 2,
 "settings": {
 "appearanceTools": true,
 "color": {
 "palette": [
 {"slug": "primary", "color": "#1e40af", "name": "Primary"},
 {"slug": "secondary", "color": "#7c3aed", "name": "Secondary"},
 {"slug": "accent", "color": "var(--c-primary)", "name": "Accent"},
 {"slug": "dark", "color": "#0f172a", "name": "Dark"},
 {"slug": "light", "color": "#f8fafc", "name": "Light"}
 ],
 "gradients": [
 {
 "slug": "primary-to-secondary",
 "gradient": "linear-gradient(135deg, #1e40af, #7c3aed)",
 "name": "Primary to Secondary"
 }
 ]
 },
 "typography": {
 "fontFamilies": [
 {
 "fontFamily": "'Inter', sans-serif",
 "slug": "inter",
 "name": "Inter",
 "fontFace": [
 {"fontFamily": "Inter", "fontWeight": "400", "fontStyle": "normal",
 "src": ["file:./assets/fonts/inter-regular.woff2"]},
 {"fontFamily": "Inter", "fontWeight": "700", "fontStyle": "normal",
 "src": ["file:./assets/fonts/inter-bold.woff2"]}
 ]
 }
 ],
 "fontSizes": [
 {"slug": "small", "size": "0.875rem", "name": "Small"},
 {"slug": "medium", "size": "1rem", "name": "Medium"},
 {"slug": "large", "size": "1.25rem", "name": "Large"},
 {"slug": "x-large", "size": "2rem", "name": "Extra Large"}
 ]
 },
 "layout": {
 "contentSize": "720px",
 "wideSize": "1200px"
 }
 },
 "styles": {
 "color": {
 "background": "var(--wp--preset--color--light)",
 "text": "var(--wp--preset--color--dark)"
 },
 "typography": {
 "fontFamily": "var(--wp--preset--font-family--inter)",
 "fontSize": "var(--wp--preset--font-size--medium)",
 "lineHeight": "1.7"
 },
 "elements": {
 "link": {
 "color": {"text": "var(--wp--preset--color--primary)"},
 ":hover": {"color": {"text": "var(--wp--preset--color--secondary)"}}
 },
 "h1": {"typography": {"fontSize": "2.5rem", "fontWeight": "700"}},
 "h2": {"typography": {"fontSize": "2rem", "fontWeight": "700"}}
 }
 }
}

การตั้งค่า ELK Stack สำหรับ WordPress

# docker-compose.yml — ELK Stack สำหรับ WordPress Log Management
version: "3.8"

services:
 elasticsearch:
 image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
 environment:
 - discovery.type=single-node
 - xpack.security.enabled=true
 - ELASTIC_PASSWORD=
 - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
 volumes:
 - es_data:/usr/share/elasticsearch/data
 ports:
 - "9200:9200"
 healthcheck:
 test: ["CMD-SHELL", "curl -s -u elastic: http://localhost:9200/_cluster/health | grep -q 'green\\|yellow'"]
 interval: 30s
 timeout: 10s
 retries: 5

 logstash:
 image: docker.elastic.co/logstash/logstash:8.12.0
 volumes:
 - ./logstash/pipeline:/usr/share/logstash/pipeline
 - ./logstash/config:/usr/share/logstash/config
 ports:
 - "5044:5044"
 environment:
 - "LS_JAVA_OPTS=-Xms1g -Xmx1g"
 depends_on:
 elasticsearch:
 condition: service_healthy

 kibana:
 image: docker.elastic.co/kibana/kibana:8.12.0
 environment:
 - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
 - ELASTICSEARCH_USERNAME=kibana_system
 - ELASTICSEARCH_PASSWORD=
 ports:
 - "5601:5601"
 depends_on:
 elasticsearch:
 condition: service_healthy

volumes:
 es_data:

---
# logstash/pipeline/wordpress.conf
input {
 beats {
 port => 5044
 }
}

filter {
 # Parse Nginx Access Log
 if [fields][log_type] == "nginx_access" {
 grok {
 match => { "message" => '%{IPORHOST:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}" %{NUMBER:status} %{NUMBER:bytes} "%{DATA:referrer}" "%{DATA:user_agent}"' }
 }
 date {
 match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
 }
 geoip {
 source => "client_ip"
 target => "geo"
 }
 useragent {
 source => "user_agent"
 target => "ua"
 }
 # ตรวจจับ WordPress Attack Patterns
 if [request] =~ /wp-login\.php/ {
 mutate { add_tag => ["login_attempt"] }
 }
 if [request] =~ /xmlrpc\.php/ {
 mutate { add_tag => ["xmlrpc_attempt"] }
 }
 if [request] =~ /wp-admin/ and [status] == "403" {
 mutate { add_tag => ["admin_blocked"] }
 }
 }

 # Parse PHP Error Log
 if [fields][log_type] == "php_error" {
 grok {
 match => { "message" => "\[%{DATA:timestamp}\] %{DATA:error_type}: %{GREEDYDATA:error_message}" }
 }
 if [error_type] == "Fatal error" {
 mutate { add_tag => ["critical"] }
 }
 }

 # Parse WordPress Debug Log
 if [fields][log_type] == "wp_debug" {
 grok {
 match => { "message" => "\[%{DATA:timestamp}\] PHP %{DATA:severity}: %{GREEDYDATA:debug_message} in %{DATA:file} on line %{NUMBER:line}" }
 }
 }
}

output {
 elasticsearch {
 hosts => ["http://elasticsearch:9200"]
 user => "elastic"
 password => ""
 index => "wordpress-%{[fields][log_type]}-%{+YYYY.MM.dd}"
 }
}

---
# Filebeat Configuration บน WordPress Server
# /etc/filebeat/filebeat.yml
filebeat.inputs:
 - type: log
 enabled: true
 paths:
 - /var/log/nginx/access.log
 fields:
 log_type: nginx_access
 fields_under_root: false

 - type: log
 enabled: true
 paths:
 - /var/log/nginx/error.log
 fields:
 log_type: nginx_error

 - type: log
 enabled: true
 paths:
 - /var/log/php8.2-fpm.log
 fields:
 log_type: php_error
 multiline:
 pattern: '^\['
 negate: true
 match: after

 - type: log
 enabled: true
 paths:
 - /var/www/html/wp-content/debug.log
 fields:
 log_type: wp_debug

output.logstash:
 hosts: ["elk-server:5044"]

# ติดตั้ง Filebeat
# curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.12.0-amd64.deb
# sudo dpkg -i filebeat-8.12.0-amd64.deb
# sudo systemctl enable filebeat
# sudo systemctl start filebeat

Kibana Dashboard สำหรับ WordPress

# สร้าง Index Pattern ใน Kibana
# 1. ไปที่ Stack Management > Index Patterns
# 2. สร้าง Pattern: wordpress-*
# 3. เลือก @timestamp เป็น Time Filter

# Kibana Saved Search — Login Attempts
# GET wordpress-nginx_access-*/_search
{
 "query": {
 "bool": {
 "must": [
 {"match": {"request": "wp-login.php"}},
 {"match": {"method": "POST"}}
 ],
 "filter": [
 {"range": {"@timestamp": {"gte": "now-24h"}}}
 ]
 }
 },
 "aggs": {
 "by_ip": {
 "terms": {"field": "client_ip.keyword", "size": 20},
 "aggs": {
 "by_status": {
 "terms": {"field": "status.keyword"}
 }
 }
 },
 "by_country": {
 "terms": {"field": "geo.country_name.keyword", "size": 10}
 },
 "over_time": {
 "date_histogram": {
 "field": "@timestamp",
 "fixed_interval": "1h"
 }
 }
 }
}

# Alert Rule — Brute Force Detection
# ถ้ามี Login Attempt จาก IP เดียวกันมากกว่า 10 ครั้งใน 5 นาที
# Kibana > Alerts > Create Rule
# Rule type: Elasticsearch query
# Query: tags:login_attempt AND method:POST
# Group by: client_ip.keyword
# Threshold: > 10 in 5 minutes
# Action: Send to Slack/Email

Security Monitoring สำหรับ WordPress

WordPress Performance Log Analysis

# Python Script วิเคราะห์ WordPress Performance จาก Nginx Log
import re
import json
from collections import Counter, defaultdict
from datetime import datetime

def analyze_nginx_log(log_path, top_n=20):
 """วิเคราะห์ Nginx Access Log สำหรับ WordPress"""
 pattern = re.compile(
 r'(?P\S+) .+ \[(?P

WordPress Block Theme คืออะไร

Block Theme เป็นรูปแบบ Theme ใหม่ที่ใช้ Full Site Editing ทั้งหมด ออกแบบ Layout ด้วย Block Editor แทน PHP Template Files ใช้ theme.json กำหนด Style และ Settings ทำให้สร้าง Theme ได้ง่ายขึ้นโดยไม่ต้องเขียน PHP มากเหมือนก่อน

ELK Stack คืออะไรและใช้กับ WordPress ทำไม

ELK Stack คือ Elasticsearch (Search Engine), Logstash (Log Processing), Kibana (Visualization) ใช้กับ WordPress เพื่อรวบรวมและวิเคราะห์ Log ทุกประเภทจาก Server ช่วยตรวจจับ Security Threats เช่น Brute Force, วิเคราะห์ Performance และ Troubleshoot ปัญหาได้รวดเร็ว

Filebeat คืออะไรและทำไมต้องใช้ร่วมกับ ELK

Filebeat เป็น Lightweight Log Shipper ติดตั้งบน WordPress Server เพื่อส่ง Log ไปยัง Logstash หรือ Elasticsearch ใช้ Resource น้อยกว่า Logstash (CPU ~1%, RAM ~50MB) เหมาะสำหรับ Server ที่มี Resource จำกัด รองรับ Multiline Log และ Back Pressure

ควรเก็บ Log อะไรบ้างสำหรับ WordPress

ควรเก็บ Nginx/Apache Access Log, Error Log, PHP Error Log (php-fpm), WordPress Debug Log (debug.log), Plugin Activity Log, Login Attempts Log, Database Slow Query Log และ WP-CLI Command Log เพื่อครอบคลุมทั้ง Performance, Security และ Troubleshooting

สรุปและแนวทางปฏิบัติ

WordPress Block Theme เป็นอนาคตของ WordPress Theme Development ที่ทำให้สร้างและจัดการ Theme ได้ง่ายขึ้น ส่วน ELK Stack เป็นโซลูชัน Log Management ที่จำเป็นสำหรับ WordPress Site ที่มี Traffic สูง การรวม Filebeat บน WordPress Server กับ ELK Stack ทำให้สามารถตรวจจับ Security Threats, วิเคราะห์ Performance Bottlenecks และ Troubleshoot ปัญหาได้อย่างรวดเร็ว ตั้ง Alert Rules สำหรับ Brute Force, XML-RPC Attack และ Suspicious File Uploads เพื่อตอบสนองต่อ Incident ได้ทันเวลา

📖 บทความที่เกี่ยวข้อง

WordPress Block Theme Home Lab Setupอ่านบทความ → WordPress Block Theme 12 Factor Appอ่านบทความ → WordPress Block Theme SaaS Architectureอ่านบทความ → WordPress Block Theme Data Pipeline ETLอ่านบทความ → WordPress Block Theme RBAC ABAC Policyอ่านบทความ →

📚 ดูบทความทั้งหมด →