SSH tricks and cheatsheet

SSH tricks and cheatsheet

Some of the commands one can use for different kinds of things in SSH -

Start an SSH agent -

eval $(ssh-agent)

# OR

# copy πŸ“‹ the commands in the output
# and paste it on the shell to run them

Generate an SSH key πŸ”‘ πŸ” pair -


ssh-keygen -t ed25519 -b 4096 -C

ssh-keygen -t rsa -b 4096 -C

Add SSH private keys to the SSH agent -

ssh-add $HOME/.ssh/private_key

List the SSH private keys added to the SSH agent -

ssh-add -L # Lists public key parameters of all identities

ssh-add -l # Lists fingerprints of all identities

Remove all identities from the SSH agent -

ssh-add -D

SSH into a destination -

ssh destination

The destination can be defined in the SSH config file, usually situated at $HOME/.ssh/config

Host server1
    User ec2-user
    IdentityFile ~/.ssh/aws

    User git
    IdentityFile ~/.ssh/gitlab

    User git
    IdentityFile ~/.ssh/github

Host bastion-prod
    User karuppiah
    IdentityFile ~/.ssh/aws

Host core-service-prod
    ProxyJump bastion-prod
    User karuppiah
    IdentityFile ~/.ssh/aws

You can also see how ProxyJump can be used to SSH into a machine using another machine as a proxy

Your Machine --> Proxy Machine --> Machine to SSH into

People do this when the machine they want to SSH into is not directly accessible from their network. For example, a lot of infrastructure setups have almost all machines in a private network, for example and only one instance is available in the public network with public IP and is also available in the private network, this machine is usually called a bastion host. People SSH into the bastion host and then SSH into other machines in the private network, as only the bastion host has a public IP while others don't. One can also directly SSH into a machine in the private network by using the bastion as a proxy machine, using ProxyJump directive in the SSH config file, or by using -J in ssh command

It's also a good idea to use different SSH key pairs for different environments (production, staging etc), and maybe even different SSH key pairs for each machine. But yes, it's not easy to manage these SSH key pairs. Maybe look for tooling in this space. Check out something like Hashicorp Boundary.

In my case, I use one key pair for each environment, which allows me to do some stuff, like this -

ssh -A bastion-prod

ssh redis

This allows me to have the SSH private key only in my local machine and does not require the private key to be present in the Bastion host to be able to SSH into the Redis server from the Bastion host. A secure way would be to use -J (proxy jump) or ProxyJump directive in the SSH config file, as mentioned in the ssh manual. See below πŸ‘‡ ⬇️ for details from the manual regarding both -

-A      Enables forwarding of connections from an authentication agent such as ssh-agent(1).  This can also be
        specified on a per-host basis in a configuration file.

        Agent forwarding should be enabled with caution.  Users with the ability to bypass file permissions on
        the remote host (for the agent's UNIX-domain socket) can access the local agent through the forwarded
        connection.  An attacker cannot obtain key material from the agent, however they can perform operations
        on the keys that enable them to authenticate using the identities loaded into the agent.  A safer
        alternative may be to use a jump host (see -J).


-J destination
        Connect to the target host by first making a ssh connection to the jump host described by destination
        and then establishing a TCP forwarding to the ultimate destination from there.  Multiple jump hops may
        be specified separated by comma characters.  This is a shortcut to specify a ProxyJump configuration
        directive.  Note that configuration directives supplied on the command-line generally apply to the
        destination host and not any specified jump hosts.  Use ~/.ssh/config to specify configuration for jump

Also, of course, it's important to keep your SSH public key in all the machines you want to SSH into inside the $HOME/.ssh/authorized_keys

You can also forward a local port in a local machine to a remote port in a remote machine. You can use -L option for this in ssh. More details below πŸ‘‡ ⬇️

-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
        Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be
        forwarded to the given host and port, or Unix socket, on the remote side.  This works by allocating a
        socket to listen to either a TCP port on the local side, optionally bound to the specified
        bind_address, or to a Unix socket.  Whenever a connection is made to the local port or socket, the
        connection is forwarded over the secure channel, and a connection is made to either host port hostport,
        or the Unix socket remote_socket, from the remote machine.

        Port forwardings can also be specified in the configuration file.  Only the superuser can forward
        privileged ports.  IPv6 addresses can be specified by enclosing the address in square brackets.

        By default, the local port is bound in accordance with the GatewayPorts setting.  However, an explicit
        bind_address may be used to bind the connection to a specific address.  The bind_address of β€œlocalhost”
        indicates that the listening port be bound for local use only, while an empty address or β€˜*’ indicates
        that the port should be available from all interfaces.

For more information about the SSH commands and how to use them, just check the corresponding command's manual

man ssh-agent

man ssh-keygen

man ssh-add

man ssh