| bin | ||
| lib | ||
| LICENSE.md | ||
| Makefile | ||
| README.md | ||
fcnatfw
fcnatfw is a tool that allows you to "forward" a UDP or TCP port to the
public internet through NATs (including CGNATs). Because it relies on
the specifics of Linux's SO_REUSEPORT implementation, it only works on
Linux (and possibly DragonFly BSD and FreeBSD, but I did not test this).
It also only works on systems that use dynamic linking and specifically
ones that allow shared library interposition (LD_PRELOAD).
The name is an abbreviation for "Full Cone NAT forward".
Installation
Before using this tool, you will need:
- a C compiler and
make(unless you are using a pre-built release) - GNU bash and coreutils (other coreutils may also work)
- a compatible
pingimplementation - miniupnpc (optional, but will not do UPnP requests if missing)
- nmap's ncat
stunclientfrom STUNTMAN software suite. Note that until #67 is merged, you will need to use my fork instead of the original, otherwise UDP mode will malfunction.
Note that while most of these tools usually can be installed with a package manager, stuntman lacks a package on GNU Guix and Debian and so you likely will have to install it manually, especially to use my fork. To do this:
- clone the STUNTMAN repository with
git clone - navigate into the created directory and run
make(Boost and OpenSSL development files must be installed) - copy
stunclientinto one of the directories specified in PATH. a good choice would be~/.local/binor/usr/local/bin. If the directory of your choice is not in the PATH shell variable, you can add a line that says something likePATH="$HOME/.local/bin:$PATH"; export PATHto~/.profileor~/.bash_profileor~/.bashrcor another file depending on your shell.
After all dependencies are ready, clone this repository with git clone https://git.kimapr.net/kimapr/fcnatfw
and run make in the created directory. Two executable files are
available:
bin/fcnatfwbin/fcnatwrap
Optionally, you can run sudo make install or make prefix=$HOME/.local install
which will install to /usr/local and ~/.local respectively. That way
you can invoke the executables more conveniently. If you skip this step
remember to replace occurances of fcnatfw and fcnatwrap later on
with the proper relative or absolute path to the executables.
Usage
First of all, it's very possible that this tool will never work for you. Its operation is highly dependant on specifics of the NATs deployed in your network. At minimum, your CGNAT must be of Full Cone NAT type (or missing entirely, that's even better); all home routers in your chain towards the Internet must either be Full Cone NAT / Direct or support UPnP IGD dynamic port forwarding. If you don't know what any of this means, just try it and any see if it works.
Run the fcnatfw command to forward a port:
fcnatfw 20000 tcp stun.kimapr.net
Arguments as follows:
- The port number. Optionally followed by
:and another port number (repeated as much as needed), this will make the UPnP mapping choose said another port number as the "external" port instead of the first one - however I do not recommend to do that. - Protocol (
tcporudp) (optional, defaults totcp) - The STUN server (host:port) (optional, defaults to
stun.kimapr.netbut I guarantee no uptime for this server thusly you may have to choose another)
The program will trace the network path to the STUN server to find any
UPnP servers it can find, install a port mapping on them, and then
enter an infinite loop making binding requests to said STUN server. The
external address (the ip:port others will use to connect to you) will
be printed to both stderr and stdout (for stdout, it prints a new ip:port
line at the beginning and every time it changes. You can thus pipe the
output of the script into another script to, say, automatically configure
your Dynamic DNS A and SRV records with the appropriate IP and port).
Note that the external port will typically be different from the internal
one, and will change dynamically just like the IP. This will make many
types of usage difficult.
Concurrently with the fcnatfw program you shall run the whatever
server program you wish to expose to the Internet. You need to either
configure the program to set SO_REUSEPORT option on its listening
socket, or if it doesn't support this, run the program under the
fcnatwrap wrapper (this will set the socket option on EVERY socket it
creates). SO_REUSEPORT allows two programs to bind to the same port
at the same time, which is important for the way this all works.
Example usage for Minecraft:
- set
fcnatwrapas the "wrapper command" in your minecraft launcher - open a world, then click
Open for LANin pause menu - in a shell prompt, run
fcnatfw PORT tcp, wherePORTis replaced by the port number that Minecraft printed in chat. - tell others to connect using the ip:port printed by
fcnatfw.
Contact
You can direct questions about this software suite, as well as improvements, to kimapr using the e-mail root@kimapr.net.
License
Copyright (C)2026 kimapr
fcnatfw is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
fcnatfw is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.