Lines starting with client $ are run on the client side. Lines with server $ are run on the remote side.

Whenever you're reading this, cryptofriday.rocks probably won't exist anymore 😃

# ssh from one host to another, the simplest way
client $ ssh ze@cryptofriday.rocks
# Terminates connection
server $ exit 

# Generating a new keypair, the interactive way
client $ ssh-keygen
# Show the generated public key ...
client $ less cryptofriday.pub
# ... and private key
client $ less cryptofriday

# Adding this private key to the server ...
client $ ssh-copy-id -i cryptofriday.pub ze@cryptofriday.rocks
# ... and logging in with it afterwards
client $ ssh -i ze@cryptofriday.rocks
# Shows ssh log, including failed authentication attempts
server $ journalctl -u sshd -f 
# Changing the configuration to "PasswordAuthentication no"
server $ vim /etc/ssh/sshd_config
# and reloading the service
server $ systemctl reload sshd
# host-based authentication is also a thing (not covered here)

# Default keypairs and client configs are located in ~/.ssh
client $ cd ~/.ssh ; ls

# ssh-agent startup, session login normally does this depending on distro
client $ eval $( ssh-agent )
# Listing available keys
client $ ssh-add -l
# Adding previously generated key
client $ ssh-add cryptofriday
# Adding everything under ~/.ssh
client $ ssh-add
# Adding a specific key. Remember about SSH_ASKPASS (and ssh-askpass)
client $ ssh-add /tmp/cryptofriday
# Security implications
client $ env | grep '^SSH_'
# Copying all keys under ~/.ssh to the remote side
client $ ssh-copy-id ze@cryptofriday.rocks
# So the server knows a lot about us, how we know about them?
client $ cat ~/.ssh/known_hosts # and maybe mess with it, talk about MITM possibilites

# Random files, random contents
client $ for i in $( seq 0 9 ); do fortune > "whatever.${i}.txt" ; done
# scp for single-time copying
client $ scp whatever.0.txt ze@cryptofriday.rocks:/tmp/fortune.txt
# sftp for a full ftp client
client $ sftp ze@cryptofriday.rocks
  sftp> pwd
  sftp> ls
  sftp> put whatever*
  sftp> cd /tmp
  sftp> mkdir sshfs
# A word about subsystems
server $ vim /etc/ssh/sshd_config
# sshfs is a FUSE filesystem over ssh
client $ sshfs ze@cryptofriday.rocks:/tmp/sshfs /tmp/remote
# Always umount it
client $ fusermount -u /tmp/remote

# Before anything, check the server configuration for GatewayPorts
server $ vim /etc/ssh/sshd_config

# On forward tunnels, check there's nothing running on localhost:5432
client $ nc -v -z -w 2 localhost 5432
# Port forwarding, local -> remote
client $ ssh -L ze@cryptofriday.rocks
# Check again
client $ nc -v -z -w 2 localhost 5432
# Connect to the remote service
client $ psql -h localhost -U postgres -d postgres -p 5432

# Forward tunnels to somewhere else, the gmail thing
client $ curl 'imaps://whatever:whatever@imap.gmail.com/INBOX?NEW'
# Set up a tunnel ...
client $ ssh -L 10993:imap.gmail.com:993 ze@cryptofriday.rocks
# ... and then connect through it ... 
client $ curl 'imaps://carlos:whatever@localhost:1993/INBOX?NEW'
# ... and after the certificate error, connect anyway
client $ curl -k 'imaps://carlos:whatever@localhost:1993/INBOX?NEW'

# Reverse tunnels, check there's nothing running on server:3000
server $ nc -v -z -w 2 localhost 3000
# start a redis instance
client $ docker run -d --rm --name redis redis:alpine
# Find out its ipaddress on the docker virtualized subnet
client $ docker inspect redis | grep IPAddress
# connect to it
client $ redis-cli -h set cryptofriday "fuck yeah"
# Set up a reverse tunnel
ssh -R 3000: ze@cryptofriday.rocks
# Connect to local redis
server $ redis-cli -h localhost -p 3000 get cryptofriday

# Dynamic socks proxy: check outbound IP address
client $ curl ifconfig.me
# Set up a dynamic tunnel
client $ ssh -D 2400 ze@cryptofriday.rocks
# Check again over the tunnel
client $ curl --socks5-hostname localhost:2400 ifconfig.me
# Which is the same address
client $ host cryptofriday.rocks
# Up a notch: tunnel to a tor proxy
client $ ssh -L -D 2400 ze@cryptofriday.rocks
client $ curl --socks5-hostname localhost:9050 ifconfig.me
# On DNS leaks, and workarounds
client $ proxychains -f ~/.proxychains.2400.conf curl ifconfig.me
client $ torsocks curl ifconfig.me

# The -w thing : better not to.

# On misc options to do nothing and to send it to background
client $ ssh -N -L 9050: ze@cryptofriday.rocks
# -T: non-TTY allocation, same effect
client $ ssh -T -L 9050: ze@cryptofriday.rocks
# -f forks to background
client $ ssh -fNn -L 9050: ze@cryptofriday.rocks
client $ nc -v -z 9050 localhost
client $ pidof ssh
client $ kill $( pidof ssh )
# Or do it on the shell, with an & at the end

# Escape sequences, from the server side
server $ ~?
server $ ~.

# X11 forwarding
client $ ssh -Y ze@cryptofriday.rocks
# For some reason I can't make -X work
server $ xeyes
server $ sol

# Writing stdin to a remote port (telnet over ssh)
client $ ssh -W ze@cryptofriday.rocks

# Proxy jumping
client $ ssh user@first-hop 'uptime'
client $ ssh -J 'user@single-hop:22' ze@cryptofriday.rocks
client $ ssh another-user@second-hop 'uptime'
client $ ssh -J 'user@first-hop:22,another-user@second-hop:22' ze@cryptofriday.rocks

# Proxy jumping the old way with stdio forwarding
client $ ssh -o ProxyCommand='ssh -W %h:%p user@single-hop' ze@cryptofriday.rocks

# Proxying over http 
client $ ssh -o ProxyCommand='corkscrew proxy.host 3128 %h %p' ze@cryptofriday.rocks

# Multiplexing connections
client $ for i in $( seq 10 ); do time ssh ze@cryptofriday.rocks true ; done
# Start a new process in one tab ...
client $ ssh -M -S /tmp/cryptofriday.sock ze@cryptofriday.rocks
# ... and make use of it in another one
client $ ssh -S /tmp/cryptofriday.sock ze@cryptofriday.rocks
# Also sample it as well
client $ for i in $( seq 10 ); do time ssh -S /tmp/cryptofriday.sock ze@cryptofriday.rocks true ; done
# Check on the master process
client $ ssh -O check -S /tmp/cryptofriday.sock a
# Tells master to stop receiving connections
client $ ssh -O stop -S /tmp/cryptofriday.sock a
# Tells master to exit
client $ ssh -O exit -S /tmp/cryptofriday.sock a

Out there