Score:0

How can I setup Nginx with a transparent socket?

cn flag

Similarly to this Cloudflare blog post, I am trying to setup Nginx with a transparent socket (with the IP_TRANSPARENT socket option). I want to do this to implement a reverse TCP proxy that effectively binds to all ports.

The IP_TRANSPARENT socket option is not natively supported by Nginx for listening so I am trying to create the socket using a Systemd socket unit and then pass it to the Nginx process using the NGINX environment variable.

The socket unit is as follows (unimportant lines have been removed):

[Socket]
ListenStream=127.0.0.1:1234
Transparent=true

[Install]
WantedBy=sockets.target

My Nginx service unit is as follows (unimportant lines have been removed):

[Service]
# Configure Nginx to use the socket inherited from Systemd
Environment=NGINX=3;
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf

And my nginx.conf is as follows (unimportant lines have been removed and upstream is the hostname of the upstream host I want to proxy to):

stream {
    server {
        proxy_pass upstream:443
        listen 127.0.0.1:1234;
    }
}

Nginx is running on a GCP compute instance behind an internal passthrough load balancer with IP address 10.11.12.13 so I have added the following iptables rule to redirect traffic to the transparent socket:

iptables -t mangle -I PREROUTING -d 10.11.12.13/32 -p tcp -j TPROXY --on-port=1234 --on-ip=127.0.0.1

As described here, GCP installs the local route for the load balancer, so there is no need to do that myself. In other words, the following command returns RTNETLINK answers: File exists:

ip route add local 10.11.12.13/32 dev lo src 127.0.0.1

However, the following curl command hangs:

curl https://10.11.12.13

The TCP connection is being established correctly from the perspective of curl, however when stracing the Nginx worker process it seems to be hanging on the accept4 system call.

Running tcpdump from the instance that Nginx is running on shows the following:

15.59.51.564902 IP [REDACTED].50028 > 10.11.12.13.443: Flags [S], seq 3519046460, win 65535, options [mss 1320,nop,wscale 6,nop,nop,TS val 3905128064 ecr 0,sackOK,eol], length 0
15.59.51.564973 IP 10.11.12.13.443 > [REDACTED].50028: Flags [S.], seq 2512605282, ack 3519046461, win 28400, options [mss 1420,nop,nop,sackOK,nop,wscale 7], length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [.], ack 1, win 4096, length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [P.], seq 1:370, ack 1, win 4096, length 369
15.59.51.601898 IP 10.11.12.13.443 > [REDACTED].50028: Flags [.], ack 370, win 231, length 0

As I understand, this means that the client is sending data, the server is acknowledging it, but then the client is not sending any more data, presumably because it's expecting a response from the server that it is not receiving. For this reason, I suspect Nginx is just ignoring the data sent by the client.

I hope I have provided enough context to understand the problem. I am not too sure where to go from here or if there is something fundamentally wrong with what I am trying to do. Any help would be greatly appreciated.

Score:0
cn flag

I found the solution here which was to set the following option on the Nginx service unit:

[Service]
NonBlocking=true

Presumably Nginx assumes that this option is set when the listening socket is created so data cannot be read if Systemd passes it a socket without this option set.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.