Since a couple of months I’m working remotely from a laptop using my desktop machine at home via SSH. For more info on that see Remote coding or Why remote coding makes sense to me.
I used to use plain SSH to get a shell but I kept having troubles when there were network errors or network changes. Eternal Terminal offers a simple solution to this problem. From the homepage:
Eternal Terminal (ET) is a remote shell that automatically reconnects without interrupting the session.
Since I’ve started using it years ago it’s been a very useful tool that does it’s best to maintain a solid connection.
How to setup
Server setup on Ubuntu 25.10
This guide install ssh server too. If yours wasn’t already setup I recommend reading my SSH Server guide after.
sudo apt-get install -y openssh-server software-properties-common # prerequisite
sudo add-apt-repository ppa:jgmath2000/et # allow installing from the official repository
sudo apt-get update # update apt sources
sudo apt-get install et # install
sudo systemctl enable ssh # start ssh on boot
sudo systemctl enable et # start et on boot
sudo systemctl --no-pager status ssh # verify that the openssh-server is running
sudo systemctl --no-pager status et # verify that the etserver is running
# as this point Eternal Terminal is setup, but I don't want telemetry
sudo sed -i 's/telemetry = true/telemetry = false/' /etc/et.cfg
sudo systemctl restart et # apply changesClient setup on Ubuntu 25.10
sudo apt-get install -y software-properties-common # prerequisite
sudo add-apt-repository ppa:jgmath2000/et # allow installing from the official repository
sudo apt-get update # update apt sources
sudo apt-get install et # install
sudo systemctl disable et # check that the server is running
# as this point Eternal Terminal is setup, but I don't want telemetry
sudo sed -i 's/telemetry = true/telemetry = false/' /etc/et.cfg
et user@hostname # Eternal terminal is ready to connect to the serverClient setup on Termux
Termux is a free android terminal client that let’s me work from my phone in any situation. Read more about how I use it here: Using Termux
pkg upgrade # update all local packages, optional
pkg install et # install the package, refreshes sources automatically
# as this point Eternal Terminal is setup, but I don't want telemetry
# the exact file path to the file might change depending on your Android build.
# if this fails you can find the termux path with "which bash"
sed -i 's/telemetry = true/telemetry = false/' /data/data/com.termux/files/usr/etc/et.cfg
et user@hostname # Eternal terminal is ready to connect to the serverHow to use
You can simply use Eternal Terminal how you’d use plain SSH: et user@hostname.
Important flags
--forward-ssh-agent: Forward ssh-agent socket. This one is very useful and removes the need to runssh-addon every connection.--macserver: Set when connecting to an macOS server. Sets —terminal-path=/usr/local/bin/etterminal--tunnel arg: Array of source:destination ports or srcStart-srcEnd:dstStart-dstEnd (inclusive) port ranges (e.g. 10080:80,10443:443, 10090-10092:8000-8002)
How it works
This article form their website explains it in details: How Eternal Terminal Works
I also made these 2 mermaid graphs to show what’s going on:
Diagrams
graph TD Client[SSH Client] subgraph "Initial Connection" Socket1[TCP Socket<br/>:random → :22] Session1[SSH Session] end subgraph "After Network Change" Socket2[TCP Socket<br/>:random → :22] Session2[Connection Failed<br/>Session Lost ❌] end Server[SSH Server] Client --> Socket1 Socket1 --> Session1 Session1 --> Server Client -.->|Attempt Reconnect| Socket2 Socket2 -.->|Timeout/Error| Session2 Session2 -.->|New Session Required| Server style Client fill:#e1f5ff style Server fill:#ffe1e1 style Socket1 fill:#fff3cd style Socket2 fill:#ffcccc style Session1 fill:#d4edda style Session2 fill:#f8d7da
graph TD Client[ET Client] subgraph "Initial Connection" SSH1[SSH Tunnel<br/>Authentication] Socket1[TCP Socket<br/>:random → :2022] Session1[Persistent Session] end subgraph "After Network Change" SSH2[SSH Tunnel<br/>Re-authentication] Socket2[New TCP Socket<br/>:random → :2022] Session2[Same Session<br/>Reconnected ✓] end Server[ET Server<br/>etserver] Client --> SSH1 SSH1 --> Socket1 Socket1 --> Session1 Session1 --> Server Client -.->|Auto Reconnect| SSH2 SSH2 -.-> Socket2 Socket2 -.-> Session2 Session2 -.-> Server style Client fill:#e1f5ff style Server fill:#ffe1e1 style SSH1 fill:#e8daff style SSH2 fill:#e8daff style Socket1 fill:#fff3cd style Socket2 fill:#fff3cd style Session1 fill:#d4edda style Session2 fill:#d4edda