5

Scenario: I want to connect from Client A to Client B using SSH/SFTP. I can not open ports on either client. To solve this issue, I got a cheap VPS to use as a relay server.

On Client B I connect to the VPS with remote port forwarding as followed:

ssh -4 -N -f -R 18822:localhost:22 <user>@<vps-ip>

On the VPS I've set up local port forwarding using -g (global) like this:

ssh -g -f -N -L 0.0.0.0:18888:localhost:18822 <user>@localhost

That way I can connect from Client A directly to Client B at <vps-ip>:18888. Works great.

Now my question is, how safe is this? As far as I know, SSH/SFTP connections are fully encrypted, but is there any chance of making it less secure by using the VPS in the middle?

Let's assume these two cases:

Case A: The VPS itself is not altered with, but traffic and files are monitored completely.

Case B: The VPS is completely compromised, filesystem content can be altered.

If I now send a file from Client A to Client B over SFTP, would it be possible for the company hosting the VPS to "intercept" it and read the file's (unencrypted) content?

  • 2
    The SSH traffic is protected end-to-end (no matter what is in the middle). That is: each end has the correct keys to encrypt and decrypt the content in the connection. Nobody else has those keys, well, as long as the crypto is sound and the implementation is correctly done, the probability of that happening is vanishingly small. Understand that the probability is not zero and mistakes on implementation do happen. However, that is the best we've got yet. – Isaac Oct 30 '18 at 3:35
  • @Isaac Would you mind leaving a full answer so I can accept it? Some technical references would be nice too! – confetti Oct 30 '18 at 10:51
  • 1
    @confetti Please, remember to award the bounty to the answer! – Mateusz Konieczny Nov 5 '18 at 11:23
7
+50

What you did

You used three ssh commands:

  1. While inside a B console you did:

    ssh -4 -N -f -R 18822:localhost:22 <user>@<vps>
    

    Command sshd (the server) to open port 18822, a remote port vps:18822 connected to localhost (B) port 22.

  2. While at a vps console you did:

    ssh -g -f -N -L 0.0.0.0:18888:localhost:18822 <user>@localhost
    

    Command ssh (the client) to open port 18888 available as an external (0.0.0.0) port on (vps) that connects to internal port 18822.

    That opens an internet visible port vps:18888 that redirects traffic to 18822 which, in turn, redirects to B:22.

  3. While at a A console (and the only connection in which A participate):

    Connect from Client A directly to Client B at vps:18888.

What matters is this last connection.
The whole SSH security depends on the authentication of A to B.

What it means

The SSH protocol

SSH provides a secure channel over an unsecured network

By using end-to-end encryption

End-to-end encryption (E2EE) is a system of communication where only the communicating users can read the messages. In principle, it prevents potential eavesdroppers – including telecom providers, Internet providers, and even the provider of the communication service – from being able to access the cryptographic keys needed to decrypt the conversation.

End to end encryption is a concept. SSH is a protocol. SSH implements end to end encryption. So can https, or any other number of protocols with encryption.

If the protocol is strong,and the implementation is correct, the only parties that know the encrypting keys are the two authenticated (end) parties.

Not knowing the keys and not being able to break the security of the protocol, any other party is excluded from the contents of the communication.

If, as you describe: from Client A directly to Client B you are authenticating directly to system B, then, only Client A and client B have the keys. No other.

Q1

Case A: The VPS itself is not altered with, but traffic and files are monitored completely.

Only the fact that a communication (day, time, end IPs, etc.) is taking place and that some amount of traffic (kbytes, MBytes) could be monitored but not the actual contents of what was communicated.

Q2

Case B: The VPS is completely compromised, filesystem content can be altered.

It doesn't matter, even if the communication is re-routed through some other sites/places, the only two parties that know the keys are A and B. That is: If the authentication at the start of the communication was between A and B.

Optionally, check the validity of the IP to which A is connecting, then: use public key authentication (use only once a private-public key pair that only A and B know), done.

Understand that you must ensure that the public key used is carried securely to the system B. You can not trust the same channel to carry the keys and then carry the encryption. There are Man-in-the-middle attacks that could break the protocol.

Q3

If I now send a file from Client A to Client B over SFTP, would it be possible for the company hosting the VPS to "intercept" it and read the file's (unencrypted) content?

No, if the public keys were safely placed on both ends, there is a vanishingly small probability of that happening.

Walk with the disk with the public key to the other side to install it, never worry again.


Comment

From your comment:

Q1

So, basically the VPS in my setup does nothing but forward the ports, and is not involved in the actual SSH connection or authentication happening from Client A to B, correct?

Kind of. Yes the VPS should not be involved in the authentication. But it is "In-The-Middle", that is, it receives packets from one side and delivers them (if it is working correctly) to the other side. But there is an alternative, the VPS (or anything In-The-Middle) could choose to lie and perform a "Man-In-The-Middle-Attack". It could lie to Client-A pretending to be Client-B and lie to Client-B pretending to be Client-A. That would reveal everything inside the communication to the "Man-In-The-Middle". That is why I stress the word should above.

I should also say that:

...there are no tools implementing MITM against an SSH connection authenticated using public-key method...

