SSH everywhere
Just a couple of notes on why I prefer ssh over other protocols, and how to configure it.
Avoid passwords, use keys
It makes it easier to automate jobs (like copying files in a script) and avoid typing passwords
First, generate the key with ssh-keygen
.
Then, add to ~/.ssh/config
something like
Host <name of remote>
HostName <ip or name of machine>
Port <port to connect>
User <username>
IdentityFile <path to generated key>
#IdentitiesOnly yes
# otherwise ssh tries all keys
Host *
IdentitiesOnly yes
At this point, copy the public key on the remote machine: ssh-copy-id -i ~/.ssh/mykey <name of remote>
.
Notice that because of ~/.ssh/config
, we do not need to specify the actual name of the remote (or its IP address), nor the username or port.
Once the public key has been successfully copied, change ~/.ssh/config
to
Host <name of remote>
HostName <ip or name of machine>
Port <port to connect>
User <username>
IdentityFile <path to generated key>
IdentitiesOnly yes
# otherwise ssh tries all keys
Host *
IdentitiesOnly yes
In other words: uncomment the first IdentitiesOnly yes
.
At last, you should be able to connect with ssh <name of remote>
without typing the password. It is possible to use ssh -v <name of remote>
to see that ssh tries to use the indicated key.
Use tmux
or screen
If the connection is lost, one generally cannot reopen the previous console with the program running.
If all programs are executed from tmux
or screen
, this is a non-issue.
As using nested tmux
or screen
sessions is impractical, I would recommend adding at least a second modifier for the nested session.
Currently, I am using a function similar to
ssht () {
ssh -t "$1" "tmux new-session -A -s new-session -A -s ssh_session\; set-option -g prefix2 C-a\; set -g mouse on"
}
This way, by typing ssht remote
, when I’m connecting to remote
, I’ll be presented to the already existent or newly created session ssh_session
. Also tmux
session on the remote will use both Ctrl+A and Ctrl+B as prefix modifier (unless configured otherwise). Thus when using nested tmux session (one on the remote, the other on the host) Ctrl+B is used for controlling the tmux
session on the host, Ctrl+A for controlling the session on the remote.
An interesting alternative is
ssht () {
ssh -t "$1" "tmux -S /tmp/tmux-k -f myconfig-file -u -2 new-session -A -s ssh_session\; set-option -g prefix2 C-a\; set -g mouse on"
}
as it would use by default a different tmux
configuration file on a different socket. This might be useful when sharing a user account on a remote machine, and when the other user also uses tmux
.
Note that if myconfig-file
does not need to exist, tmux
will display a warning but start successfully.
VirtualBox
VirtualBox makes it easy to open a connection between the host and guest operating system.
Under Settings, if the connection is NAT, add something similar to port forwarding
name| protocol | host ip | host port | guest ip | guest port
ssh | tcp | 127.0.0.1 | 2222 | | 22
It is possible to also add those settings from the command line
vboxmanage modifyvm <name of vm> --natpf1 "ssh,tcp,127.0.0.1,2222,,22"
22
is the default port on the guest for ssh
, while 2222
is an unused port on the host. A possible ~/.ssh/config
on the host could then look like
Host vdebian
HostName 127.0.0.1
Port 2222
User debian
IdentityFile ~/.ssh/id_rsa_vdebian
IdentitiesOnly yes
Starting the virtual machine and connecting (omit the first command if the VM is already running) is just vboxmanage startvm vdebian --type headless && ssh vdebian
.
On can also verify programmatically if the machine is running, and starting it if not:
#!/bin/sh
if ! vboxmanage list runningvms | grep vdebian >/dev/null; then :;
vboxmanage startvm vdebian --type headless
fi
ssh vdebian "$@"
If you want to reach the virtual machine from other machines, then you should leave the host IP empty:
vboxmanage modifyvm <name of vm> --natpf1 "ssh,tcp,,2222,,22"
Windows
Windows uses by default other protocols for connecting to remote machines. ssh
is only recently (since Windows 10) a first-class citizen, thus it is not as ubiquitous as SSH on other systems.
Native SSH
To install and configure SSH, follow the official documentation 🗄️:
# Query if OpenSSH is available, and which versions
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
# suppose output is similar top
# Name : OpenSSH.Client~~~~0.0.1.0
# State : Installed
# Name : OpenSSH.Server~~~~0.0.1.0
# State : NotPresent
# install client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
# install server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Start the sshd services, and set to autostart
Get-Service ssh-agent | Set-Service -StartupType Automatic -PassThru | Start-Service
Get-Service sshd | Set-Service -StartupType Automatic -PassThru | Start-Service
Notice that ssh-copy-id
won’t work for deploying keys, so it needs to be done manually
# note: because the default shell is cmd, use '\' instead of '/' for representing a path
ssh <win remote> mkdir 'C:\Users\username\.ssh';
scp <public key> <win remote>:'C:\Users\username\.ssh\authorized_keys';
Update (2024-02-07): If scp
fails with subsystem request failed on channel 0
, then using the option -O
should fix the issue:
# note: because the default shell is cmd, use '\' instead of '/' for representing a path
scp -O <public key> <win remote>:'C:\Users\username\.ssh\authorized_keys';
The default shell is cmd, which is… let’s change the default SSH shell at least to PowerShell. I could not find any user-specific settings, only a global one.
ssh <win remote> reg add 'HKLM\SOFTWARE\OpenSSH' /v DefaultShell /t REG_SZ /d 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
In case your user is also an administrator, you might want to take a look at this (unfortunately rejected) issue. The Microsoft port of OpenSSH has some non-standard behavior, the TLDR is to comment following lines from C:/ProgramData/ssh/sshd_config
out:
Match Group administrators
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
cygwin
The main advantage compared to the integrated ssh
is that Cygwin comes with a bash
shell, and thus a more familiar environment (tmux
and screen
included).
Download the setup from the Cygwin website, and execute it as administrator. While installing Cygwin, remember to select the openssh
and cygrunsrv
packages.
Once the installation has finished, open a Cygwin terminal as administrator(!), and execute ssh-host-config
. An interactive setup will ask some basic questions about how to configure the service.
Afterward, I needed to add a new firewall rule
New-NetFirewallRule -Name 'Cygwin-sshd' -DisplayName 'Cygwin-sshd' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Contrary to the integrated Windows ssh package, with Cygwin it is possible to deploy the key with ssh-copy-id
:
ssh-copy-id -i <key> <win remote>
Android
The most profitable way to use ssh
on Android is by using Termux (updated versions are available on F-Droid). For security reasons, connecting with a password is completely disabled. This is generally a good thing but also means that ssh-copy-id
will not work for deploying the first public key. It needs to be added manually to ~/.ssh/authorized_keys
.
In case you are unable to connect to your Android phone via SSH, you can view the logs either from Termux or adb
with logcat -s 'sshd:*'.
.
Also, note that the default port is 8022
and not 22
.
GNU/Linux distributions
If not available, install the SSH package provided by your distribution. Everything should work out of the box.
Graphical programs
Even if ssh
is used for executing mainly command line applications, it can also be used for starting graphical programs.
On Windows, when connecting with Cygwin to a remote machine that uses X11 (many Linux distributions), before executing ssh
, you should execute
startxwin;
export DISPLAY=:0.0;
while on GNU/Linux systems, export DISPLAY=:0.0;
should be sufficient.
X11 forwarding can be used in ssh
with the -X
or -Y
flags.
-
-X
might be more secure (depending on your config), but might not work with some programs (unless changing some configuration) -
-Y
will work more often, but if you use it, be sure to trust the remote machine (it could log the key presses, take screenshots, and steal other data)
Those settings can also be set in .ssh/config
, those are the options ForwardX11
and ForwardX11Trusted
, and can be set to yes
or no
(with no
being the default value, more information can be read from man ssh_config
)
I did not find any information on how to start a graphical application on a Windows remote.
Do you want to share your opinion? Or is there an error, some parts that are not clear enough?
You can contact me anytime.