HomeAssistant, Hairpin NAT and port forwarding

Greetings everyone :slight_smile:

After watching Steveocee’s video, I’ve managed to setup a HomeAssistant instance to be reachable from both local AND outside my local network.

The problem is that the port rules apply to every client :confused: on my network and do not restrict to the specific destination address I am pointing.(192.168.10.200)

All I wanted is port 8123 to be accessible for the HA instance only

Am I missing something?

[admin@MikroTik] > /ip firewall nat print all
Flags: X - disabled, I - invalid, D - dynamic 
 0    ;;; HAIRPIN NAT
      chain=srcnat action=masquerade src-address=192.168.10.0/24 dst-address=192.168.10.0/24 log=no log-prefix="" 

 1    chain=srcnat action=masquerade src-address=192.168.10.0/24 out-interface=pppoe-out1 log=no log-prefix="" 

 2    ;;; HomeAssistant
      chain=dstnat action=dst-nat to-addresses=192.168.10.200 to-ports=8123 protocol=tcp dst-address-list=WAN-IP-2021 dst-port=8123 log=no log-prefix=""

THe rules seem correct.
Although the source address on teh second NAT rule is not required.
chain=srcnat action=masquerade out-interface=pppoe-out1

Why is the expected behaviour not agreable?

If that is not what you want, then please state more clearly your expectations

Thanks for your reply. I removed the src-address from the 2nd rule.

I was expecting the port forward rules to apply ONLY for the specific devices I choose. For example I want the port 8123 to be forwarded ONLY for home assistant instance (local ip 192.168.10.200), but not for the other devices in the network.

Or I would like to forward a port X for my torrent seedbox
Or to open some ports for my xbox
etc

I’m not sure I undestand you. Port is forwarded only to one device specified in to-addresses. If you’d like to have forwarded port for some client(s), i.e. that from it/them it would be accessible, but not from anywhere else, it can be done using src-address (or src-address-list if you need more than one). But it doesn’t go together with your other examples, because those forwarded ports you most likely want to have accessible from anywhere.

Port forwarding is typically for EXTERNAL users to reach a server you are running.
Is this or is this not the case??

Accessing existing LAN devices can be done directly from LAN device to LAN device using LANIP
Is this or is this not the case??

Finally there is also a case where you want people on a LAN behind your router to use your WANIP (typically a dyndns name etc) to reach a server on the LAN.
Is this or is this not the case.

As was stated by SOB, port forwarding rules are setup such that any external user hitting your WANIP on port XXXX will gain access.
When you use hairpin NAT, it allows all users on the LAN (on the same subnet as the server) to access the server using the WANIP address and port xxxx.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

It seems maybe that none of the above is the functionality you are looking for?
It appears you want some users not all, to access a device or server on the same LAN? Plus they should use the WANIP address not the LAN address to do this???

Yes, this is the case.

Home assistant server (192.168.10.200 which translates into xxx.duckdns.org domain) is reachable from the internet. (I want this that way)

I don’t want other devices (phone, pc etc) to have port 8123 reachable from the Internet - but running canyouseeme.org port 8123 is open for all of them. Is that supposed to work that way?

That port is forwarded to 192.168.10.200, why do you think that it has anything to do with other devices?

Concur, In this case you do NOT need the hairpin nat rule
(so remove it).

ANY DEVICE on the internet that hits your WANIP with destination for that port will be able to reach your server.
How you setup server security is another matter.

What I will say is that if you know all the users and they have either
a. a static WANIP
b. Have given their dynamic WANIP a dyndns URL identification.

You can create a firewall source address list that will limit access to those IPs…
In fact there is really no excuse not to do that as one can get free dyndns URL names on the net.

chain=dstnat action=dst-nat to-addresses=192.168.10.200 to-ports=8123 protocol=tcp
dst-address-list=WAN-IP-2021 dst-port=8123 src-address-list=authorized