Password-based authentication is not the public-key method.

If you authenticate with a password, you could be subject to a Man-In-The-Middle-Attack. There are several other alternatives but are out of scope for this post.

Basically, use ssh-keygen to generate a pair of keys (lets assume on side A), and (for correct security) carry the public part inside a disk to Side B and install it in the Authorized-keys file. Do not use the network to install the public key, that is: do not use the ssh-copy-id over the network unless you really do know exactly what you are doing and you are capable of verifying the side B identity. You need to be an expert to do this securely.

Q2

About the public key though, isn't it, well, public?

  • Yes, its public.
    Well, yes, the entity that generated the public-private pair could publish the public part to anyone (everyone) and have lost no secrets. If anybody encrypts with its public key only it could decrypt any message with the matching (and secret) private key.

  • SSH encryption.
    By the way, the SSH encryption is symmetric not asymmetric (public). The authentication is asymmetric (either DH (Diffie-Hellman) (for passwords) or RSA, DSA, Ed25519 Key strength or others (for public keys)), then a symmetric key is generated from that authentication and used as communication encryption key.

  • Used for authentication.
    But to SSH, the public key (generated with ssh-keygen) carry an additional secret: It authenticates the owner of the public key.

    If you receive a public key from the internet: How do you know to whom it belongs? Do you trust whatever that public key claims it is? You should not !!

    That is why you should carry the public key file to the remote server (in a secure way) and install it there. After that, you could trust that (already verified) public key as a method to authenticate you to log-in to that server.

Q3

I've connected from the VPS, mostly for testing, to Client B before too, doesn't that exchange the public key already?

It exchange one set of public keys (a set of DH generated public keys) used for encryption. Not the authentication public key generated with ssh-keygen. The key used on that communication is erased and forgotten once the communication is closed.

Well, you also accepted (and used) a key to authenticate the IP of the remote server. To ensure that an IP is secure gets even more complex than simple(??) public-key authentication.

My impression was that the public key can be shared, but the private key or passphrase must be kept safe.

And your (general) impression is correct, but the devil is in the details ...

Who generated a key pair could publish his public key without any decrease of his security.

Who receives a public key must independently confirm that the public key belongs to whom he believes it belongs.

Otherwise, the receiver of a public key could be communicating with an evil partner.

Generate your key

  • Great answer. So, basically the VPS in my setup does nothing but forward the ports, and is not involved in the actual SSH connection or authentification happening from Client A to B, correct? About the public key though, isn't it, well, public? I've connected from the VPS, mostly for testing, to Client B before too, doesn't that exchange the public key already? My impression was that the public key can be shared, but the private key or passphrase must be kept safe. – confetti Nov 1 '18 at 20:16
  • @confetti Please read expanded/extended answer. – Isaac Nov 3 '18 at 2:27
  • Wow, that's an amazing answer. Answered every question I had. Thank you very much. I have the luxury to access both clients physically, so I can and will copy the public key off-line. Especially the ssh.com link was very helpful to understand the concept completely! – confetti Nov 3 '18 at 12:40
  • 1
    @ctrl-alt-delor On the OP description he starts the description of that command (ssh -4 -N -f -R 18822:localhost:22 <user>@<vps-ip>) with: On Client B, that is, he is making a connection from B to the vps. Then he makes an internal port swap (inside the vps) to expose the port to the internet. Then, and this is the critical point: he connects from A directly to B. There is no other connection while On client A, so, there is no other way in which A could connect to anything else. (Cont...) – Isaac Nov 6 '18 at 5:26
  • 1
    (Cont...) In short, there is only one authentication of A and that is the one that counts. In any case, I have tried to explain and expand the detail of how the connection is being built at the start of this answer to be explicitly clear to you (and other future readers). Is that explained clearly enough for you? @ctrl-alt-delor – Isaac Nov 6 '18 at 5:30
-1

If you use ssh to connect A to C, and then C to B, then it is not end to end. It is end to C, and C to other end. C can see what is being transmitted.

For end to end encryption you need ssh to connect the two ends. It matters not what you go through.

If the two ends can not see each other, but can see C, then you can set up (secure or not) connections A—C and B—C. Then use ssh to make a secure connection A—B.

  • 1
    He is opening a port from B to vps, then a redirection from vps to an external port. Then, he claims to be connecting directly from A to B thru that opened channel. Is it not what he already said? – Isaac Nov 5 '18 at 16:29
  • Please read: How to make ssh tunnel open to public? – Isaac Nov 5 '18 at 16:53
  • May be I am missing something (and so may the OP and future readers), but what I have read is exposing your data. Yes I may be an idiot, compared to you. But if I could read it wrong and make a mistake, then so will others. – ctrl-alt-delor Nov 5 '18 at 21:55
  • 1
    Yes, you are missing that there is not connection from A to C (and then to B). That is a wrong interpretation. What there is is a three step connection: (1) from B to VPS then (2) an internal port forward from port 18822 to port 18888 inside VPS and then (3) a direct connection of A to B. Please read the expanded description at the start of my answer. As long as the authentication of the last ssh command is A directly to B (and keys are not re-used) there could not be any data exposition. – Isaac Nov 6 '18 at 5:33

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.