⚠️ Critical Security Warning: VestaCP is a legacy panel with known critical vulnerabilities. The project has been discontinued with minimal maintenance since 2018. Known issues include a supply-chain backdoor (CVE-2018-25117), session validation vulnerabilities (CVE-2020-36948), and multiple unpatched security flaws. Recent analysis in 2025-2026 confirms ongoing CVE discoveries with no active patching. Migration to an actively maintained alternative is strongly recommended.
If you must run VestaCP, implement comprehensive isolation and hardening measures immediately.
| Vulnerability | Type | Severity | Status |
|---|---|---|---|
| CVE-2018-25117 | Supply-Chain Backdoor | Critical (9.3) | Unpatched |
| CVE-2020-36948 | LoginAs Session Validation | High (8.7) | Unpatched |
| CVE-2018-25116 | Authenticated RCE | Critical | Unpatched |
| Multiple XSS | Cross-Site Scripting | Medium | Partially patched |
Affected Versions: Installations from commits a3f0fa1 to ee03eff (May 31 - June 13, 2018)
Impact: Critical supply-chain compromise with credential theft and DDoS malware deployment.
Malicious Behavior:
Check if affected:
# Check installation date
cat /var/log/vesta/install.log | head -1
# Check for malicious files
ls -la /usr/local/vesta/bin/
find /tmp -name "*.lua" -type f # ChachaDDoS used Lua scripts
# Check for suspicious outbound connections
netstat -anp | grep ESTABLISHED | grep -v "127.0.0.1"
Exploit Window: Any VestaCP installation created during the ~2 week compromise period was affected. Systems installed since May 2018 may have been exploited in the wild.
Affected Version: VestaCP 0.9.8-26
Vulnerable Module: LoginAs feature
Impact: Remote attackers can manipulate authentication tokens to access user accounts without proper administrative permissions.
CVSS Score: 8.7 (High)
Exploit Pattern:
# Attackers can craft requests to LoginAs endpoint
# Insufficient session validation allows unauthorized access
curl -X POST https://vesta.example.com:8083/loginas/ \
-d "user=admin&token=manipulated_token"
Impact: Any authenticated user can execute arbitrary system commands.
Exploit Pattern:
# Via job scheduler or file manager
# Allows command execution as www-data or root
Never expose VestaCP directly to the internet. Use network isolation:
Option 1: Firewall restrictions (iptables)
# Allow only from management network
sudo iptables -A INPUT -p tcp --dport 80 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8083 -s 10.0.0.0/24 -j ACCEPT # VestaCP panel
sudo iptables -A INPUT -p tcp --dport 8083 -j DROP
sudo iptables-save > /etc/iptables/rules.v4
Option 2: Firewall restrictions (firewalld)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="8083" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="8083" protocol="tcp" reject'
sudo firewall-cmd --reload
Option 3: Firewall restrictions (UFW)
sudo ufw allow from 10.0.0.0/24 to any port 8083
sudo ufw deny 8083
sudo ufw enable
Front VestaCP with Nginx + Basic Auth:
server {
listen 443 ssl;
server_name vesta.example.com;
ssl_certificate /etc/letsencrypt/live/vesta.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vesta.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Basic authentication (extra layer)
auth_basic "VestaCP Admin Access";
auth_basic_user_file /etc/nginx/.vesta_htpasswd;
# Rate limiting
limit_req_zone $binary_remote_addr zone=vesta:10m rate=5r/s;
limit_req zone=vesta burst=10 nodelay;
# Security headers
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'" always;
location / {
proxy_pass https://localhost:8083;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For ""; # Strip to prevent injection
proxy_set_header X-Forwarded-Proto $scheme;
# Disable SSL verification for localhost proxy
proxy_ssl_verify off;
}
}
Create htpasswd file:
sudo apt install apache2-utils # Debian/Ubuntu
sudo htpasswd -c /etc/nginx/.vesta_htpasswd admin
VestaCP session configuration (/usr/local/vesta/data/sessions/ or /usr/local/vesta/php/):
<?php
// Session timeout (30 minutes)
ini_set('session.gc_maxlifetime', 1800);
ini_set('session.cookie_lifetime', 1800);
// Secure cookies
ini_set('session.cookie_secure', 1);
ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);
// CSRF protection
ini_set('session.use_strict_mode', 1);
?>
Disable LoginAs feature (mitigates CVE-2020-36948):
# Remove or rename LoginAs binary
sudo mv /usr/local/vesta/bin/v-loginas /usr/local/vesta/bin/v-loginas.disabled
# Or restrict via permissions
sudo chmod 000 /usr/local/vesta/bin/v-loginas
Secure default admin account:
# Change admin password via CLI
/usr/local/vesta/bin/v-change-user-password admin 'YourNewStrongPassword123!'
# Or interactively
/usr/local/vesta/bin/v-change-user-password admin
Best practices:
Delete unused accounts:
# List users
/usr/local/vesta/bin/v-list-users
# Delete user (use with caution)
/usr/local/vesta/bin/v-delete-user oldadmin
Generate SSL certificate:
# Let's Encrypt
sudo apt install certbot
sudo certbot certonly --standalone -d vesta.example.com
# Link to VestaCP
sudo cp /etc/letsencrypt/live/vesta.example.com/fullchain.pem /usr/local/vesta/ssl/certificate.crt
sudo cp /etc/letsencrypt/live/vesta.example.com/privkey.pem /usr/local/vesta/ssl/certificate.key
sudo chmod 600 /usr/local/vesta/ssl/certificate.key
# Restart VestaCP
sudo systemctl restart vestacp
Configure Nginx for HTTPS:
# /etc/nginx/conf.d/vesta.conf
server {
listen 443 ssl;
server_name vesta.example.com;
ssl_certificate /usr/local/vesta/ssl/certificate.crt;
ssl_certificate_key /usr/local/vesta/ssl/certificate.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
location / {
proxy_pass https://localhost:8083;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Isolate VestaCP server in restricted network:
# Block all outbound except essential
sudo iptables -A OUTPUT -o lo -j ACCEPT
sudo iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT # DNS
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT # HTTP (updates)
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # HTTPS (updates)
sudo iptables -A OUTPUT -j DROP
Deploy ModSecurity with custom rules to block known VestaCP exploits:
# Install ModSecurity
sudo apt install libapache2-mod-security2 # Debian/Ubuntu
sudo a2enmod security2
sudo systemctl restart apache2
Custom VestaCP protection rules (/etc/modsecurity/rules/vestacp.conf):
# Block LoginAs exploitation
SecRule REQUEST_URI "@rx (?i)(loginas)" \
"id:3001,\
phase:1,\
block,\
capture,\
t:none,\
msg:'VestaCP LoginAs Access Attempt',\
log"
# Block RCE patterns in job scheduler
SecRule ARGS "@rx (\||;|`|\$\(|\n|\r)" \
"id:3002,\
phase:2,\
block,\
capture,\
t:none,t:urlDecodeUni,\
msg:'VestaCP RCE Attempt',\
log"
# Block XSS patterns
SecRule ARGS "@rx (?i)(<script|javascript:|onerror=|onload=)" \
"id:3003,\
phase:2,\
block,\
capture,\
t:none,t:urlDecodeUni,t:htmlEntityDecode,\
msg:'VestaCP XSS Attempt',\
log"
# Block path traversal
SecRule REQUEST_URI "@rx (\.\.\/|\.\.\\\\)" \
"id:3004,\
phase:1,\
block,\
capture,\
t:none,\
msg:'VestaCP Path Traversal Attempt',\
log"
Secure VestaCP installation:
# VestaCP typically installs to /usr/local/vesta
sudo chown -R root:root /usr/local/vesta
sudo chmod -R 750 /usr/local/vesta
# Config files should be more restrictive
sudo chmod 600 /usr/local/vesta/conf/vesta.conf
sudo chmod 600 /usr/local/vesta/ssl/*.key
# Web root
sudo chown -R www-data:www-data /usr/local/vesta/web
sudo chmod -R 755 /usr/local/vesta/web
# Data directory
sudo chmod 700 /usr/local/vesta/data
sudo chown www-data:www-data /usr/local/vesta/data
# Prevent execution in upload directories
find /usr/local/vesta/data -type f -name "*.php" -exec chmod 644 {} \;
find /usr/local/vesta/data -type d -exec chmod 755 {} \;
Disable PHP execution in sensitive directories:
# /etc/apache2/conf-available/vesta-hardening.conf
<Directory "/usr/local/vesta/data">
php_flag engine off
RemoveHandler .php .php3 .php4 .php5 .phtml
<FilesMatch "\.(php|php3|php4|php5|phtml)$">
Deny from all
</FilesMatch>
</Directory>
<Directory "/usr/local/vesta/web">
Options -Indexes
</Directory>
VestaCP uses SQLite and MySQL/MariaDB. Secure them:
# Run secure installation for MySQL
sudo mysql_secure_installation
# Key settings:
# - Set root password
# - Remove anonymous users
# - Disallow root login remotely
# - Remove test database
Configure /etc/mysql/mariadb.conf.d/50-server.cnf:
[mysqld]
# Network security - bind to localhost only
bind-address = 127.0.0.1
skip-networking = 1
# Disable local infile
local-infile = 0
# Secure file handling
secure_file_priv = /var/lib/mysql-files
# Logging
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# VestaCP-specific: restrict database user privileges
Create restricted VestaCP database user:
-- Login to MySQL
mysql -u root -p
-- Create dedicated user with minimal privileges
CREATE USER 'vesta'@'localhost' IDENTIFIED BY 'strong-password-here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON vesta.* TO 'vesta'@'localhost';
FLUSH PRIVILEGES;
-- Do NOT grant: FILE, PROCESS, SUPER, RELOAD, SHUTDOWN
Edit /etc/php/*/apache2/php.ini or /etc/php/*/fpm/php.ini:
[Security]
expose_php = Off
allow_url_fopen = Off
allow_url_include = Off
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,passthru,leak,fopen,readfile
display_errors = Off
log_errors = On
error_reporting = E_ALL
html_errors = Off
[Resource Limits]
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
post_max_size = 20M
upload_max_filesize = 20M
max_file_uploads = 5
[Session]
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_only_cookies = 1
session.cookie_samesite = Strict
session.use_strict_mode = 1
session.gc_maxlifetime = 1800
[Open Basedir]
open_basedir = /usr/local/vesta:/tmp:/var/tmp
Restart web server:
sudo systemctl restart apache2
VestaCP installs many services. Disable what you don’t need:
# Check running services
systemctl list-units --type=service --state=running
# Disable unnecessary services (examples)
sudo systemctl stop named # DNS if not used
sudo systemctl disable named
sudo systemctl stop postfix # Mail if not used
sudo systemctl disable postfix
sudo systemctl stop dovecot # IMAP if not used
sudo systemctl disable dovecot
sudo systemctl stop pure-ftpd # FTP if not used
sudo systemctl disable pure-ftpd
sudo systemctl stop exim # Mail if not used
sudo systemctl disable exim
⚠️ Note: VestaCP is no longer actively maintained. Updates are infrequent and security patches are not guaranteed.
# Check current version
/usr/local/vesta/bin/v-list-sys-info version
# Check for updates (if any)
# VestaCP GitHub: https://github.com/outroll/vesta
# Manual update (if available)
cd /usr/local/vesta
sudo wget https://github.com/outroll/vesta/releases/latest/download/vesta.tar.gz
sudo tar xzf vesta.tar.gz
sudo chown -R root:root /usr/local/vesta
Better approach: Plan migration to maintained alternative
VestaCP log locations:
| Log File | Purpose |
|---|---|
/usr/local/vesta/log/ |
Main panel logs |
/usr/local/vesta/log/access.log |
Panel access |
/usr/local/vesta/log/error.log |
Panel errors |
/usr/local/vesta/log/auth.log |
Authentication logs |
/var/log/apache2/vesta* |
Web server logs |
/var/log/mysql/error.log |
Database errors |
/var/log/syslog |
System messages |
View recent activity:
# VestaCP logs
tail -f /usr/local/vesta/log/*.log
# Filter for login events
grep -i "login\|auth" /usr/local/vesta/log/auth.log
# Failed login attempts
grep -i "failed\|invalid" /usr/local/vesta/log/auth.log | tail -50
# Check for LoginAs usage
grep -i "loginas" /usr/local/vesta/log/*.log
# Apache access logs
tail -f /var/log/apache2/vesta_access.log
# Failed requests
grep "403\|401\|500" /var/log/apache2/vesta_access.log | tail -50
Set up alerts for:
Configure log monitoring:
# /etc/logwatch/conf/logfiles/vestacp.conf
LogFile = /usr/local/vesta/log/*.log
LogFile = /var/log/apache2/vesta*
Install AIDE or OSSEC to detect file changes:
# Install AIDE
sudo apt install aide # Debian/Ubuntu
sudo dnf install aide # RHEL/Fedora
# Initialize database
sudo aideinit
# Configure VestaCP paths in /etc/aide/aide.conf
/usr/local/vesta/ p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
/usr/local/vesta/bin/ p+i+n+u+g+s+m+sha512
/usr/local/vesta/conf/ p+i+n+u+g+s+m+c+sha512
/var/log/vesta/ p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
# Schedule daily checks
0 5 * * * /usr/bin/aide --check
Scan for CVE-2018-25117 indicators:
# Check installation date
cat /var/log/vesta/install.log | head -1
# Look for malicious files
find /tmp -name "*.lua" -type f
find /usr -name "chacha*" -type f 2>/dev/null
# Check for suspicious processes
ps aux | grep -i "ddos\|lua"
netstat -anp | grep ESTABLISHED | grep -v "127.0.0.1"
# Check for unauthorized outbound connections
iptables -L OUTPUT -v -n | grep -v "ACCEPT"
Deploy fail2ban for VestaCP:
sudo apt install fail2ban
# /etc/fail2ban/jail.local
[vestacp]
enabled = true
port = http,https,8083
filter = vestacp
logpath = /usr/local/vesta/log/auth.log
maxretry = 3
bantime = 3600
findtime = 300
[vestacp-loginas]
enabled = true
port = 8083
filter = vestacp-loginas
logpath = /usr/local/vesta/log/*.log
maxretry = 1 # Any LoginAs attempt is suspicious
bantime = 86400 # 24 hour ban
findtime = 300
Create filter (/etc/fail2ban/filter.d/vestacp.conf):
[Definition]
failregex = ^.*Failed login.*<HOST>.*$
^.*Authentication failure.*<HOST>.*$
^.*Invalid.*<HOST>.*$
^.*LoginAs.*<HOST>.*$
ignoreregex =
| Control | Status | Notes |
|---|---|---|
| Panel isolated from internet | ☐ | Behind reverse proxy/firewall |
| WAF rules deployed | ☐ | ModSecurity with VestaCP rules |
| LoginAs disabled | ☐ | Mitigates CVE-2020-36948 |
| Backdoor indicators checked | ☐ | CVE-2018-25117 scan |
| Database user restricted | ☐ | Minimal privileges only |
| PHP hardening applied | ☐ | Disable dangerous functions |
| File permissions secured | ☐ | Config files 600, directories 750 |
| Unnecessary services disabled | ☐ | DNS, mail, FTP if not used |
| File integrity monitoring | ☐ | AIDE or OSSEC |
| Centralized logging | ☐ | Forward to SIEM |
| Migration plan documented | ☐ | To maintained alternative |
If you suspect a security breach:
Isolate the server immediately
# Block all external access
sudo iptables -F
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
Preserve evidence
cp -r /usr/local/vesta/log /root/vesta-logs-$(date +%Y%m%d-%H%M%S)
cp -r /var/log/apache2 /root/apache-logs-$(date +%Y%m%d-%H%M%S)
mysqldump -u root -p vesta > /root/vesta-db-$(date +%Y%m%d-%H%M%S).sql
Check for backdoor indicators
# Check installation date
cat /var/log/vesta/install.log | head -1
# Look for malicious files
find /tmp -name "*.lua" -type f
find / -name "chacha*" -type f 2>/dev/null
# Check for suspicious processes
ps aux | grep -i "ddos\|lua"
Check for unauthorized changes
# Compare with AIDE database
sudo aide --check
# Look for recently modified files
find /usr/local/vesta -type f -mtime -7 -ls
# Check for new users
cat /etc/passwd | grep -v nologin | grep -v false
# Check cron jobs for malicious entries
crontab -l
ls -la /etc/cron.d/
Review database for unauthorized access
SELECT * FROM mysql.user WHERE Host != 'localhost';
SHOW PROCESSLIST;
Check for DDoS activity
# Check network connections
netstat -anp | grep ESTABLISHED | grep -v "127.0.0.1"
# Check for unusual outbound traffic
iftop -P -n
# Check iptables logs
grep "DROPPED" /var/log/syslog | tail -50
Change all credentials - Admin passwords, database passwords, API keys, FTP accounts
Scan for malware
sudo apt install clamav clamav-daemon
sudo freshclam
sudo clamscan -r /usr/local/vesta --move=/home/quarantine
Consider full rebuild - Given VestaCP’s vulnerability history and discontinued status, a clean migration to a modern panel is strongly recommended
Notify affected users - If customer data was exposed
Recommended modern alternatives:
| Panel | License | Active Development | Notes |
|---|---|---|---|
| HestiaCP | GPL v3 | ✅ Yes | VestaCP fork, actively maintained |
| CyberPanel | GPL v3 | ✅ Yes | OpenLiteSpeed, WordPress-focused |
| DirectAdmin | Commercial | ✅ Yes | Mature, commercial support |
| Plesk | Commercial | ✅ Yes | Enterprise features |
Migration planning: