In my previous article “Reverse Proxy and Load Balancing for Elasticsearch”, I detailed how Nginx can be used as a reverse proxy to access the Elastic Stack. In today’s article, I’ll detail how to use Nginx to secure Elastic Stack. Under the Elastic Stack Basic license, you can use the security solutions provided by Elastic Stack to protect the Elastic Stack. For OSS users, we can use the security provided by Nginx to protect our Elastic Stack. In this article I want to explain how to implement a more common and easier way to protect Elastic Stack – deploying Nginx as a reverse proxy in front of Elasticsearch and Kibana.
In today’s experiment, I will use an Ubuntu 20.04 machine to demonstrate.
The installation
Elastic Stack
For our experiment we need to install Elasticsearch already Kibana. See my previous article “Elastic: A Beginner’s Guide” to install it. I use the default Settings. Once Elasticsearch and Kibana are up, we’ll see something like this:
Elasticsearch works on localhost:9200, Kibana works on localhost:5601.
Nginx
Refer to my previous article “Beats: Monitoring Nginx Web Servers using Elastic Stack” for an installation. We can install Nginx in the following way:
sudo apt-get install nginx
Copy the code
We will also install Apache2-utils to help us create accounts for basic authentication:
sudo apt-get install apache2-utils
Copy the code
Next, we’ll create auser account for basic authentication (I chose Kibanauser, but you can of course replace it with whatever user account you want) :
sudo htpasswd -c /etc/nginx/htpasswd.users kibanauser
Copy the code
When you press Enter, you will be prompted to Enter and verify the user password.
$ sudo htpasswd -c /etc/nginx/htpasswd.users kibanauser
New password:
Re-type new password:
Adding password for user kibanauser
Copy the code
For convenience, I used 1234 as the password for the kibanauser user.
Next, we will create an nginx configuration file:
sudo vi /etc/nginx/conf.d/kibana.conf
Copy the code
Enter the following configuration:
/etc/nginx/conf.d/kibana.conf
Copy the code
Upstream: ElasticSearch {server 127.0.0.1:9200; keepalive 15; Upstream {server 127.0.0.1:5601; keepalive 15; } server { listen 8881; location / { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/htpasswd.users; proxy_pass http://elasticsearch; proxy_redirect off; proxy_buffering off; Proxy_http_version 1.1; proxy_set_header Connection "Keep-Alive"; proxy_set_header Proxy-Connection "Keep-Alive"; } } server { listen 8882; location / { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/htpasswd.users; proxy_pass http://kibana; proxy_redirect off; proxy_buffering off; Proxy_http_version 1.1; proxy_set_header Connection "Keep-Alive"; proxy_set_header Proxy-Connection "Keep-Alive"; }}Copy the code
We require nginx to use the account created with htpasswd for basic authentication to listen for connections on port 8881 to Elasticsearch and port 8882 to Kibana. That’s all we need to configure.
Restart nginx:
sudo service nginx restart
Copy the code
Verify ID card
Both Elasticsearch and Kibana are now gated with basic authentication. We can verify this with some cURL commands.
For Elasticsearch, use:
The curl -- verbose http://127.0.0.1:8881Copy the code
The output above is:
$curl --verbose http://127.0.0.1:8881 * Trying 127.0.0.1:8881... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8881 (#0) > GET/HTTP/1.1 > Host: 127.0.0.1:8881 > curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 401 Unauthorized < Server: nginx/1.18.0 (Ubuntu) < Date: Tue, 05 Jan 2021 02:37:57 GMT < Content-Type: text/html < Content-Length: 188 < Connection: keep-alive < WWW-Authenticate: Basic realm="Restricted Access" < <html> <head><title>401 Authorization Required</title></head> <body> <center><h1>401 Authorization Required</ H1 ></center> < HR ><center>nginx/1.18.0 (Ubuntu)</center> </body> </ HTML > * Connection #0 to host 127.0.0.1 left intactCopy the code
We can see from the output above that he needs validation to access. Access Elasticsearch as follows:
The curl -- verbose http://kibanauser:[email protected]:8881Copy the code
The output of the above command is:
$curl --verbose http://kibanauser:[email protected]:8881 * Trying 127.0.0.1:8881... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8881 (#0) * Server auth using Basic with user' kibanauser' > GET/HTTP/1.1 > Host: 127.0.0.1:8881 > Authorization: Basic a2liYW5hdXNlcjoxMjM0 > user-agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Server: nginx/1.18.0 (Ubuntu) < Date: Tue, 05 Jan 2021 02:42:25 GMT < Content-Type: application/json; charset=UTF-8 < Content-Length: 531 < Connection: keep-alive < { "name" : "liuxgu", "cluster_name" : "Elasticsearch "," cluster_uUID ": "6DeOscunTaevVlsn68DYYA", "version" : {"number" : "7.6.2", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943z ", "build_snapshot" : false, "lucene_version" : "Minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1"}, "tagline" : "You Know, for Search"} * Connection #0 to host 127.0.0.1 left intactCopy the code
Above, we used the username and password kibanauser:1234, so we can see the correct output.
Similarly, we can access an Ubuntu machine from another computer:
It prompts us to enter the correct username and password for access. We enter the correct username and password and click the Sign In button above:
Here we are in the Kibana interface.
If we are using another machine to access Elasticsearch, we also need to use the correct username and password:
Enter the correct username and password above: