> For the complete documentation index, see [llms.txt](https://newdocs.keeper.io/kcm-linux-rpm-method/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://newdocs.keeper.io/kcm-linux-rpm-method/security/ssl-termination-with-nginx/installing-and-configuring-nginx-for-ssl-termination.md).

# Installing and Configuring Nginx for SSL Termination

Nginx is not directly available within the CentOS or RHEL repositories, but is available within the EPEL repository. The EPEL repository must be enabled first before Nginx can be installed:

```
$ sudo yum install epel-release
```

Once EPEL has been enabled, Nginx can be installed by installing the "nginx" package. Installing this package will install a version of Nginx that is newer than version 1.3 and thus is [explicitly supported by](/kcm-linux-rpm-method/scope-of-support.md) [Keeper Connection Manager](/kcm-linux-rpm-method/scope-of-support.md):

```
$ sudo yum install nginx
```

As with other standard CentOS / RHEL packages providing a service, the Nginx service will not be started by default after the "nginx" package is installed. It must be started manually, and then configured to automatically start if the system is rebooted:

```
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
```

By default, Nginx will listen on port 80 and handle only unencrypted HTTP connections, serving the static contents of `/usr/share/nginx/html`. The rest of this document will cover reconfiguring Nginx such that it serves only HTTPS (using HTTP only to redirect browsers back to HTTPS), with a placeholder for the[ minimal additional configuration needed to provide SSL termination](/kcm-linux-rpm-method/security/ssl-termination-with-nginx.md). The resulting configuration will be used instead of Nginx' default configuration, and will be split up across two modular files:

| Filename                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/etc/nginx/conf.d/redirect-http.conf` | Configures Nginx to respond to all HTTP requests with an HTTP 301 ("Moved Permanently") redirect to the same resource under HTTPS.                                                                                                                                                                                                                                                                                                                            |
| `/etc/nginx/conf.d/guacamole.conf`     | Configures Nginx to accept HTTPS connections using a specified certificate and private key. Once SSL configuration is complete, this file will also [configure Nginx to proxy HTTPS connections to Guacamole](https://newdocs.keeper.io/kcm-linux-rpm-method/security/ssl-termination-with-nginx/pages/3DPnhmybxDnMINgp2Is5#id-.settingupsslterminationwithnginxv2.x-proxyingguacamolethroughnginx) such that HTTP is used only internally (SSL termination). |

### Configure Nginx to redirect all HTTP traffic to HTTPS <a href="#id-.installingandconfiguringnginxforsslterminationv2.x-configurenginxtoredirectallhttptraffictohttps" id="id-.installingandconfiguringnginxforsslterminationv2.x-configurenginxtoredirectallhttptraffictohttps"></a>

The main configuration file for Nginx, `/etc/nginx/nginx.conf`, contains a `server` block which serves the contents of `/usr/share/nginx/html` over HTTP:

```
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
```

The contents of this `server` block will conflict with the HTTP redirect that will need to be created, and should be commented-out or removed.  Comment out every line with a # at the beginning:

```
#    server {
#        listen       80 default_server;
#        listen       [::]:80 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }
```

With the conflicting `server` block removed, create a new file, `/etc/nginx/conf.d/redirect-http.conf`, to contain the new server block and redirect. The `server` block required is fairly straightforward. Rather than serve static content, it instructs Nginx to issue an HTTP 301 redirect ("Moved Permanently") for all requests, informing the browser that whatever they are requesting can instead be found at the same location using HTTPS:

```
server {

    listen 80;

    # Redirect all other traffic to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }

}
```

To apply the new configuration, simply reload Nginx:

```
$ sudo systemctl reload nginx
```

### Configure Nginx to accept HTTPS connections <a href="#id-.installingandconfiguringnginxforsslterminationv2.x-configurenginxtoaccepthttpsconnections" id="id-.installingandconfiguringnginxforsslterminationv2.x-configurenginxtoaccepthttpsconnections"></a>

To configure Nginx to accept HTTPS connections, you must obtain an SSL certificate for the domain associated with your server. There are two primary ways of doing this:

1. **Let's Encrypt**: A non-profit certificate authority that provides automated certificate issuance and renewal. Let's Encrypt certificates are free.
2. **Obtaining a certificate from a certificate authority**: Several commercial certificate authorities exist, many of which are also domain registrars. Unlike Let's Encrypt, obtaining a certificate from a commercial certificate authority will usually cost money.

{% tabs %}
{% tab title="Let's Encrypt" %}
The Let's Encrypt service uses a utility called "certbot" to automatically retrieve a certificate after the Let's Encrypt service has remotely verified that you control your domain. This utility is provided within the CentOS / RHEL repositories and must first be installed:

```
$ sudo yum install certbot
```

The Let's Encrypt service will verify that you control your domain be reaching back over the internet, attempting to establish an HTTP connection with your server at the domain provided and reading the contents of the `.well-known/` directory within the web root. This directory will be created and populated automatically by certbot when it runs, but the `/etc/nginx/conf.d/redirect-http.conf` file created earlier will not allow this directory to be read due to the nature of the HTTPS redirect. The `server` block within `redirect-http.conf` must first be edited to add a location which functions as an exception to this redirect, allowing Let's Encrypt to remotely access `.well-known/`:

```
server {

    listen 80;

    # Let's Encrypt requires access to /.well-known/ for its webroot plugin
    location /.well-known/ {
        root /usr/share/nginx/html;
        break;
    }

    # Redirect all other traffic to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }

}
```

To apply the new configuration, reload Nginx:

```
$ sudo systemctl reload nginx
```

The certbot tool can then be used to automatically retrieve a certificate for your domain. For example, if your Guacamole server is running at "remote.example.com", you can obtain a certificate from Let's Encrypt by running:

```
$ sudo certbot certonly -d remote.example.com --webroot --webroot-path /usr/share/nginx/html
```

The resulting certificate and private key will then be stored within a subdirectory of `/etc/letsencrypt/live/` with the same name as your domain. To apply the certificate and additionally host content via HTTPS, a new configuration file needs to be created: `/etc/nginx/conf.d/guacamole.conf`. Similar to the HTTP redirect, this file will contain a server block that defines how Nginx should serve HTTPS connections:

```
server {

    listen 443 ssl;

    # Location block pointing to Tomcat will go here

    ssl_certificate /etc/letsencrypt/live/remote.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/remote.example.com/privkey.pem;

}
```

#### Configuring automatic renewal <a href="#id-.installingandconfiguringnginxforsslterminationv2.x-configuringautomaticrenewal" id="id-.installingandconfiguringnginxforsslterminationv2.x-configuringautomaticrenewal"></a>

Let's Encrypt certificates are intentionally short-lived, expiring after 90 days. To ensure that a new certificate is retrieved, it is recommended that certbot run daily. This can be achieved by creating a script within `/etc/cron.daily` called `/etc/cron.daily/certbot` containing the following:

```
#!/bin/bash

# Attempt to renew certificates daily, reloading Nginx if an updated
# certificate is issued
certbot renew --quiet && systemctl reload nginx
```

Be sure to grant execute permission on the script so that the cron service will be able to execute it:

```
$ sudo chmod +x /etc/cron.daily/certbot
```

The certbot tool will then be automatically invoked at least once per day, renewing the certificate and reloading Nginx as needed.
{% endtab %}

{% tab title="Other certificate authorities" %}
If you have already obtained a certificate and corresponding private key from a certificate authority, there is very little extra configuration needed for Nginx to start using that certificate. To apply the certificate and additionally host content via HTTPS, a new configuration file needs to be created: `/etc/nginx/conf.d/guacamole.conf`. Similar to the HTTP redirect, this file will contain a server block that defines how Nginx should serve HTTPS connections:

```
server {

    listen 443 ssl;

    # Location block pointing to Tomcat will go here

    ssl_certificate /etc/pki/tls/certs/remote-example-com-cert.pem;
    ssl_certificate_key /etc/pki/tls/private/remote-example-com-key.pem;

}
```

where `/etc/pki/tls/certs/remote-example-com-cert.pem` is your certificate and `/etc/pki/tls/private/remote-example-com-key.pem` is your private key. Your certificate authority may have additional instructions regarding how their certificates should be used with Nginx, but the above configuration should work well for most cases. Be sure to check the documentation provided by your certificate authority to see whether they have specific recommendations.

{% hint style="warning" %}
The `/etc/pki/tls/` directory structure is standard to CentOS and RHEL. It is best practice to leverage this directory structure as intended, with the `certs/` directory containing the non-sensitive certificate and the `private/` directory containing the sensitive private key. The permissions of your private key should also be set such that non-root users of your system will not be able to read the key.
{% endhint %}
{% endtab %}
{% endtabs %}

### Finalizing the configuration (pointing Nginx at Guacamole) <a href="#id-.installingandconfiguringnginxforsslterminationv2.x-finalizingtheconfiguration-pointingnginxatgua" id="id-.installingandconfiguringnginxforsslterminationv2.x-finalizingtheconfiguration-pointingnginxatgua"></a>

With Nginx now deployed with a proper SSL certificate, the final step in providing SSL termination for Guacamole is to[ configure Nginx as a reverse proxy for Guacamole](https://newdocs.keeper.io/kcm-linux-rpm-method/security/ssl-termination-with-nginx/pages/3DPnhmybxDnMINgp2Is5#id-.settingupsslterminationwithnginxv2.x-proxyingguacamolethroughnginx). This process involves adding a `location` block within the Nginx server block for HTTPS, in this case the `/etc/nginx/conf.d/guacamole.conf` configuration file that was just created. Documentation is provided for the full content and meaning of the required `location` block, which should be added in the space noted by the "Location block pointing to Tomcat will go here" placeholder comments above.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://newdocs.keeper.io/kcm-linux-rpm-method/security/ssl-termination-with-nginx/installing-and-configuring-nginx-for-ssl-termination.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
