1

I am trying to transfer a directory from a remote server(CentOS) to my local machine(Ubuntu) over ssh. There are two users : A and B. User A can ssh into remote server and has sudo access. User B owns a directory in remote server.

To transfer a directory owned by User B as User A, sudo needs to be used.

Currently for transferring a file (from remote to local) this is what I am using :

ssh -tt userA@remote_host 'stty raw -echo; sudo cat /path/to/remote/file/owned/by/userB' > /path/to/local/file

To transfer a directory I have tried the tar approach,

ssh -tt userA@remote_host 'stty raw -echo; sudo tar -C /path/to/remote/directory/owned/by/userB/ -czf - .' | tar -C /path/lo/local/directory -xzf -

However on the local system I get this error :

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

What am I doing wrong?

1 Answers1

0

Attempt to transfer directory using ssh

ssh -tt userA@remote_host 'stty raw -echo; sudo tar -C /path/to/remote/directory/owned/by/userB/ -czf - .' | tar -C /path/lo/local/directory -xzf -

Piping the above command's output to cat (in local system) instead of tar, gives more info :

$ ssh -tt userA@remote_host 'stty raw -echo; sudo tar -C /path/to/remote/directory/owned/by/userB/ -czf - .' | cat
userA@remote_host's password: 
gzip: compressed data not written to a terminal. Use -f to force compression.
For help, type: gzip -h
Connection to remote_host closed.

To fix this, I used this command :

ssh -t userA@remote_host 'stty raw -echo; sudo tar -C /path/to/remote/directory/owned/by/userB/ -cf - . | gzip -9nf' | tar -C  /path/lo/local/directory -xzf -

Note for ssh options

Since I am using sudo to access User B's directory, ssh returns sudo: sorry, you must have a tty to run sudo if -t option is not used.

-t : Force pseudo-terminal allocation

Note for stty options

The stty option -echo is optional. It is to be used (I think) if sudo requires you to enter password.

raw : Process input as it is (do not interpret special characters, etc.)

-echo : Do not print typed characters

Note for gzip options

-9 : Set compression to maximum

-f : Force compression (As suggested by the error)

-n, --no-name : Does not include name and timestamp of the file (Helpful to compare checksums of the file in remote and local)

  • Note this is still fragile. If `tar` or `gzip` encounters a minor problem that would otherwise not break the operation entirely, a warning printed to stderr will contaminate the stream your local `tar` gets. There are scenarios when your tty prints something beyond your control (somebody uses `wall` or schedules a shutdown with `shutdown`, which generates a broadcast message); see [this](https://unix.stackexchange.com/a/12450/108618). – Kamil Maciorowski Oct 16 '20 at 04:33
  • I agree, but my options are limited apart from moving the file owned by User B to a directory owned by me(User A) and then `scp` it to local. File integrity check using checksums is the only option in the event of the scenarios you mention. – Saurabh P Bhandari Oct 16 '20 at 04:42
  • `File integrity check using checksums is the only option` – Not quite. An additional channel is possible, e.g. by sending a stream via a forwarded port. Someone rogue can write to the same port though. Forwarding a Unix socket, when done properly, can solve this. But using sockets requires more knowledge, tools and effort. Are you interested? – Kamil Maciorowski Oct 16 '20 at 04:57