Port forwarding is a very well-known networking technique used to allow external devices to access specific services within a private local area network (LAN). This mechanism works by forwarding packets addressed to the specific target port(s) on the gateway (typically, one of WAN interface addresses) to a designated host reachable on the private side of the gateway (within the LAN). The port forwarding mechanism is often used for hosting private online game servers, accessing LAN-side smart devices like IP cameras, weather stations, etc., gaining remote desktop access to select devices or their shell, while protecting other devices within the LAN from external access. Within the context of rXg configuration scaffolds, the port forwarding is referred to as ‘rXg Forwards’. UPnP (Universal Plug and Play) may be also used in certain scenarios, comprising a set of networking protocols that allow devices on a network to discover each other and establish communication automatically, without requiring manual configuration. While it is designed to make it easier for devices like computers, printers, gaming consoles, routers, and smart home devices to work together seamlessly, the use of UPnP has also raised some security concerns, since it can potentially open ports on your router without your knowledge, which might expose your network to risks if not properly secured. Typically, UPnP is disabled by default these days and its operation needs to be strictly monitored. The rXg platform also includes two additional mechanisms for port forwarding, namely ‘Transit Traffic Forwards’, ‘Device Port Forwards’, and ‘HTTP Virtual Hosts’ (also referred to as HTTP(S) proxy function), which are covered in detail in separate KB documents. At a high level, the ‘Transit Traffic Forwards’ mechanism is a reverse of a typical port forwarding, where traffic originating from the LAN side towards a specific destination (port) is intercepted and proxied through the rXg platform for a specific reason, e.g., to re-route all outbound email traffic through a specific SMTP relay. The ‘Device Port Forwards’ allows end-users with registered accounts with the given rXg platform instance to manage NAT forwarding for a specific device(s) and/or ports on them, without the involvement of the system administrator. The ‘HTTP Virtual Hosts’ function is best suited for accessing LAN-side web servers, while sharing the rXg public IP address with the associated SSL/TLS certificate.
Port Forwarding in rXg
The rXg packet forwarding engine supports a standard port forwarding mechanism, allowing selected traffic targeting one of the WAN interface address(es) and specific destination ports to be forwarded to a selected LAN-side host while optionally performing destination port mapping. This allows, for example, to configure remote desktop access to a LAN host using a random high destination port number (e.g., 53389), which is then mapped in the port forwarding rule to a well known RDP port of 3389. This approach prevents network reconnaissance scanning typically for open so-called low destination open ports, mapping the services running on the given network host.
For the purposes of this example, a remote desktop access to a LAN host VM at 10.0.31.3/24 on port 3390 is configured, assuming the use of the public high destination port of 53390.
The target LAN host VM is deployed on VLAN 31 (named ‘LAN-VID-0031’) created on the LAN interface running a link aggregation pseudo interface across two physical 10GE interfaces (see a separate KB document for LAGG configuration) and called ‘LAN’ in the ‘Network::LAN::Pseudo Interfaces’ scaffold below. The ‘LAN-VID-0031’ VLAN is associated with the ‘LAN-10.0.31.1/24’ network address block, and has a default DHCP pool associated with it, to permit individual hosts to acquire addresses in a dynamic manner. The resulting LAN configuration is accessible at the ‘Network::LAN’ scaffold and is shown below.
Configuration Process
With the network configuration shown above in place, several elements need to be created to permit the configuration of the port forwarding within the rXg. The rXg used for this KB document is running the latest stable release 15.812 code, available at the time of writing.
First, create the Applications entry describing the WAN-side view of the port forwarding policy. In this case, the ‘Ubuntu RDP’ entry is created in the ‘Policies::Packet Forwards::Applications’ scaffold, with the destination port of 53390 and TCP transport protocol, as shown below. Note that multiple destination ports can be defined simultaneously, if needed. Source ports and WAN Targets fields are unpopulated in this case, since they do not need to be restricted for this particular definition.
Next, the target host definition is created, using the IP Group entry and the associated Policies entry to describe the target LAN-side VM host.
The IP Groups entry is created in the ‘Identities::Groups::IP Groups’ scaffold, as shown below, with the new entry named ‘LAN-10.0.31.3/32-Ubuntu-RDP’ and using 10.0.31.3/32 VM address.
Once created, the ‘LAN-10.0.31.3/32-Ubuntu-RDP’ entry shows in the scaffold alongside all other ‘IP Groups’ entries created for other purposes.
The ‘LAN-10.0.31.3/32-Ubuntu-RDP-policy’ Policies entry is created under the ‘Policies::Policies’ scaffold, as shown below. The ‘Name’ is populated with the policy name. The ‘IP Groups’ is selected to match the previously created ‘LAN-10.0.31.3/32-Ubuntu-RDP’ IP Groups entry.
Once created, the ‘LAN-10.0.31.3/32-Ubuntu-RDP-policy’ entry shows in the scaffold alongside all other ‘Policies’ entries created for other purposes.
Finally, it is time to bind everything together to create a packet forwarding policy named ‘Ubuntu-RDP-53390’ within the ‘Policies::Packet Forwards::rXg Forwards’ scaffold, as shown below
Fill in the ‘Name’ field with ‘Ubuntu-RDP-53390’ to give the packet forwarding policy a name
Select an entry in the ‘Applications’ field by typing the first few letters of the target Applications entry name (‘ubuntu’ in this case)
Fill in the ‘Destination port override’ field to 3390 (this example maps the external port 53390 to the internal port 3390)
Select the ‘Destination Policy’ entry and set it to ‘LAN-10.0.31.3/32-Ubuntu-RDP-policy’ created before
The remaining fields remain either unchanged or with default settings.
Once created, the ‘Ubuntu-RDP-53390’ entry shows in the scaffold alongside all other ‘rXg Forwards’ entries created for other purposes.
The configuration process is now complete.
Testing Port Forwarding Policy
To test the port forwarding configuration, the remote desktop access was enabled on the Ubuntu 24.04.1 VM, as shown below.
This VM is accessible at 10.0.31.3/24
root@rxg-vm-vlan-31:~# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: enp6s18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether bc:24:11:fa:8b:47 brd ff:ff:ff:ff:ff:ff inet 10.0.31.3/24 brd 10.0.31.255 scope global dynamic noprefixroute enp6s18 valid_lft 2024sec preferred_lft 2024sec inet6 fe80::be24:11ff:fefa:8b47/64 scope link valid_lft forever preferred_lft forever
A remote desktop connection is then established, using the rXg WAN address and configured destination port 53390, as shown below. A public IP address or even a URL can be used as well, depending on the rXg configuration and its addressing scheme.
Once the ‘Connect’ option is selected, and password is entered, the certificate exception window is presented, as expected. The target Ubuntu VM uses a self-signed certificate.
Finally, the connection is made, as expected, and the remote desktop is presented, as shown below, confirming the connectivity was successfully established.
Additionally, it is possible to confirm that the remote desktop on the target VM is not reachable directly, as shown below, where the VM’s local address of 10.0.31.3 is used in combination with the remote desktop port of 3390.
When the connection attempt is made, the attempt fails after several seconds, as expected.
Port Forwarding in rXg Shell
For troubleshooting purposes, the operation of the port forwarding rule can be also observed in the rXg shell using the following firewall filtering rule, selecting packets with the WAN-side destination port (53390 in the case of this example) or the LAN-side destination port (3390 in this example).
tcpdump -nei pflog0 port 3390 or port 53390
The structure of the shell packet monitoring is covered in a separate KB document, but in general follows the syntax of a tcpdump (see https://www.tcpdump.org/manpages/tcpdump.1.html for more details).
[root@rxg /space/rxg]# tcpdump -nei pflog0 port 3390 or port 53390
10:17:32.843604 rule 4.f10.0-01-00-00.1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [S], seq 2293239592, win 64240, options [mss 1460,sackOK,TS val 677090642 ecr 0,nop,wscale 7], length 0
10:17:32.843608 rule 4.f10.0-01-00-00.1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [S], seq 2293239592, win 64240, options [mss 1460,sackOK,TS val 677090642 ecr 0,nop,wscale 7], length 0
10:17:32.843932 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [S.], seq 3610131775, ack 2293239593, win 65160, options [mss 1460,sackOK,TS val 1911872871 ecr 677090642,nop,wscale 7], length 0
10:17:32.844268 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [.], ack 1, win 502, options [nop,nop,TS val 677090643 ecr 1911872871], length 0
10:17:32.844750 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [P.], seq 1:43, ack 1, win 502, options [nop,nop,TS val 677090643 ecr 1911872871], length 42
10:17:32.844954 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [.], ack 43, win 509, options [nop,nop,TS val 1911872872 ecr 677090643], length 0
10:17:38.098323 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [.], ack 43, win 509, options [nop,nop,TS val 1911878126 ecr 677090643], length 0
10:17:38.098709 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [.], ack 1, win 502, options [nop,nop,TS val 677095897 ecr 1911872872], length 0
10:17:43.154293 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [.], ack 43, win 509, options [nop,nop,TS val 1911883182 ecr 677095897], length 0
10:17:43.154730 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [.], ack 1, win 502, options [nop,nop,TS val 677100953 ecr 1911872872], length 0
10:17:48.210279 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [.], ack 43, win 509, options [nop,nop,TS val 1911888238 ecr 677100953], length 0
10:17:48.210711 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [.], ack 1, win 502, options [nop,nop,TS val 677106009 ecr 1911872872], length 0
10:17:48.270202 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [F.], seq 43, ack 1, win 502, options [nop,nop,TS val 677106068 ecr 1911872872], length 0
10:17:48.271203 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [P.], seq 1:29, ack 44, win 509, options [nop,nop,TS val 1911888299 ecr 677106068], length 28
10:17:48.271263 rule 4..1/0(match): pass in on vlan31: 10.0.31.3.3390 > 192.168.150.4.46216: Flags [FP.], seq 29:38, ack 44, win 509, options [nop,nop,TS val 1911888299 ecr 677106068], length 9
10:17:48.271564 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [R], seq 2293239636, win 0, length 0
10:17:48.271569 rule 4..1/0(match): pass out on vlan31: 192.168.150.4.46216 > 10.0.31.3.3390: Flags [R], seq 2293239636, win 0, length 0
When the port forwarding rule is operating correctly, all associated matching packet logs include the statement ‘pass’, indicating that the forwarding engine has the associated configured rule(s). Any instances of the ‘block’ term indicate that specific packets are dropped, implying incorrect packet forwarding rule configuration.