DNS issue within the DMZ ("NAT reflection" ?)

I am not yet sure if I am doing something wrong. Perhaps someone can help me please.

Following situation:

IPfire setup with RED/GREEN/BLUE/ORANGE, where ORANGE is my DMZ with a linux server (nextcloud) inside. Let’s say it has 192.168.1.1 as local IP in the DMZ. It’s reachable via HTTP & HTTPS from RED and GREEN via NAT using its FQDM, i.e. my.server.com.
However, there is a problem from the DMZ: Trying to access the server from the DMZ (either the server itself, or another PC in the DMZ) using its FQDN is not working, it only works using it’s local IP 192.168.1.1.

So, I did some reading, and I know IPfire does not serve DNS to the DMZ, but the server is setup to use a public DNS server. So a nslookup my.server.com does properly return the public ip. So far so good. BUT, when I try to reach the server using curl -I https://my.server.com I get a “Failed to connect”. Which - if I understood correctly - relates to something called “NAT reflection”, which seems IPfire does not have, or does not support. Essentially, the firewall needs to tell the DMZ internally that my.server.com has the local IP 192.168.1.1.

Hence I thought, ok, no DNS in the DMZ, then I add this to the hosts list, in Network > Edit Hosts and there I create an entry with

IP: 192.168.1.1

Hostname: my

Domain: server.com

click both, PTR and Enable, and the entry appears as expected.

NOW: If I am not dreaming - after a moment I can in fact reach the server as I want to from within the DMZ using the FQDN. “Jippeee!” - I thought - but then a while later, it does not work anymore. Why? Why is this entry only working for a short period of time? Is it somewhere/somehow overwritten, perhaps IPfire “finds out” that the FQDN my.server.com actually has a public IP, and then ignores the apparent "duplicate” with the local IP defined in hosts? Or am I missing something?

I hope my problem is clearly explained. Any help would be greatly appreciated.

Edit: Just for more context, the reason this is required to work, Nextcloud does run internal checks, where it needs to be able to “access itself" using the FQDN.

Another Edit: I came across this thread here, but it seems to be related to a dynamic public IP - which is not my case.

One more Edit: Perhaps rephrasing it differently could solve my problem: How to handle/setup “NAT reflection" properly using IPfire?

I have made an additional observation, which I am not sure what it means.

I have setup a watch command on the servers cmd-line similar to this:
curl -I https://my.server.com/nextcloud/index.php/heartbeat
It continuously monitors whether my server can reach itself using the FQDN, simply by checking the response code.

It seems to return code 200 (= OK) until I rerun the NC checks in the nextcloud-admin-interface > Administration Settings > Overview. Once Nextcloud runs the internal checks - where it tries to reach itself via the FQDN - I suddenly get a “Failed to connect".

How can the DNS resolution suddenly fail, just because Nextcloud tried to connect to itself? It cannot not change anything to the firewall. However, after a while (exact time is still not determined, but definitely several minutes…) it suddenly works again and I get code 200 again. How come? Any idea?

It seems there is something regarding the “NAT reflection” not properly configured. Any help on how to configure “NAT reflection" properly would be greatly appreciated.

This is a classic NAT hairpinning (also called NAT loopback or NAT reflection) issue. When your DMZ server resolves my.server.com, it gets your public IP back, then tries to connect to that public IP, which arrives at IPFire’s RED interface. IPFire has no rule to reflect this back into ORANGE, so the packet gets dropped.

The Nextcloud observation makes total sense. When Nextcloud’s internal health check tries to connect to its own public IP from within the ORANGE zone, it hits this exact problem. The connection hangs or fails, Nextcloud marks itself as unreachable. After a while the stale connection state times out, curl gets through again until the next Nextcloud self-check cycle.

Three ways to fix this:

Option 1 — Add a hosts entry on the server itself (simplest)

Add to /etc/hosts on your Nextcloud server:

192.168.1.1  my.server.com

The server will then always resolve its own FQDN to its local IP, bypassing the NAT problem entirely. Quickest fix, works immediately.

Option 2 — Custom DNS entry in IPFire

Under Network > Domain Name System, you can add a local DNS hostname mapping my.server.com → 192.168.1.1. However, IPFire does not serve DNS to the ORANGE/DMZ zone by default. You’d need to configure the DMZ server to use IPFire’s GREEN IP as its DNS server, or run a small local resolver (unbound or dnsmasq) inside the DMZ.

Option 3 — Hairpin NAT iptables rule

You can force IPFire to reflect the traffic by adding a custom iptables DNAT rule matching traffic from ORANGE to your public IP on ports 80/443, rewriting the destination to 192.168.1.1. This works but requires custom rules maintained via /etc/sysconfig/firewall.local to survive IPFire updates.

For most setups Option 1 is the right call. Option 2 makes more sense if you have multiple servers in the DMZ that all need to reach each other by FQDN.