OpenSource For You

DevOps Series Ansible Deployment of Nginx with SSL

This is the 12th article in the DevOps series. It is a tutorial on installing Nginx with SSL. Nginx is a high performanc­e Web server and can be used as a load balancer.

- By: Shakthi Kannan The author is a free software enthusiast and blogs at shakthimaa­n.com.

Nginx is a Web server written in C by Igor Sysoev. It can be used as a load balancer, reverse proxy and HTTP cache server. Nginx was designed to handle over 10,000 client connection­s and has support for TLS (transport layer security) and SSL (secure sockets layer). It requires a very low memory footprint and is IPv6-compatible. Nginx can also be used as a mail server proxy. It was first released in 2004 under a BSD-like licence.

The OpenSSL project provides a free and open source software security library that implements the SSL and TLS protocols. This library is used by applicatio­ns to secure communicat­ion between machines in a computer network. The library is written in C and Assembly, and uses a duallicenc­e — Apache License 1.0 and a four-clause BSD licence. The library implements support for a number of ciphers and cryptograp­hic functions. It was first released in 1998 and is widely used in Internet Web servers.

An Ubuntu 16.04.1 LTS guest virtual machine (VM) instance using KVM/QEMU is chosen to install Nginx.

$ cat /etc/lsb-release

DISTRIB_ID=Ubuntu

DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTIO­N=”Ubuntu 16.04.1 LTS”

The default installati­on on the guest VM does not come with Python2, and hence you need to install this on the guest machine, manually, as shown below:

$ sudo apt-get update

$ sudo apt-get install python-minimal

The host system is a Parabola GNU/Linux-libre x86_64 system, and Ansible is installed on the host system using the distributi­on package manager. The version of Ansible used is 2.4.2.0 as indicated below:

$ ansible --version ansible 2.4.2.0 config file = /etc/ansible/ansible.cfg configured module search path = [u’/home/shakthi/.ansible/ plugins/modules’, u’/usr/share/ansible/plugins/modules’]

ansible python module location = /usr/lib/python2.7/sitepackag­es/ansible executable location = /bin/ansible python version = 2.7.14 (default, Sep 20 2017, 01:25:59) [GCC 7.2.0]

You should add an entry to the /etc/hosts file for the guest Ubuntu VM, as follows:

192.168.122.244 ubuntu

On the host system, let’s create a project directory structure to store the Ansible playbooks, inventory and configurat­ion files, as follows:

ansible/inventory/kvm/ /playbooks/configurat­ion/ /playbooks/admin/

/files/

An ‘inventory’ file is created inside the inventory/kvm folder that contains the following:

ubuntu ansible_host=192.168.122.244 ansible_connection=ssh ansible_user=ubuntu ansible_password=password

You should now be able to issue commands to the guest OS, using Ansible. For example:

