Date created: 06/10/14 14:16:09. Last modified: 08/10/19 18:00:05

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

Local SOCKS5 proxy over SSH

ssh -C2qTnN -D 8080 [email protected]_machine.com
-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 5.5.5.5. On the second machine it just needs killing on 5.5.5.5 because 
# no use of -f
#
# Redirect local port 8080 to IP 5.5.5.5 on port 8080, connect to 5.5.5.5 and redirect local port 8080 their to 6.6.6.6
# (Machine 5.5.5.5 needs key authentication to 6.6.6 to keep authentication non-interactive)
ssh -f -L 8080:localhost:8080 [email protected] "ssh -f -N -D 8080 [email protected]"

# 5.5.5.5 runs SSH on non-standard port, and no -f keeps SSH in the front.
ssh -L 8080:localhost:8080 -p 2222 [email protected] "ssh -f -N -D 8080 [email protected]"

#Using the original SOCKs command on the final host:
ssh -nL 8080:localhost:8080 [email protected] "ssh -C2qnN -D 8080 [email protected]"

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

ssh -N -L 7878:localhost:7878 [email protected]
# Telnet to local port 7878 will connect you to remotehost:7878
telnet 127.0.0.1 7878

 

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 [email protected]
# 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
ProxyJump [email protected]
User remoteserver-user

Host remoteserver-hostname
HostName ip.addr.of.remoteserver
Port 5678
ProxyJump [email protected]:1234
User remoteserver-user

# Or directly on the CLI with -J:
ssh -J [email protected] [email protected]_host.example.org
ssh -J [email protected]:22 [email protected]

Force cipher, MAC and key exchange from client:

ssh -c [email protected] -m [email protected] [email protected] [email protected]

Or in the config:

Host remoteserver
    HostKeyAlgorithms=+ssh-dss

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

Match Host sr1*
ProxyJump [email protected]
User my.user.name

Set a keep alive interval for all hosts to prevent TCP session idle timeouts and statefull 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 jumpbox2.example.org is only connected to when jumpbox1 isn't reachable (netcat fails to connect within 1 second):

Match Host jumpbox exec "nc -G 1 -z jumpbox1.example.org %p"
HostName jumpbox1.example.org
User jump.user
Match Host jumpbox exec "nc -G 1 -z jumpbox2.example.org %p"
HostName jumpbox2.example.org
User jump.user

 

Mount remote filesystem;

# via smb
sudo smbmount //172.16.0.5/bensley /media/smbserver/ -o username=bensley
# via sshfs
sudo sshfs -o idmap=user -o allow_other [email protected]:/path/to/bensley /media/smbserver/
# Via sshfs with non-standard ssh port
sudo sshfs -o idmap=user -o allow_other -o ssh_command="ssh -p 65535" [email protected]:/path/to/bensley /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 [email protected]:1234 -p 5678" [email protected]:/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 [email protected]::pair1 /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" [email protected]:~/path/*.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/