How to configure Jenkins with SSL and Nginx reverse proxy

Introduction

By default, Jenkins comes with its own built-in Winstone web server that listens on port 8080, which is great for getting started. Once you get serious about using Jenkins, you need to secure it with SSL to protect passwords and other sensitive data transmitted over the web interface.

In this article, we will show you how to set up Nginx as a reverse proxy to route requests from Jenkins clients. In order to get started, you need to fulfill each of the conditions below.

Terms

One Ubuntu 16.04 server configured with foliar sudo user and firewall by following the tutorial on initial server setup on Ubuntu 16.04 with Jenkins and Nginx installed as in the article.

  • Install Jenkins on Ubuntu 16.04
  • Install Nginx on Ubuntu 16.04
  • Provide Nginx with Let’s Encrypt on Ubuntu 16.04. Please note that this tutorial requires a registered domain name that you own or control.

When you have met these requirements, you are ready to start.

Step One – Configuring Nginx

In the prerequisites of the article How to Secure Nginx with Encrypt Come on Ubuntu 16.04, we configured Nginx to use SSL on a file /etc/nginx/sites-available/defaultso we’ll open that file to add our reverse proxy settings.

sudo nano /etc/nginx/sites-available/default

First, we will add specific access and error logs to the block server with SSL config options:

/ etc / nginx / sites-available / default

. . . 
server {
        # SSL Configuration
        #
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        access_log            /var/log/nginx/jenkins.access.log;
        error_log            /var/log/nginx/jenkins.error.log;

Then we will configure the proxy settings. Since we are sending all requests to Jenkins, we comment out the default line try_fileswhich, as written, will return a 404 error before the request reaches Jenkins.

/ etc / nginx / sites-available / default

 . . .
           location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                # try_files $uri $uri/ =404;        }
. . .

Then we’ll add the actual proxy settings. Configuration starts in Nginx with installation proxy_params which provide information such as hostname, client request protocol, and client IP address, which will be available in our log file. Further, proxy_pass sets the protocol and address of the proxied server, which in our case is the Jenkins server, which is accessible to the local host on port 8080. Then we increase proxy_read_timeout  from 60 by default in Nginx to the recommended value of 90. Finally, we will add proxy_redirect to ensure that the appropriate hostname is included.

Make sure to replace your SSL protected domain name with proxy_redirectas in the line below:

/ etc / nginx / sites-available / default

Location /  
. . .
           location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                # try_files $uri $uri/ =404;
                include /etc/nginx/proxy_params;
                proxy_pass          http://localhost:8080;
                proxy_read_timeout  90s;
                # Fix potential "It appears that your reverse proxy set up is broken" error.
                proxy_redirect      http://localhost:8080 https://your.ssl.domain.name;

After you have made these changes, save and close the file. We are not going to restart Nginx until we have Jenkins configured, but we will test our configuration:

sudo nginx -t

If all is well, the command returns:

Output

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If not, then fix any errors found until the test passes.

Note:
If you install incorrectly proxy_pass(add a slash for example), you will get something similar to the following on the Jenkins Configuration page.

If you see this error, check your settings proxy_pass and proxy_redirect in Nginx config.

Step Two – Configuring Jenkins

Jenkins to work with Nginx, you need to update Jenkins configuration so that Jenkins server only listens to the interface localhost, not all interfaces ( 0.0.0.0). If Jenkins is listening on all interfaces, then this is potentially available on an unencrypted port ( 8080).

We will change the config file /etc/default/jenkinsto make these changes.

sudo nano /etc/default/jenkins

Find the line JENKINS_ARGS and add --httpListenAddress=127.0.0.1 to existing arguments:

/ etc / default / jenkins

. . .
JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT --httpListenAddress=127.0.0.1"

Save and close the file.

To use the new configuration options, we will restart Jenkins and Nginx.

sudo systemctl restart jenkins

Because systemctl does not display the output, we will check the status:

sudo systemctl status jenkins

We must see the status active (exited) in line Active:

Output

● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; bad; vendor preset: enabled)
   Active: active (exited) since Tue 2017-04-25 22:37:29 UTC; 5s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 11360 ExecStop=/etc/init.d/jenkins stop (code=exited, status=0/SUCCESS)
  Process: 11391 ExecStart=/etc/init.d/jenkins start (code=exited, status=0/SUCCESS)

We will repeat these steps for Nginx:

sudo systemctl restart nginx

sudo systemctl status nginx

Output

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-04-25 22:36:08 UTC; 2min 51s ago
  Process: 11339 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=
  Process: 11349 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 11345 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUC
 Main PID: 11353 (nginx)

Now that we restart both servers, we should be able to visit the domain using either HTTP or HTTPS. HTTP requests will be automatically redirected to HTTPS and the Jenkins site will be served reliably.

Step Three – Testing the Configuration

We will test the configuration by resetting the admin password when we have enabled encryption. We’ll start by visiting the site with http to make sure we go to Jenkins and redirect to https, as we expected:

In your web browser, enter “HTTP: // your.ssl.domain.name” substituting your domain for your.ssl.domain.name… After pressing enter, the URL should start with https and a green padlock will indicate that the connection is secure.

Make sure Jenkins is served over HTTPS

We will enter admin in the “User” field and automatically generate a password, Jenkins will create and store it when we set it.

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

If you want to reset the password for a user with administrator rights, enter that password instead. Either way, as soon as we log in, we will change the password to make sure it’s safe.

Go to Jenkins password admin page

Click the “admin” button in the upper right corner and select “Settings” from the drop down menu. Enter and confirm the new password and click the “Save” button. You can now use Jenkins web interface reliably.

Output

In this tutorial, after doing the pre-installation, we configured Nginx as a reverse proxy for the Jenkins embedded web server in order to protect our web traffic. If you are new to Jenkins you can start with the tutorial “Getting Started with Jenkins: Create Your First Pipeline

Sidebar