'Nginx configuration Let's Encrypt Multiple Elastic Stack Ports
I have an Elastic Stack (8.0.1) consisting of Elasticsearch, Logstash, and Kibana all running within Docker containers deployed to private subnet using AWS EC2. For now, I have the entire Elastic Stack running in a single AWS EC2 instance (this is just for our initial small test environment; I know this is not the way Elasticsearch is intended to be run).
I have Nginx sitting in a public subnet acting as a proxy to the various Elastic Stack components which are all separated by their port numbers: :9200 (elasticsearch), :8080 (logstash HTTP plugin), :5601 (kibana).
Since Kibana 8+ is configured by default using TLS, I also installed Let's Encrypt with Nginx to create signed certificates that would work with browsers and maintain the SSL connectivity all the way back.
What I have works perfect for the default URL works because Nginx redirects port 80 to 443 and then to port 5601 for Kibana interaction.
What I want to do now is allow HTTPS connectivity for other ports: e.g. :9200 and :8080 (logstash http plugin). For example, I want to be able to interact with Logstash via cURL at port 8080: `curl -0 -v XPUT --user elastic: 'https://elastic.example.com:8080//<doc#> -H 'Content-Type: text/csv; charset=utf-8' --data-binary "@/filename.txt" (NOTE: running this cURL command locally on my Dockerized Elastic Stack without Nginx works great)
I don't understand how to modify the Nginx configuration that was created by Let's Encrypt to also forward traffic on to other ports (:9200 and :8080).
Here's the nginx.conf that is currently loaded into /etc/nginx/nginx.conf
http {
server {
server_name elastic.example.com;
location / {
proxy_pass https://10.6.101.20:5601;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/elastic.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/elastic.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = elastic.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name elastic.example.com;
listen 80;
return 404; # managed by Certbot
}
}
What confuses me is that it appears as if I need nested "listen" lines, one for 443 SSL and others for the :8080 and :9200 e.g.
http {
server {
listen 443 ssl; # managed by Certbot
listen 8080; # <-- Nested somehow?
server_name elastic.example.com;
location / {
proxy_pass https://10.6.101.20:8080; # <-- Proxy forward to IP and Port
}
...
}
Solution 1:[1]
After reading more, I realized that "ssl" did not have to be limited to port 443 and I could use "ssl" on any of the ports. (Therefore, I didn't need to "nest" the nginx config) Duh! So, all I needed to do for nginx.conf to be able to be the SSL reverse proxy for elasticsearch was to add the following:
http {
server {
server_name elastic.example.com;
location / {
proxy_pass https://10.6.101.20:5601;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/elastic.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/elastic.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name elastic.example.com;
location / {
proxy_pass https://10.6.101.20:9200;
}
listen 9200 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/elastic.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/elastic.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = elastic.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name elastic.example.com;
listen 80;
return 404; # managed by Certbot
}
}
So, I'm now able to do things like:
curl --user elastic:<password> -XGET "https://elastic.example.com:9200/_cluster/state?pretty"
And get back some very basic cluster information.
BUT, adding another block to the nginx.conf to be able to do something similar via the HTTP plugin for Logstash failed to work. I suspect it's something with the Nginx "location /" specification because I continue to get permission denied error, but maybe this is a question for another SO?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ScottFred |