where
add address=IP of User1 list=authorized
add address=IP of User2 list=authorized
add address=dyndnsURL of User3 list=authorized {router will resolve name}
add address=IdyndnsURL of User4 list=authorized {router will resolve name}
etc…

This however does not totally protect you as public IPs can be spoofed.
Also plain User name and passwords can be easily hacked
THe best bet is to ensure you have encryption at your server SFTP for example…

I setup a hairpin nat to access the server’s dashboard (https) with a single clean url (and work both inside/outside lan)

Example:

Is there a better way to do that?

No but thats different,
YOU SAID external users and now you change the facts to include LAN users..
If access to the server using and external URL is from users on the same subnet as the server yes you need hairpin nat rule.


Just to clarify, maybe…
You want all external users as per normal AND ONLY YOU on the LAN to be able to access the server???

Just to be clear with the rules you have, ONLY the server is exposed on that port, none of the other devices/users are exposed.

That wouldn’t make any sense. If the whole world can connect, then not allowing some local users to connect would be pointless, because they could simply use some free external proxy server and connect anyway.

Well thats the point, nothing makes sense yet LOL. Im trying to plumb the mines of of space ( a vacuum of tangible information )

Apologies for have not been clear fellas. I am starting to figure out things myself in networking and it’s clear that I am struggling.

HomeAssistant’s CP is served on a https page on the specific socket that I’ve mentioned. In order to do that it has a DNS service with integrated HTTPS support via Let’s Encrypt. It updates regurarly with my public IP

When I am home using that url a NAT loopback/hairpin makes that possible.

To come back to my original question:
can you port forward the same port (8123) on two different internal IP addresses?

The answer is no, right?

When I use portchecker on a random browser client in my network (random local IP), when it says 8123 port is open it refers only to the 192.168.10.200 that this port is binded in my router’s NAT rules?

.. right? (I would post an anakin skywalker “right?” meme, but I am not sure if it appropriate in this board)

The answer to your question is YES. through port translation.

Case Normal - Not possible.
port XXX to server YYY
port XXX to server ZZZ

The reason is that the router will not know which server to forward the traffic too!

Case Port Translation - Possible.
port xxx to server yyyy
port aaa incoming translated to XXX to server ZZZ

Here the router is being hit externally on two different ports and thus can keep track of the packet flow destinations and sources …


Case Another WANIP - Possible.
When people get multiple IPs from an ISP they can use one for the router and the above rules apply but they can take another IP and use it just for a server.
In this case though the WANIP is different and thus although the port is the same, the router can keep track of packet flow.

I get it now. If you use some online port checker, which automatically suggests your public address, then no matter from what internal machine you try it, it will be always the same public address (for usual home connection). So it’s not testing if port is forwarded to that machine, but only if port is forwarded somewhere, and where that is depends on what you configure on router. That’s if you belong to lucky users, who even have their own public address, otherwise it would be testing some ISP’s router.

Thank you @Sob for this clarification

@add1

Make a drawing of your configuration and what you like to do.

For me it seems that you do not need Hairpin at all for just one server.
Add a record to your local DNS server that points to your internal server.
External user will then use public ip they get from public DNS and connect to server using NAT only.
Internal user will get IP from internal DNS pointing til internal server.

No need to make it more complicated than needed.

And that’s exactly the reason why to choose hairpin NAT, it’s simple and 100% realiable in all situations (hint: DoH). Go team hairpin! :slight_smile:

There are + and - with Hairpin (have used both for many years)
For example in hairpin all traffic goes through the router for lan/lan client/server connction.
More complicate to setup (can be set up in may ways) compare to a simple DNS record.
If you do not have static outside IP, you need to setup Dyndns/Cloud.
But if you do not have a local DNS server, then this needs to be setup.

In short, in order to not hijack this thread, traffic going through router is one disadvantage, and that’s it. Other stuff, there’s nothing complicated and nothing special that you wouldn’t need also for proper dstnat from internet. You’re welcome to join team dns in @anav’s hairpin NAT thread and we can “fight” there. :slight_smile: