Skip to content

Instantly share code, notes, and snippets.

@moreati
Last active March 2, 2023 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moreati/00bbda2aa62642af36ed58ec766a4604 to your computer and use it in GitHub Desktop.
Save moreati/00bbda2aa62642af36ed58ec766a4604 to your computer and use it in GitHub Desktop.
Field expedient `scp -3 src:largefile dest:largefile` without scp
# `ssh -3 src.host.example:largefile dest.host.example:largefile` copies
# largefile from the source host to the destination, using the local machine
# as a relay. The file can be arbitrarily large. What if we don't have `scp`?
# We have
# - ssh connectivity from local machine to src.host.example
# - ssh connectivity from local machine to dest.dest.example
# - `ssh` client on local machine
# - `nc` command on remote machines
# - A large file called largefile on src.host.example
#
# We want
# - A copy of largefile on dest.dest.example
#
# We lack
# - Any direct connectivty from src.host.example to dest.host.example
# - Space on local machine to store largefile
# - `scp` client on local machine (or one capable of `scp -3`)
# On the destination host use `nc` to listen on port 5554, pipe any data
# received by `nc` to a new file called largefile.
# On the local machine use `ssh` to listen on port 5553, tunnel any data
# through the ssh connection and send it to the listening `nc`.
# This ssh invovation will stay running until the following command has
# completed sending.
ssh -L localhost:5553:localhost:5554 dest.host.example "nc -l localhost 5554 > largefile"
# This `ssh` invocation should be run in a seperate window or tab.
# On the source host use `sshd` to listen on port 5555, tunnel any data
# through the ssh connection back to the local machine.
# On the source host use `nc` to connect to the listening sshd on port 5555.
# On the local machine use `ssh` to connect to the previous listening `ssh`
# invocation on port 5553.
# Once the chain of connections is made the data is sent from the source host,
# through the local machine, to the destination host.
# Once all the data has been sent each connection is dropped, and each listening
# process shuts down.
ssh -R localhost:5555:localhost:5553 src.dest.example "cat largefile | nc localhost 5555"
# Variations
# - To copy a directory
# - Replace `> largefile` with `| tar xf -`
# - Replace `cat largefile |` with `tar cf - somedir |`
#
# Caveats/bugs
# - Race conditions or ordering probalems in in `nc` listening vs `ssh`
# connecting? Or vice versa?
# - May need tighter specification of binary/not binary clean options,
# or some base64 protection in some cases?
# - Some details elided to proect the guilty
#
# Further work
# - Have I (badly) reinvented an existing thing?
# - Can the two commands be reduced to a single invocation?
@moreati
Copy link
Author

moreati commented Mar 2, 2023

For a good explanation/visualisation of ssh tunnels try https://iximiuz.com/en/posts/ssh-tunnels/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment