Introduction to SSH (Secure Shell)

  1. What Is SSH?


  2. How SSH Works: A Simple Overview




  3. SSH Key Pairs
  4. ssh-keygen -t ed25519 -C "your_email@example.com"


  5. Connecting to a Remote Server

  6. ssh username@hostname

    ssh ubuntu@54.23.11.222       # AWS EC2 instance
    ssh user@myserver.com         # domain
    ssh root@192.168.1.10         # LAN server

    ssh -i mykey.pem ubuntu@<public-ip>

    ssh -p 2222 user@host


  7. First-Time Connection and Host Keys

  8. The authenticity of host 'example.com (54.x.x.x)' can't be established.
    Are you sure you want to continue connecting (yes/no)?
    


  9. SSH Directory Layout

  10. ~/.ssh/
        id_ed25519           # private key
        id_ed25519.pub       # public key
        authorized_keys      # keys allowed to log in (on server)
        known_hosts          # server fingerprints
        config               # optional config file
    


  11. SSH Config File (Simplifies Connections)

  12. Host my-ec2
        HostName 54.23.11.222
        User ubuntu
        IdentityFile ~/.ssh/mykey.pem
        Port 22

    ssh my-ec2



  13. To Copy Files via SSH

  14. scp file.txt user@host:/remote/path/

    scp user@host:/remote/path/file.txt ./

    scp -r ./myfolder user@host:/var/www/

    rsync -avz ./site/ user@host:/var/www/site/


  15. Port Forwarding (Tunneling)


  16. ssh -L 8080:localhost:3000 user@host

    ssh -R 9000:localhost:3000 user@host


  17. SSH Agent (Storing Keys Temporarily)

  18. eval "$(ssh-agent)"
    ssh-add ~/.ssh/id_ed25519


  19. Hardening SSH Security




