SSH escape commands for fun and profit
We can never say it enough, but OpenSSH is an amazing tool. Lately, I have been playing with VMs and a friend of mine showed me some really cool tricks with SSH. The SSH escape ~
commands!
What are SSH escape commands?
The ~
is a special escape command that is only recognized immediately after a newline. You can display the help with ~ ?
from any SSH session.
Note that because the command is interpreted by SSH it won't be displayed in your terminal.
daimrod@omecha:~$ Supported escape sequences: ~. - terminate connection (and any multiplexed sessions) ~B - send a BREAK to the remote system ~C - open a command line ~R - request rekey ~V/v - decrease/increase verbosity (LogLevel) ~^Z - suspend ssh ~# - list forwarded connections ~& - background ssh (when waiting for connections to terminate) ~? - this message ~~ - send the escape character by typing it twice (Note that escapes are only recognized immediately after newline.)
The first command that I find somewhat useful is ~.
. It is used to terminate the connection, which is useful when you want to kill your SSH session, for example because you've switched between networks and you need to make a new connection but you don't want to wait for the timeout. Just enter ~.
and boom, your session is closed!
Behold the ~C
command
But the command that I found really cool is ~C
. When you enter the ~C
command from an SSH session, a new prompt appears. You can list the available commands by entering ?
or help
.
daimrod@omecha:~$ ssh> ? Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -D[bind_address:]port Request dynamic forward -KL[bind_address:]port Cancel local forward -KR[bind_address:]port Cancel remote forward -KD[bind_address:]port Cancel dynamic forward
This commands allow you to forward (and to cancel) ports from your current SSH session.
I find this very useful when I'm working with VMs and I have to forward ports to access the VNC or SSH ports of the VMs.
Here is an example of me, connecting to my hypervisor, starting some VMs and forwarding the VNC ports to my localhost. Note that, though the command vncdisplay
indicates that the VNC is listening on 127.0.0.1:N
, the real port it is listening to is 5900 + N
.
$ ssh root@hypervisor # virsh Welcome to virsh, the virtualization interactive terminal. virsh # create domains/vm1.xml Domain vm1 created from domains/vm1.xml virsh # vncdisplay vm1 127.0.0.1:0 virsh # ssh> -L 5900:localhost:5900 Forwarding port. # In another terminal $ vncviewer localhost:5900 virsh # create domains/vm2.xml Domain vm2 created from domains/vm2.xml virsh # vncdisplay vm2 127.0.0.1:1 virsh # ssh> -L 9 5901:localhost:5901 Forwarding port. # In another terminal $ vncviewer localhost:5901
Pretty neat, isn't it? The only drawback, is that we still need another terminal to launch vncviewer
. But I've found a way around.
One terminal to rule them all
- Forward the port from SSH with
~C -L 5900:localhost:5900
- Suspend SSH with
~^Z
- Launch
vncviewer localhost:5900
, it doesn't start because SSH is suspended and thus is unable to forward the connection. - Suspend the
vncviewer
command and resume it in background withbg
- Resume SSH in the foreground with
fg
.
Here is a sample of the session :
$ ssh root@hypervisor # virsh virsh # create domains/vm1.xml Domain vm1 created from domains/vm1.xml virsh # vncdisplay vm1 127.0.0.1:0 virsh # ~C ssh> -L 5900:localhost:5900 Forwarding port. ~^Z[1] + Suspended ssh root@hypervisor $ vncviewer localhost:5900 ^Z[2] + Suspended vncviewer localhost:5900 $ bg [2] vncviewer localhost:5900 $ fg virsh #
Final note and conclusion
One last thing, if you nest your SSH sessions (an SSH session within another SSH session), you need to escape the ~
character if you want to send command to the SSH session within the first one.
$ ssh host1 # first SSH session host1$ ssh host2 # second SSH session host2$ ~? [help from the first SSH session] host2$ ~~? [help from the second SSH session]
Once again, OpenSSH is awesome, big thanks to all the folks working on it!