Search code examples
socketssecuritynginxnetwork-programmingdns

How possible to configure nginx to send tcp reset packet when visiting a path


Is it possible to configure NGINX (or any reverse proxy) to send TCP reset packet when visiting a specific path on my website (www.mysite.com/tcp-reset for example).

I tried pointing the path to a python socket server that does that but i get 502 from the client instead. My goal is to force the browser to re-resolve the domain name for dns rebinding attack.

Here's the python script that i used (which works when visiting the port directly):

import socket
import struct

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(("127.0.0.1", 1234))
    s.listen(5)
    while True:
        conn, addr = s.accept()
        print(f"Connection from {addr}")
        l_onoff = 1
        l_linger = 0
        s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', l_onoff, l_linger))
        conn.close()

and here's the nginx config that i used:

location /tcprst/ {
    proxy_pass http://localhost:1234/;
}

when i visit /tcprst/ I get 502 bad gateway instead.


Solution

  • Configuration

    location = /reset {
        reset_timedout_connection on;
        return 444;
    }
    

    Explanation

    return:

    Stops processing and returns the specified code to a client. The non-standard code 444 closes a connection without sending a response header [emphasis added].

    reset_timedout_connection:

    Enables or disables resetting timed out connections and connections closed with the non-standard code 444 (1.15.2). The reset is performed as follows. Before closing a socket, the SO_LINGER option is set on it with a timeout value of 0. When the socket is closed, TCP RST is sent to the client [emphasis added], and all memory occupied by this socket is released.

    Demo

    $ curl http://localhost:8000/reset
    curl: (56) Recv failure: Connection reset by peer
    

    wireshark screenshot