Copy files between two SSH clients diretctly - ssh

Our two SSH client only machines have access to another remote server with the same user account, and we want to copy files between the two clients over the wire. Can we configure this type of small local hub-spoke network to make the direct file transfer between the clients pass through the server transparently, and how?
For example, we have the hub-spoke network configuration below, where the hub is the SSH server, the spokes are SSH clients and the clients need copy files directly.
Node IP Client Server Port User Status
A 192.168.1.1 Y N N/A alice authenticated
B 192.168.1.2 Y N N/A bob authenticated
C 192.168.1.3 Y Y 22 shared authorized
$ alice#A: ssh-keygen
$ alice#A: ssh-copy-id shared#C
$ bob#B: ssh-keygen
$ bob#B: ssh-copy-id shared#C
Now, we can copy a file from alice#A to bob#B yet neither directly nor efficiently below.
$ alice#A: scp myfile shared#C:~
$ bob#B: scp shared#C:~/myfile .
However, we want to customize the network configuration not to firstly drop the file to shared#C but copy it from alice#A to bob#B directly.
#chepner proposed scp -3. I think that we have to change the hub-spoke network configuration fundamentally, i.e. the hub must act as SSH client, the spokes must run as SSH servers, then the servers can copy files directly through the transparent client proxy. Here's the example.

provided you can go from C to B, then the following should work:
in the ssh config file on A, define both B and C:
Host C
Hostname c-whatever.contoso.local
IdentityFile ~/.ssh/id_rsa
User charlie
ForwardAgent yes
Host B
Hostname b-whatever.contoso.local
IdentityFile ~/.ssh/id_rsa
User bob
ProxyJump C
ssh to B will proxy all traffic via C

Related

VS Code jump-box setup with SSH keys

