Skip to content

About VestaCP

VestaControlPanel is a solution to manage a VPS or a Dedicated server with and provide HWP (Hosting Web Panel) feature.

You can manage an unlimited number of users and host.

Features :

  • Web Hosting
  • DataBase management
  • Email management
  • DNS management
  • Monitoring server
  • Services manager (cron, firewall, fail2ban, postfix, apache, nginx, dovecot,... and many more...)
  • Automated backup
  • Customer/user template

Installation

Just follow the step on official website to install VestaCP. It is very quick !

Warning

At first, create a new user for your futur deployement. In the case where you must migrate to other server you win a lot of time.

Work with other profile than "admin" created by process installation.

Backup & Restore

Two solution to backup data and settings before to move on other server.

You can manually backup /backup folder on your old server and transfert on your new server.

To restore the archive on your new server

v-restore-user user_name user_name-20XXXXXXXX.tar.gz

Nginx tweaks

Warning

We have installed VestaCP, where our choice for the http webserver is nginx and PHP support's given by php-fpm. It's important to know because it's the principal reason of these modifications. Keep in mind For every web solution we have already installed we have a different vhost.conf.

How to fix ssl certif for the panel

Unfortunately, when you installed VestaCP and setup an SSL certificate via LetsEncrypt though the VestaCP admin panel, the certificate was not installed into the VestaCP web interface (admin panel). This meant that whenever you tried to access the VestaCP admin panel, It was presented with SSL error.

This error was present because the SSL certificate generated by VestaCP and LetsEcnrypt was not installed in the VestaVP admin panel. Instead, it was only installed on the web domain.

The origin of the problem thats vesta use two different certificates. One for the web part and the other for his control panel running under port 8083.

We have several solutions to fix this. One of the fastest and reliable is the use of symbolic links. Let's do that !

cd /usr/local/vesta/ssl
mv certificate.crt certificate.crt_old
mv certificate.key certificate.key_old
ln -s /home/admin/conf/web/ssl.[your server domain].key /usr/local/vesta/ssl/certificate.key
ln -s /home/admin/conf/web/ssl.[your server domain].crt /usr/local/vesta/ssl/certificate.crt
sudo service vesta restart

Enforce HTTPS

Under VestaCP if we want enforce HTTPS for our virtual host we must edit two files.

  • /home/$VESTA_USERNAME/conf/web/your.hostname.com.conf
  • /home/$VESTA_USERNAME/conf/web/your.hostname.com.ssl.conf

First step we open your.hostname.com.conf, it should like this =>

server {
    listen      188.156.195.195:80;
    server_name your.domain.com ;
    root        /home/probeteam/web/your.domain.com/public_html;
    index       index.php index.html index.htm;
    access_log  /var/log/nginx/domains/your.domain.com.log combined;
    access_log  /var/log/nginx/domains/your.domain.com.bytes bytes;
    error_log   /var/log/nginx/domains/your.domain.com.error.log error;

    location / {
        location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|css|js)$ {
            expires     max;
        }

        location ~ [^/]\.php(/|$) {
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if (!-f $document_root$fastcgi_script_name) {
                return  404;
            }

            fastcgi_pass    127.0.0.1:9005;
            fastcgi_index   index.php;
            include         /etc/nginx/fastcgi_params;
        }
    }

    error_page  403 /error/404.html;
    error_page  404 /error/404.html;
    error_page  500 502 503 504 /error/50x.html;

    location /error/ {
        alias   /home/probeteam/web/your.domain.com/document_errors/;
    }

    location ~* "/\.(htaccess|htpasswd)$" {
        deny    all;
        return  404;
    }

    location /vstats/ {
        alias   /home/probeteam/web/your.domain.com/stats/;
        include /home/probeteam/conf/web/your.domain.com.auth*;
    }

    include     /etc/nginx/conf.d/phpmyadmin.inc*;
    include     /etc/nginx/conf.d/phppgadmin.inc*;
    include     /etc/nginx/conf.d/webmail.inc*;

    include     /home/probeteam/conf/web/nginx.your.domain.com.conf*;
}

And we edit like that

server {
    listen      188.156.195.195:80;
    server_name your.domain.com ;
    root        /home/probeteam/web/your.domain.com/public_html;
    index       index.php index.html index.htm;
    access_log  /var/log/nginx/domains/your.domain.com.log combined;
    access_log  /var/log/nginx/domains/your.domain.com.bytes bytes;
    error_log   /var/log/nginx/domains/your.domain.com.error.log error;

    location / {
        return 301 https://$server_name$request_uri;
    }

    error_page  403 /error/404.html;
    error_page  404 /error/404.html;
    error_page  500 502 503 504 /error/50x.html;

    location /error/ {
        alias   /home/probeteam/web/your.domain.com/document_errors/;
    }

    location ~* "/\.(htaccess|htpasswd)$" {
        deny    all;
        return  404;
    }

    location /vstats/ {
        alias   /home/probeteam/web/your.domain.com/stats/;
        include /home/probeteam/conf/web/your.domain.com.auth*;
    }

    include     /etc/nginx/conf.d/phpmyadmin.inc*;
    include     /etc/nginx/conf.d/phppgadmin.inc*;
    include     /etc/nginx/conf.d/webmail.inc*;

    include     /home/probeteam/conf/web/nginx.your.domain.com.conf*;
}

