Core: homeassistant.util.get_local_ip() returns outbound IP address on OS X when VPN is present

Created on 27 Apr 2018  Â·  14Comments  Â·  Source: home-assistant/core

Home Assistant release with the issue:
0.68.0b1

Operating environment (Hass.io/Docker/Windows/etc.):
osx 10.11.6, python 3.6.5

Component/platform:
homeassistant.util.get_local_ip()
https://github.com/home-assistant/home-assistant/blob/3442b6741d969def6b97b99d8bc2c978252efed0/homeassistant/util/__init__.py#L93

Description of problem:
when os x is connected to a VPN, homeassistant.util.get_local_ip() returns the outbound IP address of the VPN instead of the local IP address

Traceback (if applicable):
this is what i get when i enter the commands from homeassistant.util.get_local_ip() into the python3 console while not connected to a VPN

>>> import socket
>>> socket.gethostbyname(socket.gethostname())
'192.168.1.xx'
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> sock.connect(('8.8.8.8', 80))
>>> sock.getsockname()
('192.168.1.xx', 53xxx)

if i am connected to a VPN, this is the result:

>>> import socket
>>> socket.gethostbyname(socket.gethostname())
'192.168.1.xx'
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> sock.connect(('8.8.8.8', 80))
>>> sock.getsockname()
('172.16.xx.x', 62xxx)

Additional information:
it affects the startup of the homekit component (https://github.com/home-assistant/home-assistant/issues/14077), but probably also other components.

Most helpful comment

My solution would be to change get_local_ip and inside the helper check for a configuration option (I also agree with homeassistant section)

This would pretty much solve the issue without affecting anyone

All 14 comments

homeassistant.util.get_local_ip will return the local_ip of the default interface. When you are connected to a VPN, the VPN becomes your default interface and therefore local_ip corresponds to the VPN IP address.

This issue will happen in any other OS, and it will affect any component that relies in using a local (LAN) IP address for communication with local devices.

I've done some research and could not find any clean solution to this besides adding an optional configuration option where user defines either the default IP or default network interface.

I can work on a fix for this (add one of the configuration options) but I ask @balloob for validation before proceeding.

I don't have the experience at working with network interfaces, but if we have to rely on a config option, would at be an idea to add it to the homeassistant section instead? That way we can override get_local_ip once and still use the function in every component without extra work.

My solution would be to change get_local_ip and inside the helper check for a configuration option (I also agree with homeassistant section)

This would pretty much solve the issue without affecting anyone

If your computer is on a VPN, it makes no sense to use local IP because you're on a VPN and thus cannot connect?

The use case is sound:

  • You run HA in a computer that connects to a remote site via VPN (eg. to upload backup, connect to a remote DB, etc)

Our get_local_ip helper function breaks under this use case

But Home Assistant will set up all their listeners to listen on the VPN interface, not the local interface?

Several component API's require an IP address to bind to (https://github.com/home-assistant/home-assistant/search?utf8=✓&q=get_local_ip&type=), example from already referred #14077

https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/homekit/__init__.py#L174

the IP address handed to these API comes from the core 'get_local_ip'

I think in that case that it needs to be solved in each of those components. Because what if the user wants to pick and choose which service to expos where.

@diplix I will add the CONF_IP_ADDRESS option to the HomeKit component then. That should solve the original issue #14077.

I think that is also a good option, although it leads to some code duplication.

Then again we can remove get_local_ip in the end 🗡

We can't remove it because it's still used if people do not configure ip

@dgomes

homeassistant.util.get_local_ip will return the local_ip of the default interface. When you are connected to a VPN, the VPN becomes your default interface and therefore local_ip corresponds to the VPN IP address.

i’m not sure if thats true. when i connect to a VPN, it becomes another interface. as far as i can see, there are many more parallel interfaces possible (on os x ethernet and wifi are used in parallel when activated, neither being default). outbound traffic is routed mostly through the vpn, though i can alter that using different routing tables. the local interface works mostly unaffected by this. home assistant is always accessible through local IPs and i remote connect from outside through my DSL providers IP address (not the VPN address).

also while setting up and using homebridge it never used up the outbound VPN address and always worked as intended, whether the VPN is up or down, without configuring a local IP.

i’m no networking expert, i’m just observing, so i’m not good at arguing my case here. however i guess letting the user define the IP thats used is a good solution. and running hass on os x with a VPN is probably an edge case.

In routing there is always a default route that uses a given interface (of course you will have several other routes and interfaces, but only one default gateway). You can surely define a limited set of routes for your VPN and in that case the VPN interface no longer becomes your default gateway (that means most of the time defaulting back to your local router).

Home Assistant binds it self to all interfaces, so it is accessible from 127.0.0.1 (loopback), wifi_interface_ip, ethernet_interface_ip and eventually vpn_interface_ip.

As this issue needs to be addressed per component, and the HomeKit one has been solved in (https://github.com/home-assistant/home-assistant/pull/14163), I'll close this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kdschlosser picture kdschlosser  Â·  374Comments

rschaeuble picture rschaeuble  Â·  230Comments

gieljnssns picture gieljnssns  Â·  277Comments

Bergasha picture Bergasha  Â·  176Comments

McGiverGim picture McGiverGim  Â·  124Comments