Allow/forbid requests on localhost only


(Vadim) #1

Hi,
I’m trying to configure RoR on two separate master nodes on multinode cluster as follows:
(1)allow any request (read/write/manage, etc.) on localhost ONLY, forbid requests from particular servers/IPs
(2)allow any request (read/write/manage, etc.) from particular servers/IPs ONLY, forbid requests on localhost

Environment: RHEL 6, ES 5.6.3, readonlyrest_1.16.15_es5.6.3
For (1) my readonlyrest.yml:

readonlyrest:
    enable: true
    response_if_req_forbidden: Access denied by RoR
    access_control_rules:
    - name: "Allow requests from localhost only"
      hosts: [127.0.0.1] 

Running cURL -XGET ‘http://11.111.22.33:9200/books/kindle/1?pretty’ on localhost or on another host rejects request with returned status 403. Here 11.111.22.33:9200 is the IP:port where the RoR is deployed.
Running cURL -XGET ‘http://127.0.0.1:9200/books/kindle/1?pretty’ on localhost returns “curl: (7)couldn’t connect to host”

Any advise how to implement these two use cases ?
Thanks in advance.


(Askids) #2

I think that adding your IP to the hosts list should resolve your first issue.

How does you ipconfig looks like? I am guessing that either the loopback entry is missing or may be redirecting to something else. Please check.


(Vadim) #3

Thank you askids for your response.
I’m able to make a successfull requests on localhost only, if the server ip, where the es/ror are running, is in the hosts: [11.111.22.33] regardless the 127.0.0.1 or localhost is in the ip list or not and using curl -XGET ‘http://11.111.22.33:9200/books/kindle?pretty’.
My assumption was to being able to run curl wit the 127.0.0.1 or localhost in it instead of 11.111.22.33 as it is in the ror docs examples, or this is not correct?
The loopback entry 127.0.0.1 is in place, I checked it on with ifconfig on 11.111.22.33


(Simone Scarduzio) #4

You should make sure that the ES HTTP server is listening also on the local interface.


(Vadim) #5

Thank you Simone for the response.
I am not sure how to check this one. Should it be the entry “localhost:9200” when I run the “netstat -tlp” on the host where the es is running or are there any other method I can use ?
Should the elasticserach.yml contain the “127.0.0.1:9300” in the discovery.zen.ping.unicast.hosts ?


(Simone Scarduzio) #6

I was thinking to make sure you tell ES to bind to the local interface:

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html


(Vadim) #7

In my case the network.host should be 127.0.0.1 but in this case I will not be able to reference the 11.111.22.33 and I will be able to connect to this node only locally, correct ?


(Simone Scarduzio) #8

can’t you bind to many interfaces with that setting?


(Vadim) #9

Here are what I tested

es.yml network.host: [11.111.22.33, 127.0.0.1]
ror.yml hosts: [127.0.0.1]
Running curl with 11.111.22.33:9200 allows to access the cluster by running curl on any server or on 11.111.22.33(localhost).
Running curl with 127.0.0.1:9200 allows to access the cluster by running curl on 11.111.22.33(localhost) only.

es.yml network.host: [127.0.0.1]
ror.yml hosts: [127.0.0.1]
Running curl with 127.0.0.1:9200 on 11.111.22.33(localhost) gives error status 503, service unavailable/1/state not recovered/initialized

So, it seems, on multinode cluster, when ror deployed and enabled on one of the master nodes, it still unclear how to configure it to being able to access the cluster via this node/ip from localhost only, i mean making requests (via curl or jest client) on localhost only. Any requests from other servers should be forbidden.

Am I missing something ?
Many thanks Simone for your help.


(Simone Scarduzio) #10

This looks like an ES issue/question. Am I right? You are trying to get the HTTP server to listen on more IPs without success.


(Vadim) #11

Thanks for the response Simone.

