You should use policy routing to implement this. The rules won't be too complicated.
Your (main) default route should point toward the VPN interface. You'll probably use OpenVPN's --redirect-gateway def1
option to have this managed automatically for you when the VPN comes up. It makes OpenVPN override the system default route with a couple of /1
routes that have the same effect and makes sure OpenVPN itself can still reach its remote peer in the normal way without the obvious routing loop.
This default route will make locally originated traffic go out through the VPN and it will also make replies to traffic that came in through the VPN go out the VPN.
Now you want to override this with a policy rule for packets that are associated with connections that came in on the non-VPN interface. You want to make those packets go back out through the non-VPN interface.
The following should accomplish this by (1) matching packets that have the non-VPN public IP address as a source address and asking those to be routed via a different routing table, (2) in that routing table, sending everything to your original (non-VPN) default route.
ip route add table 42 default via X.Y.Z.W
ip rule add from A.B.C.D/32 table 42
A.B.C.D
should be your public (non-VPN) IP address, and X.Y.Z.W
should be your original system default route (through your ISP, not through your VPN).
The similar config for IPv6 traffic is left as an exercise for you :-)
What you did
You used three ssh commands:
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.
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
.
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
Best Answer
ntop is probably your best solution for doing this. It is designed to run long term and capture exactly what youre looking for.
It can show you what remote destinations are being used the most, how much traffic sent to/from, what protocols and ports were being used etc. It can do the same for the source hosts if you run it on a router so you can see the same stats on local clients as well.
It then uses a web GUI to navigate and display this information.