How to define separate username/password for rsync source and destination? - rsync

I'm trying to setup an rsync command from a VM to a QNAP but I need to define the username/password for each (they are different values) in one rsync line. I would like to use a password file (utilizing --password-file=rsync_pass) if possible so the passwords are not in plain text in the command line.

Related

The phpseclib $sftp->chdir('//ARTDONE.G9876TT1') fails on z/OS sftp server. The windows psftp command line of "CD //ARTDONE.G9876TT1" works

I get a valid connection with phpseclib but because of the server's requirements I must issue a change remote directory command, $sftp->chdir($dir="//ARTDONE.G9876TT1"), to this directory, (exact format, not the actual name). This change directory command works with Putty's psftp.exe as "CD //ARTDONE.G9876TT1" in windows and with WinSCP's "go to this folder GUI input" but not with PHPSECLIB's sftp object method. Is there something about this directory format that needs to change when using phpseclib? The error message is "permission denied", but I get that same message for any other navigation commands.
Is there a way to issue literal sftp commands with phpseclib sftp?
Or can I use $ssh->exec("CD //ARTDONE.G9876TT1") in some way within the $sftp object that I cannot currently imagine?
The phpseclib appends / to the path in SFTP::chdir call. I believe this is what your server does not like.
Note that SFTP does not even use the concept of a working directory. It's faked locally by phpseclib (and other clients like WinSCP or OpenSSH). So you do not really need to use SFTP::chdir. You might instead use absolute paths in all phpseclib API calls. Alternatively, just setting SFTP::pwd has the same effect as calling SFTP::chdir, except that you will bypass the validation that causes you the troubles.
Accessing z/OS Data Sets via SFTP/FTP
Appending a / surely breaks the access. The OP is accessing an IBM z/OS system running an SFTP server.
IBM z/OS
z/OS is kind a hybrid operating system having a traditional MVS based "kernel" (not really named "kernel" in the doc), and a XPG 4.2 compliant UNIX kernel running in parallel. The UINX side supports file systems with directories and files. The MVS side has a completely different "file system", based on data sets which are named in a non-hierarchal system.
The UNIX file system on z/OS
There is not much to say about the UNIX file system on z/OS. Is it XPG compliant, thus the usage is not different to any other UNIX lik system.
The MVS Data Sets on z/OS
As said above, there is the traditional MVS Data Set based "file system" on z/OS, which is quite different to much you know about files and directories on UNIX system.
Disk Space on z/OS is assigned to MVS data sets. Data sets are named using dot separates names, that can be up to 44 characters long. The parts between two dots can be up to 8 characters long.
Examples:
ARTDONE.G9876TT1
ARTDONE.NEXT.DATA.SET
ARTDONE.NEXT.ANOTHER.ONE
SYS1.LINKLIB
ZUSER.SOURCE.REXX
What seems to be a hierarchy in the first three examples, is not. They are unrelated from the physical point of view, though related in a logical.
Note: Slashed / are not valid in MVS data set names.
SFTP/FTP servers on z/OS
SFTP/FPT servers in z/OS mimic the client side view of directories and files when accessing MVS Data Sets in that the dots in the names are kind of treated like slashes in UNIX. I.e. they support pwd and cd based on the dots.
Example:
cd //ARTDONE.NEXT sets the current working directory to ARTDONE.NEXT. A ls the lists all data sets, of which the name starts with ARTDONE.NEXT, i.e.
ARTDONE.NEXT.DATA.SET
ARTDONE.NEXT.ANOTHER.ONE
but not ARTDONE.G9876TT1.
But how would the server know whether a client side "directory" access is meant to access the UNIX or the MVS data world? The // at the beginning of the parameter passed to the server indicates the server shall switch to the MVS data set world.
Conclusion
client side software should be careful when verifying paths that might be sent to z/OS servers. Accept // as a special indicator. Do not append / in all cases.
More Detailes
There is much more behind this topic than can be described here. Read IBM documentation on z/OS if interested. I would recommend Introduction to the New Mainframe: z/OS Basics as a starter.

Download mainframe files to Unix with SFTP in binary mode