I dont’t think I’m facing ES issue.
Initially I setup and am running multinode ES-5.6.3 cluster (3 servers and 5 nodes (2 master + 3 data) on each of them. Everything (including indexing and reading) is working well and I even can read/write from/to ES via hadoop/hive table. All these without readonlyrest (RoR).

After then I deployed and enabled RoR on the server 11.111.22.33 on the master node listening on port 9200 and I’d like to configure it to being able to reference this node on/from localhost ONLY that is running code (java, python), curl on the server 11.111.22.33 ONLY and run on this server commands, for example curl -XGET ‘http://127.0.0.1:9200/books/kindle?pretty’ or curl -XGET ‘http://localhost:9200/books/kindle?pretty’ or curl -XGET ‘http://11.111.22.33:9200/books/kindle?pretty’ with the correct response.
All other requests, made with curl/java/python from outside the localhost (server 11.111.22.33), that is from any other server(s) should be forbidden and rejected.

Is this is possible with the RoR?
If so, what I’m misssing or doing wrong in the above configurations ?

Thanks in advance


(Simone Scarduzio) #12

Not sure what’s going on, I only know that from ROR code we don’t return 503 code at any stage.

I saw ES gives that error message with 503 when the HTTP request is malformed. Do you have any exceptions in your case?

Also is the cluster in a green state when you try to curl? Apparently the same error message is coming when the node has difficulty joining the cluster.


(Vadim) #13

You were right Simone, error status 503 was related to node not joining the cluster.

Let me reiterate once again use cases I tested and the goal was to being able to access the cluster via master node with RoR on/from localhost ONLY (server with IP 11.111.22.33)

(1)use case - localhost IP (11.111.22.33) is Not in the list for network.host

elasticsearch.yml:
network.host: [127.0.0.1]
discovery.zen.ping.unicast.hosts: […, 11.111.22.33:9300, …]

readonlyrest.yml:
hosts: [127.0.0.1]

Node started OK, cluster health=green, but master node not joined the cluster (in log file it says “… no known master node, … [my_master_node_with_ror] failed to send joint request to master …”)
I tried to add the 127.0.0.1 to the list of discovery.zen.ping.unicast.hosts without success.

(2)use case - localhost IP (11.111.22.33) is in the list for network.host

elasticsearch.yml:
network.host: [11.111.22.33, 127.0.0.1]
discovery.zen.ping.unicast.hosts: […, 11.111.22.33:9300, …]

readonlyrest.yml:
hosts: [127.0.0.1]

Node started OK, cluster health=green, started master node successfully joined the cluster.
I can run successfully cURL -XGET ‘http://127.0.0.1:9200/books/kindle?pretty’ on localhost (server with IP 11.111.22.33), which is what I wanted.
I can run successfully cURL -XGET ‘http://11.111.22.33:9200/books/kindle?pretty’ on localhost (server with IP 11.111.22.33), which might be OK too,
but I can run successfully cURL -XGET ‘http://11.111.22.33:9200/books/kindle?pretty’ from other servers too, which I’d like to forbid

Any advise what is wrong or may be somethig is missing in my configuration ?


(Simone Scarduzio) #14

OK if everything works and the problem is forbidding people from reaching your server referring to a certain address, we have “hosts_local” rule.


(Vadim) #15

Finally I got it work as I wanted - to allow requests for node+ror from localhost only and forbid requests from other hosts.
To implement it the network.host in elasticsearch.yml and hosts in readonlyrest should be identical, for example [11.111.22.33, 127.0.0.1].
I can run successfully cURL -XGET ‘http://127.0.0.1:9200/books/kindle?pretty’ and ‘http://11.111.22.33:9200/books/kindle?pretty’ on localhost (server IP 11.111.22.33) ONLY.
The same requests will be forbidden when running them on other hosts/servers.

I’ve tried experiment with the hosts_local to achieve the same, but node didn’t start and log shows “…Cannot configure ReadonlyREST plugin … Unknown rule name:‘hosts_local’”

I couldn’t understand how hosts_local should work in readonlyrest.yml and handle the requests, should it be used instead of hosts or used together ?
Are there examples and use cases elsewhere I can look at or explanation of hosts_local ?
What are the DA (destination IP address) and OA (original IP address) and how they related to each other ?

Whatever I achieved with the desired es+ror configuration is due to your help and support Simone and thank you once again.


(Simone Scarduzio) #16

@dzyubanv hosts_local works in the latest version of ROR only. It’s new.

OA = “source” address in the TCP connection
DA = “destination” address in the TCP connection

You can observe the FORBIDDEN/ALLOWED log lines, they have a OA/DA field


(Vadim) #17

Is latest ROR for ES-6.2 backword compatible and can I use it with ES-5.6.3 ?
Thanks


(Simone Scarduzio) #18

you mean ROR 1.16.19? Use ROR only for the version it was built for. I mean, it doesn’t even let you install a plugin built for the wrong version.


(Vadim) #19

Ok, I see, ES and ROR versions should match each other.
I set up multinode cluster already with ES-5.6.3, tested it without and with ROR 1.16.15 for required use cases using users/groups rules, base64 and sha256 encoding to allow/forbid access for certain indices for certain users. Lastly I configured es and ror to being able to allow requests to node with ror on/from localhost only and forbid those requests from other servers.
Thanks for the help once again.


(Simone Scarduzio) #20

Yes this is too old, you won’t have hosts_local. Get the latest from the website if you need that rule.