I'm trying to secure a single-node Elasticsearch machine. Basically, I want to put Elasticsearch behind a reverse proxy (nginx) and make sure that the only way any user or process can communicate with Elasticsearch is through the proxy.

If Elaticsearch supported listening on a unix socket, this would be trivial. I could just set appropriate permissions on the socket file and be done. But, since it doesn't, I'm left with listening on a TCP port.

I have read a bit about network namespaces and it seems like they could possible work, but I have zero experience with them.

Is there an easy and secure way to make sure that the only process/user on the machine that can communicate with Elasticsearch is nginx?

  • I'm not an expert in this area, so just a thought. With the reverse proxy in place, the Elasticsearch server should only see requests from the Nginx server. In that case, the firewall on the Elasticsearch server could be configured to only allow requests from the Nginx server's IP address to the Elasticsearch port. – Haxiel Nov 8 '18 at 6:28
  • Thanks for your comment. For requests coming from outside the server, you are right. But, as I understand it, local users on the Elasticsearch server may still be able to sniff traffic on the TCP port or send requests directly to Elasticsearch. Does that make sense? – Dominic P Nov 8 '18 at 6:34
  • I believe there is a premium component in the Elastic Stack that can implement security features including TLS encryption. If you're worried about packet sniffing, maybe that is the way to go. For the local access part, I'm not quite sure if the loopback address will be treated differently by the firewall. – Haxiel Nov 8 '18 at 6:46
  • What is the scenario you are protecting against? Some local non-root user on the node accessing elasticsearch without nginx? Some external host doing that? For the latter, the simplest way maybe is to run both elasticsearch and nginx in docker containers (google). Docker containers use network namespaces, and the standard setup is automatized to a large degree, so it's not difficult to setup without experience. – dirkt Nov 8 '18 at 7:00
  • Thanks for the comment @dirkt. Yeah, I'm trying to achieve some defense in depth and prevent a local non-root user from going around the proxy. I have considered Docker, but the server is already a KVM virtual machine, and I feel like adding Docker gives me kind of a Russian Doll situation. Also, I don't know Docker at all, and I would rather not put the effort in to learn it if there's an easier way. – Dominic P Nov 8 '18 at 7:21

To protect against a local non-root user, I'd indeed use network namespaces.

It's probably the simplest solution, because in general networking stuff is decoupled from user/group management, and while mixing both can be done with iptables, it adds overhead.

Network namespaces just rely on the fact that only root can move process to and from namespaces.

So you need a setup similar to (ns = namespace)

main ns ---- nginx ns ---- elasticsearch ns

where the connections are implemented by virtual ethernet (veth) pairs with their own LAN segment. This will mean every process in the main namespace can only ever access the nginx namespace, and the elasticsearch namespace can't be accessed directly (unless you are able to start processes in this namespace).

You need to know basics about networking (LAN segments, netmask, routes vs. default routes). ip netns ... is the command line tool to create and manage netspaces, and start processes in a namespace. ip link ... is the command line tool to create veth-pairs.

I recommend to start an xterm in each namespace, so you can see and modify the network configuration. Once everything works, just script it.

You'll need to play around with it a bit, but it's not really difficult. I can't think of an easier way to do it.


To get started with namespaces, try out the script in this answer, or look at this question.

I'm not sure where you are stuck wrt. network namespaces. Think of each namespace as a networked virtual computer of its own, which happens to share the filesystem and other stuff with the rest of the physical computer. So dealing with namespaces is the same as connecting up computers in a LAN. One important tool is a virtual ethernet pair, which you can think of as a virtual LAN cable that connects two network namespaces.

  • Thanks so much for the detailed answer. I neglected to mention that Elasticsearch is setup to run via systemd. Given that, I'm not sure how to make it run in a network namespace (see this and this). Do you think something like this would work? Or, am I over complicating things. I can't seem to find a good, simple tutorial on network namespaces. – Dominic P Nov 9 '18 at 6:15
  • I'm sure it can somehow be made to work using systemd, but I've never tried to do that. For starters, I'd try to set up everything manually, so you see and understand the parts. See edit for namespace stuff. – dirkt Nov 9 '18 at 6:42
  • Thanks for sticking with me. The extra links were really helpful. I was able to get communication setup between the elastic and the nginx namespaces. Now I'm struggling to be able to ping the nginx namespace from the main namespace. I want nginx to be able to listen on port 80/443 of the default namespace. It seems like I need a bridge to make that happen. But, I can't seem to get the bridge to work. I'll keep tinkering with it. My main issue at this point isn't with namespaces but with gaps in my understanding of basic networking. I might post a separate question about that. – Dominic P Nov 10 '18 at 7:10
  • You can use a bridge, but then both the main namespace and the nginx namespace will appear with two different external IPs, and that may not be what you want. The alternative is port forwarding via iptables (google). That's also what docker sets up for you by default. And yes, that looks like a new question. :-) – dirkt Nov 10 '18 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.