Common SSH Command Options

  1. Overview


  2. Basic Connection and Identity Options


  3. Option Description Example
    -p <port> Connect to the remote host on the specified TCP port (default is 22). ssh -p 2222 user@example.com
    -i <identity_file> Use this private key file for authentication (instead of the default ~/.ssh/id_*). ssh -i ~/.ssh/mykey.pem ubuntu@host
    -l <user> Specify the remote login user (same as user@host). ssh -l ubuntu 1.2.3.4
    -F <configfile> Use an alternative SSH config file instead of ~/.ssh/config. ssh -F ./ssh_config my-alias
    -4, -6 Force use of IPv4 (-4) or IPv6 (-6). ssh -4 user@example.com
    -C Enable compression on the SSH connection (useful on slow links). ssh -C user@example.com
    -q Quiet mode: suppress most warnings and diagnostic messages. ssh -q user@example.com


  4. Authentication and Key Handling


  5. Option Description Example
    -i <identity_file> Use specified private key file (repeated here because it is so common). ssh -i ~/.ssh/id_ed25519 user@host
    -A Enable SSH agent forwarding (forward your local agent to the remote host). ssh -A user@jumphost
    -a Disable SSH agent forwarding (explicitly turn it off). ssh -a user@host
    -K Enable GSSAPI-based authentication (Kerberos etc.), if configured. ssh -K user@host
    -o PreferredAuthentications=<methods> Specify which authentication methods to try (e.g., publickey,password). ssh -o PreferredAuthentications=publickey user@host
    -o IdentitiesOnly=yes Use only the explicitly specified identities (not every key from the agent). ssh -i ~/.ssh/work_rsa -o IdentitiesOnly=yes user@host


  6. Host Key Checking and Security


  7. Option Description Example
    -o StrictHostKeyChecking=yes|no|ask Control behavior when a host key changes or is unknown:
    yes = refuse; no = accept automatically; ask = prompt.
    ssh -o StrictHostKeyChecking=ask user@host
    -o UserKnownHostsFile=<file> Use a particular known-hosts file instead of ~/.ssh/known_hosts. ssh -o UserKnownHostsFile=./known_hosts user@host
    -o VerifyHostKeyDNS=yes|no Check host keys via DNS (SSHFP records), if configured. ssh -o VerifyHostKeyDNS=yes user@host
    -o HostKeyAlgorithms=<list> Specify which host key algorithms to accept (useful when dealing with older servers). ssh -o HostKeyAlgorithms=ssh-ed25519 user@oldhost


  8. Port Forwarding and Tunneling


  9. Option Description Example
    -L <local_port>:<host>:<host_port> Local port forward:
    listen on local port and forward to host:host_port from the remote side.
    ssh -L 8080:localhost:3000 user@server
    -R <remote_port>:<host>:<host_port> Remote port forward:
    listen on remote port and forward back to host:host_port on your local side.
    ssh -R 9000:localhost:3000 user@server
    -D <local_port> Dynamic port forwarding (SOCKS proxy) on the given local port.
    Useful for tunneling arbitrary traffic through SSH.
    ssh -D 1080 user@server
    -N Do not execute a remote command; only forward ports (no shell). ssh -N -L 5432:db.internal:5432 user@bastion
    -f Run SSH in the background (after asking for passwords / passphrases). ssh -f -N -L 8080:localhost:3000 user@server
    -g Allow remote hosts to connect to local forwarded ports (for -L / -D). ssh -g -L 8080:localhost:3000 user@server


  10. Jump Hosts and Proxies


  11. Option Description Example
    -J <user@jump>[,<user@jump2>...] Use one or more jump hosts (proxy jumps).
    SSH will connect through these hosts to reach the final destination.
    ssh -J jumphost user@target
    -o ProxyCommand=<command> Use a custom command to connect to the server (legacy way to implement jump hosts). ssh -o ProxyCommand="ssh jumphost nc %h %p" user@target
    -o ProxyJump=<host> Same as -J, for use in config files. ssh -o ProxyJump=jumphost user@target


  12. X11 Forwarding and Terminal Behavior


  13. Option Description Example
    -X Enable X11 forwarding (trusted or untrusted based on server config; sometimes restricted). ssh -X user@remote
    -Y Enable trusted X11 forwarding (less restricted, but requires caution). ssh -Y user@remote
    -t Force pseudo-tty allocation (useful when running interactive commands like top or sudo). ssh -t user@remote "sudo journalctl -f"
    -T Disable pseudo-tty allocation (never allocate a terminal). ssh -T git@github.com


  14. Debugging, Logging, and ControlMaster


  15. Option Description Example
    -v, -vv, -vvv Increase verbosity of logging (more v = more detailed).
    Useful for debugging handshake/auth problems.
    ssh -vv user@host
    -E <logfile> Append debug logs to the specified file. ssh -vvE ssh.log user@host
    -M Place the SSH connection into "master" mode for connection sharing (ControlMaster). ssh -M -S /tmp/ssh-sock user@host
    -S <ctl_socket> Specify the control socket path used for ControlMaster/ControlPath connections.
    Allows subsequent SSH calls to reuse the same TCP connection.
    ssh -S /tmp/ssh-sock user@host
    -O check|forward|exit Send control commands to an existing master connection (check status, request port forwarding, or close it). ssh -O check -S /tmp/ssh-sock user@host


  16. Generic -o Option (Config Key = Value)


  17. Example -o usage Meaning
    -o ConnectTimeout=5 Fail if connection cannot be established within 5 seconds.
    -o ServerAliveInterval=30 Send keepalive messages every 30 seconds to avoid idle disconnections.
    -o ServerAliveCountMax=3 After 3 unanswered keepalives, SSH will terminate the connection.
    -o LogLevel=ERROR Show only error messages (less verbose than the default).
    -o Compression=yes Enable compression (same effect as -C).



