Sometimes I host different services (web servers, game servers etc.) that I would like to be reachable via my real IP address, even though I'm connected to a OpenVPN server. In Windows I didn't have to change anything, it just worked with default settings, how do I set this up the same way in Linux?
1 Answer
Took me a while but I figured it out. Not as easy as I had hoped it would be but it works. Thanks to @dirkt for pointing me in the right direction.
First, create the following scripts in /usr/local/bin directory:
nsstart
:
#!/bin/sh
# Enable eno1 interface
# eno1 is the name of the interface I get my connection from, change it so it fits your system
ip link set eno1 up
# Add 'internet' namespace
ip netns add internet
# Create veth pair and add veth1 to 'internet' namespace
ip link add type veth
ip link set veth1 netns internet
ip link set veth0 up
# Create bridge interface and add eno1 and veth0 to it
ip link add type bridge
ip link set bridge0 up
ip link set eno1 master bridge0
ip link set veth0 master bridge0
# Enable namespace interfaces, add IP and route
ip netns exec internet ip link set lo up
ip netns exec internet ip link set veth1 up
# Set a free IP from your routers IP range here
# You can also use a DHCP client if you have one, mine didn't work with namespaces
ip netns exec internet ip addr add 192.168.1.99/24 dev veth1
# Set IP of the router here
ip netns exec internet ip route add default via 192.168.1.1 metric 10
nsinternet
:
#!/bin/sh
# Execute the command in internet namespace as user who called sudo
ip netns exec internet sudo -u "#$SUDO_UID" -g "#$SUDO_GID" -- "$@"
Then add and enable a systemd service in file /etc/systemd/system/internet-namespace.service
(I use systemd-networkd
to get my IP from my router, if you use something else, change it below, so the bridge is set up before the DHCP client tries to get an address for it):
[Unit]
Description=Sets up a namespace that uses real internet connection instead of OpenVPN
After=systemd-udevd.service
Before=systemd-networkd.service network.target
Wants=network.target
[Service]
Type=oneshot
RemainAfterExit=1
ExecStart=/usr/local/bin/nsstart
[Install]
WantedBy=multi-user.target
Then add this line to the sudoers
file (this is optional, it will make it so you don't have to input your password when you try to use the namespace we created):
%wheel ALL=NOPASSWD: /usr/local/bin/nsinternet
Don't forget to add bridge0
to your DHCP client.
That's it. Enable openvpn-client service and you're good to go. Now the default namespace is the one using the VPN connection, and if you want to use your real internet connection just run sudo nsinternet YOUR_COMMAND
.
tun0
endpoint of VPN inside it for VPN connections, one global namespace for direct conenctions.