How to secure a Digital Ocean Elasticsearch cluster? - elasticsearch

I need to expose my ES cluster to the world, and am securing it via Nginx with a proxy *:9201 -> localhost:9200 (working).
However, in order to form a cluster, I am trying to use the private network on DigitalOcean to get the nodes to talk to each other.
How can I expose the node-node transport on the private network interface unsecured, while not exposing port 9200 to the world?
I am trying something like
network.publish_host: 10.128.97.184
http.port: 9200
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: 10.128.97.184,10.128.97.185
in elasticsearch.yml but it's not working, probably because the port 9300 might also be nginx-protected?
my nginx file looks like
root#els-node-1:~# cat /etc/nginx/sites-enabled/elasticsearch
server {
listen *:9201;
access_log /var/log/nginx/elasticsearch.access.log;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
proxy_pass http://localhost:9200;
proxy_read_timeout 90;
}
}
And I am able to form the cluster, but I can't see how to secure the external 9200 (disable it to all but 127.0.0.1) and keep the internal interface open for addessses like 10.x.x.x
Thanks for help!

Even if you use the private network, your ES cluster is not secure as anybody within the same Digital Ocean private network can still access your nodes through the open ports 9200 and 9300 (and potentially other services).
Your best bet is to secure your boxes via iptables and only white list the IPs you know are your own servers.
Drop all incoming and forwarded packages and add explicit rules for the other nodes in the cluster only.
Also, use network.bind_host instead of network.publish_host and in addition set up ES to use the eth1 interface only, checkout the ES network docs for details.

Related

connect dotCMS cluster to external elasticsearch

I'm trying to create a cluster of three servers with dotCMS 5.2.6 installed.
They have to interface with a second cluster of 3 elasticsearch nodes.
Despite my attempts to combine them, the best case I've obtained is with both dotCMS and elastic up and running but from dot admin backend (Control panel > Configuration > Network) I always see my three servers with red status due to Index red status.
I have tested the following combinations:
In plugins/com.dotcms.config/conf/dotcms-config-cluster-ext.properties
AUTOWIRE_CLUSTER_TRANSPORT=false
es.path.home=WEB-INF/elasticsearch
Using AUTOWIRE_CLUSTER_TRANSPORT=true seems not to change the result
In plugins/com.dotcms.config/ROOT/dotserver/tomcat-8.5.32/webapps/ROOT/WEB-INF/elasticsearch/config/elasticsearch-override.yml
transport.tcp.port: 9301
discovery.zen.ping.unicast.hosts: first_es_server:9300, second_es_server:9300, third_es_server:9300
Using transport.tcp.port: 9300 cause dotCMS startup failure with error:
ERROR cluster.ClusterFactory - Unable to rewire cluster:Failed to bind to [9300]
Caused by: com.dotmarketing.exception.DotRuntimeException: Failed to bind to [9300]
Of course, port 9300 is listening on the three elasticsearch nodes they are configured with transport.tcp.port: 9300 and have no problem to start and create their cluster.
Using transport.tcp.port: 9301 dotCMS can start and join the elastic cluster but the index status is always red even if the indexation seems to work and nothing is apparently affected.
Using transport.tcp.port: 9309 (as suggested in the dotCMS online reference) or any other port number lead to the same result as 9301 case but from dot admin backend (Control panel > Configuration > Network) the Index information for each machine still repot 9301 as ES port.
Main Question
I would like to know where the ES port can be edited considering my Elasticsearch cluster is performing well (all indices are green) and the elasticsearch-override.yml within dotCMS plugin doesn't affect the default 9301 reported by the backend.
Is the HTTP interface enabled on ES? If not, I would enable it and see what the cluster health is and what the index health is. It might be that you need to adjust your expected replicas.
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-health.html
and
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-indices.html
FWIW, the upcoming version of dotCMS (5.3.0) does not support embedded elasticsearch and requires a vanilla external ES node/custer to connect to.

ElasticSearch Security and Ports

