For the first time, I need to create a KVM server that will manage virtual machines that are not on the LAN. This server has a static public IP and, given the nature of the services it needs to run, it does not need to be placed in a LAN. Primarily, the virtual machines will provide cloud services (Nextcloud) and business CRM, which need to be accessible from around the world.
Therefore, I am evaluating how to manage SSH connections to the server and how to handle traffic for the virtual machines.
Regarding SSH, the simplest approach is to directly expose port 22 and access it with an authentication key. Is this solution commonly used, or is it not secure enough? Alternatively, should I set up a VPN and then access SSH through it?
For the virtual machines, they will run on a dedicated and isolated LAN, but I need at least one machine to forward traffic on ports 80 and 443 to act as a reverse proxy. In this case, I am considering whether it makes sense to set up a machine as a router to manage traffic to and from the isolated network, or simply create an iptables rule on the KVM server to forward all HTTP and HTTPS traffic to the virtual machine with NGINX, which will then dispatch requests to the respective virtual machines for each service.
Since this is the first time I am exposing a server directly on the internet (I have always worked within a LAN), I would like to understand what the best practices are.
Ssh itself is generally fine to expose, as long as you trust your people not to reuse passwords or keys. The real benefit to wrapping ssh under a VPN tunnel is that your users can’t do stupid shit with the VPN, they just have to accept the relatively giant blob of randomly generated key that you give them, and they don’t really have any options to try to reuse it somewhere else. (We’re avoiding going into the weeds about how keys actually work, here, but for your purposes this is the right discussion to have).
Usually in a multiple user environment, you do want to require keys (not passwords) for login. It’s a good idea to require passphrases that unlock the keys as well, but in practice you can’t really make that happen unless you’re handing a key to your users, rather than allowing them to generate and use their own.
If you trust your users not to be dumbasses, it’s ok for them to use a key that they already have and use elsewhere to get into your system too. But in that case you do need to trust that they’ve actually attached a passphrase, that the passphrase isn’t stupid, etc.
If you think some of your users might be a bit “security challenged” it’s safer to generate the key yourself, and require they use that key.