I want to download a file from Mainframe server to Linux machine using SFTP command and want to preserve EOL. It seems that the actual file does not have EOL character, where as SFTP process adds EOL character while downloading it to Linux server.
Is there any option to download the file in Binary mode using SFTP command?
I tried to download data from Mainframe server using FTP and SFTP. FTP with Binary mode is preserving actual content of original file without any modification, whereas FTP with ASCII mode and SFTP commands are modifying the content of the file by adding EOL or any other special characters.
I got it worked by enabling binary mode of transfer in SFTP session:
ls /+mode=binary
The default was set to ASCII.
sftp> ls /+ /+/clientcp=ISO8859-1 /+/error.log /+/loglevel=I /+/mode=text /+/servercp=IBM-1047 /+/trim
sftp> bye
I am now able to match the size of file with FTP binary and SFTP binary.
I haven't had issues with binary files and sftp. If you want to download a text file, you should use scp, unless it's in ASCII, in which case I would think sftp should work fine.
Are you trying to download a file from the hierarchical file system or from a dataset? I don't think datasets are supported with sftp (you would use FTP for that or Secure FTP).
On z/OS there are basically three ways to move content based on your question. First is FTP, second is scp and the third is sftp.
Also, its important to identify which fileset you are trying to access; MVS or USS. MVS files are different than traditional *nix file systems. MVS files are generally fixed or variable in nature. As such, they do not rely on line terminators like \n or \r to terminate the line. The record length is available at the time of reading. USS files would have line terminators.
FTP is services are provided by a daemon that is part of the Communication Server product. It provides most modes of transfer as well as extensions to deal with platform specific items as they relate to the MVS name space. You can also access Unix files as well. Conversions like ASCII (IBM-1047 -> UTF-8) are supported or binary (just move the data and don't touch it).
scp is delivered as part of the OpenSSH implementation on z/OS and it always transfers in a character mode and will assume an encoding change to / from EBCDIC to ASCII. Its an unfortunate implementation but it is what it is. This is due to the fact that the native code page on z/OS in EBCDIC in some form. Don't expect transfers with scp to move data without conversion. Only files in the USS file system are accessible. No MVS datasets.
sftp uses the secure services of OpenSSH but acts like ftp. Depending on your client you can set the mode to transfer ascii (conversion) or binary. My client on Mac OS X will not allow ascii. Probably a client limitation. sftp also only allows you to move files that reside or are destined for the USS file domain.
To answer your question about binary in sftp the answer is yes, I use it frequently to move files to and from z/OS using binary to avoid automatic conversion. Make sure you are transferring using binary transfer and not ascii when using sftp.

zsh tab completion for ssh using IP Address

I ssh into several machines that are just IP Addresses, however I noticed a while back that tab completion stopped working when trying to SSH to them. I use zsh and I can tab complete a regular domain name with ssh, but all the IP machines that I use dont tab complete any more, did something break here? or whats the deal?
OS X - 10.9.3
zsh - 5.0.2
have you set the use-ip style?
zstyle ':completion:*' use-ip true
the documentation says that ip addresses are stripped from the host databases by default. use-ip allows completion of them.
http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-use_002dip_002c-completion-style
Your ssh might be hashing the entries at known_hosts?
Best usability solution in general for ssh IMO is to create ssh host aliases, and then just use the alias in the command line. Eg. add something like this to you ~/.ssh/config
Host foo
# HostName also accepts numeric IP addresses
HostName XXX.ZZZ.YYY.BBB
then you just use scp backup.tar foo:
Check man ssh_config for more info. From the manual:
HashKnownHosts
Indicates that ssh(1) should hash host names and addresses when they are added to ~/.ssh/known_hosts. These hashed names
may be used normally by ssh(1) and sshd(8), but they do not reveal identifying information should the file's contents be
disclosed. The default is “no”. Note that existing names and addresses in known hosts files will not be converted auto‐
matically, but may be manually hashed using ssh-keygen(1). Use of this option may break facilities such as tab-comple‐
tion that rely on being able to read unhashed host names from ~/.ssh/known_hosts.
Ok ignore the above, I see in a comment that that is not the case, will leave it there for reference though.
PS: you can always manually set the hosts to be completed by zsh using something along the lines of:
hosts=(foo.bar.com faa.bar.com fee.bar.com)
zstyle ':completion:*:hosts' hosts $hosts
Or do a much more complicated version of it, such as described here https://www.maze.io/2008/08/03/remote-tabcompletion-using-openssh-and-zsh/index.html

Automate sending of files through sftp using copssh

Every month we send reports to a server using FTP. We run a query on a database to create the files then use the ftp functionality in LabVIEW to do the transfer. This runs on a Windows system.
This works fine but now we have to switch to using SFTP and the CopSSH package has been recommended. As LabVIEW has no native SFTP functionality we are looking at how we can use the sftp.exe application from CopSSH.
From the command prompt we have set up the encryption and made the initial connection using sftp username#host and entered the password. This has been confirmed by the team on the server side so connection to the server is set up. Now we just use sftp username#host and no password is required.
Where we are struggling is how to initiate the transfer from our LabVIEW code. We are able to call system commands using the System Exec VI but is there a way to pass a list of functions to the SFTP executable?
The commands used to transfer the files when we type it at the command prompt are:
sftp username#host
put c:/Data/File1.txt remoteFile1
put c:/Data/File2.txt remoteFile2
put c:/Data/File3.txt remoteFile3
quit
This works from the command prompt but I am looking to just call the sftp executable with a list of files to transfer. I don't think this would be specific to LabVIEW as you could use a batch file to run from a scheduled job.
LabVIEW can call ActiveX and .net but we really need to use this specific application.
I have been using WinSCP which has a command line version, winscp.com. It supports sftp and allows synchronize, keepuptodate, get, put and delete on folders and files. One word of warning, keepuptodate depends on an unbroken connection. Although WinSCP can remake a connection automatically, keepuptodate cannot. I suspect it is based on Microsoft's .NET SystemIO FileSystemWatcher. I therefore do a regular synchronize to keep a mirror of my source folder tree on the remote target.
If copssh's sftp.exe is a command line utility, and System Exec in your version of LabVIEW has the 'standard input' terminal (present at least since 8.5), you should be able to simply wire the commands you want sftp.exe to run into the standard input terminal.
If that doesn't work for some reason, could you use PuTTY instead of copssh? The documentation for PuTTY's PSFTP component says that it can execute a sequence of commands in a script file using the -b command line switch, e.g.
psftp user#hostname -b myscript.scr
so you could have your LabVIEW program create the script file then run it with System Exec.
You are mixing SSH and SFTP. SSH opens a secure connection, but SFTP is a separate protocol which is run over SSH connection and requires a separate tunnel. In OpenSSH (and it's Windows Port, copSSH) it's sftp.exe application that does SFTP.
Now about FTP vs SFTP. Please check an article that explains the difference between SFTP and FTP(S). If LabView supports FTP, this doesn't help you when you need to perform SFTP transfers.
I don't know whether you can use external ActiveX controls in LabView. If you can, you are welcome to check our SFTP ActiveX control, that will let you do the transfer. If all you can do is call external application, then you'd have to use copSSH's sftp.exe.

Sender and receiver to transfer files over ssh on request?

I created a program that iterates over a bunch of files and invokes for some of them:
scp <file> user#host:<remotefile>
However, in my case, there may be thousands of small files that need to transferred, and scp is opening a new ssh connection for each of them, which has quite some overhead.
I was wondering if there is no solution where I keep one process running that maintains the connection and I can send it "requests" to copy over single files.
Ideally, I'm looking for a combination of some sender and receiver program, such that I can start a single process (1) at the beginning:
ssh user#host receiverprogram
And for each file, I invoke a command (2):
senderprogram <file> <remotefile>
and pipe the output of (2) to the input of (1), and this would cause the file to be transferred. In the end, I can just send process (1) some signal to terminate.
Preferably the sender and receiver programs are open source C programs for Unix. They may communicate using a socket instead of a pipe, or any other creative solution.
However, it is an important constraint that each file gets transferred at the moment I iterate over it: it is not acceptable to collect a list of files and then invoke one instance of scp to transfer all the files at once at the end. Also, I have only simple shell access to the receiving host.
Update: I found a solution for the problem of the connection overhead using the multiplexing features of ssh, see my own answer below. Yet, I'm starting a bounty because I'm curious to find if there exists a sender/receiver program as I describe here. It seems there should exist something that can be used, e.g. xmodem/ymodem/zmodem?
I found a solution from another angle. Since version 3.9, OpenSSH supports session multiplexing: a single connection can carry multiple login or file transfer sessions. This avoids the set-up cost per connection.
For the case of the question, I can first open a connection with sets up a control master (-M) with a socket (-S) in a specific location. I don't need a session (-N).
ssh user#host -M -S /tmp/%r#%h:%p -N
Next, I can invoke scp for each file and instruct it to use the same socket:
scp -o 'ControlPath /tmp/%r#%h:%p' <file> user#host:<remotefile>
This command starts copying almost instantaneously!
You can also use the control socket for normal ssh connections, which will then open immediately:
ssh user#host -S /tmp/%r#%h:%p
If the control socket is no longer available (e.g. because you killed the master), this falls back to a normal connection. More information is available in this article.
This way would work, and for other things, this general approach is more or less right.
(
iterate over file list
for each matching file
echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud
It might work to use sftp instead of scp, and to place it into batch mode. Make the batch command file a pipe or UNIX domain socket and feed commands to it as you want them executed.
Security on this might be a little tricky at the client end.
Have you tried sshfs?
You could:
sshfs remote_user#remote_host:/remote_dir /mnt/local_dir
Where
/remote_dir was the directory you want to send files to on the system you are sshing into
/mnt/local_dir was the local mount location
With this setup you can just cp a file into the local_dir and it would be sent over sftp to remote_host in its remote_dir
Note that there is a single connection, so there is little in the way of overhead
You may need to use the flag -o ServerAliveInterval=15 to maintain an indefinite connection
You will need to have fuse installed locally and an SSH server supporting (and configured for) sftp
May be you are looking for this:
ZSSH
zssh (Zmodem SSH) is a program for interactively transferring files to a remote machine while using the secure shell (ssh). It is intended to be a convenient alternative to scp , allowing to transfer files without having to open another session and re-authenticate oneself.
Use rsync over ssh if you can collect all the files to send in a single directory (or hierarchy of directories).
If you don't have all the files in a single place, please give some more informations as to what you want to achieve and why you can't pack all the files into an archive and send that over. Why is it so vital that each file is sent immediately? Would it be OK if the file was sent with a short delay (like when 4K worth of data has accumulated)?
It's a nice little problem. I'm not aware of a prepackaged solution, but you could do a lot with simple shell scripts. I'd try this at the receiver:
#!/bin/ksh
# this is receiverprogram
while true
do
typeset -i length
read filename # read filename sent by sender below
read size # read size of file sent
read -N $size contents # read all the bytes of the file
print -n "$contents" > "$filename"
done
At the sender side I would create a named pipe and read from the pipe, e.g.,
mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection
Then to send a file I'd try this script
#!/bin/ksh
# this is senderprogram
FIFO=$HOME/my-connection
localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO
If the file size is large you probably don't want to read it at one go, so something on the order of
BUFSIZ=8192
rm -f "$filename"
while ((size >= BUFSIZ)); do
read -N $BUFSIZE buffer
print -n "$buffer" >> "$filename"
size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"
Eventually you'll want to extend the script so you can pass through chmod and chgrp commands. Since you trust the sending code, it's probably easiest to structure the thing so that the receiver simply calls shell eval on each line, then send stuff like
print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO
and then define a local function read_and_copy_bytes. Getting the quoting right is a bear, but otherwise it should be straightforward.
Of course, none of this has been tested! But I hope it gives you some useful ideas.
Seems like a job for tar? Pipe its output to ssh, and on the other side pipe the ssh output back to tar.
I think that the GNOME desktop uses a single SSH connection when accessing a share through SFTP (SSH). I'm guessing that this is what's happening because I see a single SSH process when I access a remote share this way. So if this is true you should be able to use the same program for this purpose.
The new version of GNOME used GVFS through GIO in order to perform all kind of I/O through different backends. The Ubuntu package gvfs-bin provides various command line utilities that let you manipulate the backends from the command line.
First you will need to mount your SSH folder:
gvfs-mount sftp://user#host/
And then you can use the gvfs-copy to copy your files. I think that all file transfers will be performed through a single SSH process. You can even use ps to see which process is being used.
If you feel more adventurous you can even write your own program in C or in some other high level language that provides an API to GIO.
One option is Conch is a SSH client and server implementation written in Python using the Twsited framework. You could use it to write a tool which accepts requests via some other protocol (HTTP or Unix domain sockets, FTP, SSH or whatever) and triggers file transfers over a long running SSH connection. In fact, I have several programs in production which use this technique to avoid multiple SSH connection setups.
There was a very similar question here a couple of weeks ago. The accepted answer proposed to open a tunnel when ssh'ing to the remote machine and to use that tunnel for scp transfers.
Perhapse CurlFTPFS might be a valid solution for you.
It looks like it just mounts an external computer's folder to your computer via SFTP. Once that's done, you should be able to use your regular cp commands and everything will be done securely.
Unfortunately I was not able to test it out myself, but let me know if it works for ya!
Edit 1: I have been able to download and test it. As I feared it does require that the client have a FTP server. However, I have found another program which does has exactly the same concept as what you are looking for. sshfs allows you to connect to your client computer without needing any special server. Once you have mounted one of their folders, you can use your normal cp commands to move whatever files you need to more. Once you are done, it should then be a smile matter of umount /path/to/mounted/folder. Let me know how this works out!
rsync -avlzp user#remotemachine:/path/to/files /path/to/this/folder
This will use SSH to transfer files, in a non-slow way
Keep it simple, write a little wrapper script that does something like this.
tar the files
send the tar-file
untar on the other side
Something like this:
tar -cvzf test.tgz files ....
scp test.tgz user#other.site.com:.
ssh user#other.site.com tar -xzvf test.tgz
/Johan

Resources