Cobbler on CentOS 7 with NGINX and https

cobbler / nginx / linux / centos

Rather than running Cobbler with the default Apache2 installation, below details how to serve Cobbler's WSGI Python services via NGINX's uwsgi_pass. This details the setup on CentOS 7.

Install Cobbler

The latest version of Cobbler can be installed from the EPEL repository on CentOS 7. First, be sure EPEL repos have been enabled, then install Cobbler and its friends. This guide is only focused on getting Cobbler WebUI working behind NGINX— full configuration of Cobbler, dnsmasq, and so on, is outside the scope of the article.

yum -y install epel-release  
yum -y install cobbler cobbler-web dnsmasq pykickstart  

Ensure NGINX is installed

NGINX can be installed from source, or via a package. I typically compile the latest version from git, but it can also be installed from the EPEL repos.

yum -y install nginx  

This setup assumes that NGINX is configured to run as user www-data. If this is not the case, then be sure to modify the uWSGI configuration and Cobbler file ownerships as necessary. Failure to do this will result in the WebUI being unusable. The default Cobbler package in EPEL for CentOS 7 ships with a default owner of apache (all of my other servers use www-data, so I have chosen to change it to match that convention).

Create NGINX config

server {  
    listen 80 default;
    listen [::]:80 default;
    server_name cobbler.example.com _;

    location ~ ^/cblr(?!/svc/)(.*)?$ {
        alias /var/www/cobbler/$1;
    }

    location ~ ^/cobbler_track/(.*)?$ {
        alias /var/www/cobbler/$1;
    }

    location /cobbler {
        alias /var/www/cobbler;
    }

    location /cblr/svc/ {
        include uwsgi_params;
        uwsgi_pass unix:/run/cobbler_svc.sock;
    }

    location /cobbler_api {
        rewrite ^/cobbler_api/?(.*) /$1 break;
        proxy_pass http://127.0.0.1:25151;
    }

    # only force-redirect the web ui
    rewrite ^/$ https://cobbler.example.com/cobbler_web permanent;
    rewrite ^/cobbler_web https://cobbler.example.com$request_uri? permanent;
}

server {  
    # NOTE: remove 'http2' if using nginx < 1.9
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl on;
    ssl_certificate /path/to/your/cert.pem;
    ssl_certificate_key /path/to/your/private.key;

    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_buffer_size 8k; 

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # NOTE: remove or adjust this line as needed,
    # if you're using custom DH params
    # (more info: https://weakdh.org/sysadmin.html)
    ssl_dhparam /etc/ssl/private/dhparams.pem;

    server_name cobbler.example.com;

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

    location /cobbler_webui_content {
        alias /var/www/cobbler_webui_content;
    }

    location ~ ^/cblr(?!/svc/)(.*)?$ {
        alias /var/www/cobbler/$1;
    }

    location /cblr/svc/ {
        include uwsgi_params;
        uwsgi_pass unix:/run/cobbler_svc.sock;
    }

    location /cobbler {
        alias /var/www/cobbler;
    }

    location /cobbler_web {
        rewrite ^/cobbler_web/?(.*) /$1 break;
        include uwsgi_params;
        uwsgi_pass unix:/run/cobbler_web.sock;        
    }

    # redirect requests for / to the Web UI
    rewrite ^/$ https://cobbler.example.com/cobbler_web permanent;
}

Once NGINX has been configured, test the configuration to be sure there are no issues:

nginx -t  

If all is well, reload (or restart) NGINX to pull in the new config.

systemctl reload nginx  

uWSGI Install & Config

Install latest uWSGI via pip, then create a directory for our config files.

yum -y install python-devel python-pip  
pip install uwsgi  
mkdir /etc/uwsgi  

Create the first config file at /etc/uwsgi/cobbler_web.ini

[uwsgi]
wsgi-file = /usr/share/cobbler/web/cobbler.wsgi

master = true  
processes = 2  
max-requests = 5000

socket = /run/cobbler_web.sock  
chmod-socket = 660  
chown-socket = www-data:www-data  
uid = www-data  
gid = www-data  
vacuum = true

die-on-term = true  

And the second config file at /etc/uwsgi/cobbler_svc.ini

[uwsgi]
wsgi-file = /var/www/cobbler/svc/services.py

master = true  
processes = 2  
max-requests = 5000

socket = /run/cobbler_svc.sock  
chmod-socket = 666  
chown-socket = www-data:www-data  
uid = www-data  
gid = www-data  
vacuum = true

die-on-term = true  

Fault 1: ... 'login failed'

If Nginx is running as www-data, you will likely receive the following error message:

Fault 1: "<class 'cobbler.cexceptions.CX'>:'login failed'"  

Fix ownership of the web.ss auth file and webui_sessions. Failure to do this will result in a 500 error with the above error message.

chown www-data.www-data /var/lib/cobbler/web.ss  
chown www-data.www-data /var/lib/cobbler/webui_sessions  

After this is done, you need to fix the issue permanently with one of the following fixes:

  • Open /usr/lib/systemd/system/cobblerd.service and add the following line:
ExecStartPost=/bin/bash -c "/bin/sleep 5 ; /bin/chown www-data.www-data /var/lib/cobbler/web.ss"  

Then reload systemd configuration: systemctl daemon-reload

  • Alternatively, open /usr/lib/python2.7/site-packages/cobbler/cobblerd.py, find the line reading http_user = "apache" (line 65 in my version of cobblerd.py), and change it to http_user = "www-data". This may not be a good solution, as your changes may get overwritten during updates.

Service Setup

Next, we need to create systemd manifests.

Create /lib/systemd/system/cobbler-web.service and add the following:

[Unit]
Description=uWSGI instance for Cobbler WebUI  
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
ExecStart=/usr/bin/uwsgi /etc/uwsgi/cobbler_web.ini  
ExecStopPost=/usr/bin/rm /run/cobbler_web.sock

[Install]
WantedBy=multi-user.target  

Create /lib/systemd/system/cobbler-svc.service and add the following:

[Unit]
Description=uWSGI instance for Cobbler Service  
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
ExecStart=/usr/bin/uwsgi /etc/uwsgi/cobbler_svc.ini  
ExecStopPost=/usr/bin/rm /run/cobbler_svc.sock

[Install]
WantedBy=multi-user.target  

Then, perform a daemon-reload and enable & start the services

systemctl daemon-reload  
systemctl enable cobbler-web  
systemctl enable cobbler-svc  
systemctl start cobbler-web  
systemctl start cobbler-svc  

After starting the services, visit https://cobbler.example.com/cobbler_web and enter your credentials to login (or cobbler/Cobbler if you haven't configured authentication yet).

Good luck ^_^

Share on : Twitter, Facebook or Google+