Prerequisite
- A dedicated server. (Pre-installed PVE)
- Public IP address (Optional, but you must be able to access the server)
- Some virtual machine (You can install these vms later.)
Getting Started ๐
Configure to SDN (Software-Defined Network)
- Navigate to the Datacenter menu.
- Expand the SDN menu in center menu.
- Select the Zones menu under the SDN menu.
- Add a simple zone.
- ID: for example “sdn01”
- MTU: auto
- Nodes: All (No restrictions)
- IPAM: pve
- DNS Server: (Keep empty)
- Reverse DNS Server: (Keep empty)
- DNS Zone: (Keep empty)
- automatic DHCP: (Keep empty, or if you need DHCP.)
- Create a VNets
- Name: for example “vnet1”
- Alias: (allow empty)
- Zone: (Just created)
- Isolate Ports: (Keep empty)
- VLAN Aware: (Keep empty)
- Create a Subnets
- Select just created VNet
- Click create button
- General
- Subnet: for example “10.0.0.0/24”
- Gateway: for example “10.0.0.1”
- Select SNAT
- If you need DHCP (DHCP Ranges)
- Click Add button
- Start Address: 10.0.0.10
- End Address: 10.0.0.100
Create some virtual machines
Network option need to select vnet1 (just created SDN name) in bridge option.
Other configs are normal or custom. But you should configure the DNS server.
If you don’t need DHCP, you must be able to configure the IP address and subnet mask and gateway.
Tips: You can use OpenWrt to manage virtual machine network. ** But VNet cannot allow DHCP, because not recommend contain multi-gateway DHCP in a LAN. **
Configure the port mapping
Because, We cannot use ext network to access to vm in default.
- Create a shell script in /bin directory.
You should need to change this shell configure.
cat << EOF > /bin/pve-nat
#!/bin/bash
# ========================================================
# pve-nat - Simple Proxmox VE NAT Port Mapping Manager
#
# Usage:
# pve-nat add <public_port> <internal_ip> <internal_port>
# pve-nat del <public_port> <internal_ip> <internal_port>
# pve-nat add <public_port_range, E.g.: 60000:60100> <internal_ip> <internal_port_range, E.g.: 60000:60100>
# pve-nat del <public_port_range, E.g.: 60000:60100> <internal_ip> <internal_port_range, E.g.: 60000:60100>
# pve-nat list
#
# Example:
# pve-nat add 8080 10.0.0.2 80
# pve-nat del 8080 10.0.0.2 80
# pve-nat list
# ========================================================
# === Configuration ===
WAN_IFACE="enp59s0" # Public network interface name, you need to change it
WAN_IP="100.44.33.111" # Public IP address, you need to change it
SDN_NET="10.0.0.0/24" # SDN / internal network, you need to change it
# ======================
add_rule() {
local PUB_PORT_RANGE=$1
local VM_IP=$2
local VM_PORT_RANGE=$3
local PUB_START PUB_END VM_START VM_END
PUB_START=${PUB_PORT_RANGE%%:*}
PUB_END=${PUB_PORT_RANGE##*:}
VM_START=${VM_PORT_RANGE%%:*}
VM_END=${VM_PORT_RANGE##*:}
[[ "$PUB_PORT_RANGE" != *:* ]] && PUB_END=$PUB_START
[[ "$VM_PORT_RANGE" != *:* ]] && VM_END=$VM_START
if (( PUB_END - PUB_START != VM_END - VM_START )); then
echo "Error: Public and internal port ranges must be of equal length."
exit 1
fi
echo "Adding port forwarding: $WAN_IP:$PUB_PORT_RANGE -> $VM_IP:$VM_PORT_RANGE"
local i PUB_PORT VM_PORT
for ((i=0; i<=PUB_END-PUB_START; i++)); do
PUB_PORT=$((PUB_START + i))
VM_PORT=$((VM_START + i))
echo " -> $WAN_IP:$PUB_PORT -> $VM_IP:$VM_PORT"
iptables -t nat -A PREROUTING -i "$WAN_IFACE" -p tcp --dport "$PUB_PORT" \
-j DNAT --to-destination "$VM_IP:$VM_PORT"
iptables -t nat -A POSTROUTING -s "$SDN_NET" -d "$VM_IP" -p tcp --dport "$VM_PORT" \
-j SNAT --to-source "$WAN_IP"
done
}
del_rule() {
local PUB_PORT_RANGE=$1
local VM_IP=$2
local VM_PORT_RANGE=$3
local PUB_START PUB_END VM_START VM_END
PUB_START=${PUB_PORT_RANGE%%:*}
PUB_END=${PUB_PORT_RANGE##*:}
VM_START=${VM_PORT_RANGE%%:*}
VM_END=${VM_PORT_RANGE##*:}
[[ "$PUB_PORT_RANGE" != *:* ]] && PUB_END=$PUB_START
[[ "$VM_PORT_RANGE" != *:* ]] && VM_END=$VM_START
if (( PUB_END - PUB_START != VM_END - VM_START )); then
echo "Error: Public and internal port ranges must be of equal length."
exit 1
fi
echo "Removing port forwarding: $WAN_IP:$PUB_PORT_RANGE -> $VM_IP:$VM_PORT_RANGE"
local i PUB_PORT VM_PORT
for ((i=0; i<=PUB_END-PUB_START; i++)); do
PUB_PORT=$((PUB_START + i))
VM_PORT=$((VM_START + i))
echo " -> remove $WAN_IP:$PUB_PORT -> $VM_IP:$VM_PORT"
iptables -t nat -D PREROUTING -i "$WAN_IFACE" -p tcp --dport "$PUB_PORT" \
-j DNAT --to-destination "$VM_IP:$VM_PORT"
iptables -t nat -D POSTROUTING -s "$SDN_NET" -d "$VM_IP" -p tcp --dport "$VM_PORT" \
-j SNAT --to-source "$WAN_IP"
done
}
list_rules() {
echo "=== Current DNAT Rules ==="
iptables -t nat -L PREROUTING -n -v | grep DNAT || echo "(No DNAT rules found)"
echo
echo "=== Current SNAT Rules ==="
iptables -t nat -L POSTROUTING -n -v | grep SNAT || echo "(No SNAT rules found)"
}
case "$1" in
add)
if [ $# -ne 4 ]; then
echo "Usage: $0 add <public_port|range> <internal_ip> <internal_port|range>"
exit 1
fi
add_rule "$2" "$3" "$4"
;;
del)
if [ $# -ne 4 ]; then
echo "Usage: $0 del <public_port|range> <internal_ip> <internal_port|range>"
exit 1
fi
del_rule "$2" "$3" "$4"
;;
list)
list_rules
;;
*)
echo "Usage:"
echo " $0 add <public_port|range> <internal_ip> <internal_port|range>"
echo " $0 del <public_port|range> <internal_ip> <internal_port|range>"
echo " $0 list"
;;
esac
EOF
- Configuration port mapping.
chmod +x /bin/pve-nat
# Example: allow access to 10.0.0.50/24:22
# You should use other port, don't use 22, because 22 port is PVE SSH port.
pve-nat add 2222 10.0.0.50 22
# You also install netfilter-persistent to persistent DNAT list.
apt install netfilter-persistent
netfilter-persistent save
Completed all configuration ๐
Now, you can use command ssh -p 2222 username@100.44.33.111 to access to your vm.