jamesmcm / vopono

Run applications through VPN tunnels with temporary network namespaces
GNU General Public License v3.0
888 stars 46 forks source link

Accessing services outside of namespace from within the namespace #262

Closed jramseygreen closed 8 months ago

jramseygreen commented 8 months ago

Let's say I have program A running with vopono inside a namespace, and service B running on my machine as normal, accessible over port 8080.

Program A needs to connect to program B for proper functionality, but I can't work out how I can connect to port 8080 outside of the namespace. Currently I would have to run both program A and program B in the namespace to be able to access localhost:8080 from program A.

Is there any way to do this without having to have both programs in the namespace?

Thanks

jamesmcm commented 8 months ago

This should be doable with --allow-host-access - see issue #159

Note that from inside the network namespace you will need to use its IP address for the host - e.g. usually 10.200.1.1

jramseygreen commented 8 months ago

Great that works! I'll also update the documentation of this feature when I get a spare moment.

Just wondering if there's a way to automatically get the ip address for the namespace host? I fear that the ip may change between reboots or something and any configuration using it will break as a result.

jamesmcm commented 8 months ago

The netns IP is available as VOPONO_NS_IP for the POSTUP script: https://github.com/jamesmcm/vopono/blob/44e484952035dc3e4f73d998814528b8176b2098/src/exec.rs#L156-L161

The host IP is available as the VOPONO_HOST_IP env var - see https://github.com/jamesmcm/vopono/blob/44e484952035dc3e4f73d998814528b8176b2098/src/exec.rs#L192-L196 but only for the application itself not the POSTUP script atm, that is an easy change though.

Also see the USERGUIDE - https://github.com/jamesmcm/vopono/blob/44e484952035dc3e4f73d998814528b8176b2098/USERGUIDE.md#configuration-file

FWIW it will only change if you have vopono namespaces running before (or anything else using those addresses - 10.200.1.1 and 10.200.1.2 ).

Also maybe for issue #260 it might be good to write both the forwarded port (if it exists) and local IPs to files in the netns dir /etc/netns/$NETNS_NAME/ in addition to the environment variables, so it's more flexible (especially when running servers like Plex).

jramseygreen commented 8 months ago

So I am talking about settings in a webapp

When I spin up my server I would have vopono in a systemd service. I am basically looking for something like programmatically grabbing the ip address associated with the created namespace and doing something like adding it to the namespace's hosts file (?) so that I could point to e.g. http://hostsystem:8080 in a service running inside the vopono namespace, if I had added 10.200.1.2 vopono to the theoretical namespace hosts file.

I'm not very adept with this kind of stuff, so forgive me if I'm mis understanding or if this isn't something that's really possible

If it's helpful I did so far come up with


ns=$(echo $(ip netns list) | awk '{print $1}')
ip=$(sudo ip netns exec "$ns" ip addr show | awk -v ns="$ns" '$0 ~ ns && /inet / {print $2}' | cut -d'/' -f1)
echo "$ip"
echo "$ns"
jamesmcm commented 8 months ago

That's a good idea, there is already some support to set the hosts file so it shouldn't be too hard to add the fixed entry for the host's IP.

jramseygreen commented 8 months ago

I've worked at it a bit and I have a solution which is working for me

default_hostname="vopono"

# Get the namespace and IP address
ns=$(ip netns list | awk '{print $1}')
ip_address=$(ip a | grep "scope global $ns" | awk '{print $2}' | cut -d '/' -f 1)

# Check if the entry exists in the hosts file
if grep -q "$default_hostname" /etc/hosts; then
    # Replace the existing IP address
    sed -i "s/^.*$default_hostname.*$/$ip_address $default_hostname/g" /etc/hosts
    echo Replaced existing vopono entry
else
    # Create a new entry
    echo "$ip_address $default_hostname" >> /etc/hosts
    echo Created vopono entry
fi

I start this in a script once all my vopono stuff has span up and it allows me to access services outside of the namespace through http://vopono:1234 (provided I use the --allow-host-access flag of course). Marvellous :D

It would be even cooler if this was more tightly integrated into the vopono app itself though

jamesmcm commented 8 months ago

Now on master, with --allow-host-access the host IP ($VOPONO_HOST_IP) will be entered the the network namespace's hosts as vopono.host

So you can access http://vopono.host:1234 from inside the network namespace.

jramseygreen commented 8 months ago

Very cool, thanks