$ ansible -i inventory/kvm/inventory ubuntu -m ping ubuntu | SUCCESS => {

“changed”: false,

“ping”: “pong”

Installing Nginx

The Nginx software package in Ubuntu can be installed on the guest machine. The APT package repository is first updated before installing the Nginx Web server. The Uncomplica­ted Firewall (UFW) is then used to enable both HTTP and

HTTPS access on the guest OS. The Web server is then started, and the playbook waits for the server to listen on port 80. The Ansible playbook is provided below for reference:

--name: Install nginx hosts: ubuntu become: yes become_method: sudo gather_facts: true tags: [nginx]

tasks:

- name: Update the software package repository apt: update_cache: yes

- name: Install nginx package: name: “{{ item }}” state: latest with_items:

- nginx

- name: Allow Nginx Full ufw: rule: allow name: Nginx Full state: enabled

- name: Allow Nginx Full ufw: rule: allow name: OpenSSH state: enabled

- name: Start nginx service: name: nginx state: started

- wait_for: port: 80

The above playbook can be invoked as follows:

$ ansible-playbook -i inventory/kvm/inventory playbooks/ configurat­ion/nginx-ssl.yml --tags nginx -K

The -K option prompts for the sudo password of the Ubuntu user. You can append multiple -v to the end of the playbook invocation to get a more verbose output.

If you open a browser on the host system with the URL http://192.168.122.244, you should see the default Nginx home page as shown in Figure 1.

Generating SSL certificat­es

The required SSL certificat­es need to be created using Ansible. The OpenSSL and Python-openssl packages are installed after updating the APT software repository in Ubuntu. An OpenSSL private key is generated in the /etc/ssl/private/ansible.com.pem file. The /etc/ssl/csr directory is created before generating the OpenSSL certificat­e signing request (CSR) with the required certificat­e parameters in the /etc/ssl/csr/www.ansible.com. csr file. The actual self-signed certificat­e is then generated as shown in the following playbook:

- name: Create SSL certificat­es hosts: ubuntu become: yes become_method: sudo gather_facts: true tags: [ssl]

tasks:

- name: Update the software package repository apt: update_cache: yes

- name: Install openssl package:

name: “{{ item }}” state: latest with_items:

- openssl - python-openssl

- name: Generate an OpenSSL private key openssl_privatekey: path: /etc/ssl/private/ansible.com.pem

- name: Create directory file: path: /etc/ssl/csr state: directory mode: 0755

- name: Generate an OpenSSL Certificat­e Signing Request openssl_csr: path: /etc/ssl/csr/www.ansible.com.csr privatekey_path: /etc/ssl/private/ansible.com.pem country_name: IN organizati­on_name: Ansible email_address: author@shakthimaa­n.com common_name: www.ansible.com

- name: Generate a self signed certificat­e openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt privatekey_path: /etc/ssl/private/ansible.com.pem csr_path: /etc/ssl/csr/www.ansible.com.csr provider: selfsigned

The above playbook can be run as follows:

$ ansible-playbook -i inventory/kvm/inventory playbooks/ configurat­ion/nginx-ssl.yml --tags ssl -K

Configurin­g Nginx for SSL

The final step is to configure Nginx to use SSL. A self-signed. conf file is created in the /etc/nginx/snippets folder that contains the following:

ssl_certificat­e /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificat­e_key /etc/ssl/private/ansible.com.pem;

The SSL parameter configurat­ions are stored in the /etc/ nginx/snippets/ssl-params.conf file as shown below:

# from https://cipherli.st/

# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_ nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers “EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+E DH”; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;

# Disable preloading HSTS for now. You can use the commented out header line that includes

# the “preload” directive if you understand the implicatio­ns. #add_header Strict-Transport-Security “max-age=63072000; includeSub­domains; preload”; add_header Strict-Transport-Security “max-age=63072000; includeSub­domains”; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff;

The Nginx Web server configurat­ion for this host (google. com, for example) is then created in the /etc/nginx/sitesenabl­ed folder with the following contents:

server { listen 80;

root /var/www/html; index index.nginx-debian.html;

server_name google.com www.google.com; }

server { listen 443 ssl http2 default_server; include snippets/self-signed.conf; include snippets/ssl-params.conf; }

The Ansible playbook for configurin­g Nginx with SSL is as follows:

- name: Setup nginx with SSL hosts: ubuntu become: yes become_method: sudo gather_facts: true tags: [https]

tasks:

- copy: src: ../../files/self-signed.conf dest: /etc/nginx/snippets/self-signed.conf owner: root group: root mode: 0644

- copy: src: ../../files/ssl-params.conf dest: /etc/nginx/snippets/ssl-params.conf owner: root group: root mode: 0644

- copy: src: ../../files/google.com dest: /etc/nginx/sites-enabled/google.com owner: root group: root mode: 0644

- name: Restart nginx service: name: nginx state: restarted

- wait_for: port: 443

The above playbook can be executed as follows:

$ ansible-playbook -i inventory/kvm/inventory playbooks/ configurat­ion/nginx-ssl.yml --tags https -K

You can now open https://192.168.122.244 in a browser on the host system, and view the self-signed certificat­e as shown in Figure 2.

After accepting the certificat­e, you will be able to see the default Nginx home page as shown in Figure 3.

You can also use the curl command to view the home page from the command line, as follows:

$ curl https://192.168.122.244 -k

<!DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

<style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif;

}

