[2.0.32] Linux Headless behind pfsense FW

Anything that prevents you from playing the game properly. Do you have issues playing for the game, downloading it or successfully running it on your computer? Let us know here.
Jimlo
Burner Inserter
Burner Inserter
Posts: 5
Joined: Mon Mar 03, 2025 7:24 pm
Contact:

[2.0.32] Linux Headless behind pfsense FW

Post by Jimlo »

Hello all!

I'm a bit lost and am experiencing some odd behaviors with the ports on my headless server. In short: I'm expecting to be running my server on default port 34197 but Factorio pingpong servers say I'm hosting on 57021.

For context, I'm using DDNS on my ISPs router which has a port set up as an exposed host which connected to my PFSense firewall, where my Factorio headless server sits behind on a docker container.

I've run across this helpful thread explaining issues running into Outbound Hybrid NAT rules for PFSense. So I went ahead and configured Hybrid Outbound NAT and set my self up with a WAN Firewall rule to allow incoming connections to my server on port 34197

And a screenshot of my Outbound Hybrid NAT rule:
#1
Image
#2
Image

A screenshot of my WAN FW Rule:
Image


Now I'm running into a weird behavior where my server is configured to use the default port, 34197, but the Factorio pingpong servers say I'm hosting on port 57021. While attempting to connect to my server, I can watch the Firewall logs block incoming connections on my WAN interface to 57021. These blocked connections are expected, as I've only configured WAN Rules to allow incoming connections on 34197.

And if it matters at all, this is the docker image I'm pulling from: factoriotools/factorio:stable

Here's the current running logs of the server:

Code: Select all

