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.