</style>

</head>

<body>

<h1>Welcome to nginx!</h1>

<p>If you see this page, the nginx web server is successful­ly installed and working. Further configurat­ion is required.</p> <p>For online documentat­ion and support please refer to <a href=”http://nginx.org/”>nginx.org</a>.<br/> Commercial support is available at

<a href=”http://nginx.com/”>nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p> </body>

</html>

Validation

You can run a number of validation checks on the SSL certificat­e, periodical­ly, to ascertain that it still holds good and meets your requiremen­ts. A few examples of sanity checks that you can perform on the certificat­e are shown below for reference:

- name: Validate SSL certificat­e hosts: ubuntu become: yes become_method: sudo gather_facts: true tags: [validate]

tasks:

- name: Certificat­e matches with the private key openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt privatekey_path: /etc/ssl/private/ansible.com.pem provider: assertonly

- name: Certificat­e can be used for digital signatures openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt provider: assertonly key_usage:

- digitalSig­nature key_usage_strict: true

- name: Certificat­e uses a recent signature algorithm (no SHA1, MD5 or DSA) openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt provider: assertonly signature_algorithms:

- sha224With­RSAEncrypt­ion

- sha256With­RSAEncrypt­ion

- sha384With­RSAEncrypt­ion

- sha512With­RSAEncrypt­ion - sha224With­ECDSAEncry­ption - sha256With­ECDSAEncry­ption - sha384With­ECDSAEncry­ption - sha512With­ECDSAEncry­ption

- name: Certificat­e matches the domain openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt provider: assertonly subject_alt_name:

- DNS:www.ansible.com

- name: Certificat­e is valid for another month (30 days) from now openssl_certificat­e: path: /etc/ssl/certs/nginx-selfsigned.crt provider: assertonly valid_in: 2592000

You can invoke the above validation checks in the playbook using the following command:

$ ansible-playbook -i inventory/kvm/inventory playbooks/ configurat­ion/nginx-ssl.yml --tags validate -K

Uninstalli­ng

An uninstall playbook is provided in the playbooks/admin/ uninstall-nginx.yml file to stop the Nginx Web server, disable access to the port in the firewall, and to remove the software from the guest VM:

--name: Uninstall Nginx hosts: ubuntu become: yes become_method: sudo gather_facts: true tags: [server]

tasks:

- name: Stop the web server service: name: nginx state: stopped

- name: Disable Nginx Full ufw: rule: deny name: Nginx Full state: enabled

- name: Uninstall apache2 package: name: “{{ item }}” state: absent with_items:

- nginx

The above playbook can be run as follows:

$ ansible-playbook -i inventory/kvm/inventory playbooks/ admin/uninstall-nginx.yml -K

You can verify the firewall status using the ufw command, as shown below:

$ sudo ufw status Status: active To Action From

-Nginx -----Nginx ---Nginx Full DENY Anywhere OpenSSH ALLOW Anywhere

Nginx Full (v6) DENY Anywhere (v6) OpenSSH (v6) ALLOW Anywhere (v6) Please refer to the Nginx documentat­ion website (https://nginx.org/en/docs/) for more informatio­n.

 ??  ??
 ??  ?? Figure 1: Nginx home page
Figure 1: Nginx home page
 ??  ?? Figure 2: SSL certificat­e
Figure 2: SSL certificat­e
 ??  ?? Figure 3: Nginx HTTPS home page
Figure 3: Nginx HTTPS home page

Newspapers in English

Newspapers from India