+++ readlink -f /docker-entrypoint.sh
++ dirname /docker-entrypoint.sh
+ INSTALLED_DIRECTORY=/
+ FACTORIO_VOL=/factorio
+ LOAD_LATEST_SAVE=true
+ GENERATE_NEW_SAVE='"true"'
+ PRESET=
+ SAVE_NAME=
+ BIND=
+ CONSOLE_LOG_LOCATION=
+ mkdir -p /factorio
+ mkdir -p /factorio/saves
+ mkdir -p /factorio/config
+ mkdir -p /factorio/mods
+ mkdir -p /factorio/scenarios
+ mkdir -p /factorio/script-output
+ [[ ! -f /factorio/config/rconpw ]]
+ [[ ! -f /factorio/config/server-settings.json ]]
+ [[ ! -f /factorio/config/map-gen-settings.json ]]
+ [[ ! -f /factorio/config/map-settings.json ]]
++ find -L /factorio/saves -iname '*.tmp.zip' -mindepth 1
++ wc -l
+ NRTMPSAVES=0
+ [[ 0 -gt 0 ]]
+ [[ '' == \t\r\u\e ]]
+ //docker-dlc.sh
Disable mod elevated-rails for DLC
Disable mod quality for DLC
Disable mod space-age for DLC
+ EXEC=
++ id -u
+ [[ 0 == 0 ]]
+ usermod -o -u 845 factorio
usermod: no changes
+ groupmod -o -g 845 factorio
+ chown -R factorio:factorio /factorio
+ EXEC='runuser -u factorio -g factorio --'
+ [[ -f /bin/box64 ]]
+ sed -i '/write-data=/c\write-data=\/factorio/' /opt/factorio/config/config.ini
++ find -L /factorio/saves -iname '*.zip' -mindepth 1
++ wc -l
+ NRSAVES=1
+ [[ "true" != true ]]
+ [[ 1 == 0 ]]
+ [[ "true" == true ]]
+ FLAGS=(--port "$PORT" --server-settings "$CONFIG/server-settings.json" --server-banlist "$CONFIG/server-banlist.json" --rcon-port "$RCON_PORT" --server-whitelist "$CONFIG/server-whitelist.json" --use-server-whitelist --server-adminlist "$CONFIG/server-adminlist.json" --rcon-password "$(cat "$CONFIG/rconpw")" --server-id /factorio/config/server-id.json --mod-directory "$MODS")
++ cat /factorio/config/rconpw
+ '[' -n '' ']'
+ '[' -n '' ']'
+ [[ true == true ]]
+ FLAGS+=(--start-server-load-latest)
+ exec runuser -u factorio -g factorio -- /opt/factorio/bin/x64/factorio --port 34197 --server-settings /factorio/config/server-settings.json --server-banlist /factorio/config/server-banlist.json --rcon-port 27015 --server-whitelist /factorio/config/server-whitelist.json --use-server-whitelist --server-adminlist /factorio/config/server-adminlist.json --rcon-password je2Ohxiw7vi6ahz --server-id /factorio/config/server-id.json --mod-directory /factorio/mods --start-server-load-latest
   0.000 2025-03-03 19:22:45; Factorio 2.0.32 (build 81349, linux64, headless, space-age)
   0.000 Operating system: Linux
   0.000 Program arguments: "/opt/factorio/bin/x64/factorio" "--port" "34197" "--server-settings" "/factorio/config/server-settings.json" "--server-banlist" "/factorio/config/server-banlist.json" "--rcon-port" "27015" "--server-whitelist" "/factorio/config/server-whitelist.json" "--use-server-whitelist" "--server-adminlist" "/factorio/config/server-adminlist.json" "--rcon-password" <private> "--server-id" "/factorio/config/server-id.json" "--mod-directory" "/factorio/mods" "--start-server-load-latest"
   0.000 Config path: /opt/factorio/config/config.ini
   0.000 Read data path: /opt/factorio/data
   0.000 Write data path: /factorio [214259/243172MB]
   0.000 Binaries path: /opt/factorio/bin
   0.011 System info: [CPU: Intel(R) Core(TM) i5-6600T CPU @ 2.70GHz, 4 cores, RAM: 31971 MB]
   0.011 Environment: DISPLAY=<unset> WAYLAND_DISPLAY=<unset> DESKTOP_SESSION=<unset> XDG_SESSION_DESKTOP=<unset> XDG_CURRENT_DESKTOP=<unset> SDL_VIDEODRIVER=<unset> __GL_FSAA_MODE=<unset> __GL_LOG_MAX_ANISO=<unset> __GL_SYNC_TO_VBLANK=<unset> __GL_SORT_FBCONFIGS=<unset> __GL_YIELD=<unset>
   0.012 Running in headless mode
   0.012 Audio is disabled
   0.013 Info ModManager.cpp:444: FeatureFlag expansion-shaders = false
   0.013 Info ModManager.cpp:444: FeatureFlag freezing = false
   0.013 Info ModManager.cpp:444: FeatureFlag quality = false
   0.013 Info ModManager.cpp:444: FeatureFlag rail-bridges = false
   0.013 Info ModManager.cpp:444: FeatureFlag segmented-units = false
   0.013 Info ModManager.cpp:444: FeatureFlag space-travel = false
   0.013 Info ModManager.cpp:444: FeatureFlag spoiling = false
   0.017 Loading mod core 0.0.0 (data.lua)
   0.033 Loading mod base 2.0.32 (data.lua)
   0.212 Loading mod base 2.0.32 (data-updates.lua)
   0.276 Checksum for core: 544741660
   0.276 Checksum of base: 183736295
   0.505 Prototype list checksum: 2902124721
   0.538 Info PlayerData.cpp:66: Local player-data.json available, timestamp 1741029693
   0.538 Info PlayerData.cpp:73: Cloud player-data.json unavailable
   0.540 Factorio initialised
   0.540 Info AuthServerConnector.cpp:616: Performing TLS check.
   0.540 Info HttpSharedState.cpp:55: Downloading https://auth.factorio.com/tls-check/success
   0.902 Info AuthServerConnector.cpp:641: TLS check success.
   0.902 Info HttpSharedState.cpp:55: Downloading https://auth.factorio.com/api-login?api_version=6
   1.799 Info AuthServerConnector.cpp:201: Got token from auth server for username(Jimlo).
   1.803 Info ServerSynchronizer.cpp:20: nextHeartbeatSequenceNumber(0) initialized Synchronizer nextTickClosureTick(0).
   1.803 Info ServerMultiplayerManager.cpp:806: updateTick(18446744073709551615) changing state from(Ready) to(PreparedToHostGame)
   1.803 Info ServerMultiplayerManager.cpp:806: updateTick(18446744073709551615) changing state from(PreparedToHostGame) to(CreatingGame)
   1.803 Loading map /factorio/saves/_autosave1.zip: 630400 bytes.
   1.814 Loading level.dat: 803003 bytes.
   1.820 Info Scenario.cpp:153: Map version 2.0.32-0
   1.840 Blueprint storage "blueprint-storage-2.dat" was not found, trying to load previous version storage "blueprint-storage.dat"
   1.841 Loading script.dat: 1195 bytes.
   1.845 Checksum for script __level__/control.lua: 522968567
   1.846 Info UDPSocket.cpp:32: Opening socket at (IP ADDR:({0.0.0.0:34197}))
   1.846 Hosting game at IP ADDR:({0.0.0.0:34197})
   1.846 Info HttpSharedState.cpp:55: Downloading https://auth.factorio.com/generate-server-padlock-2?api_version=6
   2.195 Info AuthServerConnector.cpp:108: Obtained serverPadlock for serverHash () from the auth server.
   2.195 Info ServerMultiplayerManager.cpp:806: updateTick(713) changing state from(CreatingGame) to(InGame)
   2.214 Info ServerRouter.cpp:664: Asking pingpong servers (pingpong1.factorio.com:34197, pingpong2.factorio.com:34197, pingpong3.factorio.com:34197, pingpong4.factorio.com:34197) for own address
   2.214 Info UDPSocket.cpp:44: Opening socket for broadcast
   2.215 Error InterruptibleStdioStream.cpp:60: Got EOF on stdin; closing
   2.215 Info RemoteCommandProcessor.cpp:126: Starting RCON interface at IP ADDR:({0.0.0.0:27015})
   2.215 Info CommandLineMultiplayer.cpp:288: Maximum segment size = 100; minimum segment size = 25; maximum-segment-size peer count = 10; minimum-segment-size peer count = 20
   2.332 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.11.95:57021}) (confirmed by pingpong1)
   2.349 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.11.95:57021}) (confirmed by pingpong3)
   2.482 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.11.95:57021}) (confirmed by pingpong4)
   2.674 Info MatchingServer.cpp:123: Matching server game `20760104` has been created.
   2.682 Info ServerMultiplayerManager.cpp:738: Matching server connection resumed
