0

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?

3
  • Are you sure you still have a dedicated IP address that's reachable from the outside? Today most ISPs use NAT, so no matter what you do on your local machine, you won't be reachable. That said, one way to use different IP connections is to use different network namespaces for those applications that connect via VPN, and those that connect directly.
    – dirkt
    Commented Mar 29, 2017 at 7:11
  • @dirkt Yes I'm sure, the second I disconnect from OpenVPN the servers I host become available through that IP. I thought that different namespaces allowed using real IP for some outbound connections and OpenVPN for others? Not inbound connections?
    – Krzaku
    Commented Mar 29, 2017 at 8:19
  • Ah, hosted servers. As long as you are in a different network namespace, all connections, no matter if inbound or outbound, will be treated according to the setup in the namespace. So why do you think inbound connections are different? One namespace with the tun0 endpoint of VPN inside it for VPN connections, one global namespace for direct conenctions.
    – dirkt
    Commented Mar 29, 2017 at 8:40

1 Answer 1

0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .