How to SCP a file from a 2-deep connection - scp

Say I SSH into a server Server1 and from there SSH into server Server2 which is only accessible from a connection to Server1. Below simulates the example terminal commands for this behaviour:
[name#mylaptop]$ ssh user#Server1
user#Server1's password:
*** Welcome to Server1! ***
[user#Server1]$ ssh user2#Server2
user2#Server2's password:
*** Welcome to Server2! ***
[user2#Server2]$
Now I have a file, named file.txt in my home directory on Server2:
[user2#Server2]$ ls
file.txt
[user2#Server2]$
Is it possible to use scp to copy file.txt from Server2 onto mylaptop with a single command (i.e. not needing to first copy the file to Server1)?
In other words, can this be done easier than the following:
[name#mylaptop]$ ssh user#Server1
user#Server1's password:
*** Welcome to Server1! ***
[user#Server1]$ scp user2#Server2:~/file.txt .
user2#Server2's password:
file.txt 100% 690 0.7KB/s 00:00
[user#Server1]$ logout
Connection to Server1 closed.
[name#mylaptop]$ scp user1#Server1:~/file.txt .
user#Server1's password:
file.txt 100% 690 0.7KB/s 00:00
[name#mylaptop]$ ls
file.txt

It's possible and relatively easy, even when you need to use certificates for authentication (typical in AWS environments).
The command below will copy files from a remotePath on server2 directly into your machine at localPath. Internally the scp request is proxied via server1.
scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1#server1" user2#server2:/<remotePath> <localpath>
If you use password authentication instead, try with
scp -o ProxyCommand="ssh -W %h:%p user1#server1" user2#server2:/<remotePath> <localpath>
If you use the same user credentials in both servers:
scp -o ProxyCommand="ssh -W %h:%p commonuser#server1" commonuser#server2:/<remotePath> <localpath>

You can use port forwarding:
Execute
ssh -L60000:Server2:22 user#Server1
in one terminal and keep this process open.
Then in another terminal run
scp -P 60000 user2#localhost:file.txt .
(You can replace 60000 by your favourite port number)

Try the answers on ServerFault :
https://serverfault.com/questions/37629/how-do-i-do-multihop-scp-transfers.
The answers cover a variety of flavours of ssh.

Related

FIDO2 for SSH login on Linux Server

To establish an SSH connection between my PC (Linux) and server (Linux) I have to enter the password of the user.
ssh USER#<IP-Address>
Now I want to replace the password with FIDO2. For this I have executed the following commands on my PC and followed the instructions.
ssh-keygen -t ed25519-sk -O resident -O application=ssh:YourTextHere -f ~/.ssh/id_mykey_sk`
and
ssh-copy-id -i ~/.ssh/id_mykey_sk.pub USER#<IP-Address>
Now I have the problem when I try to establish the SSH connection it still asks for the password instead of the FIDO2 stick. What could be the reason for this?
I found out, that when I run the commands
eval `ssh-agent -s`
and
ssh-add -K
it works as expected.
Establish a connection to my server via
ssh USER#<IP-Address>
will now work with the FIDO2 key.

Is there any way for SSH to automatically insert password?

I am currently developing some work in clients and servers application and my college allows us to use their machines (linux) to host and test the apps.
My problem is that every single time I want to ssh into the machine the server prompts me to insert the password. I managed to use the information here to use a key in order to login but it still asks me for my password into the machine.
Using Putty I can save my password and login straight, is there anyway to do this using this command:
ssh -t (myUser#theSSHLink) -p 22
via Git Bash?
try:
USERHOST="myUser#theSSHLink"
cd ${HOME}
if [ ! -f ".ssh/id_rsa" ]; then
ssh-keygen -t rsa
fi
ssh $USERHOST mkdir -p .ssh
cat .ssh/id_rsa.pub | ssh $USERHOST 'cat >> .ssh/authorized_keys'
Running the above will ask for your password (from the user#host) twice. Afterwards, it shouldn't ask for a password when you try to ssh.

How to: scp over Jumphost, each with privatekeys

I want to have an scp command over a Jumphost to the targetserver. Both, the Jumphost and the targetserver, require an key for the login.
If there would be no key required, I think this command would work:
scp -o ProxyJump=usernameJumpserver#ipJumpserver filename usernameTargetserver#ipTargetserver:/path/filename
So, including a key, I get to this command:
scp -i /pathOnMyClient/key -o ProxyJump=usernameJumpserver#ipJumpserver filename usernameTargetserver#ipTargetserver:/path/filename
Then I get the error "usernameTargetServer#ipTargetserver: Permission denied (publickey)."
I can't add the (probably?) required -i /pathJumpserver/key to it. How does it work?
as you cannot enter the password of your ssh key at the jumphost I suggest to load your key into your local ssh-agent and then use one of:
> scp -o ProxyJump=user#jump.host localfile user#target.host:
> scp -o ProxyJump=user#jump.host user#target.host:file localdir
this works for me!
HTH
Stefan K.
So we have:
LocalHost
JumpHost
DestinationHost
On LocalHost, in ~/.ssh/config add:
Host JumpHost
User JumpHostUser
IdentityFile ~/.ssh/id_rsa
# other optional settings:
# Port 2222
# HostName 192.168.0.1
Host DestinationHost
User DestinationHostUser
IdentityFile ~/.ssh/id_rsa_jumphost
And you can use what #StefanKaerst suggested:
scp -o ProxyJump=JumpHost DestinationHost:/file /LocalFile
scp -o ProxyJump=JumpHost /Localile DestinationHost:/File
I have it aliased as
scpj='scp -o ProxyJump=JumpHost'
So I only type:
scpj DestinationHost:/file /LocalFile
You need to have all the keys in place though, both from local to jump, from jump to destination and from local to destination.
I could not get this working with ProxyJump, so I fell back to the more verbose ProxyCommand instead. This works for me for copying from A to C through B:
scp -i <path on A to key for C> \
-oProxyCommand="ssh -i <path on A to key for B> -W %h:%p <user>#B" \
/path/to/my/file <user>#C:~/
That worked for me:
scp -o ProxyJump=USER_NAME#35.1.2.3 local-File.txt 10.1.2.3:~/
Advanced ssh from windows, not much fun at all.
I've found this working.
Create a C:\Users\u.username\.ssh\config file like:
Host jumphost.server
HostName jumphost.server
User u.username
ForwardAgent yes
IdentityFile C:\Users\u.username\.ssh\id_rsa
Host * !jumphost.server
ProxyCommand ssh.exe u.username#jumphost.server -W %h:%p
IdentityFile C:\Users\u.username\.ssh\id_rsa
(replace your data for jumphost.server, as well as your username and path to ssh private key)
Then scp from final target.server is working that way (from powershell):
scp -F .\.ssh\config u.username#target.server:/path/to/file C:\Users\u.username\
or from local windows to target linux:
scp -F .\.ssh\config C:\Users\u.username\file u.username#target.server:/path/to/file
The flag -F is loading predefined config.

sshpass with proxycommand returns without running anything

In our environments, we have several servers in production. Every time I want to search for something, it may be in 1 of 4 different servers.
I am creating a script to automate this search, so that I directly know which server is involved.
I am connecting through a jumphost.
So far the following command works fine :
$ ssh -oProxyCommand="ssh -W %h:%p user#jumphost" user#server "ls"
Now, because I have to run this several times, I am searching for a way to only have to use the password once.
Both the jumphost and the server require the same password, and public keys are not an option (not allowed, I literally cannot do it).
I have been reading about sshpass for this and am trying this :
$ sshpass -p password ssh -oProxyCommand="ssh -W %h:%p user#jumphost" user#server "ls"
(I know -p is not safe and will use -e of -f as soon as I am successful with this step).
When I do this, I can login in both systems but the command returns before I see the result of ls.
I have tried to have the -t option to ssh without any success.
I have also tried the -J option from ssh, with the same results (command returns without returning any results).
$ sshpass -p password ssh -J user#jumphost user#server "ls"
Any suggestions?
EDIT:
Solution was to use sshpass twice :
$ sshpass -p password ssh -oProxyCommand="sshpass -p ssh -W %h:%p user#jumphost" user#server "ls"
Try running ssh in verbose mode:
ssh -vvv -oProxyCommand="ssh -W %h:%p user#jumphost" user#server "ls"
I'm sure it will show something of interest. A hook with which you can figure this out.

Ansible percent expand

I have an ansible playbook which connects to a virtual machine via a non-standard ssh port (forwarded to localhost) and a different user than the host user (vagrant).
The ssh port is specified in the ansible inventory:
[vms]
localhost:2222
The username given on the command line to ansible-playbook:
ansible-playbook -i <inventory from above> <some playbook> -u vagrant
The communication with the VM works correctly, however, %p always expands to 22 and %r to the host username.
Consequently, I cannot flush the SSH connection (for the user's changed group membership to take effect) like this:
- name: flush the ssh connection
command: ssh -o ControlPath="~/.ansible/cp/ansible-ssh-%h-%p-%r" -O stop {{inventory_hostname}}
delegate_to: 127.0.0.1
Am I making a silly mistake somewhere? Alternatively, is there a different way to flush the SSH connection?
The percent expand is not expanded by ansible, but by ssh later on.
Sorry, forgot to add the most important part
Using
command: ssh -o ControlPath=[...] -O stop {{inventory_hostname}}
will use default port, because you didn't specify it on the command-line. You would have to specify also the port to "flush" the connection this way:
command: ssh -o ControlPath=[...] -O stop -p {{inventory_port}} {{inventory_hostname}}
But I don't think it is needed. Ansible should clean up the connections when the playbook ends and I don't see any different reason why to do that.