There are three main reasons your ssh sessions (or other persistent connections) may be disrupted when using cellphone towers/a mobile hotspot for internet access:
- Your IP address is changing. This is usually not the cause of the problem. Theoretically this can happen with any provider (mobile or otherwise) that doesn't give you a static IP address, but even with mobile hotspot providers your IP (usually) doesn't change often enough to be regularly disrupting your connections. You can check if this is happening by using any "What is my IP address?" type site, periodically reloading the site, and watching to see if your IP address changes.
- Your connection to your provider is being interrupted (example cause: weak signal). If this is your problem, you will also likely see it affecting other connection types (streaming video, web browsing), not just ssh connections.
- Your provider uses NAT, and has a very short timeout for removing "inactive" connections from their NAT table. If your internet connection has no problems for other uses (web browsing, video streaming), but your ssh sessions stop responding if you stop typing for more than a minute or two, this is likely to be the cause of your problem.
Solutions for problems #1 and #2:
For these problems, the best solution is to use something other than SSH that is better suited to unstable/changing connections. Two common options are MOSH and Eternal Terminal. MOSH does not support scrollback (you can only see the most recent screen of output), so you may want to use something like screen or tmux to add that functionality. Eternal Terminal does support scrollback. It is sometimes possible to install MOSH (but not Eternal Terminal) under a regular user account on the server without needing root access.
If your problem is brief interruptions to your connection, you may also be able to stick to using ssh and make your server's SSH configuration a little more disruption-tolerant by disabling TCPKeepAlive, and either disabling client alive checks by setting "ClientAliveInterval 0" or allowing several failed checks before ending a connection by setting "ClientAliveCountMax 20".
Some of the solutions in the previous two paragraphs require root access on the server to set up. If you don't have root access, you can get a cheap Virtual Private Server (VPS) from a web hosting company and set up one of the options above on the VPS. Then when you want to connect to another system, you can first connect to the VPS and then use it to ssh to the other less-disruption-tolerant system.
Solutions for problem #3:
The solution for problem #3 is to make sure information is regularly sent over your ssh connection so it doesn't time out in your internet provider's NAT table.
First, it may help to test that you are solving the right problem. The script below will cause the server to send output over your ssh connection once every 30 seconds for one hour. If your ssh connection stays connected for an hour without dropping while this script is running, it's likely you are on the right track. (If it doesn't, try an interval less than 30 seconds, or look into other potential causes for ssh disconnects above.)
INTERVAL=30
START_TIME=`date +%s`
END_TIME=$(( $START_TIME + 3600 ))
while [ `date +%s` -lt $END_TIME ]
do
date
sleep $INTERVAL
done
echo "Test completed successfully - your ssh connection lasted at least one hour."
Assuming the script above kept the ssh connection from dropping, you now have the solution, and just need a way to make it happen automatically. The way to do this is to make ssh do "alive" checks every 30 seconds, which causes messages to be sent over your ssh connection every 30 seconds and keeps it from being purged from your internet provider's NAT table for inactivity. You can either configure the server or the ssh client on your computer to do the "alive" checks (either will work, you don't need both).
To set it up on the server side, edit /etc/ssh/sshd_config and set "ClientAliveInterval 30" - this will make the server send a message to the client every 30 seconds to check for a response from the client. You may also want to set "ClientAliveMaxCount 10" to allow up to 10 checks to fail before the server closes the ssh connection (in case there's a mild disruption). Be sure to restart sshd so the changes to your configuration will take effect.
If you don't have root access on the server (or need to connect to multiple servers) it is also possible to set this up on your computer instead. You can make your computer send alive checks every 30 seconds to any server you connect to by using the following:
Host *
ServerAliveInterval 30
ServerAliveCountMax 8
On Linux or MacOS, these lines would go in ~/.ssh/config . If you are using OpenSSH on Windows, the lines would go in C:\Users\yourusername\.ssh\config (if the file doesn't exist you can create it, just make sure it doesn't have a .txt extension).
If you are using PuTTY, then in your session settings under the "Connection" section, you can set "Seconds between keepalives" to 30 to produce similar behavior. With PuTTY, you will need to put this in the settings for each server/connection, there doesn't seem to be a global setting.