erebe / wstunnel

Tunnel all your traffic over Websocket or HTTP2 - Bypass firewalls/DPI - Static binary available
Other
3.22k stars 290 forks source link

Feature request for solving connection drop problems. #163

Closed ErfanM98 closed 7 months ago

ErfanM98 commented 11 months ago

Is your feature request related to a problem? Please describe. Since this tool is usually is being used in restricted networks, connection drops are common. For example, in some networks in Iran, long TCP connection is sometimes dropped by the censorship systems. This causes the wstunnel to be broken with different errors. But this error is common after a few minutes of connection: “ERROR :: Cannot do tls handshake with the server”

Describe the solution you'd like I think two solutions are suitable for this issue:

  1. Adding a re-connect feature or retry feature after a connection error.
  2. The second solution is more generalized: specifying a script in command line options to be run on connection errors.

Describe alternatives you've considered Currently I am running another python script that checks the connection status and restarts the connection for every hour. But this solution is not good enough since the connection drops are not predictable.

erebe commented 11 months ago

Hello,

wstunnel should reconnect, if a new connection to the client is made. But this is a hard question, as it will depend on the kind of traffic you are encapsulating.

If it is TCP, force/silently reconnecting will do no good, because it is most likely that your censorship system just dropped the packet of data in the middle. Reconnecting while the app is not knowing it, will just leave the connection in a broken state as some piece of data is missing.

If it is UDP, it might work, but will depend on again of if your application is resilient or not to such scenario. So in the end, this feature is of limited use, because it can only work for a subset of UDP applications.

Can you let me know what kind of traffic you are forwarding, and share your python script, so I can understand it better ?

ErfanM98 commented 11 months ago

Thanks for your response. My connection type is TCP only. I'm going to show last error messages when the connection drops.

ERROR :: Cannot do tls handshake with the server
ERROR :: Cannot do tls handshake with the server
ERROR :: Cannot establish websocket connection with the server
ERROR :: Cannot establish websocket connection with the server
ERROR :: Cannot establish websocket connection with the server
ERROR :: Cannot establish websocket connection with the server
ERROR :: Cannot establish websocket connection with the server
ERROR :: Cannot establish websocket connection with the server

the above errors would keep going until I exit the program. Also, sometimes the following error is occurring: IMG_2024

this is my python script (I removed some parts of it to make it shorter and just keep the main idea):

cmd = "./wstunnel-linux-x64 -D 8987 wss://205.233.181.132:8443 --hostHeader=myhost --tlsSNI=myhost -q"

p = subprocess.Popen(cmd, stdout=PIPE, bufsize=1, close_fds=ON_POSIX, start_new_session=False, text=True, shell=True,
                     stderr=subprocess.STDOUT)

while True:
    time.sleep(10)
    # read line without blocking
    try:
        line = get_new_line(p) # read the output of wstunnel
    except Empty:
        pass
    else:  # got line
        # check connection
        con, delay = check_connection(8987, "https://www.youtube.com/generate_204")
        if con:
            continue # connection is not broken, wstunnel is still working
        # connection problem
        p.terminate() # terminate prevoius tunnel, since it is broken, and start new tunnel:
        p = subprocess.Popen(cmd, stdout=PIPE, bufsize=1, close_fds=ON_POSIX, start_new_session=False, text=True,
                             shell=True, stderr=subprocess.STDOUT)
erebe commented 11 months ago

Thank you, I am going to try to look at it when i go back from vacation ~2 weeks. Will see if i can do something with those errors

ErfanM98 commented 10 months ago

Thank you for your assistance. If I can do any help please let me know. Enjoy your vacation!

erebe commented 10 months ago

Hi back,

Can you run wstunnel client in verbose mode (-v) and let me know the full error messages you get ?

ErfanM98 commented 10 months ago
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: ====
<socket: 379>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
<socket: 382>: hClose: resource vanished (Broken pipe)
====
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
Network.Socket.sendBuf: resource vanished (Broken pipe)
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: Opening Websocket stream
DEBUG :: ====
<socket: 441>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: Opening Websocket stream
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: ====
<socket: 435>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
<socket: 446>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
<socket: 439>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
<socket: 444>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: ====
<socket: 337>: hClose: resource vanished (Broken pipe)
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
mywebsite.xyz:8443: Network.Connection.connectionGetChunk: end of file
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: ====
HandshakeFailed Error_EOF
====
DEBUG :: Closing tcp connection to 205.233.181.112:8443
DEBUG :: ====
HandshakeFailed Error_EOF
====
erebe commented 9 months ago

Hi back,

Sorry for the delay, life caugth up quickly after vacations. I had the opportunity to check your issue, sadly I haven't managed to reproduce the exact same errors.

I made some change in this version https://github.com/erebe/wstunnel/suites/14662115643/artifacts/832088597 would you mind trying it and let me know if it solves your issue ?

If not, can you re-post the debug log

ErfanM98 commented 9 months ago

Sorry for my late response. I will test it and post the results soon here.

ErfanM98 commented 9 months ago

It's about four days that wstunnel is running and it seems there were no connection issues and the problem is solved. thanks.

erebe commented 9 months ago

Wonderful, thank you :) I let this ticket open until I make a new release of wstunnel

erebe commented 7 months ago

https://github.com/erebe/wstunnel/releases/tag/v6.0

uuonda commented 2 weeks ago

@erebe Hello. What's the state of this in wstunnel right now?

Connection drop is quite an issue for me. Websocket is unexpectedly disconnected by the server which also makes tunneling software close any overlayed connections. How does wstunnel handle this?

Let's say I want to forward SSH over WS. Is it possible to automatically resume websocket without resetting tunnelled TCP connection?

Note: this is not related to censorship.

erebe commented 1 week ago

Hello @uuonda ,

This is not fixable at wstunnel level, when the connection with the server drop, the wstunnel client has no way to know which data has been really been transmitted to the server, or if some has been lost in the middle. The only solution is to forward the close of the connection to the client and let it handle the the retry/re-connect.

We can imagine a world where wstunnel client would not forward the close to the client and silently handle the de-connection/re-connection, but it will mean in most casesm that the data transmitted will be corrupted. I.e: sending AAAAABBBBBCCCCDDD the remote endpoint will only see AAAAABBBBBDDD, if wstunnel client handle the reconnection silently.

The only way is for the client to handle the reconnection