When you look for tutorials on how to install Proxmox, it always stops after the initial installation - which is quite dangerous, since it leaves a Proxmox host being exposed to the internet while listening to Ports 22 and 8006.
Heck, there is not even any SSH-hardening covered - your SSH is typically set to default values, which means: Password-authentication with the root account is perfectly possible. While you can mitigate some of these things by harding SSH or by installing fail2ban (which we will do anyhow), the host still exposes ports 22 and 8006.
For a secure system, these ports (and actually, apart from one single port ANY ports) have to be disabled. The only acceptable management access to the system should either happen via a Jumpserver or - if not available - via a direct VPN-connection.
In this gist, you find all the required steps to secure your Proxmox exposed host. This gist should work for any Proxmox host with - say - Hetzner, OVH or other vendors, it obviously also works on your internal systems (it is probably not a bad idea to have them secured a bit as well).
- Have a working Proxmox installation :-)
apt install fail2ban sudo ufw
useradd -m user
Then, set a strong password
passwd user
Add the user to the sudo group
usermod -aG sudo user
Log out off the SSH session
exit
Copy the SSH-key for this user to the machine (from your local machine):
ssh-copy-id user@<IP>
Re-Login to the machine, this time not as root
ssh user@<IP>
On the machine, open the SSH-settings
sudo nano /etc/ssh/sshd_config
Here, uncomment and set the following values
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Then, reload the SSH-Daemon
sudo systemctl restart sshd
Allow only SSH-connections to the machine
sudo ufw allow 22/tcp
sudo ufw enable
Open the network configuration
sudo nano /etc/network/interfaces
Here, you need to note down the name of the primary networking device (i.e. an ethernet connection with inet static and an external IP-address, or a vmbr-definition with an external IP-address):
Have a look at one of my network configurations:
auto lo
iface lo inet loopback
iface enp34s0 inet manual
auto vmbr0
iface vmbr0 inet static
address xx.xx.xx.77/24
gateway xx.xx.xx.1
bridge-ports enp34s0
bridge-stp off
bridge-fd 0
The name I need to remember, is vmbr0.
Add a new bridge:
auto vmbr1
iface vmbr1 inet static
address 10.1.1.254/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up iptables -t nat -A POSTROUTING -s '10.1.1.0/24' -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.1.1.0/24' -o vmbr0 -j MASQUERADE
Save the configuration, and reboot the machine (could also be done via ifup -a
and / or sudo systemctl restart networking
, but does not work all the time, so it is more secure to restart the machine)
sudo reboot
Download a script to automate this:
wget https://git.io/vpn -O openvpn-install.sh
Make it executable
chmod +x openvpn-install.sh
Run it
sudo ./openvpn-install.sh
Obviously, you need to adjust the settings to your liking. :-)
Cat the generated .ovpn-file
cat <Path-to>/<Ovpn-File>.ovpn
and copy its contents to your local machine (I typically just do a copy, then create an empty file in my text-editor, paste the stuff in there, and then just save it as .ovpn-file).
Import it into your local OPVN-client.
On the machine, execute the following statements:
sudo ufw allow 1194/udp
sudo ufw reload
Now, exit from the machine, and connect from your local machine via VPN to the remote machine - which should work. Also, open a new SSH-connection from your local machine to the remote machine via the internal IP-address:
ssh [email protected]
This should also work and connect you with your machine.
On the remote machine, you can now disable SSH apart from your VPN-connection and allow it from the VPN-connection only
sudo ufw delete allow 22/tcp
sudo ufw allow from 10.8.0.0/24 to any port 22
sudo ufw allow from 10.8.0.0/24 to any port 8006
sudo ufw reload
Now, SSH and access to the Proxmox-GUI only work from your VPN connection.
Lastly, edit /etc/default/ufw and allow forwarding:
DEFAULT_FORWARD_POLICY="ACCEPT"
Restart the machine to make everything work.
Since we now have completely shut off external access from our Proxmox, we should allow some access to - say - web-workloads.
If you want to start such workload, make sure, its network stack is bound to vmbr1. We now need to create a NAT-Rule for UFW, so that every web-request to the machine - which in our example runs on the internal IP 10.1.1.100 - is forwarded to the VM or container.
Do that by editing /etc/ufw/before.rules
and by inserting these lines before *filter:
### NAT ###
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-F
# Port Forwardings
-A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to-destination 10.1.1.100
-A PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to-destination 10.1.1.100
# Forward traffic through eth0 - Change to match you out-interface
-A POSTROUTING -s 10.1.1.0/24 -o vmbr0 -j MASQUERADE
COMMIT
### EOF NAT ###
Please make sure, that you are forwarding from the correct network interface - should be the same as identified above (vmbr0 in my case).
Reload UFW
sudu ufw reload
Done!