So the main problem we were trying to solve with this was locking down our Elasticsearch and making it so that no one could execute a POST or DELETE to our ES service, but we were still able to query ES.
We were able to solve part of this. Now our index is built on the server side only and a POST or DELETE can’t be executed externally.
The issue is, now, we can’t get anything to work on the javascript application. We’ve tried to pass API keys through on the header, and they appear to be there but it’s not working.
We’ve tried to set it up so that only host from certainly IPs can read from ES without any kind of authentication but that doesn’t seem to be working.
So my question is: is there a setting somewhere that I’m missing that simply makes ES “read only” without any kind of authentication or noting the host. For instance, we’re trying to figure out if we can implement “read only” as the default for ES unless you execute a curl server side with the auth keys (which is working).
We’re pulling data from ES using AJAX and absolutely nothing seems to be getting through now. We constantly get a “Failed to load resource: net::ERR_SSL_PROTOCOL_ERROR” error in console.
We’re running SSL and executing everything across https.
The api keys in the header simply don’t seem to be authenticating with javascript. The idea was that we’d match the api keys with the query and then authenticate based on the hosts.
It would be ideal if we could lock down individual indicies as read only unless you provide the API keys.
Sorry, I can certainly post all of that. I was really just looking for a “Yes, there is a setting you can change for it.” or a “No, that’s not possible.” so as to not waste anyones time.
I was thinking that there may be a way to completely lock the entire system down and make it read only without any kind of authentication. Basically like a read only access global permission. The only exception would be a curl with some kind of auth_key.
Not using reverse proxy but we are using a load balancer.
Something else that I’m not clear on, it seems like everything that supposed to be in my readonlyrest.yml is actually working in my elasticsearch.yml file. This could also be the problem on my end.
Not sure if I can share that code (government project) but I’d like to see if I can.
SSL cert is letsencrypt on all of our environments except for production.
I should also mention that this is all in a docker container (rancher setup). Not sure if that matters at all.
Certainly appreciate all of the help and reaching out to me about this.
The SSL is necessary for the credentials to be encrypted when they are transmitted as HTTP headers. This is a non functional requirement (for security).
I don’t understand why you mix settings that should be in elasticsearch.yml with settings that go in readonlyrest.yml. Where did you see such example?
The example of elasticsearch.yml was in one of the docker containers that we used. Maybe an older version of readonlyrest? It seems that everything is only working in my elasticsearch.yml. I’ve changed all of me settings in the readonlyrest.yml file and nothing seems to be affected.
Alright. I’ll try that. I’m not sure why, but all of the access controls seem to be working correctly in the elasticsearch.yml. I’m able to curl using the account settings in the yml. I don’t have a readonlyrest.yml
I tried it with a readonlyrest.yml and took those settings out of the elasticsearch.yml. They didn’t seem to be affected or working in the readonlyrest.yml
For legacy reasons, our settings are still picked up from elasticsearch.yml if they are not found in readonlyrest.yml. But this does not mean it’s the correct way to do it, as it implies security risks.
Make sure that your readonlyrest.yml file lives in the same directory with elasticsearch.yml, and the file permissions are right for the elasticsearch process to read it.
Looks like we were able to get this working by using the SSL keystore and passing the hash from the yml file into the ajax script. Seems to be working well. Thank you for all of your help!
If you want read only for specific indices without authentication there is definitely a way to do that. This is what we have been doing with our indices.
If you put this as the last access control rule in your readonlyrest.yml that should allow readonly access to specific indices. This is public to the world.
I imagine the host filtering didn’t work because you are calling the index via AJAX which executes client side so the IP will be that of the user. If you don’t want it public you would have to use basic auth or api keys.