135 lines
6.5 KiB
Markdown
135 lines
6.5 KiB
Markdown
# 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 `ping` implementation
|
|
- [miniupnpc](https://miniupnp.tuxfamily.org/) (optional, but will not do UPnP requests if missing)
|
|
- nmap's [ncat](https://nmap.org/ncat/)
|
|
- `stunclient` from [STUNTMAN software suite](https://www.stunprotocol.org/).
|
|
Note that until [#67](https://github.com/jselbie/stunserver/pull/67)
|
|
is merged, you will need to use [my fork](https://github.com/Kimapr/stunserver)
|
|
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 `stunclient` into one of the directories specified in PATH.
|
|
a good choice would be `~/.local/bin` or `/usr/local/bin`. If the
|
|
directory of your choice is not in the PATH shell variable, you can
|
|
add a line that says something like `PATH="$HOME/.local/bin:$PATH"; export PATH`
|
|
to `~/.profile` or `~/.bash_profile` or `~/.bashrc` or another file
|
|
depending on your shell.
|
|
- if you are using my fork, you can use `make install` similar to how
|
|
is shown below instead of copying `stunclient` manually.
|
|
|
|
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/fcnatfw`
|
|
- `bin/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.
|
|
|
|
Note that, even though there is a `configure` script present, you do not
|
|
need to use it. It is only there to improve compatibility with the
|
|
GNU Build System. `configure` understands only install prefix options
|
|
and environment variables, and silently discards anything else. Notably,
|
|
cross-compilation options are ignored (but you can set the CC variable).
|
|
When using `configure` shell script code will be transformed to
|
|
hardcode executables used in the script by absolute path found at
|
|
configure-time instead of finding them in PATH at run-time (except ping).
|
|
|
|
## 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:
|
|
1. 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.
|
|
2. Protocol (`tcp` or `udp`) (optional, defaults to `tcp`)
|
|
3. The STUN server (host:port) (optional, defaults to `stun.kimapr.net` but 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 `fcnatwrap` as the "wrapper command" in your minecraft launcher
|
|
- open a world, then click `Open for LAN` in pause menu
|
|
- in a shell prompt, run `fcnatfw PORT tcp`, where `PORT` is 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/>.
|
|
|