Introduction to ssh-keygen

  1. What Is It?


  2. Basic Usage: Generating a Key Pair

  3. ssh-keygen -t ed25519 -C "your_email@example.com"


  4. Key Types and Algorithms


  5. Type Option Notes
    Ed25519 -t ed25519 Modern, fast, short keys, recommended default if supported.
    RSA -t rsa Widely supported, use 3072 or 4096 bits for security.
    ECDSA -t ecdsa Elliptic curve, okay, but ed25519 is often preferred.
    DSA -t dsa Deprecated/insecure, do not use.

    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"


  6. Common Options (Quick Table)


  7. Option Meaning Example
    -t <type> Key type (rsa, ed25519, ecdsa, ...). ssh-keygen -t ed25519
    -b <bits> Key size (mainly for RSA). ssh-keygen -t rsa -b 4096
    -C <comment> Add a comment (often an email or label). ssh-keygen -C "laptop key"
    -f <filename> Specify output file (private key path). ssh-keygen -f ~/.ssh/myserver_ed25519
    -N <passphrase> Set passphrase non-interactively (be careful with shell history). ssh-keygen -N "mySecret" ...
    -p Change the passphrase of an existing key. ssh-keygen -p -f ~/.ssh/id_ed25519
    -y Read a private key and print the corresponding public key. ssh-keygen -y -f ~/.ssh/id_ed25519 > id_ed25519.pub
    -l Show fingerprint of a key. ssh-keygen -l -f ~/.ssh/id_ed25519.pub
    -E <hash> Specify hash for fingerprints (e.g., md5, sha256). ssh-keygen -l -E sha256 -f id_ed25519.pub


  8. Default Locations and File Names

  9. ~/.ssh/
        id_ed25519        ← default ed25519 private key
        id_ed25519.pub    ← its public key
        id_rsa            ← default RSA private key
        id_rsa.pub        ← its public key
    
    ssh-keygen -t ed25519 -f ~/.ssh/id_github -C "github key"


  10. Changing or Adding a Passphrase

  11. ssh-keygen -p -f ~/.ssh/id_ed25519


  12. Printing the Public Key from a Private Key (-y)

  13. ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub


  14. Checking Key Fingerprints (-l, -E)

  15. ssh-keygen -l -f ~/.ssh/id_ed25519.pub
    ssh-keygen -l -E sha256 -f ~/.ssh/id_ed25519.pub


  16. Managing known_hosts Entries


  17. Command Meaning
    ssh-keygen -F hostname Find and print host keys for hostname in known_hosts.
    ssh-keygen -R hostname Remove all keys for hostname from known_hosts (useful if the remote host changed its key).

    ssh-keygen -R example.com


  18. Typical Real-World Workflows

  19. # 1) Generate key
    ssh-keygen -t ed25519 -f ~/.ssh/id_github -C "github-email@example.com"
    
    # 2) Print the public key
    cat ~/.ssh/id_github.pub
    
    # 3) Copy the printed key into GitHub > Settings > SSH and GPG keys
    
    # 4) Use in SSH config
    cat >> ~/.ssh/config <<EOF
    Host github.com
        HostName github.com
        User git
        IdentityFile ~/.ssh/id_github
    EOF
    

    ssh-keygen -t ed25519 -f ~/.ssh/id_server -C "server key"
    
    # copy public key to server (if ssh-copy-id is available)
    ssh-copy-id -i ~/.ssh/id_server.pub user@server
    
    # or manually:
    cat ~/.ssh/id_server.pub  # copy this line
    # then paste it into server's ~/.ssh/authorized_keys
    


  20. Security Tips

  21. chmod 600 ~/.ssh/id_ed25519



SSH authorized_keys and Multiple Public Keys

  1. What Is ~/.ssh/authorized_keys?



  2. Can It Contain Multiple Public Keys?

  3. ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMyKeyForLaptop    laptop
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAnotherKeyForPC   desktop
    ssh-rsa     AAAAB3NzaC1yc2EAAAADAQABAAABAQDemoKey...   old-server
    


  4. Format of a Single Line in authorized_keys

  5. <key-type> <base64-key-data> [<comment>]
    
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlaBlaBla... my-laptop
    ssh-rsa     AAAAB3NzaC1yc2EAAAADAQABAAABAQDemo... old-key
    


  6. Adding Multiple Keys Manually

  7. cat id_ed25519.pub >> ~/.ssh/authorized_keys
    cat work_ed25519.pub >> ~/.ssh/authorized_keys
    
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAALaptopKeyBase64... laptop
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAASomeWorkKeyBase64... work
    


  8. Using ssh-copy-id to Add Keys

  9. ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
    


  10. Per-Key Restrictions and Options

  11. <options> <key-type> <base64-key> <comment>
    
    command="/usr/local/bin/backup-script.sh" ssh-ed25519 AAAAC3Nz... backup-key
    


  12. How the Server Uses Multiple Keys



  13. File Permissions (Important!)

  14. chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys
    



