Difference between revisions of "SSH"

From Freephile Wiki
Jump to navigation Jump to search
(adds example with rsync)
 
(14 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
[[File:Ssh cheat sheet.pdf|thumb]]
 +
See the [[Using keys]] article as well
 +
 
== Best Practices ==
 
== Best Practices ==
  
<abbr title="National Institute of Standards and Technology">NIST</abbr> has released their August 2014 draft "Security of Automated Access Management Using Secure Shell (SSH)" available at http://csrc.nist.gov/publications/drafts/nistir-7966/nistir_7966_draft.pdf
+
NIST has released their August 2014 draft "Security of Automated Access Management Using Secure Shell (SSH)" available at http://csrc.nist.gov/publications/drafts/nistir-7966/nistir_7966_draft.pdf
 +
 
 +
You might want to read https://stribika.github.io/2015/01/04/secure-secure-shell.html
  
 
HOWTO can be found at http://www.debuntu.org/ssh-key-based-authentication
 
HOWTO can be found at http://www.debuntu.org/ssh-key-based-authentication
 +
 +
Another good site with HOWTO and explanatory info, along with commercial products and support, is https://www.ssh.com/ssh/
  
 
== Configuration ==
 
== Configuration ==
Line 51: Line 58:
 
Hostname github.com
 
Hostname github.com
 
IdentityFile /home/greg/.ssh/<id_rsa.MYKEY>
 
IdentityFile /home/greg/.ssh/<id_rsa.MYKEY>
 +
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1
  
 
host *.amazonaws.com
 
host *.amazonaws.com
Line 58: Line 66:
 
HostName ec2-72-44-63-125.compute-1.amazonaws.com
 
HostName ec2-72-44-63-125.compute-1.amazonaws.com
 
</source>
 
</source>
 +
 +
Note the KexAlgorithms line for GitHub.  You might need to add this if you're getting a 'failed to negotiate a key exchange' error from github.  See <code>ssh -vQ kex</code> for the algos your system supports.  And fix up your moduli file <ref>https://stribika.github.io/2015/01/04/secure-secure-shell.html</ref>
 +
 +
== Server Configuration ==
 +
 +
<blockquote>It is strongly recommended that LogLevel be set to VERBOSE. This way, the key fingerprint for any SSH key used for login is logged. This information is important for SSH key management, especially in legacy environments.
 +
</blockquote> <ref>https://www.ssh.com/ssh/sshd_config/</ref>
 +
 +
<pre>
 +
PasswordAuthentication no
 +
PrintMotd yes
 +
LogLevel VERBOSE
 +
PermitRootLogin prohibit-password
 +
UsePAM no
 +
</pre>
 +
(Don't forget to sudo service ssh restart)
  
 
== Client ==
 
== Client ==
Line 65: Line 89:
 
Installing a program like [http://projects.gnome.org/seahorse/ Seahorse] makes it trivially easy to manage your GnuPG encryption keys.  Seahorse just makes it easier for you to do what you otherwise would accomplish with several commands.  You can generate a private key; and add the public key to remote servers enabling you to login to those remote servers without using a password.
 
Installing a program like [http://projects.gnome.org/seahorse/ Seahorse] makes it trivially easy to manage your GnuPG encryption keys.  Seahorse just makes it easier for you to do what you otherwise would accomplish with several commands.  You can generate a private key; and add the public key to remote servers enabling you to login to those remote servers without using a password.
  
 +
=== VSCode and VirtualBox ===
 +
When using [[VirtualBox]] to manage Linux VMs on your local Windows host, you can setup your SSH config file with a simple stanza to forward local connections on port 2222 to the SSH server on the VM like this.
 +
<syntaxhighlight lang="bash">
 +
Host 127.0.0.1
 +
  HostName 127.0.0.1
 +
  User root
 +
  Port 2222
 +
  IdentityFile C:/Users/greg/.ssh/id_ed25519
 +
</syntaxhighlight>
 +
In this way, [[VSCode]] will be able to seamlessly connect to the VM, without prompting for a password every time.
  
 
== Fingerprints ==
 
== Fingerprints ==
Line 73: Line 107:
 
</source>
 
</source>
  
 +
== Public Key ==
 +
{{ambox
 +
|text=
 +
<code>ssh-keygen -t ed25519 -b 4096</code> is the new standard rather than using the old RSA key encryption format. Ed25519 has a smaller key size (so faster and more efficient) and can be more secure.
 +
}}
 +
 +
Normally, with <code>ssh-keygen -t rsa -C "you@example.com"</code> you get a (private) key file <code>id_rsa</code>, plus a (public) key denoted with the extension .pub <code>id_rsa.pub</code>.  But what about formats like .pem?  Amazon AWS manages access with "keypairs" and you are prompted to download the private X509 certificate file as a .pem file when you generate the keypair.  Where is the public key?  Amazon displays the 'fingerprint' for the file which is usually enough to identify the private file, but can you place a fingerprint in the <code>authorized_keys</code> file?  If you have a private key file and want to show the public key that corresponds to it, you can do so with <code>ssh-keygen</code>
 +
<source lang="bash">
 +
# show me the public key that corresponds to my private id_rsa key
 +
ssh-keygen -yf /home/greg/.ssh/id_rsa
 +
# show me the public key that corresponds to my private pem file that I got from the Amazon AWS Console
 +
ssh-keygen -yf /home/greg/.ssh/amazon-aws.pem
 +
</source>
 +
 +
This will output something like
 +
<pre>
 +
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaCu+OVCGMogx12xeX0ZzhVZWML93QCJaV4uilfIsAkizwSHFy/Q5h/JGEYc0l1wwkQ5PENMCQJhBv530h7wQsCE+maqm4lXgFyoDkWLm9N9Oa0fvLuI++WywC12V8HsKcJmDwZtf5zL1o2zB8VY3oqkD2AF/IGccip+aYo9HQ97dyXIRt9m/pFQVNwbRf0uBA0C4b8uQLB2zMCZqGYeUZX65MaplG2NthBHvxsaODX0YeRVdn9bJuujXvXmnlwzl6vF8WgGusYbumxy12QaO//onQJA9y8/gdsggL24VwgBnp4GZiNZBN18dKYL9bGuiQzHPEqfnePARd0gGksz+j
 +
</pre>
 +
 +
You can then append this to the <code>/home/ubuntu/.ssh/authorized_keys</code> file on your AWS linux host to enable another key to login to the host.
 +
 +
== Using Multiple Keys ==
 +
Sometimes you have so many keys, that you can be denied access even when supplying a key file with the <code>--IdentityFile</code> or <code>-i</code> option.  The problem is that you would '''assume''' that <code>ssh -i /home/me/.ssh/my_private_key me@example.com</code> is directing ssh to use a specific key.  That's not what's happening.  Instead, it's adding that key to the list of keys that it would otherwise present to the server.  That list of keys (in your ssh-agent, if running) found in your .ssh directory may well contain 3 or more.  And thus, you get blocked by authentication failure (using the wrong keys) before your '''added''' key is tried.  Use the somewhat misnamed option '''IdentitiesOnly''' (should be named ''ThisIdentityOnly'') to solve this problem.  <code>IdentitiesOnly</code> will instruct SSH to use ONLY the keys you tell it to use.
 +
 +
<code>ssh -o IdentitiesOnly=true -i /home/me/.ssh/my_private_key me@example.com</code> will now work
 +
 +
== Using No Keys ==
 +
Sometimes you can get an error about '''too many authentication failures''' when you want to enter your password, but before you even get to enter your password.  This can happen when the source system silently offers a couple of keys (which are not authorized on the target host).  If the target host has a very low tolerance for auth failures in sshd_config like <code>MaxAuthTries=2</code>, they you'll get disconnected before you ever enter a password.  The way to counteract this is to tell ssh not to use Public Key Authentication at all:
 +
<code>ssh -o PubkeyAuthentication=no me@example.com</code>
 +
 +
== Tunnel ==
 +
You have a headless server running your development or production database(s).  You work on a nice workstation or laptop.  You want to use a graphical database administration tool like MySQL Workbench on the remote server. 
 +
<source lang="text">
 +
  # send local MySQL traffic on 33306 to the remote side standard port 3306
 +
  # this allows me to open a desktop client locally on the extended port
 +
  # and talk to the server like it was local through an encrypted SSH tunnel
 +
  # eqivalent to ssh -L 127.0.0.1:33306:127.0.0.1:3306 greg@freephile
 +
  # By putting this stanza in .ssh/config I can just "ssh eqt"
 +
Host do eqt et freephile freephile.org
 +
  HostName freephile.org
 +
  LocalForward 33306 localhost:3306
 +
  User greg
 +
  IdentityFile  ~/.ssh/id_rsa
 +
</source>
 +
 +
=== Debugging ===
 +
To find out what is connected and/or listening on a given port, you can use <code>[[lsof]]</code> with the <code>-i</code> option for '''Internet files'''
 +
e.g.
 +
<source lang="bash">
 +
# mysql
 +
sudo lsof -i :3306
 +
# postgres
 +
sudo lsof -i :5432
 +
# mail
 +
sudo lsof -i :smtp
 +
# how much is chrome doing (don't necessarily need sudo)
 +
lsof -c chrome
 +
</source>
 
== Reverse Tunnel ==
 
== Reverse Tunnel ==
 
Maybe you've got a production database server that wasn't setup properly for security, and only allows "local" database connections.  You need to access your production data from places other than your datacenter.  You could fix it - but that would take a lot of effort that the boss doesn't care about.  SSH to the rescue!
 
Maybe you've got a production database server that wasn't setup properly for security, and only allows "local" database connections.  You need to access your production data from places other than your datacenter.  You could fix it - but that would take a lot of effort that the boss doesn't care about.  SSH to the rescue!
Line 94: Line 186:
 
ubuntu@amazon:/home/ubuntu/wiki-extensions/
 
ubuntu@amazon:/home/ubuntu/wiki-extensions/
 
</source>
 
</source>
[[Category:System Adminstration]]
+
 
 +
== Logging ==
 +
On the server side, to see what's going on, <code>tail /var/log/auth.log</code>
 +
 
 +
== On Windows ==
 +
Since late 2018, Microsoft has included a '''fork''' of the OpenSSH project in Windows.<ref>"OpenSSH has been added to Windows (as of autumn 2018), and is included in Windows Server and Windows client." - https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview
 +
 
 +
At the time of writing, the Microsoft fork is 618 commits ahead, 168 commits behind openssh:master of the OpenBSD OpenSSH project. 'portable' in the OpenSSH project was the term used when the software was made compatible with Unixes other than OpenBSD. The '''open source OpenSSH project repo is at https://github.com/openssh/openssh-portable '''
 +
 
 +
The Microsoft fork of OpenSSH is at https://github.com/PowerShell/openssh-portable
 +
</ref>
 +
 
 +
Your client config on Windows is at 
 +
<tt>%userprofile%\. ssh\config</tt>
 +
 
 +
 
 +
{{References}}
 +
 
 +
[[Category:System Administration]]
 +
[[Category:Security]]
 +
[[Category:SSH]]

Latest revision as of 10:09, 11 January 2024

Ssh cheat sheet.pdf

See the Using keys article as well

Best Practices[edit | edit source]

NIST has released their August 2014 draft "Security of Automated Access Management Using Secure Shell (SSH)" available at http://csrc.nist.gov/publications/drafts/nistir-7966/nistir_7966_draft.pdf

You might want to read https://stribika.github.io/2015/01/04/secure-secure-shell.html

HOWTO can be found at http://www.debuntu.org/ssh-key-based-authentication

Another good site with HOWTO and explanatory info, along with commercial products and support, is https://www.ssh.com/ssh/

Configuration[edit | edit source]

Setup a local user configuration for your SSH sessions to make things much easier.

Using the configuration below, I can simply "ssh server4" rather than ssh grundlett@server4.example.com or, "ssh server2" rather than "ssh -v -L 55432:localhost:5432 grundlett@server2.example.com"

cat .ssh/config

# keep ssh connections open
ServerAliveInterval 60

# set some aliases
host server2
HostName server2.example.com
# send local Postgres traffic on 55432 to remote side standard port 5432
# this allows me to open a desktop client locally on the extended port
# and talk to the server (like it was local) through an encrypted SSH tunnel
LocalForward 55432 localhost:5432

host server3
HostName server3.example.com
host server4
HostName server4.example.com
host server5
HostName server5.example.com

host it
HostName it00.example.net
ForwardX11 yes

# set some options for a pattern of hosts
host *.example.com server*
User grundlett

# HOW TO FORWARD X screen, and use agent forwarding
host example.com
User greg
ForwardAgent yes
ForwardX11 yes

host github.com
User <PUT YOUR USER HERE>
Hostname github.com
IdentityFile /home/greg/.ssh/<id_rsa.MYKEY>
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1

host *.amazonaws.com
User root
IdentityFile /home/grundlett/.ssh/ec2-keypair.pem
host amazon
HostName ec2-72-44-63-125.compute-1.amazonaws.com

Note the KexAlgorithms line for GitHub. You might need to add this if you're getting a 'failed to negotiate a key exchange' error from github. See ssh -vQ kex for the algos your system supports. And fix up your moduli file [1]

Server Configuration[edit | edit source]

It is strongly recommended that LogLevel be set to VERBOSE. This way, the key fingerprint for any SSH key used for login is logged. This information is important for SSH key management, especially in legacy environments.

[2]

PasswordAuthentication no
PrintMotd yes
LogLevel VERBOSE
PermitRootLogin prohibit-password
UsePAM no

(Don't forget to sudo service ssh restart)

Client[edit | edit source]

An encryption tool

Installing a program like Seahorse makes it trivially easy to manage your GnuPG encryption keys. Seahorse just makes it easier for you to do what you otherwise would accomplish with several commands. You can generate a private key; and add the public key to remote servers enabling you to login to those remote servers without using a password.

VSCode and VirtualBox[edit | edit source]

When using VirtualBox to manage Linux VMs on your local Windows host, you can setup your SSH config file with a simple stanza to forward local connections on port 2222 to the SSH server on the VM like this.

Host 127.0.0.1
  HostName 127.0.0.1
  User root
  Port 2222
  IdentityFile C:/Users/greg/.ssh/id_ed25519

In this way, VSCode will be able to seamlessly connect to the VM, without prompting for a password every time.

Fingerprints[edit | edit source]

The SSH key fingerprint tells you the authenticity of a host. Normally this info is stored in /etc/ssh/ for a Debian-based distro. You can also use the same command here to look at the fingerprint for your public key.

ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
2048 dd:54:23:d4:20:bc:f3:4c:88:a5:af:21:dd:a5:36:5d /etc/ssh/ssh_host_rsa_key.pub (RSA)

Public Key[edit | edit source]

Normally, with ssh-keygen -t rsa -C "you@example.com" you get a (private) key file id_rsa, plus a (public) key denoted with the extension .pub id_rsa.pub. But what about formats like .pem? Amazon AWS manages access with "keypairs" and you are prompted to download the private X509 certificate file as a .pem file when you generate the keypair. Where is the public key? Amazon displays the 'fingerprint' for the file which is usually enough to identify the private file, but can you place a fingerprint in the authorized_keys file? If you have a private key file and want to show the public key that corresponds to it, you can do so with ssh-keygen

# show me the public key that corresponds to my private id_rsa key
ssh-keygen -yf /home/greg/.ssh/id_rsa
# show me the public key that corresponds to my private pem file that I got from the Amazon AWS Console
ssh-keygen -yf /home/greg/.ssh/amazon-aws.pem

This will output something like

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaCu+OVCGMogx12xeX0ZzhVZWML93QCJaV4uilfIsAkizwSHFy/Q5h/JGEYc0l1wwkQ5PENMCQJhBv530h7wQsCE+maqm4lXgFyoDkWLm9N9Oa0fvLuI++WywC12V8HsKcJmDwZtf5zL1o2zB8VY3oqkD2AF/IGccip+aYo9HQ97dyXIRt9m/pFQVNwbRf0uBA0C4b8uQLB2zMCZqGYeUZX65MaplG2NthBHvxsaODX0YeRVdn9bJuujXvXmnlwzl6vF8WgGusYbumxy12QaO//onQJA9y8/gdsggL24VwgBnp4GZiNZBN18dKYL9bGuiQzHPEqfnePARd0gGksz+j

You can then append this to the /home/ubuntu/.ssh/authorized_keys file on your AWS linux host to enable another key to login to the host.

Using Multiple Keys[edit | edit source]

Sometimes you have so many keys, that you can be denied access even when supplying a key file with the --IdentityFile or -i option. The problem is that you would assume that ssh -i /home/me/.ssh/my_private_key me@example.com is directing ssh to use a specific key. That's not what's happening. Instead, it's adding that key to the list of keys that it would otherwise present to the server. That list of keys (in your ssh-agent, if running) found in your .ssh directory may well contain 3 or more. And thus, you get blocked by authentication failure (using the wrong keys) before your added key is tried. Use the somewhat misnamed option IdentitiesOnly (should be named ThisIdentityOnly) to solve this problem. IdentitiesOnly will instruct SSH to use ONLY the keys you tell it to use.

ssh -o IdentitiesOnly=true -i /home/me/.ssh/my_private_key me@example.com will now work

Using No Keys[edit | edit source]

Sometimes you can get an error about too many authentication failures when you want to enter your password, but before you even get to enter your password. This can happen when the source system silently offers a couple of keys (which are not authorized on the target host). If the target host has a very low tolerance for auth failures in sshd_config like MaxAuthTries=2, they you'll get disconnected before you ever enter a password. The way to counteract this is to tell ssh not to use Public Key Authentication at all: ssh -o PubkeyAuthentication=no me@example.com

Tunnel[edit | edit source]

You have a headless server running your development or production database(s). You work on a nice workstation or laptop. You want to use a graphical database administration tool like MySQL Workbench on the remote server.

  # send local MySQL traffic on 33306 to the remote side standard port 3306
  # this allows me to open a desktop client locally on the extended port
  # and talk to the server like it was local through an encrypted SSH tunnel
  # eqivalent to ssh -L 127.0.0.1:33306:127.0.0.1:3306 greg@freephile
  # By putting this stanza in .ssh/config I can just "ssh eqt"
Host do eqt et freephile freephile.org
  HostName freephile.org
  LocalForward 33306 localhost:3306
  User greg
  IdentityFile  ~/.ssh/id_rsa

Debugging[edit | edit source]

To find out what is connected and/or listening on a given port, you can use lsof with the -i option for Internet files e.g.

# mysql
sudo lsof -i :3306
# postgres
sudo lsof -i :5432
# mail
sudo lsof -i :smtp
# how much is chrome doing (don't necessarily need sudo)
lsof -c chrome

Reverse Tunnel[edit | edit source]

Maybe you've got a production database server that wasn't setup properly for security, and only allows "local" database connections. You need to access your production data from places other than your datacenter. You could fix it - but that would take a lot of effort that the boss doesn't care about. SSH to the rescue!

To setup the reverse tunnel from DESTINATION to SOURCE, you first get on the destination box and ssh to the source while telling that ssh session to "listen" on a high-number port

on DESTINATION (where you want to use the data)

ssh -R 19999:localhost:22 grundlett@source.ip

Then you get on the source machine, and ssh to localhost, but specify the high-range port number you reserved earlier.

on SOURCE machine

ssh localhost -p 19999

If you do these in screen sessions, they should survive any network connectivity issues and you can log out completely. See above config section to set this up by default for certain situations.

With rsync[edit | edit source]

If you need to pass SSH options to rsync, then use the --rsh= (-e) option.

rsync -n -e "ssh -i /home/greg/.ssh/ec2-west-wiki.pem" -vatz --stats \
/var/www/phase3-extensions/ \
ubuntu@amazon:/home/ubuntu/wiki-extensions/

Logging[edit | edit source]

On the server side, to see what's going on, tail /var/log/auth.log

On Windows[edit | edit source]

Since late 2018, Microsoft has included a fork of the OpenSSH project in Windows.[3]

Your client config on Windows is at %userprofile%\. ssh\config


References[edit source]

  1. https://stribika.github.io/2015/01/04/secure-secure-shell.html
  2. https://www.ssh.com/ssh/sshd_config/
  3. "OpenSSH has been added to Windows (as of autumn 2018), and is included in Windows Server and Windows client." - https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview At the time of writing, the Microsoft fork is 618 commits ahead, 168 commits behind openssh:master of the OpenBSD OpenSSH project. 'portable' in the OpenSSH project was the term used when the software was made compatible with Unixes other than OpenBSD. The open source OpenSSH project repo is at https://github.com/openssh/openssh-portable The Microsoft fork of OpenSSH is at https://github.com/PowerShell/openssh-portable