I have setup an elastic-search cluster with two data nodes , one master node and one client node with KIBANA.
I was running it with iptables disabled on each node (CC 6). Now i need to enable iptables and i want to know which of the ports (9200 , 9300) , i need to open on each node and in which direction (incoming or outgoing). The discovery is using uni-cast.
I would also like to know on which node i should place authentication , i.e just the client node ?
Cluster: mycluster
data-node1
data-node2
master-node1
client-node1
Thanks.
9200 is used for the HTTP API, 9300 is used for communication between nodes and cluster.
For the above configuration I would:
Bind port 9200 on all hosts to 127.0.0.1
Bind port 9300 on all hosts to the local lan, i.e. 192.168.x.x
Run nginx and apply basic authentication (htpasswd for example), reverse proxy to 127.0.0.1:5601 (kibana), assuming you're running your client node on the same machine as you are running Kibana on.
In your Kibana configuration, have it connect to localhost:9200 and bind the interface to 127.0.0.1

How to bind Elasticsearch 2.0 on both Loopback and Non-Loopback interfaces?

Starting from version 2.0 Elasticsearch binds only on the loopback interface by default (_local_ in terms of configuration).
The documentation says that there is a way to switch to another network, for example, _non_loopback_ binds to the first non-loopback interface. It works fine.
But I cannot figure out how do I combine these settings so that Elasticsearch binds on both loopback and non-loopback interfaces simultaneously?
PS. My reason is that I use Logstash on each Elasticsearch instance that connects to it via localhost, but I also want other Elasticsearch instances to see each other to form the cluster...
For 2.0 you would need to use
network.bind_host: 0
As of ElasticSearch 7.x, this configuration has changed yet again. for a simple single node cluster bound to loopback, local and external IPs, you essentially do this:
network.host: [_local_, _site_, _global_]
cluster.initial_master_nodes: node-1
The cluster node setting is explained here while the network host setting is in the documentation here, although it doesn't say how you would assign multiple values to network.host.
Go to
'<path_to_elasticsearch>/elasticsearch-2.3.4/config'
Open elasticsearch.yml
Add
network.host: 0.0.0.0
Now check which port elasticsearch is using (9200 is default), go to firewall inbound rules and add those ports.

camel elasticsearch access port 80

I have port 9200 proxied via 80 on my server running elasticsearch. I have a camel route that needs to index documents to this server.
Is it supported in the camel-elasticsearch plugin? ie access elastic search via a non 9300 port?
I understand that port 9300 uses a native elasticsearch transport protocol.
What are my options here? Can I proxy 9300 via apache? I'm not sure if that works.
Or does the camel-elasticsearch plugin support http transport? Please help. Thanks.
The port you are referring to, it is the HTTP port:
http.port A bind port range. Defaults to 9200-9300.
http.publish_port The port that HTTP clients should use when communicating with this node. Useful when a cluster node is behind a
proxy or firewall and the http.port is not directly addressable from
the outside. Defaults to the actual port assigned via http.port.
http.bind_host The host address to bind the HTTP service to. Defaults to http.host (if set) or network.bind_host.
http.publish_host The host address to publish for HTTP clients to connect to. Defaults to http.host (if set) or
network.publish_host.
http.host Used to set the http.bind_host and the http.publish_host Defaults to http.host or network.host.
So you really don't need a proxy, you can have elasticsearch listen directly on port 80.
If you already have a process running on port 80; then you can proxy the connections to 9200 (and leave elastic search as default).
Java Transport Client ---> Apache HTTP Proxy(80) ----> ES (9300) [ Can
I do this? As I understand that Java Transport Client uses a non-http
protocol? ]
The protocol has nothing to do with the port.
Simply pass 80 to InetSocketTransportAddress. See the documentation for a complete example.

Port 9300 on Elasticsearch

According to the documentation, Elasticsearch reserves port 9300-9400 for cluster communication and port 9200-9300 for accessing the elasticsearch APIs. You get the impression that these ranges are inclusive: so port 9300 is part of the first and the second port range.
Now, my IT ops department won't like that, so hopefully I got it wrong. Anyone knows?
Elasticsearch will bind to a single port for both HTTP and the node/transport APIs.
It'll try the lowest available port first, and if it is already taken, try the next. If you run a single node on your machine, it'll only bind to 9200 and 9300.
See also: Elasticsearch Internals: Networking Introduction

Resources