0

Everything described below is done via a Bash script.

I desire to capture the state of a defined set of files on a defined set of remote hosts. The "state" of a file depends on the type of file:

  • Regular file: full path, content of the file, mode, owner, group
  • Symbolic link: full path of the link itself, the pointed-to path, mode (always 777), owner, group
  • Directory: full path, mode, owner, group

When creating a local file to represent the state of a remote file, I distinguish between files with the same full path but which differ on different hosts by appending to the local filename a hash of the traits listed above. I then tar the remote file up (non-recursively, so that in the case of a directory, I get just the directory), pipe it though SSH, untar it to my local machine, and mv it to the filename with a hash appended. I use tar because it preserves the traits I care about.

HASH=$(ssh -n "$ONE_HOST" "{ cat $ONE_FILE_PATH; stat -c \"%a %u %g %F\" $ONE_FILE_PATH; } | sha512sum")
ONE_HASH=${ONE_HASH:0:20}

TARGET_FILENAME_FOR_COPY="$FILENAME"."$ONE_HASH"
TARGET_PATH_FOR_COPY="$TARGET_DIRECTORY_FOR_COPY"/"$TARGET_FILENAME_FOR_COPY"

ssh -n "$ONE_HOST" \
     "tar -C $DIRECTORY --no-recursion -cf - $FILENAME" | \
     tar -xf - -C "$TARGET_DIRECTORY_FOR_COPY"

mv "$TARGET_PATH_UNHASHED" "$TARGET_PATH_FOR_COPY"

This is all in place and working.

Now, for the case of regular files, I have an additional need to handle sensitive files whose content I don't wish to copy (though the content will continue to be represented in the hash). My goal is to create the exact same local file I would in the process described above, but that the file should be empty rather than contain the content of the remote file.

Note: I cannot copy the file and then empty the copy of content. Being a sensitive file, its content must not be transferred over the network.

I don't know of a way to get tar to transfer a "shell" of a regular file that has the mode, owner, and group of the file but omits the content in the tarball. Unless somebody knows of a trick to get tar to do this, I think I will have to look at some mechanism other than tar.

How can I most easily accomplish this?

UPDATE #1

One approach I'm trying is to first make a temporary copy of the file (using cp -p to preserve the file attributes I care about) on the remote system, empty that temporary file of content (with truncate -s 0), and then copy that to my local machine with tar / ssh as described above. This is awkward and inelegant. I'm hoping to find a way to do this without resorting to the use of a temporary file.

0

You could mount an empty file on top of the sensitive files prior to running tar.

touch /tmp/emptyfile
mount --bind /tmp/emptyfile /home/user/.ssh/id_rsa

Or something similar.

  • Oh, that's clever! I like that. But I do see one gotcha... For the duration of the copy operation, the content of the sensitive file would be unavailable to local processes that need it. – Dave Mar 9 '18 at 18:57
  • unfortunately, yes, unless they already have an open file descriptor. This Answer shows how you can use pam-namespaces to make user-specific mountpoints, but its a bit beyond the scope of a remote backup. – Hydranix Mar 9 '18 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.