Thanks to Emile LeBlanc and Alan J Rosenthal, I now have the following solution to this problem. In my case, I am connecting from my home linux machine, to a work linux machine (running tcsh), by ssh. So in my .login file (in my home directory on the target machine at work) I include the lines:
if ($?term) then if ($?SSH_CLIENT) then unset autologout sendnulls & endif endifThis calls the script "sendnulls" in the background, whenever I login using ssh.
And in my .logout file (again, in my home directory on the target machine at work) I include the lines:
if ($?SSH_CLIENT) then kill %sendnulls endifThis kills the "sendnulls" script when I logout.
Here "sendnulls" is the following sh shell script (again, on the target machine at work):
: set -e while true do dd if=/dev/zero count=1 bs=1 2>/dev/null sleep 300 done
The effect of this is that once every five minutes, the target machine uses the "dd" command to send a zero-value byte through the ssh connection's stdout, to my home computer. Since it is a zero-value byte, and since the stderr diagnostic output is redirected to /dev/null, this has no observable consequence. However, it is still enough to convince my router that the ssh connection is not idle, so the router does not disconnect it.
-- Jeffrey Rosenthal (contact me)
Update: I later upgraded my D-Link Router firmware from 2.xx to 3.39 (by going to support.dlink.ca and selecting "DI" and "604" then "revision E" ...), and that appears to have solved the problem, i.e. I no longer need to run sendnulls (as above) to keep my connection open.
hi, jeffrey, I wanted to thank you for putting up your page on the "D-Link Router SSH/Telnet Timeout Fix"; it definitely did the trick for me. [...] I did convert your scripts a little for my uses. i use bash on redhat linux (v's 8&9), and the syntax is a little different than sh. also i guess this version (as configured/compiled by redhat) does not use .login (or even .bash_login), though it apparently uses .bash_logout. i also added a process id detection so that the kill script would kill only the single PID with the particular sendnulls script started for that session (since i might also theoretically be logged in from behind another router, elsewhere, as well).. also, i put some echo's in for feedback, which can of course be commented back out for silent operation. finally, i added another test so that ssh'ing in from a particular location is what causes sendnulls to start (since i also ssh in from other locations which *don't* have routers behind them..) the person using these scripts will have to fill in with the current value of their router where it says "[your-ip-here]".. so, anyway, i offer these scripts to you, in case you want to post them for fellow bash/rh-linux users.. These are my versions of your scripts, tailored to redhat linux systems (v8 or 9) with bash as your shell. as with your original scripts, these go in your directory on the server machine (the machine you're ssh'ing *into*), not the machine behind the router you're ssh'ing out of. edit the ~/bin/detect_ssh_ip for your router's ip. == somewhere in my .bashrc ======================================== # if incoming ssh connection is from home, # send it nulls to keep it alive if [ -f $HOME/bin/detect_ssh_ip ]; then . $HOME/bin/detect_ssh_ip fi == ~/bin/detect_ssh_ip ============================================ #!/bin/bash # run script for keeping dlink di-604 router alive if [[ -n $TERM ]]; then # echo "term is not null" if [[ -n $SSH_CLIENT ]]; then # echo "ssh_client is not null" SSH_IP=`echo $SSH_CLIENT | cut -f 1 -d ' '` # put your router's IP here (e.g. "22.214.171.124"). keep # the quotes. if [ "$SSH_IP" = "[your-ip-here]" ]; then sendnulls & export SENDNULLS_PID=$! echo "$SSH_IP: sendnulls started (pid $SENDNULLS_PID)" fi fi fi == ~/bin/sendnulls ================================================ #!/bin/bash while true do dd if=/dev/zero count=1 bs=1 2>/dev/null sleep 60 done == ~/.bash_logout ================================================= # ~/.bash_logout # kill script for keeping dlink di-604 router alive if [[ -n $SENDNULLS_PID ]]; then # comment out next line if you don't feel like seeing the # feedback echo "killing sendnull (pid $SENDNULLS_PID)" kill -9 $SENDNULLS_PID fi