Date created: 06/10/14 14:16:09. Last modified: 08/30/20 19:35:05

'ssh', 'sshfs', 'scp' & 'rsync' - Notes


Local SOCKS5 proxy over SSH

ssh -C2qTnN -D 8080
-C Request compression of all data
-2 Enforce SSH protocol version 2
-q Qiuet mode
-T Disable pseudo-tty allocation
-n Prevents reading from stdin
-N Do not execute a remote command
-D[bind_addr:]port Specifies a local “dynamic” application-level port forwarding

-L [bind_address:]port:host:hostport Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side
-f Requests ssh to go to background just before command execution

# Socks proxy tunneled through two hosts - In the first example you need kill the background SSH process
# on the local machine and on On the second machine it just needs killing on because 
# no use of -f
# Redirect local port 8080 to IP on port 8080, connect to and redirect local port 8080 their to
# (Machine needs key authentication to 6.6.6 to keep authentication non-interactive)
ssh -f -L 8080:localhost:8080 username@ "ssh -f -N -D 8080 username@"

# runs SSH on non-standard port, and no -f keeps SSH in the front.
ssh -L 8080:localhost:8080 -p 2222 username@ "ssh -f -N -D 8080 username@"

#Using the original SOCKs command on the final host:
ssh -nL 8080:localhost:8080 username@machine1 "ssh -C2qnN -D 8080 username@machine2"

Redirect local port to port on remote machine for firewall bypass;

ssh -N -L 7878:localhost:7878 user@
# Telnet to local port 7878 will connect you to remotehost:7878
telnet 7878


Reverse SSH Tunnels

Reverse SSH to a machine behind NAT using a machine outside of the NAT (such as public IP);

# On the machine behind the NAT
ssh -R 5555:localhost:22 remoteuser@machine.with.public.ip
# Then SSH to the machine with public IP from a remote location.
# On the machine with public IP SSH to self on redirected port
ssh localhost -p 5555

# Alternatively, use a ProxyJump command in ~/.ssh/config:
# Port can be specified if using non-standard ports using ":1234"
Host remoteserver-hostname
HostName ip.addr.of.remoteserver
User remoteserver-user

Host remoteserver-hostname
HostName ip.addr.of.remoteserver
Port 5678
User remoteserver-user

# Or directly on the CLI with -J:
ssh -J
ssh -J fred@


Cipher, MAC and Kex Options

Force cipher, MAC and key exchange from client:

ssh -c -m user@host


For legacy Cisco equipment:

ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 test@


Or in the SSH config file:

Host remoteserver
Ciphers +aes256-ctr
Ciphers +aes256-cbc


Jump Hosts / Bastion Hosts

Use a wildcard match on hostname so that all devices with a similar name use the same jump host:

Match Host sr1*

Set a keep alive interval for all hosts to prevent TCP session idle timeouts and stateful firewall idle NAT timeouts:

Host *
    ServerAliveInterval 240

SSH config can't contain multiple HostName entries for a host, e.g. to have a fallback IP/hostname. Once can use multiple Match statements with an "exec" statement which can return false and fall through to the next Match statement. Below is only connected to when jumpbox1 isn't reachable (netcat fails to connect within 1 second):

Match Host jumpbox exec "nc -G 1 -z %p"
User jump.user
Match Host jumpbox exec "nc -G 1 -z %p"
User jump.user



Mount remote filesystem;

# via smb
sudo smbmount // /media/smbserver/ -o username=bensley
# via sshfs
sudo sshfs -o idmap=user -o allow_other bensley@ /media/smbserver/
# Via sshfs with non-standard ssh port
sudo sshfs -o idmap=user -o allow_other -o ssh_command="ssh -p 65535" username@ /media/smbserver
# SSHFS to a box through an intermediate box (jump host), both on non-standard ports (jump box on 1234, end host on 5678)
sshfs -o idmap=user -o allow_other -o ssh_command="ssh -J -p 5678" sshfs-user@sshfs.server.ip.addr:/a/path/ /local/mount/point



rsync options:

# Common rsync options
# a = archive mode; equals -rlptgoD (no -H,-A,-X)
# c = skip based on checksum, not mod-time & size
# D = same as --devices --specials
# g = preserve group
# h = output numbers in a human-readable format
# i = output a change-summary for all updates
# l = copy symlinks as symlinks
# o = preserve owner (super-user only)
# p = preserve permissions
# P = same as --partial and --progress (don't delete partial transfers, show progress of current transfer)
# r = recurse
# t = preserves times
# v = increase verbosity
# z = use compression
# --compress-level=9 = set the compression level to 9 (max)
# --devices = preserve device files (super-user only)
# --delete-during = delete files as we go (don't scan through before hand or after, faster)
# --force = force the deletion of non-empty directorys
# --ignore-errors = ignore I/O errors when deleting files
# --specials = preserve special files
# --stats print out transfer stats at the end

# Example when copying from a remote rsync folder name "pair1" defined in the rsyncd config, which helps to hide the full path on the remote side:
rsync -rzhitP --delete-during --ignore-errors --force --stats --compress-level=9 user@ /backup/pair1

Resume rsync failed transfer over non-standard port (with a bandwidth limit):

rsync -rlptgoDivc --progress --stats --partial --bwlimit=300 -e "ssh -p 1234" user@*.txt /media/storage/backup

To exclude a directory use a relative path to the source directory. E.g. to exclude Firefox history stored in /Users/MyUser/Library/Caches/Firefox/Profiles/jn6pe0j8.default/cache2/entries/ remove either /Users/MyUser/ or ~/ from the exclude option:

rsync -vrhit --partial --progress --stats --delete --exclude=.DS_Store --exclude=Library/Caches/Firefox/Profiles/jn6pe0j8.default/cache2/entries/ /Users/MyUser/ /Volumes/NAS/

# Online copy jpg pictures. Excluding everything with --exclude '*' and matching *.jpg and *.jpg doesn't copy anything. The exclude supersedes the includes. Using --include '*/' to include all directories with the '*.jpg' and '*.JPG' matches:

rsync -rzhitP --partial --progress --stats --include '*/' --include '*.jpg' --include '*.JPG' --exclude "*" ./source/ ./destination/