The really weird thing was I did have it up and running correctly! Then I was messing around attempting to host a second docker container for the Space Age expansion and I bungled it all up. I went the nuclear option, wiped everything out and started building from scratch and have gotten myself stuck here. Please help!
Last edited by Jimlo on Tue Mar 04, 2025 5:03 pm, edited 1 time in total.
adam_bise
Filter Inserter
Filter Inserter
Posts: 581
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by adam_bise »

I have factorio headless behind pfsense. I will post the config when I get home.
adam_bise
Filter Inserter
Filter Inserter
Posts: 581
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by adam_bise »

It's been a minute since I set this up so I will just post my config. I do remember you had to do a special rule for UDP hole punching.

Nat Config:
fwnat.png
fwnat.png (159.91 KiB) Viewed 1016 times
ACE / Filter:
fwace.png
fwace.png (163.03 KiB) Viewed 1016 times
UDP Hole Punch Entry:
fwhole.png
fwhole.png (62.82 KiB) Viewed 1016 times
UDP Hole Punch Detail:
fwhole2.png
fwhole2.png (137.37 KiB) Viewed 1016 times
NAT Mode:
fwnatmode.png
fwnatmode.png (76.74 KiB) Viewed 1016 times
Jimlo
Burner Inserter
Burner Inserter
Posts: 5
Joined: Mon Mar 03, 2025 7:24 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by Jimlo »

Interesting, thanks so much for posting those! I'll have to tinker a bit with my Outbound NAT rule as I see some differences in my rules. I'll report back when I get off work and have done some testing.
Jimlo
Burner Inserter
Burner Inserter
Posts: 5
Joined: Mon Mar 03, 2025 7:24 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by Jimlo »

Well, still no dice. I wondered if it may be something with docker, so I've eliminated that from the scenario and installed straight onto my linux server. I went through, deleted all my NAT configs and associated FW rules and have rebuilt them, but am still running into the same behavior.

Interestingly enough if I follow your Hybrid Outbound NAT I run into more issues as seen in the logs here:

