С одной физической сетевой картой.
Например мы хотим организовать следующую схему:
1. После запуска сервер устанавливает соединение с VPN-провайдером, и весь трафик идет через VPN.
2. Некоторым программам VPN не нужен, пусть это например будут TOR, I2P (у них и так шифрование, плюс им бы желательно скорость работы повыше, а напрямую соединяться быстрее, чем через VPN). Плюс, например, мы хотим ходить на некоторые сайты в обход VPN, либо иметь возможность запускать в обход VPN какие-либо трафикоемкие программы, например торрент-клиент. Ну пусть еще будет отдельный локальный сервис, например FTP, также висящий на отдельном IP.
Как.
В Linux есть замечательный механизм network namespaces, который на одной машине позволяет создать несколько изолированных друг от друга сетевых подсистем, почти как сеть в виртуальной машине. Не бойтесь, все делается на уровне ядра, потому тормозов, характерных для виртуальных машин не будет. И пусть слово «изолированных» вас тоже не пугает, когда надо — изолированных, а когда надо — мы их свяжем.
Поскольку в процессе нам придется поднимать/опускать физические и виртуальные сетевые карты, настоятельно советую отключить Network Manager, а основную сеть настроить вручную. С включенным Network Manager может ничего не получиться, т.к. он в самый ответственный момент влезет и напоганит в конфигурации.
Как на Slackware отключить Network Manager и настроить сеть вручную (копия)
Конфигурация namespace’ов производится с помощью iproute2.
1. Создаем новый неймспейс с именем provns:
ip netns add provns
2. Создаем две связанных между собой виртуальных сетевых карты (интерфейса)
ip link add veth0 type veth peer name veth1
3. Поднимаем интерфейс veth0:
ifconfig veth0 0.0.0.0 up
4. Ассоциируем вторую виртуальную карту с созданным нэймспейсом:
ip link set veth1 netns provns
Получился один дополнительный namespace, связанный с основным виртуальными сетевыми интерфейсами veth0 и veth1.

Теперь надо связать виртуальный интерфейс veth0 с физической сетевой картой (интерфейсом) eth0. Сделать это можно разными способами, например, присвоить интерфейсам разные IP-адреса из разных подсетей и сделать маскарадинг с помощью IPTABLES, а можно воспользоваться мостами.
Мост — специальное сетевое устройство (в данном случае не физическое, а логическое) позволяющее связать два (и более) сетевых интерфейса на канальном уровне, как в маршрутизаторе.
Подробнее про мосты:
— Linux Bridge
— Виртуальные сетевые устройства в Linux: Linux Bridge
— 10 примеров команды brctl в Linux для сетевого Ethernet моста
— Эти статьи в PDF
Итак:
5. Отключаем физический интерфейс eth0:
ifconfig eth0 down
6. Включаем его, но IP-адрес не присваиваем (IP-адрес будет присвоен мосту):
ifconfig eth0 0.0.0.0 up
7. Создаем мост br0:
brctl addbr br0
8. Соединяем (добавляем интерфейсы к мосту) eth0 и veth0:
brctl addif br0 eth0 veth0
9. Поднимаем (включаем) мост, присваивая ему IP-адрес и маску подсети:
ifconfig br0 192.168.0.15 netmask 255.255.255.0 up
Получилось как на схеме:

10. Устанавливаем маршрут по умолчанию в основном namespace:
ip route add default via 192.168.0.1 dev br0 src 192.168.0.15
Далее конфигурируем namespace:
Выполнение любых команд в указанном namespace производится командой
ip netns exec <имя_namespace> <команда> [параметры_команды]
Например, если мы хотим выполнить ifconfig в namespace с именем provns, то команда будет:
ip netns exec provns ifconfig
11. Поднимаем (включаем) сетевой интерфейс veth1 внутри нэймспейса provns, и присваиваем ему адрес 192.168.0.20:
ip netns exec provns ifconfig veth1 192.168.0.20 netmask 255.255.255.0
12. Прописываем внутри нэймспейса маршрут по умолчанию:
ip netns exec provns ip route add default via 192.168.0.1 dev veth1 src 192.168.0.20
13. Поднимаем внутри namespace’а loopback-интерфейс:
ip netns exec provns ifconfig lo 127.0.0.1
