Nginx Reverse Proxy with Let's Encrypt
This guide describes how to secure an existing Elasticsearch server using an Nginx reverse proxy via a native HTTPS connection on port 443 with a Let's Encrypt certificate.
Prerequisites
- Active Elasticsearch server
- No services installed on ports 80 or 443
- SSH root access to the Elasticsearch server
Preparation
First, log in to the Elasticsearch server via SSH to perform the remaining configuration steps. If you did not provide a public SSH key for the server when ordering it, you can retrieve the login credentials from the Customer Center under the menu item Server → Password Vault in the Customer Center.
This guide sets up the reverse proxy for the Elasticsearch server XXXXX.creolineserver.com with Kibana. Please adjust the hostname accordingly in all of the following configuration files. Our servers with pre-installed Elasticsearch are all provided with Kibana and an Nginx reverse proxy.
Log in to the server via SSH using the root user:
ssh root@XXXXX.creolineserver.com Nginx Installation
By using Nginx, you can configure a Let’s Encrypt certificate alongside the HTTPS connection on port 443, which is automatically renewed before it expires.
apt update && apt install curl gnupg2 ca-certificates lsb-release
# Install the official Nginx repository
wget -qO - http://nginx.org/packages/keys/nginx_signing.key | apt-key add -
echo "deb http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list
# Install the Nginx web server
apt update && apt install nginx
After installation, you can use systemctl to check whether the Nginx server was successfully installed and started.
systemctl status nginx
● nginx.service - nginx - high-performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2021-09-22 16:01:18 CEST; 6s ago Nginx Configuration
Disable the default vhost configuration with the following command:
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled Then add a new configuration file using the following command:
nano /etc/nginx/conf.d/elasticsearch-proxy.conf server {
listen 80;
server_name localhost XXXXX.creolineserver.com;
location / {
proxy_pass http://127.0.0.1:9200;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_buffering off;
client_max_body_size 100M;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location /kibana {
proxy_pass http://127.0.0.1:5601/kibana;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_buffering off;
client_max_body_size 100M;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
} If you have changed the Elasticsearch HTTP API port, you must update the NGINX configuration accordingly. The same applies to the Kibana port and the corresponding /kibana location directive. The Kibanasettings are only required if you have installed Kibana for Elasticsearch.
Next, check the configuration for syntax errors and reload the NGINX configuration so that your changes take effect.
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl reload nginx Let’s Encrypt Installation
Install the Certbot package to issue Let’s Encrypt certificates:
apt update && apt install certbot python3-certbot-nginx Let’s Encrypt Configuration
After successfully installing the Certbot package, you can issue the necessary SSL certificate using the certbot command.
If this is your first time using the certbot command, you’ll need to enter an email address to receive expiration notifications and important security alerts.
certbot --nginx -d XXXXX.creolineserver.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): <Your email address>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the nonprofit
organization that develops Certbot? We'd like to send you emails about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the web server configuration.
2: Redirect - Redirect all requests to secure HTTPS access. Choose this for
new sites, or if you're confident your site works over HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [Enter] (press 'c' to cancel): 2
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for XXXXX.creolineserver.com
Using default port 80 for authentication.
Waiting for verification...
Cleaning up challenges
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://XXXXX.creolineserver.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=XXXXX.creolineserver.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Enable HTTPS redirection if you want to automatically redirect incoming traffic on port 80 (HTTP) to port 443 (HTTPS).
Automatic Renewal of SSL Certificates
For automatic renewal, the certbot.service and certbot.timer are already included with the certbot package, so a manual cron job is no longer needed.
If you do not wish to use the two systemd services provided by certbot, you can also trigger the certbot package twice daily via a cron job using crontab -e:
52 0,12 * * * certbot renew --post-hook "nginx -t && systemctl reload nginx" The cron job is only necessary if the systemd services certbot.service and certbot.timer have been disabled.
Firewall Configuration
You can then block direct access to Elasticsearch via the Cloud Firewall, so that all future HTTP requests must be sent exclusively through the Nginx proxy.
To do this, create a new firewall rule that allows incoming TCP traffic on ports 80 and 443, and use another rule to block all other incoming traffic.
Please note that additional rules are required to access Kibana. If your application server has a static IP address, it is recommended that you allow HTTP and HTTPS communication exclusively from the application server’s source address.
Testing HTTP(S) Requests
You can use curl to verify that the configuration was successful and that the Nginx proxy is functioning as intended.
curl https://XXXXX.creolineserver.com
{
"name" : "XXXXX.creolineserver.com",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "Mi_bhUolSw2UTHTnVNoKZA",
"version" : {
"number" : "7.14.2",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "6bc13727ce758c0e943c3c21653b3da82f627f75",
"build_date" : "2021-09-15T10:18:09.722761972Z",
"build_snapshot" : false,
"lucene_version" : "8.9.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
} If you enabled HTTPS redirection during the Let's Encrypt configuration, you can also test the redirection:
curl -I http://XXXXX.creolineserver.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.21.3
Date: Wed, 22 Sep 2021 15:12:31 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://XXXXX.creolineserver.com The HTTP status code 301 and the Location header in the response indicate that the HTTPS redirection is working correctly.
The Elasticsearch server can now be accessed from your application via https:// without specifying a port.\nYou can test accessing Kibana using a browser of your choice by entering the following URL (the server name must be adjusted beforehand):
https://XXXXX.creolineserver.com/kibana Disable Nginx Version in HTTP Responses
In the default Nginx configuration, the Nginx version is included in the Server header of every HTTP response. This behavior can be disabled via the nginx.conf file.
To do this, edit the file /etc/nginx/nginx.conf and add the parameter server_tokens off; to the http block.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
include /etc/nginx/conf.d/*.conf;
} To apply the changes, the Nginx server configuration must be reloaded:
nginx -t && systemctl reload nginx The Nginx version being used is then hidden in the HTTP responses:
curl -I https://XXXXX.creolineserver.com
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 23 Sep 2021 06:11:34 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 554
Connection: keep-alive
X-elastic-product: Elasticsearch