Access RDP over SSH with network proxy

Hello! :wave:

I’ve been struggling with certain setup over the past few weeks. I have a VM instance running on Linux machine. The OS inside the VM is Windows Server with RDP enabled. I can connect to it on my local network no problem.

As I plan to host that machine in the cloud, I want to secure it from any brute force attacks that might happen. My idea is to use SSH as the entry point, so RDP can be accessed within the guest only if SSH session was established successfully to the host server.

This is the config of the VM:

architecture: x86_64
config:
  limits.cpu: "4"
  limits.memory: 8GiB
  volatile.cloud-init.instance-id: 8855e2a9-f0e5-420a-acb1-fc00d32ff663
  volatile.eth0.host_name: tap0161153f
  volatile.eth0.hwaddr: 00:16:3e:c1:fc:12
  volatile.last_state.power: RUNNING
  volatile.uuid: dfb8663a-aadf-4c08-bef4-ddb1ed2a8831
  volatile.uuid.generation: dfb8663a-aadf-4c08-bef4-ddb1ed2a8831
  volatile.vsock_id: "2463382061"
devices:
  eth0:
    ipv4.address: 10.10.182.165
    name: eth0
    network: incusbr0
    type: nic
  port-3389:
    connect: tcp:10.10.182.165:3389
    listen: tcp:127.0.0.1:3389
    nat: "true"
    type: proxy
  root:
    path: /
    pool: default
    size: 40GiB
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

And iptables rules (same rules apply to IPv6):

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
sshguard   tcp  --  anywhere             anywhere             tcp dpt:ssh /* SSH Guard */
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh /* SSH */
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps /* DHCP */
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc /* DHCP */
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
REJECT     tcp  --  anywhere             anywhere             reject-with tcp-reset
REJECT     udp  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain sshguard (1 references)
target     prot opt source               destination  

I’ve tried setting listen: tcp:127.0.0.1:3389 to external IP address of the host as well as an arbitrary IP address from 10.10.182.1/24 network but nothing seems to work after setting the SSH tunnel with ssh -L 3389:localhost:3389 zubmic@192.168.1.248

I’ve also tried with incus network forward commands, but no luck either.

Is it even possible to configure it in a way that I’ve described it? If so, what’s the proper way?

Attaching a diagram in case I wasn’t clear enough about what I would like to do:

My first though is: try ssh -L 3389:127.0.0.1:3389

On some systems, localhost in /etc/hosts includes IPv6 (::1), although others have a separate localhost6.

In NAT mode you should be able to check the rules added by incus using iptables -L -n -v -t nat

Have you tried non-NAT mode? There might be special magic required to make iptables redirect traffic from the loopback interface.

Also, according to the docs you don’t need to hard-code the guest IP address in the config, you can just say connect: tcp:0.0.0.0:3389

You can specify that the connect address should be the IP of the instance by setting the connect IP to the wildcard address (0.0.0.0 for IPv4 and [::] for IPv6).

Hi Brian, thanks for your reply!

My first though is: try ssh -L 3389:127.0.0.1:3389

On some systems, localhost in /etc/hosts includes IPv6 (::1), although others have a separate localhost6.

I switched from localhost to 127.0.0.1 as you’re right about that one. I remember reading somewhere that it’s recommended to not use it.

In NAT mode you should be able to check the rules added by incus using iptables -L -n -v -t nat

I checked the NAT table and it’s empty, even after adding the proxy. The incus info tells me that it’s using nfttables.

Have you tried non-NAT mode? There might be special magic required to make iptables redirect traffic from the loopback interface.

The instance is not a container, but a VM. When I try to add the proxy without nat=true it tells me that only NAT mode is supported for proxies on VM instances.

Also, according to the docs you don’t need to hard-code the guest IP address in the config, you can just say connect: tcp:0.0.0.0:3389

This is a nice tip, but also doesn’t apply in the NAT mode. It cannot be the wildcard address when NAT mode is in use.

The proxy works when listen address is set to 192.168.1.248:3389, but it beats the purpose of using firewall to filter out the traffic as the port becomes visible to anyone on the network. :confused:

I’ve tried setting up PREROUTING and POSTROUTING rules, but no luck either.