Code: Select all

   3.036 Info UDPSocket.cpp:44: Opening socket for broadcast
   3.036 Info CommandLineMultiplayer.cpp:288: Maximum segment size = 100; minimum segment size = 25; maximum-segment-size peer count = 10; minimum-segment-size peer count = 20
   3.153 Warning ServerRouter.cpp:541: Received own address message reply with conflicting address (got IP ADDR:({77.12.190.212:13626}), expected IP ADDR:({77.12.190.212:29054}))
   3.153 Warning ServerMultiplayerManager.cpp:654: Determining own address has failed. Best guess: IP ADDR:({77.12.190.212:29054})
   3.170 Warning ServerRouter.cpp:541: Received own address message reply with conflicting address (got IP ADDR:({77.12.190.212:24239}), expected IP ADDR:({77.12.190.212:29054}))
   3.303 Warning ServerRouter.cpp:541: Received own address message reply with conflicting address (got IP ADDR:({77.12.190.212:42899}), expected IP ADDR:({77.12.190.212:29054}))
   3.504 Info MatchingServer.cpp:123: Matching server game `20766418` has been created.
   3.520 Info ServerMultiplayerManager.cpp:738: Matching server connection resumed
But if I check the "Static Port" as recommend in other posts and on the netgear docs, then I clear up those "conflicting address" errors, but am left with a seemingly high random port. Today it seems to be 57027.

Code: Select all

   2.779 Info ServerMultiplayerManager.cpp:806: updateTick(0) changing state from(CreatingGame) to(InGame)
   2.786 Info ServerRouter.cpp:664: Asking pingpong servers (pingpong1.factorio.com:34197, pingpong2.factorio.com:34197, pingpong3.factorio.com:34197, pingpong4.factorio.com:34197) for own address
   2.786 Info UDPSocket.cpp:44: Opening socket for broadcast
   2.787 Info CommandLineMultiplayer.cpp:288: Maximum segment size = 100; minimum segment size = 25; maximum-segment-size peer count = 10; minimum-segment-size peer count = 20
   2.904 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.190.212:57027}) (confirmed by pingpong1)
   2.920 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.190.212:57027}) (confirmed by pingpong3)
   3.054 Info ServerRouter.cpp:547: Own address is IP ADDR:({77.12.190.212:57027}) (confirmed by pingpong4)
   3.248 Info MatchingServer.cpp:123: Matching server game `20766439` has been created.
   3.254 Info ServerMultiplayerManager.cpp:738: Matching server connection resumed
I noticed that some of my pfsense field options don't contain the same verbiage as yours. I'm currently running:
2.7.2-RELEASE (amd64)
built on Mon Mar 4 19:53:00 UTC 2024
FreeBSD 14.0-CURRENT
NineNine
Filter Inserter
Filter Inserter
Posts: 424
Joined: Mon Oct 24, 2022 11:20 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by NineNine »

I'm not a networking expert, but I've had enough experience with ISP-provided routers to suggest that you might save yourself a lot of headache in the long run by either buying a real router, or using Open-WRT on any hardware.
adam_bise
Filter Inserter
Filter Inserter
Posts: 581
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by adam_bise »

Wait, you have 2 routers?

You will need inbound and outbound NAT rules for the upstream router as well.

Have you gotten the server to work directly behind the Netgear router?

Perhaps the Netgear router has a passthrough mode you can use so only the pfsense is doing any natting?

I don't even know how or if the outbound NAT would work in a double NAT setup.

I would try to eliminate one of your routers, or at least put this server behind the first router.

Given that you are still seeing the wrong port number, I would guess the problem still lies with UDP hole punching. That UDP hole punching config does work on my pfsense router, but I don't have an upstream router.

You could look for a place on the Netgear router to configure an upstream outbound NAT, if that is even a thing, IDK

Perhaps on Netgear an outbound NAT like this: interface=WAN source=<ip pfsense> source proto=UDP source port=34197 dest=any dest proto=UDP
And on pfsense: interface=WAN source=<ip of factorio server> source proto=UDP source port=34197 dest=any dest proto=UDP

You would still need the inbound nat as well:
On netgear inbound nat: Interface=WAN Source=any source port=any dest=WAN IP dest port=34192 NAT IP=pfsense IP NAT port= 34197
On pfsense inbound nat: Interface=WAN Source=any source port=any dest=WAN IP dest port=34192 NAT IP=factorio server IP NAT port= 34197
adam_bise
Filter Inserter
Filter Inserter
Posts: 581
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by adam_bise »

