Reading Time: 2 minutes

DigitalOcean Zabbix (SSL) with NGINX and Certbot

The default Zabbix image from DigitalOcean installs Zabbix on CentOS without an SSL. This tutorial will show you how to set up an SSL using Let’s Encrypt Certbot. I expect that you are comfortable in Vim and general Linux administration.

Install Vim

yum -y update
yum install vim

Install Let’s Encrypt Certbot

yum -y install epel-release
yum -y install yum-utils
yum -y install certbot

Modify NGINX Config for Certbot

This will be needed to be added to the server block in the NGINX config. This file is located at: /etc/nginx/conf.d/zabbix.conf

location ^~ /.well-known/ {
    alias /usr/share/nginx/html/.well-known/;
}

Set Up Certbot SSL

There are many ways to run Certbot but in this example we will use the webroot plugin to validate ownership of the web server using the http method.

certbot certonly --webroot -w /usr/share/nginx/html -d zabbix.redomadigital.org --email youremail@gmail.com --agree-tos

NGINX Config for SSL

It’s probably going to be easier to modify the server block for http (80) and convert that to the http 443 server block than to copy and move things around. The next set of instructions will be to force SSL using the http (80) server block configuration.

server {
    listen 443 ssl;
    server_name zabbix.redomadigital.org;
    index index.php;

    ssl_certificate      /etc/letsencrypt/live/zabbix.redomadigital.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/zabbix.redomadigital.org/privkey.pem;

    access_log /var/log/nginx/ssl_zabbix.access.log;
    error_log  /var/log/nginx/ssl_zabbix.error.log;

    set $webroot '/usr/share/zabbix';

    root $webroot;

    large_client_header_buffers 8 8k;
    client_max_body_size 10M;


    location = /favicon.ico {
        log_not_found off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    
    # certbot validation
    location ^~ /.well-known/ {
        autoindex on;
        alias /usr/share/nginx/html/.well-known/;
    }

    # deny running scripts inside writable directories
    location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
        return 403;
        error_page 403 /403_error.html;
    }

    # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # caching of files
    location ~* \.(ico|pdf|flv)$ {
        expires 1y;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
        expires 14d;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;

        fastcgi_param  SCRIPT_FILENAME  $webroot$fastcgi_script_name;

        include fastcgi_params;
        fastcgi_param  QUERY_STRING     $query_string;
        fastcgi_param  REQUEST_METHOD   $request_method;
        fastcgi_param  CONTENT_TYPE     $content_type;
        fastcgi_param  CONTENT_LENGTH   $content_length;
        fastcgi_intercept_errors        on;
        fastcgi_ignore_client_abort     off;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }
}

NGINX Server Block for SSL

server {
    listen          80;
    server_name     zabbix;

    # certbot validation
    location ^~ /.well-known/ {
        alias /usr/share/nginx/html/.well-known/;
    }

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

Auto Renewal for SSL

// TODO

Allow 443 Through Firewall

After everything is set up it still won’t work. We need to allow HTTPS (TCP 443) through the firewall of CentOS.

You can check and see what is blocked and allowed by using this command.

firewall-cmd --list-all

firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all

Finally!

Hope this helps!