introduction#
here i expose my ssh usages & some advanced notions about it
i’ll speak about the ssh protocol as the openssh implementation
i’m tempted to write my articles in lower case only as i usually write so outside
read this article like a cheat sheet
fundamentals#
secure shell - ssh, is a very versatile protocol but generally used to access a remote server command line securely
- encapsulate in tcp/ip
- use port tcp/22 by default
- use asymetric cryptography
the first time accessing a remote ssh host, its public key fingerprint is prompted to know if you are accessing the wanted host - security reasons, prevent MitM attacks - asking you if you trust it or not
if yes, the fingerprint is paste in your ~/.ssh/known_hosts
w/ the associate ip address & encryption protocol; its now trusted by your local machine
modifications#
on the ssh server side, connexions behaviour can be modified in /etc/ssh/sshd_config
(sshd stands for ssh daemon)
basic ssh setup let you connect to a host entering an username & a password beside root
if modifications is made, for the changes to take effect: the sshd service needs to be restarted
systemctl restart sshd
for hosts using systemd, like debian distros
good practices#
change the ssh access port from the port 22
check if the root login is disabled (yes by default)
using ssh keys or certificates (authentication) + username & password (authorisation)
use differents keys to access different servers
use
~/.ssh/config
to easily manage keys & remote hostsuse a passphrase for your private keys
use an ssh bastion to centralise your connections from the outside
keys#
the server has a public key that everyone can see, only you have the private key to connect to the server; public key -> the lock, private key -> the key…
private & public keys are generated simultaneously, various encryption algorithms could be choosen
private keys default location is ~/.ssh
in your local machine - perfectly fine with it
w/ openssl, this command brings forms to fill to create a public & a private key pair
ssh-keygen # to generate keys
to automate or create many at once w/out filling the forms:
-C
can be used to add a comment to a key-t
to choose the encryption algorithm - rsa by default-b
number of bytes, the more the better encryption-f
the location, usefull when creating many keys at once-N ""
specify a passphrase, replace what’s inside""
pushing a public key to a remote host, after running the ssh-keygen
command - make sure an ssh server is running on the remote host & that you have login for it
ssh-copy-id -i path/to/key.pub username@remotehost
or
cat path/to/key.pub | ssh username@remotehost "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
passphrases#
passphrases can be added to private ssh keys, preventing the usage of the key if stolen
config file#
~/.ssh/config
serve the ssh client to manage its remote hosts
it simplifies your connexions, since you only use to do ssh debian-vm
for example
Host abitraryname
Hostname remotehost
User username
Port sshport
IdentityFile /path/to/privatekey
after changes, no need to restart a service
ssh abitraryname
certificates#
works in the same way tls/ssl does for https
used to scale ssh, usefull to create a limited time access
after creating a public & a private key (saw in keys), those can be signed w/ a Certificate Authority (CA) certificate
ssh-keygen -s hostca -I hostname.domain.tld -h -n hostname.domain.tld -V +52w key.pub
-s hostca
specify the file name of the CA private key-I hostname.domain.tld
the certificate’s identity-h
specify its an host certificate, not an user one-n hostname.domain.tld
url to access the future host-V +52w
certificates’s validity period (52 weeks)
(a passphrase can be asked)
key-cert.pub
should be generated
to use it, paste the the ca to the /etc/ssh
folder on the local host for example
and edit in the /etc/ssh/sshd_config
file:
HostCertificate /etc/ssh/key-cert.pub
the remote host now present a certificate to anyone who connects
to the client side, trust the ca in `$HOME/.ssh/know_hosts
@cert-authority *.domain.tld ssh-rsa <hostca.pub content>
file transfering#
ways to transfer ressources to & from a remote host
from a remote host#
gather a file from a remote host
scp username@remotehost:/remote/path/to/file .
gather a folder from a remote host
scp -r username@remotehost:/remote/path .
synchronising files from a remote host using rsync
rsync username@remotehost:/remote/path/to/file .
rsync -r username@remotehost:/remote/path .
to a remote host#
send a file to a remote host
scp filename username@remotehost:/remote/path
send a folder to a remote host
scp -r directoryname username@remotehost:/remote/path
rsync
ing
rsync filename username@remote-host:/remote/path
rsync -r directoryname username@remote-host:/remote/path
mount a remote folder#
mount a remote directory on local system w/ sshfs (ssh file system)
apt install -y sshfs # depends on your package manager
mkdir mount-dir
mount the remote directory in the created folder
sshfs username@remote-host:/remote/path mount-dir
changes in the mount-dir
will also be made in remote-host:/remote/path
to unmount it
umount mount-dir
sftp#
ssh file transfer protocol, or secure file transfer protocol
can be used with the sftp
command to open a remote shell
sftp username@remotehost
can navigate with pwd
, ls
, cd
& use get
or put
to gather or send ressources
get filename
put filename
or
get /path/to/remote/file /path/to/local/directory
put /path/to/local/file /path/to/remote/directory
a gui like filezilla for an easier transfer experience (gui) can be done
x11 forwarding#
use remote app gui on local host
config remote server#
run with root or sudoer
apt install -y xauth # to forward x11 packets, depends pkgs manager
allowing x11 fowarding in /etc/ssh/sshd_config
by removing #
87#AllowAgentForwarding yes
88#AllowTcpForwarding yes
89#GatewayPorts no
90X11Forwarding yes
91#X11DisplayOffset 10
92#X11UseLocalhost yes
93#PermitTTY yes
systemctl restart sshd
ssh into it & try launching xapplications
depending on the remote server configuration, some extra work could be intended
ssh tunneling#
to access specific ressources, vpns expose an entire network which cannot be relevant for security reasons
ssh tunneling encapsulate a layer 3-7 traffic between 2 hosts over ssh
ssh encryption is added to the communication - so that if an unsecured communication is used, it is encrypted
it can also be used to bypass firewall restrictions by fowarding ports
uncontrolled or unmonitored tunnels can be used as backdoors, for data exfiltration, bouncing attacks & more
local fowarding#
forward a port from a ssh client to a ssh server (launched from the ssh client)
extremely usefull to access a remote service denyied by a firewall, it needs the remote host to be accessible with ssh
let’s say you have a raspberry pi at 192.168.1.12
(remote host) w/ ssh access via the pi
user
it shosting a web server locally on its 5000
port & you want to access it locally through your machine
ssh -N -L 127.0.0.1:8080:127.0.0.1:5000 pi@192.168.1.12
ssh -N -L 8080:127.0.0.1:5000 pi@192.168.1.12
-N
prevents from running an active ssh session
all traffic (http requests) sent to localhost:8080 on local machine will be forwarded to raspberry pi’s 5000 port - responses sended back to you
LocalForward
variable can be edited in the config file to avoid putting it every connexion
reverse ssh tunnels#
also called remote ssh tunnels or ssh remote forwarding
forward a port on a remote host (ssh server) to a port on a local machine (ssh client)
initialised by the remote server
used to access a service hosted on a remote local network, from another network (or internet)
widely use to exploit systems on private networks
let’s say: the remote server is locally running a web server on its port 80
, its local network address is 192.168.1.23
the local machine public ip address is 8.8.8.8
- google one & accessible w/ ssh
ssh -N -R localhost:8080:192.168.1.23:80 root@8.8.8.8
ssh -N -R 8080:192.168.1.23:80 root@8.8.8.8
the service running the remote server port 80
will be accessible by the local machine loopback address on port 8080
prevent tunnels#
PermitTunnel no
can be changed in /etc/ssh/sshd_config
to prevent tunnels creation
ssh bastions#
can be called ssh jump servers, ssh proxies or ssh agent forwarding
a single server accessible via ssh from the internet to redirect ssh sessions to others hosts
usefull to centralise & secure ssh connexions in a corporate network to reduce the “attack surface” to just one machine
teleport is an opensource solution if not using openssh
advices#
- only the ssh port should be accessible for incomming connexions
- the ssh port is changed from 22
- root user is disabled
- be very aware of the security implementations
- prevent users to use an ssh active session into the bastion itself
other purposes#
can be used to encapsulate data, doing other services than transporting ssh packets
can be used as a “vpn”, doing dynamic ssh port forwarding & encapsulate your data w/out exposing an entire network (ssh + socks5 proxy)
command#
ssh -J bastionaddress username@remotehost
-J
parameter can be avoided by configuring the ProxyJump
permanently in config file
parameters saw in config file can be added too
Host arbitraryname
ProxyJump bastionaddress
creation of an ssh user that cannot ssh into the bastion itself, called bastionuser
in /etc/ssh/sshd_config
give this user to anyone using the bastion
Match User bastionuser
PermitTTY no
X11Forwarding no
PermitTunnel no
GatewayPorts no
ForceCommand /usr/sbin/nologin
then modify the parameters
ssh -J bastionuser@bastionaddress username@remotehost
for the ~/.ssh/config
Host remotehost
ProxyJump bastionuser@bastionaddress
chrooting#
change root (chroot) method changes appareant root directory for the running user to a root directory called a chrooting jail
usefull when giving access to untrusted or unmonitored users
ssh support chrooting by restricting an ssh session to a directory
you can create a fancy one manually but it is very long, for each user
rssh is a simpler way to do so
create a new user with the /usr/bin/rssh
shell
useradd -m -d /home/chrooteduser -s /usr/bin/rssh chrooteduser
passwd chrooteduser
or change existing user shell to /usr/bin/rssh
usermod -s /usr/bin/rssh chrooteruser
works for sftp & scp
dnssec#
ssh use tofu trust on first use, it trusts the ssh server the first time connecting to it
so if someone tried to impersonate the remote host identity or the host change, its fingerprint will be different & a warning will pop up saying that’s not the wanted server
if targetted by a man-in-the-middle attack the first connexion, you could be at risk using ssh connexion
dnssec has many features to improve the standard & old dns protocol, one of which is: dns answers are not tampered
it is possible that an attacker can hijack ssh connexions & create valid dnssec responses, but less likely
use ssh-keygen
as usual w/ an url using dnssec & a .
at its end to stop the domain for beeing repeated twice
ssh-keygen subdomain.domainwithdnssec.tld.
then
ssh -o VerifyHostKeyDNS=yes subdomain.domainwithdnssec.tld.