How to get tcp socket option in a Phoenix web app

I am working on a Phoenix web app. The incoming requests are actually redirected by IPTABLES. Right now I want to know the original destination before iptables redir the connection. For a normal tcp app with c/c++, I can call getsockopt with SO_ORIGINAL_DST.

I’m wondering if possible to get the underlying gen_tcp (through ranch_transport??) and then calling getsocketopt to it. Any advise?

Even if there would be such way to do it reliably then you would hit the wall with not being able to call getsockopt on that as SO_ORIGINAL_DST is not supported by Erlang. You can try to write your own ranch_transport which would use socket module instead, but that will be tremendous task which would require quite a lot low-level understanding of BEAM. Question is whether it is feasible.

EDIT: maybe there are better solutions for what you need. You can use for example L7 proxy instead of L4, and that can add proper header to HTTP requests, or you can use socket activation to make application listen on restricted port instead of L4 proxying.

1 Like

Thanks for the reply.

L7 proxy is not available in my use case. But “socket activation” sounds well for me. Let me have a try and then get back if any good news.

Thanks again.

You can use local Nginx/HAproxy with reverse proxy configuration to listen directly on 80/443 and then forward requests to the Phoenix application, it doesn’t need to be external service.

For socket activation with systemd you can check out my example project that shows how it can be achieved.