Jenkins has always been a bit of an elephant in the room to me. Not being a developer I have always just shrugged it off a tool used for running unit tests, however, as I moving more into orchestration and automation I am finding the need for a tool which can run both tasks and unit tests, so this weekend I decided to finally take the plunge and have a play around with it.
As always I started off with a blank CentOS 7 server hosted in Digital and ran my bootstrap script to get the basics sorted.
Once I had that in order I grabbed the repo file for the Jenkins RPM repository and installed the package along with Java and NGINX;
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm — import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install nginx httpd-tools java-1.7.0-openjdk jenkins
As there is only going to be me using this installation I decided that I would use NGINX to provide both the SSL termination and also the password protection for the installation.
I started by creating the password file for NGINX to use;
htpasswd -c /etc/nginx/.htpasswd my_username
The NGINX config file which was called /etc/nginx/conf.d/jenkins.conf looks like this;
server {
listen 80;
server_name jenkins.super-awesome-domain.io;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name jenkins.super-awesome-domain.io;
ssl_certificate /etc/letsencrypt/live/jenkins.super-awesome-domain.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jenkins.super-awesome-domain.io/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins.access.log;
location / {
auth_basic “Restricted”;
auth_basic_user_file /etc/nginx/.htpasswd;
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_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://jenkins.super-awesome-domain.io;
}
}
As you have noticed I got the certificate from the incredibly awesome LetEncrypt . As the domain I was using was already resolving to the server getting the certificate was a simple as running the following commands and then following the on screen prompts;
cd /root/
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt/
./letsencrypt-auto certonly
As I wasn’t going to directly expose Jenkins to the world, I configured it to listen on localhost, that way we don’t have a Java service bond directly publicly available NIC. To do this run the following command;
echo ‘JENKINS_ARGS=” — webroot=/var/cache/jenkins/war — httpListenAddress=127.0.0.1 — httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT’ > /etc/default/jenkins
Finally, it’s time to enable the firewall, by default Firewalld has the ssh port (22) configured. As the bootstrap script installed Fail2Ban, and also password enabled login is disabled on the instance so I am happy to keep the port open. So we just need to enable ports 80 & 443;
systemctl enable firewalld && systemctl restart firewalld
firewall-cmd — zone=public — add-port=80/tcp — permanent
firewall-cmd — zone=public — add-port=443/tcp — permanent
firewall-cmd — reload
Finally, its time to enable and start the rest of the services;
systemctl enable jenkins.service && systemctl restart jenkins.service
systemctl enable nginx.service && systemctl restart nginx
If everything went as planned you should be able to access Jenkins at the domain name you configured in the NGINX configuration.
Once I had access to the GUI I configured Jenkins to deploy this blog whenever it detects a change at the repo . I won’t go into to the details here as there are both AWS access keys and Cloudflare API keys involved in the configuration, and knowing my luck I would end up getting hacked because I exposed them.