การติดตั้งด้วยตนเองทั้งหมด: ตั้งแต่ VPS ที่เพิ่งซื้อจนถึงแดชบอร์ดที่ใช้งานได้ ทีละขั้นตอน
การเตรียมเซิร์ฟเวอร์ การสร้างเว็บไซต์ ฐานข้อมูล config.php และ SSL อธิบายไว้ที่นี่
คำสั่งสำหรับเครื่องมือความปลอดภัยแต่ละตัวและ cron อยู่ใน
คู่มืออ้างอิง FAQ พร้อมลิงก์ตามเนื้อหา
กฎสำคัญ: เมื่อแก้ไข SSH หรือไฟร์วอลล์ อย่าปิดการเชื่อมต่อปัจจุบัน จนกว่าจะทดสอบการเชื่อมต่อใหม่ในหน้าต่างแยกแล้ว หากยังสูญเสียการเข้าถึง ผู้ให้บริการโฮสต์เกือบทั้งหมดมีคอนโซลฉุกเฉิน (VNC/Recovery) ในแดชบอร์ดควบคุม
01. ซื้อ VPS ที่ติดตั้ง Ubuntu/Debian แล้ว — เริ่มจากตรงไหน
หลังจากซื้อ ผู้ให้บริการโฮสติ้งจะส่ง: ที่อยู่ IP, ชื่อผู้ใช้ (โดยทั่วไปคือ root) และรหัสผ่าน (หรือคีย์ SSH) เท่านี้ก็เพียงพอสำหรับการเข้าสู่ระบบ ลำดับขั้นตอน (แต่ละขั้นตอนคือหัวข้อด้านล่าง):
- เชื่อมต่อกับเซิร์ฟเวอร์ผ่าน SSH;
- อัปเดตระบบ กำหนดชื่อโฮสต์และเขตเวลา;
- สร้างผู้ใช้ทั่วไปที่มีสิทธิ์
sudo (อย่าทำงานภายใต้ root);
- ตั้งค่าการเข้าสู่ระบบด้วยคีย์ SSH และ ปิดการเข้าสู่ระบบด้วยรหัสผ่าน;
- เปิดใช้ไฟร์วอลล์และการป้องกันอัตโนมัติ;
- (ตามต้องการ) ติดตั้งแดชบอร์ดจัดการ HestiaCP — เว็บเซิร์ฟเวอร์ ฐานข้อมูล อีเมล พร้อมใช้งานทันที
02. การเชื่อมต่อ SSH ครั้งแรก
SSH คือเทอร์มินัลที่เชื่อมต่อไปยังเซิร์ฟเวอร์อย่างปลอดภัย แทนที่ 203.0.113.10 ด้วย IP ของคุณ
203.0.113.10 เป็น ตัวอย่าง ไม่ใช่ที่อยู่จริง (สงวนไว้สำหรับเอกสาร) อย่าใส่ค่านี้ตามที่เห็น ให้เปลี่ยนเป็น IP จริงของเซิร์ฟเวอร์คุณจากอีเมลของผู้ให้บริการโฮสต์ มิฉะนั้นจะเชื่อมต่อไม่ได้
Windows 10/11: เปิด PowerShell หรือ “Terminal” แล้วใช้ ssh ที่มีในตัว (หรือใช้ไคลเอนต์ PuTTY / MobaXterm)
macOS / Linux: เปิด “Terminal”
# เข้าสู่ระบบด้วย root (รหัสผ่านมาจากผู้ให้บริการโฮสต์):
ssh root@203.0.113.10
# หากผู้ให้บริการโฮสต์ให้ไฟล์คีย์แทนรหัสผ่าน:
ssh -i พาธ/ไปยัง/คีย์ root@203.0.113.10
เมื่อเชื่อมต่อครั้งแรก SSH จะถามเรื่อง “authenticity of host” ให้พิมพ์ yes รหัสผ่านจะไม่แสดงขณะพิมพ์ (เป็นเรื่องปกติ) หากผู้ให้บริการโฮสต์ให้รหัสผ่านชั่วคราวมา ให้เปลี่ยนด้วยคำสั่ง passwd
03. การอัปเดตระบบและการตั้งค่าพื้นฐาน
ขั้นแรก — อัปเดตแพ็กเกจทั้งหมดและตั้งชื่อโฮสต์กับเขตเวลา
# อัปเดตระบบ:
apt update && apt upgrade -y
# ยูทิลิตีพื้นฐาน:
apt install -y curl wget ufw fail2ban unattended-upgrades
# เขตเวลา (ตัวอย่าง) และชื่อโฮสต์:
timedatectl set-timezone Asia/Bangkok
hostnamectl set-hostname myserver
# อัปเดตความปลอดภัยอัตโนมัติ:
dpkg-reconfigure -plow unattended-upgrades
รายการเขตเวลา — timedatectl list-timezones หากเมื่อสิ้นสุดการอัปเดตปรากฏหน้าต่างสีน้ำเงิน "Daemons using outdated libraries" — ให้เลือกบริการทั้งหมด (Spacebar) แล้วกด OK ปลอดภัยแน่นอน
04. การสร้างผู้ใช้ที่มีสิทธิ์ sudo
การใช้งานด้วย root ตลอดเวลาไม่ปลอดภัย ให้สร้างผู้ใช้ทั่วไปและมอบสิทธิ์ sudo (รันคำสั่งระดับผู้ดูแลเมื่อจำเป็น) แทนที่ deploy ด้วยชื่อใดก็ได้
# สร้างผู้ใช้ (จะตั้งรหัสผ่านและถามข้อมูล — กด Enter ข้ามได้):
adduser deploy
# เพิ่มเข้ากลุ่ม sudo:
usermod -aG sudo deploy
# ตรวจสอบ (ในฐานะ root):
su - deploy
sudo whoami # ควรแสดง: root
exit
จากนั้นให้เข้าสู่เซิร์ฟเวอร์ด้วยผู้ใช้นี้: ssh deploy@203.0.113.10 และรันคำสั่งผู้ดูแลโดยใส่คำนำหน้า sudo
05. คีย์ SSH และการปิดการเข้าสู่ระบบด้วยรหัสผ่าน
การเข้าสู่ระบบด้วยคีย์ปลอดภัยกว่ารหัสผ่าน เพราะรหัสผ่านอาจถูกเดาได้ แต่คีย์แทบเป็นไปไม่ได้ ก่อนอื่นให้สร้างคีย์บนเครื่องคอมพิวเตอร์ของคุณ คัดลอกไปยังเซิร์ฟเวอร์ ทดสอบการเข้าสู่ระบบ แล้วจึงปิดรหัสผ่านเป็นขั้นตอนสุดท้าย
ขั้นตอนที่ 1. สร้างคีย์บนเครื่องของคุณ (Windows PowerShell / macOS / Linux):
ssh-keygen -t ed25519 -C "my-laptop"
# กด Enter ทุกคำถาม (คีย์จะถูกเก็บไว้ที่ ~/.ssh/id_ed25519)
ขั้นตอนที่ 2. คัดลอกคีย์สาธารณะไปยังเซิร์ฟเวอร์:
# macOS / Linux:
ssh-copy-id deploy@203.0.113.10
# Windows (PowerShell):
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ขั้นตอนที่ 3. ทดสอบการเข้าสู่ระบบด้วยคีย์ในหน้าต่างใหม่ — ควรเข้าได้โดยไม่ต้องใช้รหัสผ่าน:
ssh deploy@203.0.113.10
อย่าทำตัวเลือก B จนกว่าการเข้าสู่ระบบด้วยคีย์จะได้รับการทดสอบและใช้งานได้จริง (ขั้นตอนที่ 1–3) และอย่าปิดเซสชันที่ใช้งานอยู่ ตัวเลือกนี้ปิดการเข้าสู่ระบบด้วยรหัสผ่านสำหรับผู้ใช้ทุกคน รวมถึง root ด้วย หากไม่มีคีย์ที่ใช้งานได้ คุณจะสูญเสียการเข้าถึงเซิร์ฟเวอร์โดยสิ้นเชิง — กู้คืนได้เพียงผ่านคอนโซลของผู้ให้บริการโฮสต์เท่านั้น ถ้าไม่มีคีย์ ให้เลือกตัวเลือก A
ขั้นตอนที่ 4. เพิ่มความเข้มงวดในการเข้าถึง SSH วางการตั้งค่าไว้ในไฟล์แยกต่างหาก ไม่แตะไฟล์คอนฟิกหลัก เลือกตัวเลือกตามสถานการณ์:
ตัวเลือก A — ปิดเฉพาะ root คงรหัสผ่านไว้. ไม่ต้องใช้คีย์ และไม่สูญเสียการเข้าถึง:
echo 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null
sudo systemctl restart ssh
ตัวเลือก B — การทำ hardening แบบเต็มรูปแบบ. ปิดการเข้าสู่ระบบด้วยรหัสผ่านและคง root ไว้เฉพาะด้วยคีย์ ให้ทำต่อเมื่อแน่ใจแล้วว่าการเข้าสู่ระบบด้วยคีย์ใช้งานได้:
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
KbdInteractiveAuthentication no
EOF
sudo systemctl restart ssh
ทั้งสองตัวเลือกจะปิดการเข้าสู่ระบบด้วยรหัสผ่านของ root PermitRootLogin no ห้าม root โดยสิ้นเชิง ส่วน prohibit-password คงการเข้าสู่ระบบด้วยคีย์เท่านั้น (สำหรับการดูแลระบบ ให้เข้าสู่ระบบด้วย deploy แล้วใช้ sudo) หากต้องการเปลี่ยนพอร์ต SSH — ให้เพิ่มบรรทัด Port 2222 แต่ก่อนอื่นให้เปิดพอร์ตใหม่ในไฟร์วอลล์ (หัวข้อถัดไป) และทดสอบการเข้าสู่ระบบ ไม่เช่นนั้นคุณจะปิดกั้นการเข้าถึงของตัวเอง
06. ไฟร์วอลล์พื้นฐานและการป้องกันอัตโนมัติ
ปิดทุกสิ่งที่ไม่จำเป็นด้วยไฟร์วอลล์ และเปิดใช้ fail2ban (แบนการเดารหัสผ่าน SSH) ก่อนอื่น ให้อนุญาต SSH ก่อน มิฉะนั้นเมื่อเปิด UFW คุณจะสูญเสียการเข้าถึง
# อนุญาต SSH (หรือพอร์ตของคุณ ถ้าเปลี่ยน) และเว็บ:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
# เปิดใช้ไฟร์วอลล์:
sudo ufw enable
sudo ufw status verbose
# fail2ban — ป้องกัน SSH จากการเดารหัสผ่าน (โปรไฟล์พื้นฐานทำงานทันที):
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
นี่เป็นขั้นต่ำ การตั้งค่า fail2ban สำหรับใช้งานจริง บล็อกลิสต์ ipsum, UFW ขั้นสูง และเครื่องมืออื่น ๆ — อยู่ใน
กลุ่ม “เครื่องมือความปลอดภัย” ของคู่มือ ตัวแดชบอร์ด Arcivéo Monitor เองจะแสดงสถานะทั้งหมดนี้ให้เห็นอย่างชัดเจน
07. ติดตั้งแผงควบคุม HestiaCP (ตัวเลือกเสริม)
HestiaCP — แผงควบคุมโฮสติ้งฟรี: ติดตั้งและตั้งค่าเว็บเซิร์ฟเวอร์ (nginx + apache), PHP, ฐานข้อมูล (MariaDB), อีเมล, DNS และใบรับรอง SSL พร้อมเว็บอินเทอร์เฟซสำหรับเว็บไซต์ สะดวกหากไม่อยากตั้งค่าทุกอย่างด้วยตนเองและวางแผนจะโฮสต์เว็บไซต์ (รวมถึงตัว Arcivéo Monitor เองด้วย)
ติดตั้ง HestiaCP บนเซิร์ฟเวอร์ที่สะอาด (Ubuntu/Debian รุ่นใหม่ที่รองรับ, RAM อย่างน้อย ~1–2 GB) ก่อนติดตั้งเว็บเซิร์ฟเวอร์และฐานข้อมูลอื่น — มิฉะนั้นจะเกิดความขัดแย้ง การติดตั้งใช้เวลา 10–20 นาทีและจะรีบูตเซิร์ฟเวอร์
# ดาวน์โหลดตัวติดตั้งและรัน:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh
ตัวติดตั้งจะถามอีเมลและชื่อโฮสต์ จากนั้นจะติดตั้งสแตกทั้งหมด หลังรีบูต แผงควบคุมจะเข้าถึงได้ที่ https://YOUR_IP:8083 (ตัวติดตั้งจะแสดงชื่อผู้ใช้และรหัสผ่านในตอนท้าย)
HestiaCP จัดการเอง ทั้ง UFW และ fail2ban — ไม่ต้องตั้งค่าแยกต่างหาก มันจะจัดการให้ ส่วนคีย์ SSH และการปิดการใช้รหัสผ่าน (หัวข้อก่อนหน้า) ก็ยังควรทำอยู่ดี
08. ความต้องการของระบบและ ionCube
แดชบอร์ดเป็นแอปพลิเคชัน PHP บนสแตก LAMP/LEMP ทั่วไป:
- ระบบปฏิบัติการ: Linux (แนะนำ Ubuntu/Debian);
- เว็บเซิร์ฟเวอร์: nginx หรือ Apache พร้อม PHP-FPM;
- PHP 8.0+ พร้อมส่วนขยาย:
pdo_mysql, openssl, curl, json, mbstring;
- ionCube Loader — ส่วนขยาย PHP ที่จำเป็นสำหรับการทำงานของแดชบอร์ด;
- ฐานข้อมูล: MySQL 5.7+ หรือ MariaDB 10.3+;
- HTTPS — จำเป็น (การเข้าสู่ระบบและ WebAuthn ทำงานผ่าน https เท่านั้น);
- sudo สำหรับผู้ใช้ของเว็บเซิร์ฟเวอร์ (ชุดสิทธิ์จำกัด — ขั้นตอนที่ 13).
# ตรวจสอบเวอร์ชัน PHP และส่วนขยาย:
php -v
php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'
การติดตั้ง ionCube Loader (หากยังไม่ได้ติดตั้ง) บนโฮสติงที่มีแผงควบคุม (HestiaCP, cPanel) เปิดใช้ ionCube ได้ด้วยการติ๊กเครื่องหมายในการตั้งค่า PHP ติดตั้งด้วยตนเองบน Ubuntu/Debian:
# ดูเวอร์ชัน PHP และไดเรกทอรีของส่วนขยาย:
php -v
EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
# ดาวน์โหลดและแตกไฟล์โหลดเดอร์ (64-bit):
cd /tmp
wget -q https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xzf ioncube_loaders_lin_x86-64.tar.gz
# คัดลอกโหลดเดอร์สำหรับเวอร์ชัน PHP ของคุณไปยังไดเรกทอรีส่วนขยาย:
sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/
# เปิดใช้งาน (CLI + PHP-FPM) และรีสตาร์ต:
echo "zend_extension=ioncube_loader_lin_${PHPVER}.so" | sudo tee /etc/php/${PHPVER}/mods-available/ioncube.ini
sudo phpenmod ioncube
sudo systemctl restart php${PHPVER}-fpm
# ตรวจสอบ — ในผลลัพธ์จะปรากฏบรรทัด "with the ionCube PHP Loader":
php -v
เวอร์ชันของโหลดเดอร์ต้องตรงกับเวอร์ชัน PHP (เช่น ioncube_loader_lin_8.1.so สำหรับ PHP 8.1) หากใช้ PHP หลายเวอร์ชัน — ให้เปิดใช้โหลดเดอร์สำหรับแต่ละเวอร์ชัน
09. โดเมนและ DNS
หากต้องการเปิดแดชบอร์ดผ่านที่อยู่แบบ monitor.example.com และรับ SSL ฟรี ต้องมีโดเมนที่ชี้มายังเซิร์ฟเวอร์ของคุณ ในแดชบอร์ดจัดการ DNS ให้สร้าง A-record:
ชนิด: A
ชื่อ: monitor (ซับโดเมน → monitor.example.com)
หรือ @ (โดเมนหลัก → example.com)
ค่า: 203.0.113.10 ← IP ของเซิร์ฟเวอร์คุณ
TTL: 3600
รอสักครู่แล้วตรวจสอบว่าโดเมนชี้มายังเซิร์ฟเวอร์:
dig +short monitor.example.com # ต้องคืนค่า IP ของคุณ
# หรือถ้าไม่มี dig:
getent hosts monitor.example.com
ใบรับรอง SSL ของ Let's Encrypt ออกให้เฉพาะโดเมนเท่านั้น — DNS ต้องชี้มายังเซิร์ฟเวอร์ ก่อน การออกใบรับรอง
10. สร้างเว็บไซต์และอัปโหลดไฟล์แดชบอร์ด
Apache: ตั้ง DocumentRoot ไปที่รากของแดชบอร์ด ไม่ใช่ public/ ไฟล์สไตล์ (CSS/JS), sw.js, manifest.json อยู่ใน assets/ ข้างๆ public/ และถูกเรียกจากรากของเว็บไซต์ .htaccess ที่รากคือฟรอนต์คอนโทรลเลอร์ หากบน Apache ตั้ง DocumentRoot ไปที่ public/ แดชบอร์ดจะเปิดขึ้นมา โดยไม่มีสไตล์ สำหรับ nginx ล้วนจะตรงกันข้าม: ใช้ public/ เป็นราก ส่วน assets/ ให้บริการด้วยกฎแยกต่างหาก (ดูบล็อก nginx ด้านล่าง)
ไฟล์แดชบอร์ด (ไฟล์แพ็กเกจดิสทริบิวชัน) ดาวน์โหลดได้หลังจากซื้อในบัญชีผู้ใช้ my.arciveo.com → “ดาวน์โหลด” แตกไฟล์ก่อนอัปโหลด
1) สร้างไดเรกทอรีของแดชบอร์ด แล้วอัปโหลด เนื้อหาของดิสทริบิวชัน เข้าไป (เพื่อให้ภายในมี public/, assets/, config.php ฯลฯ):
sudo mkdir -p /var/www/monitor
# จากนั้นอัปโหลดไฟล์ดิสทริบิวชันไปยัง /var/www/monitor (FileZilla / WinSCP / scp)
2) ตั้งค่าเว็บเซิร์ฟเวอร์ Apache: ตั้ง DocumentRoot ไปที่รากของแดชบอร์ด (ไม่ใช่ /public); ต้องมี AllowOverride All เส้นทางไปยังซ็อกเก็ต PHP-FPM ถูกกำหนดอัตโนมัติ ให้วางบล็อกลงในเทอร์มินัล ทั้งบล็อก:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # ตรวจหาซ็อกเก็ต PHP-FPM อัตโนมัติ
sudo tee /etc/apache2/sites-available/monitor.conf > /dev/null <<'EOF'
<VirtualHost *:80>
ServerName monitor.example.com
DocumentRoot /var/www/monitor
<Directory /var/www/monitor>
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:__PHPSOCK__|fcgi://localhost"
</FilesMatch>
</VirtualHost>
EOF
sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/apache2/sites-available/monitor.conf
sudo a2dissite 000-default.conf
sudo a2ensite monitor.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
nginx: nginx ไม่มี .htaccess จึงใช้ public/ เป็นราก ส่วน assets/, sw.js, manifest.json (อยู่สูงขึ้นไปหนึ่งระดับ) ให้บริการด้วยกฎแยกต่างหาก:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # ตรวจหาซ็อกเก็ต PHP-FPM อัตโนมัติ
sudo tee /etc/nginx/sites-available/monitor.conf > /dev/null <<'EOF'
server {
listen 80;
server_name monitor.example.com;
root /var/www/monitor/public;
index index.php;
# assets, service worker และ manifest อยู่สูงกว่า public/ หนึ่งระดับ
location ~ ^/(assets/|sw\.js|manifest\.json) { root /var/www/monitor; }
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:__PHPSOCK__;
}
}
EOF
sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/nginx/sites-available/monitor.conf
sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
การอัปโหลดไฟล์ — SFTP/SCP (FileZilla, WinSCP) หรือ scp:
# ตัวอย่างผ่าน scp จากเครื่องคอมพิวเตอร์ในเครื่อง:
scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
ตั้งค่าสิทธิ์ให้ไฟล์ — เป็นขั้นตอนที่จำเป็น หากอัปโหลดด้วย root หรือผ่าน SFTP ไฟล์จะเป็นของ root และเว็บเซิร์ฟเวอร์ (www-data) จะอ่านไม่ได้ — แดชบอร์ดจะเปิดขึ้นมา ว่างเปล่าหรือมีข้อผิดพลาด 403 (ในล็อก: .htaccess unreadable / directory not executable) คำสั่งด้านล่างแก้ปัญหานี้:
# ปรับสิทธิ์ของ webroot ทั้งหมดให้เป็นมาตรฐาน: ไดเรกทอรีที่ root สร้างขึ้นจะเข้าถึงไม่ได้
# โดยเว็บเซิร์ฟเวอร์ (www-data) — ถ้าไม่ทำ แดชบอร์ดจะแสดงหน้าว่างหรือ 403
# Apache ทำงานภายใต้ www-data; หากคุณใช้เว็บยูสเซอร์อื่น — ให้เปลี่ยน
cd /var/www/monitor
# สร้างโฟลเดอร์ทำงานก่อน chown — ไม่งั้นไดเรกทอรีใหม่จะยังเป็น root:root
# และเมื่อ chmod 750 เว็บเซิร์ฟเวอร์ (www-data) จะเขียนลงไปไม่ได้
sudo mkdir -p data/lynis data/logwatch tmp logs
sudo chown -R www-data:www-data /var/www/monitor
sudo find /var/www/monitor -type d -exec chmod 755 {} \;
sudo find /var/www/monitor -type f -exec chmod 644 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 750 data tmp logs
3) เปิดสิทธิ์อัปโหลดไฟล์ผ่าน SFTP ให้ตัวเอง หลังคำสั่งด้านบน ไฟล์ทั้งหมดเป็นของ www-data ขณะที่ FileZilla / WinSCP เชื่อมต่อด้วยผู้ใช้ของคุณเอง การอัปโหลดจึงล้มเหลวด้วย SSH_FX_PERMISSION_DENIED (Permission denied) การเข้าสู่ระบบเป็น root เพื่ออัปโหลดก็ทำไม่ได้ เพราะปิดการเข้าสู่ระบบ root ไปแล้วในขั้นตอน 05 เลือกหนึ่งในสองทางเลือกต่อไปนี้
ทางเลือก A — ACL เฉพาะผู้ใช้ของคุณ (แนะนำ) สิทธิ์เขียนมีเฉพาะคุณคนเดียว เว็บเซิร์ฟเวอร์ยังคงเขียนทับโค้ดของแผงควบคุมไม่ได้:
sudo apt install -y acl
# สิทธิ์เขียนให้ผู้ใช้ของคุณทั้งไดเรกทอรีของแผงควบคุม:
sudo setfacl -R -m u:deploy:rwX /var/www/monitor
# กฎเดียวกันเป็นค่าเริ่มต้น — สำหรับไฟล์และโฟลเดอร์ที่สร้างขึ้นภายหลัง:
sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor
ทางเลือก B — ผ่านกลุ่ม www-data ง่ายกว่า แต่เว็บเซิร์ฟเวอร์ก็ได้สิทธิ์เขียนไฟล์ของแผงควบคุมด้วย หากมีช่องโหว่ใน PHP โค้ดอาจถูกสับเปลี่ยนได้ ลำดับคำสั่งมีความสำคัญ — config.php และโฟลเดอร์ทำงานจะถูกปิดเป็นลำดับสุดท้าย:
sudo usermod -aG www-data deploy
# สิทธิ์เขียนของกลุ่ม + setgid (บิต 2): ไฟล์ที่อัปโหลดผ่าน SFTP จะยังอยู่
# ในกลุ่ม www-data มิฉะนั้นแผงควบคุมจะเขียนทับไม่ได้
sudo find /var/www/monitor -type d -exec chmod 2775 {} \;
sudo find /var/www/monitor -type f -exec chmod 664 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 2750 /var/www/monitor/data /var/www/monitor/tmp /var/www/monitor/logs
หลังทางเลือก B ให้ เชื่อมต่อใหม่ใน FileZilla (เซิร์ฟเวอร์ → ตัดการเชื่อมต่อ แล้วเข้าสู่ระบบอีกครั้ง) กลุ่มใหม่จะมีผลเมื่อเข้าสู่ระบบใหม่เท่านั้น ก่อนหน้านั้นก็ยังไม่มีสิทธิ์ ตรวจสอบ: id deploy — ในรายการกลุ่มต้องปรากฏ www-data; ls -ld /var/www/monitor — สิทธิ์ drwxrwsr-x โดยตัวอักษร s แทน x หมายความว่าตั้ง setgid แล้ว
11. ฐานข้อมูล
สร้างฐานข้อมูลและผู้ใช้ จากนั้นนำเข้าสคีมา วางบล็อกนี้ลงในเทอร์มินัลทั้งหมด monitor_db และ monitor_user เป็นชื่อตัวอย่าง คุณกำหนดชื่อของคุณเองได้ตามต้องการ จดจำชื่อฐานข้อมูล ผู้ใช้ และรหัสผ่านไว้ เพราะจะต้องกรอกลงใน config.php ในขั้นตอนถัดไป:
# 1. ฐานข้อมูล กำหนดรหัสผ่านครั้งเดียวใน DBPASS แล้วจะถูกแทนที่ในทุกบรรทัด
# วางบล็อกนี้ลงในเทอร์มินัลทั้งหมด; sudo mysql เข้าเป็น root ผ่าน unix-socket
# (ไม่ต้องใช้รหัสผ่าน root) อย่าใช้ `sudo mysql -u root -p` แบบอินเทอร์แอกทีฟ
# ด้วยการคัดลอกวาง — เมื่อวาง บรรทัด SQL จะไปที่ช่องถามรหัสผ่านและหายไป
DBPASS='CHOOSE_A_PASSWORD' # ← แก้เฉพาะบรรทัดนี้
sudo mysql <<SQL
CREATE DATABASE IF NOT EXISTS monitor_db CHARACTER SET utf8mb4;
CREATE USER IF NOT EXISTS 'monitor_user'@'localhost' IDENTIFIED BY '$DBPASS';
GRANT ALL ON monitor_db.* TO 'monitor_user'@'localhost';
FLUSH PRIVILEGES;
SQL
# ตรวจสอบ (ควรแสดง monitor_db):
mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;"
# นำรหัสผ่านเดียวกันนี้ไปกรอกใน config.php → DB_PASS.
ไม่จำเป็นต้องนำเข้าสคีมา — แดชบอร์ดจะสร้างตารางและบัญชี admin เองเมื่อเปิดในเบราว์เซอร์ครั้งแรก (จาก database/db.sql) หากฐานข้อมูลว่างเปล่า การนำเข้าสคีมาด้วยตนเองจำเป็นเฉพาะเมื่อการเริ่มต้นอัตโนมัติไม่ทำงาน
หากคุณใช้ตัวติดตั้งผ่านเบราว์เซอร์ public/start_db.php — ให้ลบทิ้งทันทีหลังติดตั้ง: มันเปิดให้สร้างฐานข้อมูลใหม่ได้โดยไม่ต้องยืนยันตัวตน ตราบใดที่ไฟล์นี้ยังอยู่ในรากของแดชบอร์ดหรือใน public/ แดชบอร์ดจะแสดงคำเตือนสีแดง
12. การตั้งค่า config.php
config.php ในรากของแดชบอร์ด (/var/www/monitor/config.php) เป็นไฟล์เดียวที่ต้องแก้ไขด้วยมือ การตั้งค่าทั้งหมดของแดชบอร์ดกำหนดไว้ในไฟล์นี้ผ่านค่าคงที่ define() เปิดไฟล์ในโปรแกรมแก้ไข:
sudo nano /var/www/monitor/config.php
ใส่ค่าของคุณในตำแหน่งที่ไฮไลต์ไว้ ส่วนที่เหลือคงไว้ตามเดิม:
// --- ฐานข้อมูล (จากขั้นตอนที่ 11) ---
define('DB_HOST', 'localhost'); // คงไว้
define('DB_NAME', 'db_name'); // ที่สร้างในขั้นตอนที่ 11
define('DB_USER', 'user'); // ที่สร้างในขั้นตอนที่ 11
define('DB_PASS', 'db_password'); // ที่กำหนดในขั้นตอนที่ 11
define('DB_CHARSET', 'utf8mb4'); // คงไว้
// --- แอปพลิเคชัน ---
define('APP_URL', 'https://monitor.example.com'); // ที่อยู่แดชบอร์ด ไม่มีสแลชท้าย
define('TIMEZONE', 'Asia/Bangkok'); // เขตเวลาของคุณ
// --- เวลาเซสชัน ---
define('SESSION_LIFETIME', 28800); // เวลาว่างก่อนต้องเข้าสู่ระบบใหม่ วินาที (28800 = 8 ชม.)
สิ่งที่ต้องแก้:
DB_NAME, DB_USER, DB_PASS — ชื่อฐานข้อมูล ผู้ใช้ และรหัสผ่านเดียวกันกับที่คุณกำหนดตอนสร้างฐานข้อมูลในขั้นตอนที่ 11 (หากคงตัวอย่างไว้ — monitor_db / monitor_user) อย่าแตะ DB_HOST และ DB_CHARSET
APP_URL — ที่อยู่เต็มของแดชบอร์ดพร้อม https:// ไม่มีสแลชท้ายและไม่มี www ต้องตรงกับโดเมนที่คุณเปิดใช้งานลิขสิทธิ์ (ขั้นตอนที่ 16) ไม่เช่นนั้นคีย์จะถูกปฏิเสธ
TIMEZONE — เขตเวลาของคุณ (รายการ — timedatectl list-timezones) มีผลเฉพาะการแสดงวันที่ของแดชบอร์ดเท่านั้น ไม่มีผลต่อเวลาที่รันงาน cron (ตรงนั้นใช้เขตเวลาของระบบ)
SESSION_LIFETIME — จำนวนวินาทีที่ไม่มีการใช้งานก่อนที่แดชบอร์ดจะขอให้เข้าสู่ระบบใหม่ (ค่าเริ่มต้น 8 ชั่วโมง) เช่น 3600 = 1 ชั่วโมง, 86400 = หนึ่งวัน
- บล็อกการบันทึกข้อผิดพลาด (
display_errors, log_errors, error_log) — คงไว้ตามค่าเริ่มต้น
บันทึกไฟล์ (Ctrl+O, Enter จากนั้น Ctrl+X) แล้วรีสตาร์ท PHP-FPM ไม่เช่นนั้นการเปลี่ยนแปลงจะไม่มีผลเพราะ OPcache:
sudo systemctl restart php*-fpm
config.php เป็นไฟล์ลับ (มีรหัสผ่านฐานข้อมูลอยู่ในนั้น) ไฟล์นี้อยู่ในรากของแดชบอร์ดซึ่งเป็นเว็บรูท แต่ถูกปิดกั้นไว้: สิทธิ์ 640 (กำหนดในขั้นตอนที่ 10) และการห้ามชัดเจนใน .htaccess ของราก อย่านำไปเผยแพร่ในรีโพซิทอรีสาธารณะและอย่าส่งให้ฝ่ายสนับสนุนพร้อมรหัสผ่านจริง
13. ตั้งค่า sudo สำหรับเว็บเซิร์ฟเวอร์
PHP ทำงานภายใต้ผู้ใช้ของเว็บเซิร์ฟเวอร์ ซึ่งไม่มีสิทธิ์รันคำสั่งระบบ การให้สิทธิ์จึงจำกัดเฉพาะจุด: sudo เฉพาะจุด สำหรับยูทิลิตี้ที่กำหนด และ อ่านล็อกผ่านกลุ่ม (โดยไม่ใช้ sudo) การเจาะชั้นเว็บจึงไม่ได้สิทธิ์ root
ในตัวอย่าง www-data คือผู้ใช้มาตรฐานของ Apache หากคุณใช้ผู้ใช้อื่น (บางแผงควบคุมรัน PHP ภายใต้ผู้ใช้แยกต่างหาก) ให้แทนที่ทุกจุด ตรวจสอบด้วย: ps -o user= -C php-fpm | sort -u
1. สร้าง /etc/sudoers.d/monitor ด้วย sudo visudo -f /etc/sudoers.d/monitor แล้ววางเนื้อหาต่อไปนี้ (ลบบรรทัดของโมดูลที่ไม่ได้ใช้ออก):
# UFW — สถานะและกฎ (หน้า “ไฟร์วอลล์”)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw status, /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw allow [0-9]*, /usr/sbin/ufw deny [0-9]*, /usr/sbin/ufw --force delete [0-9]*
# Fail2ban — สถานะ, แบน และปลดแบน (banned คืนค่าการแบนของทุก jail ในคำสั่งเดียว;
# ban/unban จำเป็นสำหรับปุ่มบนแผงควบคุม)
www-data ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *, /usr/bin/fail2ban-client banned, /usr/bin/fail2ban-client set * banip *, /usr/bin/fail2ban-client set * unbanip *
# อัปเดตความปลอดภัย (การ์ด “อัปเดต”) อ่านอย่างเดียว แต่ต้องเป็น root เท่านั้น:
# แคช apt (~70 MB) เข้าถึงได้เฉพาะ root, ผู้ที่ไม่ใช่ root จะสร้างใหม่ทุกครั้งที่เรียก
# (4.2 วินาที CPU เทียบกับ 0.01 วินาที) ไม่มี wildcard — เป็นคำสั่งเดียวนี้พอดี ไม่ติดตั้งอะไร
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable
# IPset (แผนที่การโจมตี, แดชบอร์ด)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ipset list -t ipsum
# CrowdSec
www-data ALL=(ALL) NOPASSWD: /usr/bin/cscli decisions list *, /usr/bin/cscli alerts list *, /usr/bin/cscli bouncers list *, /usr/bin/cscli scenarios list *
# Auditd — ค้นหาเหตุการณ์ + อ่านบรรทัดล่าสุดของล็อก (พาธที่แน่นอน)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ausearch -m *
www-data ALL=(ALL) NOPASSWD: /usr/bin/tail -n 300 /var/log/audit/audit.log
# Monit / ModSecurity / AppArmor / PSAD
www-data ALL=(ALL) NOPASSWD: /usr/bin/monit status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/apache2ctl -M
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
www-data ALL=(ALL) NOPASSWD: /usr/sbin/aa-status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/psad --Status
# พอร์ตที่เปิดอยู่ (ล็อกเคอร์เนล/SSH/Falco อ่านได้โดยไม่ใช้ sudo — ผ่านกลุ่ม
# systemd-journal ดูข้อ 2; ไม่ควรให้ sudo กับ journalctl และไม่ปลอดภัย)
www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln
# PostgreSQL (เฉพาะเมื่อใช้งาน) — สคริปต์อ่านอย่างเดียวแบบตายตัว,
# สร้างตาม FAQ “PostgreSQL ไม่แสดงผล”; หากไม่มี ให้ลบบรรทัดนี้ออก
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
sudo chmod 440 /etc/sudoers.d/monitor
sudo visudo -c # ควรได้ผลลัพธ์ "parsed OK"
2. การเข้าถึงล็อกและ journal ของ systemd. โมดูลอ่าน /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide โดยตรง (บน Debian/Ubuntu ล็อกเหล่านี้อยู่ในกลุ่ม adm) เหตุการณ์ของเคอร์เนล, SSH และ Falco ดึงจาก journald ด้วยคำสั่ง journalctl โดยไม่ใช้ sudo ผ่านกลุ่ม systemd-journal เพิ่มผู้ใช้เว็บลงใน ทั้งสอง กลุ่มแล้ว รีสตาร์ท PHP-FPM:
sudo usermod -aG adm,systemd-journal www-data
sudo systemctl restart php*-fpm # จำเป็น มิฉะนั้นกลุ่มจะไม่มีผล
3. หาก ClamAV หรือ Suricata เขียนล็อกไม่เข้ากลุ่ม adm (บางครั้งเป็น root:root) — ให้สิทธิ์เข้าถึงผ่าน ACL:
sudo apt install acl
sudo setfacl -R -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null
sudo setfacl -d -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null
4. ตัวห่อ ModSecurity. ล็อกตรวจสอบของ WAF (/var/log/apache2/modsec_audit.log) เป็นของ root ด้วยสิทธิ์ 640 ผู้ใช้เว็บอ่านโดยตรงไม่ได้ หน้า ModSecurity ดึงโหมดเอนจิน เหตุการณ์ และรายการกฎที่ใช้งานอยู่ผ่านสคริปต์อ่านอย่างเดียวแบบตายตัว — ซึ่งได้รับอนุญาตในไฟล์ sudoers ในบรรทัดด้านบนแล้ว:
sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF'
#!/bin/sh
echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')"
echo "---LOG---"
tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null
echo "---RULES---"
for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do
[ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; }
done
EOF
sudo chown root:root /usr/local/bin/monitor-modsec
sudo chmod 755 /usr/local/bin/monitor-modsec
หากไม่มีไฟล์
/etc/modsecurity/modsecurity.conf ตัว WAF จะไม่ทำงาน: แพ็กเกจวางไว้เพียง
modsecurity.conf-recommended และเอนจินกฎยังคงปิดอยู่ — วิธีเปิดใช้งานดู
FAQ → “การติดตั้ง ModSecurity”
ผู้ใช้ในทุกบรรทัดของ sudoers ต้องตรงกับผู้ใช้ของพูล FPM: บน Apache/Debian ทั่วไปคือ
www-data ส่วนใน HestiaCP พูลของไซต์ทำงานภายใต้เจ้าของไซต์ (เช่น
admin) — ตรวจสอบด้วย
grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf
5. หากมี Nginx อยู่หน้า Apache (HestiaCP, ISPmanager และแผงควบคุมอื่น — ที่นั่น Nginx พร็อกซี PHP ไปยัง Apache และให้บริการไฟล์สแตติกด้วยตัวเอง) ไดเรกทอรีระบบถูกปิดด้วยไฟล์ .htaccess แต่ Nginx ไม่อ่านไฟล์เหล่านี้: ไฟล์สแตติกใด ๆ (.json, .txt, .log, .dat) มันจะส่งออกโดยตรง โดยข้าม Apache แคชและข้อมูลของแผงควบคุมจะรั่วออกไปภายนอก — เช่น tmp/modsec_cache.json ที่มีเหตุการณ์ของ WAF และ IP ของผู้โจมตี เพิ่มการปฏิเสธการเข้าถึงในไฟล์คอนฟิกของไซต์ Nginx:
location ^~ /data/ { deny all; }
location ^~ /tmp/ { deny all; }
location ^~ /logs/ { deny all; }
location ^~ /includes/ { deny all; }
location ^~ /cron/ { deny all; }
location ^~ /database/ { deny all; }
location = /config.php { deny all; }
คำนำหน้า ^~ จำเป็น: มันถูกเลือกก่อนกฎ regular สำหรับไฟล์สแตติกภายใน location / มิฉะนั้นการปฏิเสธจะไม่ทำงาน
ใน HestiaCP ให้วางเป็นไฟล์แยก /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny (และ nginx.conf_deny สำหรับ HTTP) — คอนฟิกของไซต์จะรวม nginx.ssl.conf_* และเมื่อสร้างใหม่จะไม่ทับไฟล์เหล่านี้ ใช้งานด้วย: sudo nginx -t && sudo systemctl reload nginx
ตรวจสอบ: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — ควรได้ 403 หาก Apache ทำงานโดยไม่มี Nginx (ฟังพอร์ต 80/443 เอง) ไม่ต้องเพิ่มอะไร — .htaccess เพียงพอแล้ว
ตรวจสอบพาธของไบนารีด้วย
which (เช่น
which ufw cscli ausearch ss) แก้ไข sudoers ผ่าน
visudo เท่านั้น รายชื่อฐานข้อมูล MySQL
ทั้งหมด เปิดใช้งานด้วย GRANT แยกต่างหาก (
FAQ → “เห็นเพียงฐานข้อมูลเดียว”)
14. การจำกัดการเข้าถึงตาม IP
จำกัดการเข้าถึงมอนิเตอร์ตามที่อยู่ IP — แม้ URL จะถูกเปิดเผย หน้าเข้าสู่ระบบก็จะไม่เปิด สามารถทำได้ที่ระดับเว็บเซิร์ฟเวอร์ (ตัวอย่างสำหรับ nginx ด้านล่าง) หรือในแดชบอร์ดเอง (“การตั้งค่า” → “การจำกัดการเข้าถึงตาม IP”) หากคุณใช้ Apache ให้ใช้การจำกัดในแดชบอร์ด
หากไซต์ nginx ตั้งค่าตามขั้นตอนที่ 10 ไว้แล้ว อย่าเพิ่ม location / ตัวที่สอง — ให้ใส่บรรทัด allow/deny ลงในบล็อกที่มีอยู่แล้ว การมี location / ที่เหมือนกันสองตัวใน server { } เดียวกันคือข้อผิดพลาดของการตั้งค่า nginx จะไม่รีสตาร์ท
# ในไฟล์คอนฟิก nginx (ภายใน server { }):
# เปิด ACME-path ของ Let's Encrypt ไว้ให้ข้ามการจำกัด IP —
# เพื่อให้การออกและต่ออายุ SSL อัตโนมัติ (ขั้นตอนที่ 15) ไม่ขึ้นกับตัวกรอง IP
location ^~ /.well-known/acme-challenge/ { allow all; }
location / {
allow 203.0.113.10; # ← ใส่ IP ของคุณ
allow 10.0.0.0/8; # เครือข่ายภายใน (ถ้าจำเป็น)
deny all;
try_files $uri $uri/ /index.php?$query_string;
}
# รีโหลด nginx:
sudo nginx -t && sudo systemctl reload nginx
15. ออกใบรับรอง SSL (HTTPS)
แดชบอร์ดทำงานผ่าน HTTPS เท่านั้น เซสชันการเข้าสู่ระบบใช้คุกกี้ที่ปลอดภัย และ WebAuthn (2FA) ทำงานได้เฉพาะบน HTTPS เท่านั้น ไม่สามารถเข้าสู่ระบบผ่าน http:// ได้
ใบรับรองใช้งานฟรี (Let's Encrypt) โดเมนต้องชี้ DNS มายังเซิร์ฟเวอร์อยู่แล้ว คำสั่งขึ้นอยู่กับเว็บเซิร์ฟเวอร์ที่ใช้:
# Apache:
sudo certbot --apache -d monitor.example.com
# nginx — เฉพาะเมื่อคุณใช้ nginx จริง ๆ เท่านั้น อย่ารันบน Apache:
# apt จะดึง nginx มาและยึดพอร์ต 80 ทำให้ขัดแย้งกับ Apache
# sudo apt install python3-certbot-nginx
# sudo certbot --nginx -d monitor.example.com
# certbot จะเขียน HTTPS ลงในคอนฟิกและตั้งค่าต่ออายุอัตโนมัติให้เอง
สิ่งที่ certbot จะถาม: e-mail → ยอมรับ Terms (Y) → ส่ง e-mail ให้ EFF (แล้วแต่คุณ) จากนั้นจะออกใบรับรองให้เอง เขียน <VirtualHost *:443> ตั้งค่าการรีไดเรกต์ http→https และต่ออายุอัตโนมัติ
DNS ต้องชี้มายังเซิร์ฟเวอร์ก่อนรัน certbot (การยืนยันความเป็นเจ้าของผ่านพอร์ต 80) ตรวจสอบ: dig +short monitor.example.com → IP ของเซิร์ฟเวอร์ เปิดพอร์ต 80/443: sudo ufw allow 80,443/tcp
หลังออกใบรับรอง: https://monitor.example.com จะเปิดพร้อมรูปกุญแจ และ http:// จะรีไดเรกต์ไปยัง https:// (APP_URL ใน config.php ตั้งค่าไว้แล้วในขั้นตอนที่ 12)
16. เข้าสู่ระบบและการตั้งค่าเริ่มต้น
เปิด https://monitor.example.com เข้าสู่ระบบด้วย admin / useradmin แล้วทำตามเช็กลิสต์:
- เปลี่ยนรหัสผ่าน admin — ส่วน “ผู้ใช้” ในเมนู
- เปิดใช้ WebAuthn (2FA) — “คีย์ WebAuthn” → ลงทะเบียนคีย์/passkey (ต้องใช้ HTTPS) ลงทะเบียนสองคีย์ทันที: หากคีย์เดียวที่มีสูญหาย จะไม่สามารถเข้าสู่ระบบด้วยคีย์นั้นได้ รายละเอียด
- จำกัดการเข้าถึงตาม IP — “การตั้งค่า” → “การจำกัดการเข้าถึงตาม IP” (ใส่ IP ของคุณก่อนเปิดใช้งาน มิฉะนั้นคุณจะปิดกั้นการเข้าถึงของตัวเอง)
- กรอกลิขสิทธิ์ — เปิดใช้งานโค้ด
ARCIVEO-… จากบัญชีผู้ใช้กับโดเมนของคุณ แล้ววางคีย์ใน “การตั้งค่า” → “ลิขสิทธิ์” รายละเอียด
- ตั้งค่าการแจ้งเตือน — Telegram และ/หรือ Email ใน “การตั้งค่า” รายละเอียด
- ลบตัวติดตั้ง
public/start_db.php หากยังหลงเหลืออยู่ (ขั้นตอนที่ 11)
18. Cron และการบำรุงรักษา
ตั้งค่าครั้งเดียว เป็นทางเลือกเช่นกันแต่แนะนำให้ทำ คำสั่งโดยละเอียดอยู่ในคู่มือ:
- งาน Cron (รายงาน อัปเดตรายการ การตรวจสอบ);
- การสำรองข้อมูล;
- การอัปเดตและย้ายแดชบอร์ด;
- การกู้คืนการเข้าถึง — เผื่อกรณีทำ security key หรือรหัสผ่านหาย
มีบางอย่างไม่ทำงานหรือแสดง “ไม่มีข้อมูล”? ดูที่กลุ่ม
“การวินิจฉัย” ในคู่มือ