Establishing an SSH connection via a jump box
Hi everyone, I have been trying to set up my environment on VS Code to run my code from my Windows laptop on a remote Linux server (through my University department's proxy), by following this tutorial. It is working fine, but every time I connect to the host, I need to enter my password and would like to avoid this by configuring my SSH keys - it seems like I haven't found the proper way to do so.
Generating the keys
Let's call my local Windows machine local, the proxy host1 and the final endpoint host2. I created a private/public key pair on local, transferred the public key to host1 so that it is now in ~/.ssh/authorized_keys, and repeated the process by generating a new key pair on host1 and transferring the public key on host2. I followed the instructions here for generating and transferring the keys:
Generate key on local:
ssh-keygen -t rsa -b 4096
Transfer public key to host1:
$USER_AT_HOST="your-user-name-on-host#hostname"
$PUBKEYPATH="$HOME\.ssh\id_rsa.pub"
$pubKey=(Get-Content "$PUBKEYPATH" | Out-String); ssh "$USER_AT_HOST" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '${pubKey}' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Generate key on host1:
ssh-keygen -t rsa -b 4096
Transfer public key to host2:
export USER_AT_HOST="your-user-name-on-host#hostname"
export PUBKEYPATH="$HOME/.ssh/id_rsa.pub"
ssh-copy-id -i "$PUBKEYPATH" "$USER_AT_HOST"
VS Code config
I then edited my config file according to this, which now looks as follows:
Host host1
HostName host1
User me
ForwardX11 yes
IdentityFile C:\Users\Me\.ssh\id_rsa
Host host2
HostName host2
ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -q -W %h:%p host1
ForwardX11Trusted yes
User me
IdentityFile ~/.ssh/id_rsa
It seems that the first jump works fine (I don't need to enter my password twice) but I am still asked for it when establishing the connection. My guess is that I haven't configured the IdentityFile properly? When connecting through PowerShell in two steps (i.e. SSH into host1 and then host2), I don't need to enter my password. I would really appreciate any advice!
I've been stucking in the same situation.I tried a lot ,and finally managed to connect without password prompts. Below it's how I've done it, Hope it'll help.
Suppose I(machine A) want to connect to machine C via Machine B(JumpServer), generate keys using ssh-keygen on machine A, then copy the content of public key file(default as id_rsa.pub) to authorized keys file(default as authorized_keys in .ssh folder) of both machine B and machine C(or using ssh-copy-id if available). At last the IdentityFile field of both hosts of machine B and machine C in the config file(host1 and host2 in your case), fill them with ~/.ssh/id_rsa or C:\Users\your_user_name.ssh\id_rsa(the private key you generate on machine A ).
Finally it connects as expected.(I guess in this siutation but not for sure that the identity file in the local machine A is always the subject to connect, so machine B and machine C need to use the identity of machine A for all authorizations)
I met exactly the same situation, that is making this ssh connection: local (Windows) -> host1 (Linux) -> host2 (Linux)
The problem here is that for the second jump to host2, the ProxyCommand "ssh.exe -q -W %h:%p host1" actually looks for host2's IdentityFile "~/.ssh/id_rsa" on local. Because the keys you generated on host1 is different from the one on local, using the key on local would fail to make the second jump.
Solutions:
Simply use the same key for two jumps. Copy the id_rsa.pub on local to host2's authorized_keys.
Copy the key files on host1 to local, rename them and fill host2's IdentityFile with the path of the key file on local.
Referring to this question, modifying the ProxyCommand may enable ssh to use the key on host1 during the second jump. However, I haven't been able to make it work on my Windows local machine.

Bulding an SSH tunnel

I have three hosts: A, B, C. B can connect to C through ssh, via port 221. A cannot connect to C because it's behind a router, but can connect to B through ssh. What I need, is to connect from A to C.
The situation is summarized below:
A -- p22 ---> B OK
B -- p221---> C OK
A -- p???---> C not working
I have tried many variations of ssh tunneling but looks like I don't get how tunneling works. Also, I have no root privileges on any of the hosts, therefore I cannot do port forwarding on port 22. I am therefore not sure this tunneling can be done at all. If it can, however, I would appreciate the exact commands to run on each host so that I can finally ssh from A to C.
While you could set up an explicit tunnel in this situation, it's much more convenient to use the -J option
ssh -J B -p 221 C
or the ProxyJump option explicitly
ssh -o ProxyJump=B -p 221 C
ssh will first connect to B for you (prompting for a password if necessary), then connect to C from B. From your point of view, you will have connected directly to C.
The idea of ssh -L local_port:another_host:destination_port user#host is to say a/ start listening locally on local_port b/ connect to remote host (as usual), and once you're there, connect to that another_host and c/ forward everything you will receive locally to that another host's destination_port
so, I would try the following (from host A)
ssh -C -N -L 2222:C:221 user#B
then from another terminal
ssh -p 2222 user#localhost
I did not test the above. Happy to dig deeper if required.
Here is the human readable explanation (hopefully) :
starting from host A
ssh, connect as user on host B (no port specified as 22 is the default)
-C compress all content in transit in the tunnel
-N says to not open a tty (interactive) session on host B
-L says "once you're on B, start listening on this host (A) on port 2222 (as you are not root) and forward everything to C, port 221"
If you're using password authentication, it should work. Certificate authentication would require a bit of additional configuration on B to correctly forward your certificate to C (which exact syntax I don't remember right now)

sshfs with two consecutive ssh authentications

with two consecutive ssh authentications I mean the following:
I ssh to remote system A
from remote system A, I ssh to remote system B
There is no way to ssh to B directly.
I have no problems mounting directories from A using sshfs.
I thought about mounting directories from B on A but unfortunately A does not have sshfs installed. Even if, I would not know if it works.
Is there maybe another way to access directories on B in a convenient way?
My ~/.ssh/config looks like this now:
Host A
User user
HostName A.example.com
ControlMaster auto
ControlPath ~/.ssh/%r#%h:%p
Host B
User user
HostName B.example.com
ProxyCommand ssh -W %h:%p A
How would my sshfs command look like?
This does not work:
sshfs -o allow_other,defer_permissions -o user#B.example.com:/somedir ~/somedir
It outputs the error message:
remote host has disconnected
Use ProxyCommand or ProxyJump to do that transparently for the end application (sshfs). For example in ~/.ssh/config
Host A
# other configuration options needed
Host B
ProxyCommand ssh -W %h:%p A
Then you should be able to use sshfs transparently by directly specifying host B.

remote login to ubuntu server via SSH

I have 3 Ubuntu machines. First one (A) is my local machine, second one (B) is a gateway to the third (C) Ubuntu server. I can SSH from my local machine, A, to B and then SSH from B to C. I can't SSH from A to C directly.
What I need is to remotely log (graphical) into C from B? and if possible from A? I'm no network guy and the tunneling concept and port 3389 is confusing me.
Appreciate your help.
Confusing or not, you need tunneling. The easiest:
ssh -L 7722:address.of.C:22 address.of.B
will log you into B. At the same time, it will set up a tunnel between the current machine's port 7722 (can be any unused port over 1024, I arbitrarily selected 7722) and C's port 22 (the ssh port). Then, in another terminal,
ssh -X -p 7722 localhost
will open a SSH connection to your local port 7722, which is being tunneled to C's 22. It is functionally equivalent to ssh address.of.C while the above tunnel exists.
When you are done, just exit the second connection to leave C, then exit the first connection to deconstruct the tunnel.
If you don't have two terminals to work with, it is a bit more complex since you need a way to refer to the tunnel in order to be able to close it later.
ssh -fNM -S /tmp/tunnel.B.to.C.control 7722:address.of.C:22 address.of.B
ssh -X -p 7722 localhost
ssh -O exit -S /tmp/tunnel.B.to.C.control address.of.B
Here, /tmp/tunnel.B.to.C.control is an arbitrary name of file in a location where you can create a file. The first command sets up a tunnel and exits (instead of logging in), but stays in memory and records its activities in the named file. The last command then releases the tunnel, the memory and the file.

ssh tunneling through a telnet server

Suppose the network is like:
A(192.68.0.1)--------------------B(192.68.0.2)------------------C(192.68.0.3)
A is my ssh server, C is a target ssh server, and I can telnet from A to B(my account is not root).
B is a server not allow ssh login from others, but B can login to C via ssh.
Is it possible to connect C from A through B via ssh?
If you can run programs on B, you can use something like simpleproxy to forward the TCP connection to C.
Then you SSH from A to some port on B (not 22), which will forward your connection to C. Everything will still be encrypted since the SSH session is A<->C.
ok telnet to b
you can actually ssh to yourself on b, but the following command may not work but try it first
ssh -L0.0.0.0:2200:192.68.0.3:22 127.0.0.1 ...
if sshd is not running on b... then ssh to c
ssh -L0.0.0.0:2200:192.68.0.3:22 192.68.0.3
do a
netstat -an | grep 2200 -- Do this on b (192.68.0.2)
if the netstat has 127.0.0.1 listening on 2200 and not 0.0.0.0 this trick wont work... but if it does... you can then connect to ssh on port 2200 to b and it will hit c
ssh 192.68.0.2:2200
i have you ssh to localhost on b because i cant remember the command to not spawn a shell and im too lazy to look it up... but if the solution above does not work you wont be able to redirect ports with ssh without root, you would have to change the config file on b
you would have to add
GatewayPorts yes to the sshd config file in /etc/sshd/conf/sshd_config
http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch09_02.htm -- this talks all about port forwarding with ssh