Some of the commands one can use for different kinds of things in SSH -
Start an SSH agent -
eval $(ssh-agent)
# OR
ssh-agent
# copy π the commands in the output
# and paste it on the shell to run them
Generate an SSH key π π pair -
ssh-keygen
ssh-keygen -t ed25519 -b 4096 -C email@gmail.com
ssh-keygen -t rsa -b 4096 -C email@gmail.com
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
HostName 52.164.241.168
User ec2-user
IdentityFile ~/.ssh/aws
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/gitlab
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github
Host bastion-prod
HostName 51.210.192.12
User karuppiah
IdentityFile ~/.ssh/aws
Host core-service-prod
HostName 10.50.16.87
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 10.10.0.0/16
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
hosts.
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