trzsz-ssh ( tssh ) with tsshd supports intermittent connectivity, allows roaming, and can be used on high-latency links such as cellular data connections, unstable Wi-Fi, etc.
It aims to provide complete compatibility with openssh, mirroring all its features, while also offering additional useful features not found in the openssh client, plus:
-
Keeps the session alive if the client goes to sleep and wakes up later, or temporarily loses its connection.
-
Allows the client to "roam" and change IP addresses, switching between any networks, while keeping alive.
tsshd was inspired by mosh, and the tsshd works like mosh-server, while the tssh --udp works like mosh.
| Feature | mosh ( mosh-server ) | tssh ( tsshd ) |
|---|---|---|
| Low Latency | ?? | ✅ KCP |
| Keep Alive | ✅ | ✅ |
| Client Roaming | ✅ | ✅ |
| Local Echo & Line Editing | ✅ | Not Planned |
| Multi Platform / Windows | mosh#293 | ✅ |
| SSH X11 Forwarding | mosh#41 | ✅ |
| SSH Agent Forwarding | mosh#120 | ✅ |
| SSH Port Forwarding | mosh#337 | ✅ |
| Output Scrollback | mosh#122 | ✅ |
| OSC52 Sequence | mosh#637 | ✅ |
| ProxyJump | mosh#970 | ✅ |
| tmux -CC Integration | mosh#1078 | ✅ |
tssh and tsshd works exactly like ssh, there are no plans to support local echo and line editing, and will not have the mosh issues: mosh#1041, mosh#1281, mosh#1295, etc.
-
Install tssh on the client ( your local machine ).
-
Install tsshd on the server ( the remote host ).
-
Use
tssh --udp xxxto login to the server. Or configure as follows in~/.ssh/configto omit--udp:Host xxx #!! UdpMode yes
-
The
tsshplays the role ofsshon the client side, and thetsshdplays the role ofsshdon the server side. -
The
tsshwill first login to the server normally as an ssh client, and then run a newtsshdprocess on the server. -
The
tsshdprocess listens on a random udp port between 61001 and 61999 (can be customized byUdpPort), and sends its port number and some secret keys back to thetsshprocess over the ssh channel. The ssh connection is then shut down, and thetsshprocess communicates with thetsshdprocess over udp.
┌───────────────────────┐ ┌───────────────────────┐
│ │ │ │
│ tssh (process) │ │ tsshd (process) │
│ │ │ │
│ ┌───────────────────┐ │ │ ┌───────────────────┐ │
│ │ │ │ │ │ │ │
│ │ KCP/QUIC Client │ │ │ │ KCP/QUIC Server │ │
│ │ │ │ │ │ │ │
│ └───────┬───▲───────┘ │ │ └───────┬───▲───────┘ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ ┌───────▼───┴───────┐ │ │ ┌───────▼───┴───────┐ │
│ │ ├─┼────────────────┼─► │ │
│ │ Client Proxy │ │ │ │ Server Proxy │ │
│ │ ◄─┼────────────────┼─┤ │ │
│ └───────────────────┘ │ │ └───────────────────┘ │
└───────────────────────┘ └───────────────────────┘
-
The client
KCP/QUIC ClientandClient Proxyare on the same machine and in the same process, and the connection between them will not be interrupted. -
The server
KCP/QUIC ServerandServer Proxyare on the same machine and in the same process, and the connection between them will not be interrupted. -
If the client doesn't receive a heartbeat from the server for a period of time, it might be due to network changes causing the original connection to be interrupted. In this case, the
Client Proxywill re-establish a connection to theServer Proxy, and communicate through the new connection after successful authentication. From the perspective of theKCP/QUIC Clientand theKCP/QUIC Server, the connection is never interrupted.
-
The
KCP/QUIC Serverlistens only on the localhost at 127.0.0.1, and accepts only one connection. Once theServer Proxyin the same process successfully connects, all other connections will be rejected. -
The
Client Proxylistens only on the localhost at 127.0.0.1, and accepts only one connection. Once theKCP/QUIC Clientin the same process successfully connects, all other connections will be rejected. -
The
Server Proxyonly forwards packets from the unique and authenticatedClient Proxy. TheClient Proxycan change its IP address and port, but once a newClient Proxyis authenticated, theServer Proxywill only forward packets from the newClient Proxy, ignoring the oldClient Proxyaddress. -
The
Client Proxyconnects for the first time or reconnects to theServer Proxyafter changing its IP address and port, it needs to send an authentication message (encrypted using the AES-GCM-256 algorithm, with a one-time key randomly generated by the server, which is sent to the client via the SSH tunnel during login). After theServer Proxysuccessfully decrypts the authentication message (without tampering), it verifies that whether the client ID matches the expectations and whether the sequence number is greater than the sequence number in all previous authentication messages. If so, it marks the client address as an authenticated address and sends an authentication confirmation message (encrypted using the AES-GCM-256 algorithm) to the client. After theClient Proxyreceives the authentication confirmation message from theServer Proxyand decrypts it successfully (without tampering), it verifies the server ID and the sequence number. If they match the expectations, it starts communicating with theServer Proxyusing the new address, forwarding messages from the local processKCP/QUIC Clientto theServer Proxy. TheServer Proxythen forwards the messages to the local processKCP/QUIC Serverservice. -
The
KCP/QUIC Clientand theKCP/QUIC Serveruse the open-source KCP / QUIC protocols, and use encrypted transmission (the key is a one-time key randomly generated by the server, which is sent to the client via the SSH tunnel during login).
Host xxx
#!! UdpMode Yes
#!! UdpPort 61001-61999
#!! TsshdPath ~/go/bin/tsshd
#!! UdpAliveTimeout 86400
#!! UdpHeartbeatTimeout 3
#!! UdpReconnectTimeout 15
#!! ShowNotificationOnTop yes
#!! ShowFullNotifications yes
#!! UdpProxyMode UDP
-
UdpMode:No(the default: tssh works in TCP mode),Yes(default protocol:QUIC),QUIC(QUIC protocol: faster speed),KCP(KCP protocol: lower latency). -
UdpPort: Specifies the range of UDP ports that tsshd listens on, the default value is [61001, 61999]. -
TsshdPath: Specifies the path to the tsshd binary on the server, lookup in $PATH if not configured. -
UdpAliveTimeout: If the disconnection lasts longer thanUdpAliveTimeoutin seconds, tssh and tsshd will both exit, and no longer support reconnection. The default is 86400 seconds. -
UdpHeartbeatTimeout: If the disconnection lasts longer thanUdpHeartbeatTimeoutin seconds, tssh will try to reconnect to the server by a new path. The default is 3 seconds. -
UdpReconnectTimeout: If the disconnection lasts longer thanUdpReconnectTimeoutin seconds, tssh will display a notification indicating that the connection has been lost. The default is 15 seconds. -
ShowNotificationOnTop: Whether the connection loss notification is displayed on the top. The default is yes, which may overwrite some of the previous output. Set it toNoto display notifications on the current line of the cursor. -
ShowFullNotifications: Whether to display the full notifications or a brief notification. The default is yes, which may output several lines to the screen. Set it toNowill output only one line. -
UdpProxyMode: The default transport protocol isUDP. IfUDPtraffic is blocked by firewalls in your network environment, you can set it toTCPto work around the restriction, though this may introduce additional latency.
-
Install with apt on Ubuntu
sudo apt install tsshdsudo apt update && sudo apt install software-properties-common sudo add-apt-repository ppa:trzsz/ppa && sudo apt update sudo apt install tsshd
-
Install with apt on Debian
sudo apt install tsshdsudo apt install curl gpg curl -s 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x7074ce75da7cc691c1ae1a7c7e51d1ad956055ca' \ | gpg --dearmor -o /usr/share/keyrings/trzsz.gpg echo 'deb [signed-by=/usr/share/keyrings/trzsz.gpg] https://ppa.launchpadcontent.net/trzsz/ppa/ubuntu jammy main' \ | sudo tee /etc/apt/sources.list.d/trzsz.list sudo apt update sudo apt install tsshd
-
Install with yum on Linux
sudo yum install tsshd-
Install with gemfury repository.
echo '[trzsz] name=Trzsz Repo baseurl=https://yum.fury.io/trzsz/ enabled=1 gpgcheck=0' | sudo tee /etc/yum.repos.d/trzsz.repo sudo yum install tsshd
-
Install with wlnmp repository. It's not necessary to configure the epel repository for tsshd.
curl -fsSL "https://sh.wlnmp.com/wlnmp.sh" | bash sudo yum install tsshd
-
-
Install with yay on ArchLinux
yay -S tsshdyay -Syu yay -S tsshd
-
Install with scoop on Windows
scoop install tsshdscoop bucket add extras scoop install tsshd
Need to allow
C:\Users\<user>\scoop\apps\tsshd\<version>\tsshd.exethrough the firewall for it to work properly. -
Install with Go ( Requires go 1.25 or later )
go install github.com/trzsz/tsshd/cmd/tsshd@latestgo install github.com/trzsz/tsshd/cmd/tsshd@latest
The binaries are usually located in ~/go/bin/ ( C:\Users\your_name\go\bin\ on Windows ).
-
Build from source ( Requires go 1.25 or later )
sudo make installgit clone --depth 1 https://github.com/trzsz/tsshd.git cd tsshd make sudo make install -
Download from the GitHub Releases and install locally
download and install locallysudo apt install /tmp/tsshd_*.deb sudo dpkg -i /tmp/tsshd_*.deb sudo dnf install /tmp/tsshd_*.rpm sudo yum install /tmp/tsshd_*.rpm sudo rpm -i /tmp/tsshd_*.rpm tar zxvf tsshd_*.tar.gz && sudo cp tsshd_*/tsshd /usr/bin/
Feel free to email the author [email protected], or create an issue. Welcome to join the QQ group: 318578930.
❤️ Sponsor trzsz ❤️, buy the author a drink 🍺 ? Thank you for your support!