Jimlo wrote: Mon Mar 03, 2025 8:14 pm my ISPs router which has a port set up as an exposed host which connected to my PFSense firewall
Please post the details of this.

Also, please post the WAN IP address of your pfsense router. If it is a private address, then I can't say if this setup would even work.
Jimlo
Burner Inserter
Burner Inserter
Posts: 5
Joined: Mon Mar 03, 2025 7:24 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by Jimlo »

Sorry for the slow responses, between work and other activities I haven't been able to tinker around with this as frequently as I would like.
adam_bise wrote: Wed Mar 05, 2025 2:05 amWait, you have 2 routers?
Yes, an ISP provided Fritz!box 7530 with an "exposed host" connected to a Protectli machine running PFSense.
adam_bise wrote: Wed Mar 05, 2025 2:05 am You will need inbound and outbound NAT rules for the upstream router as well.

Have you gotten the server to work directly behind the Netgear router?

Perhaps the Netgear router has a passthrough mode you can use so only the pfsense is doing any natting?
I was wondering if this might be the case. By setting up the required port forwarding rules on the ISP provided Fritz!box modem/router, I can get a Factorio server to run and be accessible directly behind the Fritz!box router. The Fritz!box does have an "exposed host" mode that can be enabled which says that the "host is completely visible and accessible in the internet without protection. Firewall protection is disabled for this device." This is the best technical explanationI'm able to find of this. Sorry it's in German, but I am in Germany (as a native English speaker). After re-reading this, I do believe I might be hung up on this translated bullet point: "Incoming connections for whose target port separate IPv4 port shares are not forwarded to the "Exposed Host", but to the device selected in the separate share."
adam_bise wrote: Wed Mar 05, 2025 2:05 am I don't even know how or if the outbound NAT would work in a double NAT setup.

I would try to eliminate one of your routers, or at least put this server behind the first router.

Given that you are still seeing the wrong port number, I would guess the problem still lies with UDP hole punching. That UDP hole punching config does work on my pfsense router, but I don't have an upstream router.
I would like to eliminate my ISP provided router, but currently it also functions as a DSL modem for a VDSL2 connection. I'm still learning a bit more about that, but from what I see the Protectli Vault doesn't have VDSL2 support.

I definitely agree that it does seem the problem is somewhere with the UDP hole punching. Why else would I be getting a mostly, random high port? And from my understanding, a double NAT setup is not going to work with my current network setup.
adam_bise wrote: Wed Mar 05, 2025 2:05 amAlso, please post the WAN IP address of your pfsense router. If it is a private address, then I can't say if this setup would even work.
Unfortunately, it is indeed a private address and as I've looked into it more, I think I have to agree with you. Thanks for taking some time to think about my situation! I might have to look into getting a 3rd party modem to eliminate some of the drawbacks and limitations of the ISP provided Fritz!box.
adam_bise
Filter Inserter
Filter Inserter
Posts: 581
Joined: Fri Jun 08, 2018 10:42 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by adam_bise »

Glad you are getting closer to a solution. Your DSL / Router seems to be both a modem and router combined. There is typically a way to disable the router function of these. Sometimes labeled as "passthrough mode". Alternatively you could get a compatible DSL modem that doesn't have any router function and connect that to your pfsense.

Regards.

-Adam
Jimlo
Burner Inserter
Burner Inserter
Posts: 5
Joined: Mon Mar 03, 2025 7:24 pm
Contact:

Re: [2.0.32] Linux Headless behind pfsense FW

Post by Jimlo »

adam_bise wrote: Fri Mar 07, 2025 5:00 pm Glad you are getting closer to a solution. Your DSL / Router seems to be both a modem and router combined. There is typically a way to disable the router function of these. Sometimes labeled as "passthrough mode". Alternatively you could get a compatible DSL modem that doesn't have any router function and connect that to your pfsense.

Regards.

-Adam
Interesting, I was thinking the exposed host functionality was originally accomplishing this, but after reading more about it and looking into your suggestion, there is a PPPoE Passthrough mode. Although there seems to be some drawbacks impacting speeds. I'll play around with setting up PPPoE Passthrough on my PFSense box and report the results back here when I get a chance. Thanks again, Adam!
Post Reply

Return to “Technical Help”