A go-written port forwarding tool, perfect for NAT servers

The cause was that the incus machine on shareNL could not run docker. With @RodickYu’s reminder, it was found that port binding could not be used, and --network host must be used to start it. However, this is particularly unfriendly to NAT servers, so this tool was created.

port link maintains multiple port forwarding through a background server, binding both TCP and UDP. It can forward remote ports to local ones or local ones to another local.

Project address: runoneall/portlink: A pure Golang port forwarding tool used to forward remote ports to local

Binary file download (7z compressed)
portlink-bin.7z (2.7 MB)

14 Likes

I also used AI to create a golang port forwarding just now from A->server->B, mainly for mstsc. I used it purely for personal use.

1 Like

Just right, thanks for sharing.

1 Like

Thank you for sharing

Okay

taGreat. Not bad

Can you write a tutorial and a binary file, after all, not everyone is a developer

Sure, wait for me to pack it up

Thank you for sharing

Great thank you for sharing

Okay, the binary file is on the GitHub release

https://github.com/runoneall/portlink/releases/download/v1/portlink-linux-amd64

wget download is all you need.

Thank you for sharing!

Can we remove the ports behind the NAT machines?

No, it’s hardcoded to forward the port to shareNL on the internal port.

1 Like

This feeling is perfectly satisfied with gost.

It feels a bit heavy, with not many usable features.

Thank you for sharing!

Why was IPC designed instead of using command-line parameters to express the port to forward?\nUsing command-line parameters (or a configuration file), the program could run as a systemd background service and automatically restart if it crashes.\n\nWith the IPC approach, when the server program restarts, its internal state (port forwarding rules) is lost.\nIf you want to package it as a systemd service, you would need to write a second service to call the client program to reinsert the port forwarding rules.

1 Like

I reviewed the key code for UDP forwarding in server/forward_udp.go.

Compared to normal NAT, the two UDP connections are completely separate, and the remote server cannot obtain the client’s IP address information.

Here, simply calling connMap.Clear() is sufficient.

Using clientAddr.AddrPort() is more efficient.

It returns a netip.AddrPort type, specifically designed to be used as a map key.

Due to Go 1 compatibility guarantees, the address types in the net package cannot be changed, but their internal implementations have already been converted to netip package types.

Converting to strings involves additional operations, which are unnecessary here.

Starting from Go 1.25, you can use wg.Go() for a more concise implementation.

https://pkg.go.dev/[email protected]#WaitGroup.Go

6 Likes

Thank you for sharing

1 Like