A <--ssh--> B <--ssh--> C , The computer A can NOT copy file to C with scp directly.
I have install lrzsz in the computer C. How to transfer files between A and C.
You need nc installed on B then you can use B as a proxy and connect from A directly to C using:
ssh -o ProxyCommand "ssh user1#B nc %h %p 2>/dev/null" user2#C
Replace "user1" and "user2" with your login names on the respective computers.
Replace the outer ssh with scp and user2#C with the source and destination files using the syntax accepted by scp and you're good to go!
For example:
scp -o ProxyCommand "ssh user1#B nc %h %p 2>/dev/null" user2#C:file1.txt .
copies file1.txt from your home directory on C to the current local directory.
I didn't actually test the command lines as exposed above. For both ssh/scp commands I also added -i with the path to my private key to avoid ssh and scp asking for passwords.
To make the things pleasant to use, you can write in your ~/.ssh/config on A something like this:
Host = B
User = user1
IdentityFile = ~/.ssh/id_dsa_B
Host = C
User = user2
IdentityFile = ~/.ssh/id_dsa_C
ProxyCommand = ssh user1#B nc %h %p 2>/dev/null
Replace in the sample above "user1" and "user2" with your actual login names on the corresponding machines and "id_dsa_B" and "id_dsa_C" with your private key(s) you use for the two machines. I assume you know how to generate and use public/private keys.
Then you can simply use:
ssh C
scp C:file.txt .
If B's ssh server allows port forwarding, you can do, for example,
A$ ssh -N -L10022:C:22 B
and leave that running, then in a seperate shell,
A$ scp -P 10022 file.txt localhost:
Read more about ssh port fowarding. You don't have to use port 10022, any unused port will work.
Related
I have 3 Linux machines, namely client, server1 and server2.
I am trying to achieve something like this. I would like to copy the latest file in a particular directory of server1 to server2. I will not be doing this by logging into server1 directly, but I always log on to client machine first. Let me list down the step by step approach which is happening now:
Log on to client machine using ssh
SSH into server1
Go to directory /home/user1 in server1 using the command ls /home/user1 -Art | tail -n 1
SCP the latest file to /home/user2 directory of server2
This manual operation is happening just fine. I have automated this using a one line script like below:
ssh user1#server1 scp -o StrictHostKeyChecking=no /home/user1/test.txt user2#server2:/home/user2
But as you can see, I am uploading the file /home/user1/test.txt. How can I modify this script to always upload the latest file in the directory /home/user1?
If zsh is available on server1, you could use its advanced globbing features to find the most recent file to copy:
ssh user1#server1 \
"zsh -c 'scp -o StrictHostKeyChecking=no /home/user1/*(om[1]) user2#server2:/home/user2'"
The quoting is important in case your remote shell on server1 is not zsh.
You can use SSH to list the last file and after user scp to copy the file as follow:
FILE=$(ssh user1#server1 "ls -tp $REMOTE_DIR |grep -v / | grep -m1 \"\""); scp user1#server1:$FILE user2#server2:/home/user2
Before launch these command you need to set the remote directory where to search for the last modified file as:
REMOTE_DIR=/home/user1
Is there any way I can combine the following commands into one command? I do not want to login in each time for each command.
sshpass -p 'somepwd' ssh user#server "mkdir -p /home/user/test"
sshpass -p 'somepwd' scp file.sh user#server:/home/user/test
sshpass -p 'somepwd' scp /test/somefile.txt user#server:/home/user/test
sshpass -p 'somepwd' ssh user#server -C "cd /home/user/test;./file.sh"
I did check the answer for combing multiple commands when using ssh and scp; Based on that I would still need 3 logins, one for first ssh and mkdir, one for scp and one for ssh and running the shell script.
Is there a better solution?
Use public/private keys instead of password authentication. Not only will this simplify the use of ssh, it is much more secure, especially after you disallow password authentication on the server you are connecting to. Using password authentication means you will get hacked, or your server has already been compromised and you don't know it yet. The rest of this answer assumes you have set up public/private keys.
I see you have files in /test. Don't put your work in the root directory, this invites security issues. Instead, work in your home directory unless you are experienced with setting up permissions properly.
Because file.sh is in your current directory (whatever that is) and you want a file from /test/ you cannot use rsync. rsync would be a good choice if all your files lived in the same directory.
Here is what we are left with; I have not messed with the location of /test/ because I don't know enough about the task:
ssh user#server "mkdir -p /home/user/test"
scp file.sh user#server:/home/user/test
scp /test/somefile.txt user#server:/home/user/test
ssh user#server -C "cd /home/user/test;./file.sh"
With GNU tar and ssh:
tar -c file.sh test/somefile.txt | sshpass -p 'somepwd' ssh user#server -C "tar -C / --transform 's|test/||;s|^|/home/user/test/|' --show-transformed-names -xv; cd /home/user/test; ./file.sh"
For more secure methods to pass the password with sshpass, see man sshpass.
I have a server "B" which can SCP files to/from server "A" and can also SCP files to/from server "C".
i.e.
A <-----> B <-----> C
Server "A" and server "C" cannot reach each other. Only server B can reach both.
I would like to transfer a file from A to C without (or minimal) storage on server B.
Is there a way of piping files across from A to C without storing it in B or with minimal steps?
Thanks.
From scp(1):
DESCRIPTION
... Copies between two remote hosts
are also permitted.
scp host1:foo.txt host2:foo.txt
You can do this without scp if you like. Log into machine 'B' and run this:
ssh userA#A 'cat /source/file' | ssh userC#C 'cat > /dest/file'
You should set up one or both of these ssh instances to use a key for login, so that you're not prompted for passwords by two ssh instances at the same time.
If you want the file copy process to be a little more error-proofed, or if you want to transfer more than one file at a time, you can use tar:
ssh userA#A 'cd /source/dir && tar cf - file1 file2...' |
ssh userC#C 'cd /dest/dir && tar xvf -'
If you'd rather run the command from A, then something like this should work:
tar cf - file... | ssh userB#B 'ssh userC#C "cd /dest/dir && tar xvf -" '
You could do it with a tunnel:
# Open a tunnel to server C
$ ssh -L 2222:<server C>:22 -N -l user <server B> &
# Copy the file to server C
$ scp <file> -P 2222 localhost:<remote filename>
Note that the tunnel is still running after step 2.
I can login by ssh -X servA from local, then ssh -X servB from servA
To copy data from local to servB, I scp files from local to servA, then from servA to servB.
Is it feasible to copy files from local to servB directly and vice versa?
You can use nc (net cat) as a proxy for ssh.
So for your example, edit your ~/.ssh/config file to look like this:
Host servB
ProxyCommand ssh -q servA nc servB 22
As long as nc is in your path you should now be able to ssh or scp directory to servB
If you don't have nc you can do it with ssh -W if your version is new enough (>= OpenSSH 5.4),
Host ServB
ProxyCommand ssh -W ServB:22 servA
Use ProxyCommand in ssh config file.
This is what I usually do (I do it in a Mac machine don't know if it's different from a Windows machine):
Once you have set up connection with any of the servA or servB you can do:
Copy from local to servA or servB:
$ scp -P <port-number used> <file location to copy from> <username_in servA/servB>#localhost:<file location to copy to>
NOTE: This works being in your local machine without ssh-ing to any of the servA/servB, just need to establish connection.
or from servA to servB:
$ scp -P <port-number used> <username_in servA>#localhost:<file location to copy from> <port-number used> <username_in servB>#localhost:<file location to copy to>
NOTE: I haven't tried this scp from server to server but seems a little bit straight forward.
Just trying to help here.
Is there a way to try multiple passwords when using sshpass command? I have a txt file named hosts.txt listing multiple system IPaddresses and each system uses different passwords (for example - 'mypasswd', 'newpasswd, nicepasswd'). The script reads the hosts.txt file and execute a set of commands on each system. Since I don't know which system uses which of these given passwords, i wanted to try all these set along with sshpass command and execute the script with the password that works.. Is that possible?
#!/bin/bash
while read host; do
sshpass -p 'mypasswd' ssh -o StrictHostKeyChecking=no -n root#$host 'ls;pwd;useradd test'
done < hosts.txt
Instead of trying to get password based authentication, isn't it an option to setup key based auth? You can then either add your one public key to ll systems or optionally generate different ones and use the -i keyfile option or create an entry in the ssh configuration file as below.
Host a
IdentityFile /home/user/.ssh/host-a-key