How to Write a SSH Config File

  1. What Is ~/.ssh/config?


  2. File Location and Basic Structure

  3. ~/.ssh/config
    

    chmod 600 ~/.ssh/config
    

    Host ALIAS_OR_PATTERN
        Option1 value
        Option2 value
        ...
    



  4. Minimal Working Example

  5. Host my-server
        HostName 203.0.113.42
        User ubuntu
        IdentityFile ~/.ssh/id_myserver
    

    ssh my-server
    

    ssh -i ~/.ssh/id_myserver ubuntu@203.0.113.42
    


  6. Common SSH Config Directives


  7. Directive Meaning Example
    Host Start a block of settings for a host alias or pattern. Host my-server
    HostName Real DNS name or IP to connect to. HostName 203.0.113.42
    User Remote login user (same as ssh user@host). User ubuntu
    Port Port number (default 22). Port 2222
    IdentityFile Path to the private key to use. IdentityFile ~/.ssh/id_myserver
    IdentitiesOnly If yes, use only the keys listed here, not all from ssh-agent. IdentitiesOnly yes
    ForwardAgent Forward your local ssh-agent to the remote host (yes/no). ForwardAgent yes
    ProxyJump Jump host (bastion) for connecting to another host. ProxyJump bastion.example.com
    LocalForward Set up local port forwarding (local_port host:host_port). LocalForward 8080 localhost:3000
    RemoteForward Set up remote port forwarding. RemoteForward 9000 localhost:3000
    ServerAliveInterval Send keepalive every N seconds. ServerAliveInterval 30
    ServerAliveCountMax Number of unanswered keepalives allowed before disconnect. ServerAliveCountMax 3
    StrictHostKeyChecking How to handle unknown/changed host keys (yes/no/ask). StrictHostKeyChecking ask


  8. Multiple Hosts and Wildcards

  9. Host github.com
        User git
        IdentityFile ~/.ssh/id_github
    
    Host *.example.com
        User deploy
        IdentityFile ~/.ssh/id_company
    
    Host *
        ServerAliveInterval 60
        ServerAliveCountMax 3
    


  10. Practical Examples: GitHub, Personal Server, Jump Host

  11. # 1) GitHub SSH
    Host github.com
        HostName github.com
        User git
        IdentityFile ~/.ssh/id_github
        IdentitiesOnly yes
    
    # 2) Personal VPS
    Host vps
        HostName 198.51.100.10
        User root
        Port 22
        IdentityFile ~/.ssh/id_vps
        IdentitiesOnly yes
        ServerAliveInterval 30
        ServerAliveCountMax 3
    
    # 3) Internal server via jump host (bastion)
    Host bastion
        HostName bastion.mycompany.com
        User ubuntu
        IdentityFile ~/.ssh/id_company
    
    Host internal-app
        HostName internal.app.local
        User ubuntu
        ProxyJump bastion
        IdentityFile ~/.ssh/id_company
    

    ssh github.com
    ssh vps
    ssh internal-app
    


  12. Using Include to Split Configs

  13. ~/.ssh/
        config
        config.d/
            github.conf
            work.conf
            personal.conf
    

    Include ~/.ssh/config.d/*.conf
    
    Host *
        ServerAliveInterval 60
        ServerAliveCountMax 3
    


  14. Conditional Config with Match Blocks

  15. Match CONDITION1 CONDITION2 ...
        Option value
        ...
    Match all
        # reset conditions
    

    Match host my-server localaddress 192.168.1.100
        Compression yes
        ServerAliveInterval 15
    
    Match all
    

    Match user deploy
        IdentitiesOnly yes
        IdentityFile ~/.ssh/id_deploy
    


  16. Testing and Debugging Your Config

  17. ssh -G my-server
    

    ssh -vvv my-server
    



  18. Security Considerations



Using rsync (Local & over SSH)

  1. What Is rsync?


  2. Key Options You Will Use All the Time

  3. Option Description Details
    -a Archive mode (recommended default) Preserves:
      • permissions
      • timestamps
      • symlinks
      • device files
      • recursive directories

    Equivalent to: -rlptgoD
    -v Verbose output Prints names of files being transferred.
    -z Compress data during transfer Improves transfer speed on slow networks.
    --delete Mirror deletions Removes files on destination that no longer exist in source.
    Useful for exact mirroring.
    Always test with --dry-run first.
    --dry-run
    -n
    Simulation mode Shows what would change without making modifications.
    --progress Show per-file transfer progress Useful for large files, shows speed and ETA.
    -e ssh Use SSH as the remote shell Usually optional, but needed for customizing SSH options (port, key file, etc.).


  4. Local Usage (Directory to Directory)



  5. Basic Remote Usage over SSH



  6. Using rsync with SSH Config Aliases



  7. Common Patterns: Mirroring & Backups



  8. Excluding Files and Directories



  9. Permissions, Ownership, and Timestamps



  10. Speed Tuning and Large Transfers



  11. Typical Real-World Workflows