Improve SSL/TLS security

To increase the security level of your SSL / TLS certificates under vesta you will need to make changes.

Vesta has its own creation scheme and its own configuration files. You will find them in details here.

Take care these settings are specific to the behavior of VestaCP.

First, we will modify nginx.conf

vim /etc/nginx/nginx.conf

Like that (writed 29/10/2018)

# Server globals
user                    www-data;
worker_processes        auto;
worker_rlimit_nofile    65535;
timer_resolution         50ms; #In order to free some CPU cycles
error_log               /var/log/nginx/error.log crit;
pid                     /var/run/nginx.pid;

# Worker config
events {
        worker_connections  1024;
        use                 epoll;
        multi_accept        on;
}

http {
    # Main settings
    sendfile                        on;
    tcp_nopush                      on;
    tcp_nodelay                     on;
    client_header_timeout           1m;
    client_body_timeout             1m;
    client_header_buffer_size       2k;
    client_body_buffer_size         256k;
    client_max_body_size            256m;
    large_client_header_buffers     4   8k;
    send_timeout                    30;
    keepalive_timeout               60 60;
    reset_timedout_connection       on;
    server_tokens                   off;
    server_name_in_redirect         off;
    server_names_hash_max_size      512;
    server_names_hash_bucket_size   512;

    # Log format
    log_format  main    '$remote_addr - $remote_user [$time_local] $request '
                        '"$status" $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  bytes   '$body_bytes_sent';
    #access_log          /var/log/nginx/access.log main;
    access_log off;

    # Mime settings
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Compression
    gzip                on;
    gzip_comp_level     9;
    gzip_min_length     512;
    gzip_buffers        8 64k;
    gzip_types          text/plain text/css text/javascript text/js text/xml application/json application/javascript application/x-javascript application/xml application/xml+rss application/x-font-ttf image/svg+xml font/opentype;
    gzip_proxied        any;
    gzip_disable        "MSIE [1-6]\.";

    # Proxy settings
    proxy_redirect      off;
    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass_header   Set-Cookie;
    proxy_connect_timeout   90;
    proxy_send_timeout  90;
    proxy_read_timeout  90;
    proxy_buffers       32 4k;

    # Cloudflare https://www.cloudflare.com/ips
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 104.16.0.0/12;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 2400:cb00::/32;
    set_real_ip_from 2606:4700::/32;
    set_real_ip_from 2803:f800::/32;
    set_real_ip_from 2405:b500::/32;
    set_real_ip_from 2405:8100::/32;
    set_real_ip_from 2c0f:f248::/32;
    set_real_ip_from 2a06:98c0::/29;
    real_ip_header     CF-Connecting-IP;

    # SSL PCI Compliance
   ssl_protocols TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
   ssl_dhparam /etc/nginx/dhparam.pem;
   ssl_session_timeout 10m;
   ssl_session_cache shared:SSL:10m;
   ssl_session_tickets off;
   ssl_stapling on;
   ssl_stapling_verify on;
   resolver 1.1.1.1 1.0.0.1;
   resolver_timeout 5s;
   add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    #ssl_ciphers        "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

    # Error pages
    error_page          403          /error/403.html;
    error_page          404          /error/404.html;
    error_page          502 503 504  /error/50x.html;

    # Cache settings
    proxy_cache_path /var/cache/nginx levels=2 keys_zone=cache:10m inactive=60m max_size=1024m;
    proxy_cache_key "$host$request_uri $cookie_user";
    proxy_temp_path  /var/cache/nginx/temp;
    proxy_ignore_headers Expires Cache-Control;
    proxy_cache_use_stale error timeout invalid_header http_502;
    proxy_cache_valid any 1d;

    # Cache bypass
    map $http_cookie $no_cache {
        default 0;
        ~SESS 1;
        ~wordpress_logged_in 1;
    }

    # File cache settings
    open_file_cache          max=10000 inactive=30s;
    open_file_cache_valid    60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors   off;

    # Wildcard include
    include             /etc/nginx/conf.d/*.conf;
}

Now we must add an other param at our vhost.conf located under /home/$USER_VESTA/conf/web.

# add it just after ssl_certificate_key in **server {** bloc code
ssl_trusted_certificate /home/$VESTA_USER/conf/web/ssl.your.domain.tld.crt;

osTicket POP Fix

Out of the box we can't use our installation of osTicket. The popup on the website stay white whitout any text inside.

This behavior is due to the vhost template creation of VestaCP. To fix that we have modify and adapt the vhost.conf.

server {
    listen      188.156.195.195:443 ssl http2;
    server_name your.domain.com ;
    root        /home/probeteam/web/your.domain.com/public_html;
    index       index.php index.html index.htm;
    access_log  /var/log/nginx/domains/your.domain.com.log combined;
    access_log  /var/log/nginx/domains/your.domain.com.bytes bytes;
    error_log   /var/log/nginx/domains/your.domain.com.error.log error;

    ssl         on;
    ssl_certificate      /home/probeteam/conf/web/ssl.your.domain.com.pem;
    ssl_certificate_key  /home/probeteam/conf/web/ssl.your.domain.com.key;
    ssl_trusted_certificate /home/probeteam/conf/web/ssl.your.domain.com.crt;

    location / {

        location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|css|js)$ {
            expires     max;
        }

        location ~ [^/]\.php(/|$) {
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if (!-f $document_root$fastcgi_script_name) {
                return  404;
            }

            fastcgi_pass    127.0.0.1:9004;
            fastcgi_index   index.php;
            include         /etc/nginx/fastcgi_params;
        }
    }

    error_page  403 /error/404.html;
    error_page  404 /error/404.html;
    error_page  500 502 503 504 /error/50x.html;

    location /error/ {
        alias   /home/probeteam/web/your.domain.com/document_errors/;
    }

    location ~* "/\.(htaccess|htpasswd)$" {
        deny    all;
        return  404;
    }

    location /vstats/ {
        alias   /home/probeteam/web/your.domain.com/stats/;
        include /home/probeteam/conf/web/your.domain.com.auth*;
    }

    include     /etc/nginx/conf.d/phpmyadmin.inc*;
    include     /etc/nginx/conf.d/phppgadmin.inc*;
    include     /etc/nginx/conf.d/webmail.inc*;

    include     /home/probeteam/conf/web/snginx.your.domain.com.conf*;
}

As beneath

server {
    listen      188.156.195.195:443 ssl http2;
    server_name your.domain.com ;
    root        /home/probeteam/web/your.domain.com/public_html;
    index       index.php index.html index.htm;
    access_log  /var/log/nginx/domains/your.domain.com.log combined;
    access_log  /var/log/nginx/domains/your.domain.com.bytes bytes;
    error_log   /var/log/nginx/domains/your.domain.com.error.log error;

    ssl         on;
    ssl_certificate      /home/probeteam/conf/web/ssl.your.domain.com.pem;
    ssl_certificate_key  /home/probeteam/conf/web/ssl.your.domain.com.key;
    ssl_trusted_certificate /home/probeteam/conf/web/ssl.your.domain.com.crt;

    set $path_info "";

        location ~ /include {
            deny all;
            return 403;
        }

        if ($request_uri ~ "^/api(/[^\?]+)") {
            set $path_info $1;
        }

        location ~ ^/api/(?:tickets|tasks).*$ {
            try_files $uri $uri/ /api/http.php?$query_string;
        }

        if ($request_uri ~ "^/scp/.*\.php(/[^\?]+)") {
            set $path_info $1;
        }

        if ($request_uri ~ "^/.*\.php(/[^\?]+)") {
            set $path_info $1;
        }

        location ~ ^/scp/ajax.php/.*$ {
            try_files $uri $uri/ /scp/ajax.php?$query_string;
        }

        location ~ ^/ajax.php/.*$ {
            try_files $uri $uri/ /ajax.php?$query_string;
        }

    location / {
        try_files $uri $uri/ index.php;



        location ~ [^/]\.php(/|$) {
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            #if (!-f $document_root$fastcgi_script_name) {
            #    return  404;
            #}

            fastcgi_pass    127.0.0.1:9004;
            fastcgi_index   index.php;
            include         /etc/nginx/fastcgi_params;
            fastcgi_param  PATH_INFO        $path_info;
        }
    }

    error_page  403 /error/404.html;
    error_page  404 /error/404.html;
    error_page  500 502 503 504 /error/50x.html;

    location /error/ {
        alias   /home/probeteam/web/your.domain.com/document_errors/;
    }

    location ~* "/\.(htaccess|htpasswd)$" {
        deny    all;
        return  404;
    }

    location /vstats/ {
        alias   /home/probeteam/web/your.domain.com/stats/;
        include /home/probeteam/conf/web/your.domain.com.auth*;
    }

    include     /etc/nginx/conf.d/phpmyadmin.inc*;
    include     /etc/nginx/conf.d/phppgadmin.inc*;
    include     /etc/nginx/conf.d/webmail.inc*;

    include     /home/probeteam/conf/web/snginx.your.domain.com.conf*;
}

Restart nginx and the popup must work now !