NGINX Proxy Manager and Internal Vs External IP Addresses

Hi there!
I am trying my luck here to describe my issue. I am not sure if it’s the right place, sorry if it’s flooding the forum, but even after googling quite extensively, I couldn’t manage to find a way to address the following. If anyone with right knowledge can help: I am pretty sure that would be very helpful for few HA lovers, with concerns for security and privacy.

Rationales behind my goals are multiple, and all related to HTTPS access to different containers. Mainly:
1/ Allow display iframes in the HA UI (like Portainer and Music Assistant)
2/ Allow Voice assist (TTS and STT) to work directly from my wall mounted tab (Ipad running IoS) + from outside home (Browser requires HTTPS connection for Voice services)

My setup is the following, where I managed to configure HTTPS (SLL certificate using NGINX/duckdns/Let’s encrypt). This part is fine!

Now, I can connect HA using my duckdns URL over https from either local network (192.168.18.0/24) or externally (ie: from my phone connected to Mobile data). So both of the above Use Case are OK.

I defined the following rules in NGINX:

For this, I used following Access List, mapped to the last 2 Proxy Hosts declarations.

On one hand, that works well:
=> when I access https://music_assistant.xxx.duckdns.org from outside, restriction applies and I am requested to auth using HTTP authentication.
=> But on the other hand, even when I am requesting from my LAN itself, the auth is prompted.

I can see in the browser (Inspect > Network), that the “requester” IP address always remains my public IP (218.x.x.x) => so the Access List doesn’t apply and the restriction exclusion (“allow”) are never used.


(when connected on my LAN + same when I trying from outside)

Since I have AdGuard, I know I can manually rewrite DNS to force “music_assistant.xxx.duckdns.org” to 192.168.18.17 (ie: docker host IP).
This is indeed apparently “solving” the issue, as the requester seen in the web page becomes this private IP. But in that case, we’d never meet the Access List condition above (“deny all” but 192.168.18.0/24) => so the restriction on http_auth is never triggered, when accessing from outside my LAN.

I believe that is because the request is always going up to duckdns.org servers, before coming back to my router, so NGINX always see an incoming request coming from outside… This is also what I kinda understand from the nslookup (from my terminal, inside the LAN):

▶ curl -Iv https://music_assistant.xxxx.duckdns.org/
*   **Trying 218.x.x.x:443...**
* Connected to music_assistant.xxxx.duckdns.org (218.x.x.x) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=*.xxxx.duckdns.org
*  start date: Sep  6 06:17:40 2023 GMT
*  expire date: Dec  5 06:17:39 2023 GMT
*  subjectAltName: host "music_assistant.xxxx.duckdns.org" matched cert's "*.xxxx.duckdns.org"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: HEAD]
* h2 [:scheme: https]
* h2 [:authority: music_assistant.xxxx.duckdns.org]
* h2 [:path: /]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x7fc53400c400)
> HEAD / HTTP/2
> Host: music_assistant.xxxx.duckdns.org
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/2 401 
HTTP/2 401 
< server: openresty
server: openresty
< date: Thu, 07 Sep 2023 16:18:41 GMT
date: Thu, 07 Sep 2023 16:18:41 GMT
< content-type: text/html
content-type: text/html
< content-length: 176
content-length: 176
< www-authenticate: Basic realm="Authorization required"
www-authenticate: Basic realm="Authorization required"
< strict-transport-security: max-age=63072000;includeSubDomains; preload
strict-transport-security: max-age=63072000;includeSubDomains; preload
< 
* Connection #0 to host music_assistant.xxxx.duckdns.org left intact

Is there a way to tune the config to address this ?
A magic NGINX parameter or sthg ? :wink:

Edit:
I also found out NAT-loopback stuffs (https://www.draytek.com/assets/files/faq/2020/G81300/loopback-1.jpg) but I guess my (shitty) ISP router doesn’t allow to play with this…