Can't wrap my head around this; how to remotely access service with dynamic ports behind firewall?

edited March 28 in Help

The past few days I've been trying to find a solution to a challenge I'm facing but I just can't seem to wrap my head around it. I'm probably too deep into the rabbit hole, so I was hoping you guys can give me a nudge into the right direction.

The issue is as follows; I have a Windows machine running behind a firewall.
This Windows machine runs an application service that has many inbound ports, i.e. ports that need to be accessible from the internet, ranging from 40000 - 60000.
I can't open port ranges on the firewall, I can only open single ports. Since opening 20k ports by hand is not doable my idea was to use a VPS as endpoint for the clients to connect to and tunnel all traffic to the Windows machine, like so:

To do so I tried wireguard; but this would require some blackmagic iptables that I couldn't get to work.
So I started looking into remote port forwarding via ssh (i.e. ssh -R). This works, but again just one port at a time. Now technically I could write like a script that loops over the ports but it feels like I'm not using the right tool for the job.

What would you recommend for my usecase?

Thanks for thinking along.

Comments

  • AuroraZeroAuroraZero ModeratorHosting Provider

    @Freek said:
    The past few days I've been trying to find a solution to a challenge I'm facing but I just can't seem to wrap my head around it. I'm probably too deep into the rabbit hole, so I was hoping you guys can give me a nudge into the right direction.

    The issue is as follows; I have a Windows machine running behind a firewall.
    This Windows machine runs an application service that has many inbound ports, i.e. ports that need to be accessible from the internet, ranging from 40000 - 60000.
    I can't open port ranges on the firewall, I can only open single ports. Since opening 20k ports by hand is not doable my idea was to use a VPS as endpoint for the clients to connect to and tunnel all traffic to the Windows machine, like so:

    To do so I tried wireguard; but this would require some blackmagic iptables that I couldn't get to work.
    So I started looking into remote port forwarding via ssh (i.e. ssh -R). This works, but again just one port at a time. Now technically I could write like a script that loops over the ports but it feels like I'm not using the right tool for the job.

    What would you recommend for my usecase?

    Thanks for thinking along.

    Black Magic lmfao!!! You were on the right scent with wireguard.

    May I ask why the ports can't be opened?

    Free Hosting at YetiNode | Cryptid Security | URL Shortener | LaunchVPS | ExtraVM | Host-C | In the Node, or Out of the Loop?

  • JabJab Senpai

    @Freek said: I can't open port ranges on the firewall, I can only open single ports. Since opening 20k ports by hand is not doable my idea was to use a VPS as endpoint for the clients to connect to and tunnel all traffic to the Windows machine, like so:

    Script the firewall, holy balls, why going VPS endpoint o.O

    Haven't bought a single service in VirMach Great Ryzen 2022 - 2023 Flash Sale.
    https://lowendspirit.com/uploads/editor/gi/ippw0lcmqowk.png

  • edited March 28

    What you need is indeed that iptables magic. I actually had this exact issue last week, and gave up at the same step. :D

    If you're able to reinstall the Linux VPS, perhaps using a router OS with a webgui will make the magic easier to configure. I'm using OPNsense, but any of the bunch should work well.

    Thanked by (1)Freek
  • havochavoc OGContent Writer

    Maybe one of the many reverse proxies allows mapping one to many?

    Else yeah you'll need to adjust the forwarding rules on the fly

  • edited March 28

    @AuroraZero said:

    Black Magic lmfao!!! You were on the right scent with wireguard.

    May I ask why the ports can't be opened?

    Yeah iptables isn't really my forte
    Technically the ports can be opened but I was just interested, or rather intrigued, if this would work as well

    @Jab said:
    Script the firewall, holy balls, why going VPS endpoint o.O

    As an learning exercise?

    @havoc said:
    Maybe one of the many reverse proxies allows mapping one to many?

    Else yeah you'll need to adjust the forwarding rules on the fly

    Any examples you would recommend looking into?

    Thanks

  • havochavoc OGContent Writer

    @Freek said:
    Any examples you would recommend looking into?

    Thanks

    Afraid not - haven't investigated because I can't see myself needing it. I'd be surprised if it isn't possible though.

  • When you say “Internet”, do you mean the general public or just a certain number/group of users?

    If it’s the latter, you could probably use something like Tailscale.

    Thanked by (2)Freek bdl
  • edited March 28

    @Freek said:

    @AuroraZero said:

    Black Magic lmfao!!! You were on the right scent with wireguard.

    May I ask why the ports can't be opened?

    Yeah iptables isn't really my forte
    Technically the ports can be opened but I was just interested, or rather intrigued, if this would work as well

    Yeah this should work fine - both wireguard and iptables are extremely efficient, so the major downsides are "just" the extra complexity and longer network path.

    It's a good learning exercise too :). This trick is what many circumvention tactics rely on.

    Thanked by (1)Freek
  • I got a middle ground between copy/paste and learning exercise for you: a thread from a half English / half French (the exercise bit) self hosting solution Yunohost (Y-U-No-Host???).

    People face trouble self hosting because of closed mail ports or dynamic IPs, and circumvent that in the same way as you intend to do.

    The thread discusses such a setup using a VPS running Wireguard and gives pointers for masquerading and such.

    Thanked by (1)Freek
  • Try nftables. iptables is deprecated anyway and the syntax for nftables are easier to understand.

    For me as a firewall n00b anyways.

    Thanked by (3)Freek IAmNix GeekWanderer

    The all seeing eye sees everything...

  • Something like this should work:

    add the following in /etc/sysctl.conf:
    net.ipv4.ip_forward = 1

    run
    $ sysctl -p
    to apply changes

    #traffic to wg0 other end should be appear to originate from this server
    iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
    
    #allow forward traffic
    iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 40000:60000 -m conntrack --ctstate NEW -j ACCEPT
    iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    
    # forward the specfic ports 
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 40000:60000 -j DNAT --to-destination 10.8.0.2
    

    Change ip and interface names.

    I guess you should also allow traffic from the virtual interface to the application server interface on the windows machine firewall

    There are also other alternatives if you don't want to get your hands dirty with vpn and/or iptables, but I am not sure if they are easier to setup. For example:
    https://github.com/sshuttle/sshuttle
    or
    ssh -D and some kind of proxy chaining

    What is the application by the way? Are you sure it's ok to expose so many ports in the wild? Can you use ssh client or some proxy client in the client machines?

    Thanked by (2)Freek IAmNix
  • @Freek said:
    I can't open port ranges on the firewall, I can only open single ports. Since opening 20k ports by hand is not doable my idea was to use a VPS as endpoint for the clients to connect to and tunnel all traffic to the Windows machine, like so:

    You can use a proper router. Most Asus routers allow port range opening:

    1. Port ranges using a colon ":" between the starting and ending port, such as 300:350.

    @Freek said:
    So I started looking into remote port forwarding via ssh (i.e. ssh -R). This works, but again just one port at a time. Now technically I could write like a script that loops over the ports but it feels like I'm not using the right tool for the job.

    That would be:

    ssh 123.45.67.89 $(for i in `seq 40000 60000` ;do echo -L $i:localhost:$i ;done)
    

    But that's just stupid.

    @Freek said:
    What would you recommend for my usecase?

    VPN. Setup a direct wireguard line OR use a "free" VPN service like Tailscale to bring your machine and VM on the same network and follow that up with IP table port forwarding. Take note of the virtual network interface of tailscale.

    Allow port range through your firewall:

    ufw allow 40000:60000/tcp
    

    Edit: nano /etc/default/ufw

    Add:

    DEFAULT_FORWARD_POLICY="ACCEPT"
    

    Create a shell script and load it on boot:

    sleep 60
    
    # RDP
    iptables -t nat -A PREROUTING -i tailscale0 -p tcp --dport 3389 -j DNAT --to-destination 172.16.10.10:3389
    
    # Reverse proxy
    iiptables -t nat -A PREROUTING -i tailscale0 -p tcp --dport 40000:60000 -j DNAT --to 172.16.10.10:40000-60000
    

    Edit: nano /etc/network/interfaces

    And add the shell script to your VPN network interface (the one with tailscale0 as header):

    post-up /root/dnat.sh
    
    Thanked by (2)Freek host_c

    Websites have ads, I have ad-blocker.

  • Thanks all for the tips, I appreciate it :)

    @TheDP said:
    When you say “Internet”, do you mean the general public or just a certain number/group of users?

    If it’s the latter, you could probably use something like Tailscale.

    The general public. Tailscale also crossed my mind but unfortunately wouldn't work in this case.

    @itsdeadjim said:
    Something like this should work:

    add the following in /etc/sysctl.conf:
    net.ipv4.ip_forward = 1

    run
    $ sysctl -p
    to apply changes

    #traffic to wg0 other end should be appear to originate from this server
    iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
    
    #allow forward traffic
    iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 40000:60000 -m conntrack --ctstate NEW -j ACCEPT
    iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    
    # forward the specfic ports 
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 40000:60000 -j DNAT --to-destination 10.8.0.2
    

    Change ip and interface names.

    Thank you very much for the examples, they really helped me. Together with these and the pointers from @wankel and @somik I managed to get it to work. My iptables rules now look as follows

    iptables -A FORWARD -i wg0 -j ACCEPT; 
    iptables -A FORWARD -o wg0 -j ACCEPT; 
    iptables -t nat -A PREROUTING -i enp3s0 -p tcp --dport 40000:65535 -j DNAT --to-destination 10.8.0.2; 
    iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT; 
    iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp3s0 -j MASQUERADE
    

    I suspect there is some overlap/duplication between them but I haven't been able to figure that out yet. Do you see any redundant rules by any chance?

    @itsdeadjim said:
    What is the application by the way? Are you sure it's ok to expose so many ports in the wild? Can you use ssh client or some proxy client in the client machines?

    It's a blockchain related application. It's in it early stages and not indeed not very pretty. I've isolated it to a VM in it's own VLAN that has no access towards the rest of my network.

  • host_chost_c Hosting Provider

    @Freek

    Not that I do not enjoy a challenge, just get a router this time =)

    Mid-End Consumer ones for example.

    Or if you have a mini pc around with 2 NIC, do a pFsense/OPENsense/ other software poison Router.

    You will be much more happier.

    Thanked by (1)Freek

    Host-C - VPS Services Provider - AS211462

    "If there is no struggle there is no progress"

  • @Freek said:
    It's a blockchain related application. It's in it early stages and not indeed not very pretty. I've isolated it to a VM in it's own VLAN that has no access towards the rest of my network.

    Btw, another option would be to use DMZ if your router has a DMZ feature. You can use it to forward ALL ports to one VM (like in this case).

    Thanked by (1)Freek

    Websites have ads, I have ad-blocker.

  • I stumbled on this excellent article: https://www.procustodibus.com/blog/2022/09/wireguard-port-forward-from-internet/

    I've now narrowed down my iptables rules to just this one:

    iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
    

    However, I'm doubting if it's not 'too little'... The sole use of this VPS is to forward the traffic towards the Windows VM, that's all it does. Am I missing something?

    Alternatively these two rules also work, but I still don't understand the difference between these rules and the one-liner above:

    iptables -A FORWARD -i wg0 -j ACCEPT
    iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
    
  • mentally strong people open ports one by one

    Thanked by (1)Tivini
Sign In or Register to comment.