仅通过VPN路由特定流量

乔什·雷蒙德(Josh Raymond)

我查询过以前问过类似问题的人,但是还没有得到一个可以在我给定情况下使用的直接答案,所以这里是。

我在Linux(Fedora 22)上运行,并拥有付费的VPN服务,但是我只需要特定的程序即可使用VPN来进行Internet流量,并且可以将我的标准ISP连接用于其他所有功能(例如,Web浏览,等等)

我们将使其变得简单,并将其限制为通过WINE运行的最常用的程序《魔兽世界》。

现在,我通过网络接口进行了VPN设置,因此我通过enp10s0(我的计算机eth0的怪异名称)的所有流量都可以通过VPN服务进行隧道传输,但是,我只需要特定的程序(或这些程序使用的端口即可)具体而言)以通过VPN。

如何设置隧道,并使其仅通过VPN路由所需的端口,同时使其他所有路由保持未路由状态?

马里乌斯·马图蒂亚

你所要求的并没有存在。这就是为什么您对找到的答案不满意的原因(有些答案可能是我的):所有答案都提供了建议的解决方法,而不是真正的解决方案,无论是简单的还是复杂的。

让我解释。所有操作系统中的路由均由目标地址决定:您可能有数条路由,但它们之间的选择并不基于调用连接的应用程序,而仅取决于目标地址。句号

让我举一个简单的例子。当VPN客户端建立与其服务器的连接后,仍然可以将连接路由到VPN外部的给定站点,例如example.org。但是,所有尝试到达该特殊地址的应用程序都将路由到VPN外部:您不能让某些应用程序通过VPN进入example.org,而其他应用程序则通过VPN之外。

Linux内核允许源路由,这种情况变得更加丰富:这意味着您可以拥有两个或更多路由表,并且它们之间的选择取决于源地址,而不是目标地址。

一个不平凡的例子:我的电脑有两条外线,有两个不同的公共IP。可以通过任一接口进行联系,并且重要的是,我对给定连接的答复将通过与连接进入的接口相同的接口:否则,当它们到达发起连接的人员时,它们将被视为无关紧要而被丢弃。这是源路由。

足够公平,那我们开始的联系又如何呢?一些应用程序允许您指定绑定地址,例如openssh客户端

-b bind_address

使用本地计算机上的bind_address作为连接的源地址。仅在具有多个地址的系统上有用。

对于他们来说,让一个实例通过VPN(例如,路由表1),而另一个实例将在VPN外部(例如,路由表2),则没有问题。但其他应用程序,如Firefox,不仅是出了名的难绑定到特定的源IP地址(但看到这里的一个非常聪明的解决办法),但也有刻薄和肮脏的,因为它们不会让你有自己的两个副本同时运行,每个绑定到一个不同的源地址。换句话说,尽管由于上述技巧,您可以强制一个实例绑定到您选择的源地址,但是您不能让该实例的另一个版本绑定到另一个源地址。

这就解释了为什么我们使用变通方法:它们都基于相同的思想,它们与PC的其余部分相比使用单独的网络堆栈。因此,您可以以降低复杂性的近似顺序获得虚拟机,泊坞窗,容器,名称空间。在它们的每一个中,您将都有一个或多个路由表,但是每个表都可以有多个实例(VM / docker /容器/命名空间),还可以自由地混合它们,其中的每一个都运行自己的应用程序,如Firefox,幸福地分开了。从其他的。

也许您仍然对其中一种解决方法感兴趣?

编辑:

最简单的解决方法是网络名称空间。下面的脚本处理了NNS的所有必要方面:将其放在(然后newns选择)文件中(通常选择您的名字,但您可以根据自己的喜好进行选择)/usr/local/bin,然后chmod 755 FILE_NAME可以按以下方式使用它:

       newns NAMESPACE_NAME start
       newns NAMESPACE_NAME stop

它将xterm为您打开一个属于我,因为xterm可以工作,但是如果您希望使用其他功能,则可以更改它),它属于新的命名空间。如果愿意,可以从xterm内部启动vpn,然后开始游戏。您可以通过以下命令轻松检查您是否正在使用VPN:

    wget 216.146.38.70:80 -O - -o /dev/null | cut -d" " -f6 | sed 's/<\/body><\/html>//'

这将返回您的公共IP。在xterm中设置VPN后,您可以检查其他窗口中的公共IP是否不同。您最多可以打开254个xterm,其中包含254个不同的NNS和不同的连接。

#!/bin/bash

#
# This script will setup an internal network 10.173.N.0/24; if this causes
# any conflict, change the statement below.

export IP_BASE=10.173

# It will open an xterm window in the new network namespace; if anything
# else is required, change the statement below.

export XTERM=/usr/bin/xterm

# The script will temporarily activate ip forwarding for you. If you
# do not wish to retain this feature, you will have to issue, at the 
# end of this session, the command
# echo 0 > /proc/sys/net/ipv4/ip_forward 
# yourself. 

 ###############################################################################

 WHEREIS=/usr/bin/whereis

 # First of all, check that the script is run by root:


 [ "root" != "$USER" ] && exec sudo $0 "$@"

 if [ $# != 2 ]; then
    echo "Usage $0 name action"
    echo "where name is the network namespace name,"
    echo " and action is one of start| stop| reload."
    exit 1
 fi

 # Do we have all it takes?

 IERROR1=0
 IERROR2=0
 IERROR3=0
 export IP=$($WHEREIS -b ip | /usr/bin/awk '{print $2}')
 if [ $? != 0 ]; then
    echo "please install the iproute2 package"
    IERROR1=1
 fi

 export IPTABLES=$($WHEREIS -b iptables | /usr/bin/awk '{print $2}')
 if [ $? != 0 ]; then
    echo "please install the iptables package"
    IERROR2=1
 fi

 XTERM1=$($WHEREIS -b $XTERM | /usr/bin/awk '{print $2}')
 if [ $? != 0 ]; then
    echo "please install the $XTERM package"
    IERROR3=1
 fi
 if [ IERROR1 == 1 -o IERROR2 == 1 -o IERROR3 == 1 ]; then
    exit 1
 fi

 prelim() {

 # Perform some preliminary setup. First, clear the proposed 
 # namespace name of blank characters; then create a directory
 # for logging info, and a pid file in it; then determine 
 # how many running namespaces already exist, for the purpose
 # of creating a unique network between the bridge interface (to 
 # be built later) and the new namespace interface. Lastly, 
 # enable IPv4 forwarding. 

    VAR=$1
    export NNSNAME=${VAR//[[:space:]]}

    export OUTDIR=/var/log/newns/$NNSNAME

    if [ ! -d $OUTDIR ]; then
            /bin/mkdir -p $OUTDIR
    fi
    export PID=$OUTDIR/pid$NNSNAME

    # Find a free subnet

    ICOUNTER=0
    while true; do
            let ICOUNTER=ICOUNTER+1
            ip addr show | grep IP_BASE.$ICOUNTER.1 2>&1 1> /dev/null
            if [ ! $? == 0 -a $ICOUNTER -lt 255 ]; then
                    export Nns=$ICOUNTER
                    break
            elif [ ! $? == 0 -a $ICOUNTER -gt 254 ]; then
                    echo "Too many open network namespaces"
                    exit 1
            fi
    done
    if [ $Nns == 1 ]; then
            echo 1 > /proc/sys/net/ipv4/ip_forward
    fi

 }

 start_nns() {

 # Check whether a namespace with the same name already exists. 

    $IP netns list | /bin/grep $1 2> /dev/null
    if [ $? == 0 ]; then
            echo "Network namespace $1 already exists,"
            echo "please choose another name"
            exit 1
    fi

    # Here we take care of DNS

    /bin/mkdir -p /etc/netns/$1
    echo "nameserver 8.8.8.8" > /etc/netns/$1/resolv.conf
    echo "nameserver 8.8.4.4" >> /etc/netns/$1/resolv.conf
                                                                           

    # The following creates the new namespace, the veth interfaces, and
    # the bridge between veth1 and a new virtual interface, tap0.
    # It also assigns an IP address to the bridge, and brings everything up

    $IP netns add $1
    $IP link add veth-a$1 type veth peer name veth-b$1
    $IP link set veth-a$1 up
    $IP tuntap add tap$1 mode tap user root
    $IP link set tap$1 up
    $IP link add br$1 type bridge
    $IP link set tap$1 master br$1
    $IP link set veth-a$1 master br$1
    $IP addr add $IP_BASE.$Nns.1/24 dev br$1
    $IP link set br$1 up

    # We need to enable NAT on the default namespace

    $IPTABLES -t nat -A POSTROUTING -j MASQUERADE

    # This assigns the other end of the tunnel, veth2, to the new 
    # namespace, gives it an IP address in the same net as the bridge above, 
    # brings up this and the (essential) lo interface, sets up the 
    # routing table by assigning the bridge interface in the default namespace
    # as the default gateway, creates a new terminal in the new namespace and 
    # stores its pid for the purpose of tearing it cleanly, later. 

    $IP link set veth-b$1 netns $1
    $IP netns exec $1 $IP addr add $IP_BASE.$Nns.2/24 dev veth-b$1
    $IP netns exec $1 $IP link set veth-b$1 up
    $IP netns exec $1 $IP link set dev lo up
    $IP netns exec $1 $IP route add default via $IP_BASE.$Nns.1
    $IP netns exec $1 su -c $XTERM $SUDO_USER &
    $IP netns exec $1 echo "$!" > $PID



}

stop_nns() {

# Check that the namespace to be torn down really exists

    $IP netns list | /bin/grep $1 2>&1 1> /dev/null
    if [ ! $? == 0 ]; then
            echo "Network namespace $1 does not exist,"
            echo "please choose another name"
            exit 1
    fi

    # This kills the terminal in the separate namespace, 
    # removes the file and the directory where it is stored, and tears down
    # all virtual interfaces (veth1, tap0, the bridge, veth2 is automatically
    # torn down when veth1 is), and the NAT rule of iptables. 

    /bin/kill -TERM $(cat $PID) 2> /dev/null 1> /dev/null
    /bin/rm $PID
    /bin/rmdir $OUTDIR
    $IP link set br$1 down
    $IP link del br$1
    $IP netns del $1
    $IP link set veth-a$1 down
    $IP link del veth-a$1
    $IP link set tap$1 down
    $IP link del tap$1
    $IPTABLES -t nat -D POSTROUTING -j MASQUERADE
    /bin/rm /etc/netns/$1/resolv.conf
    /bin/rmdir /etc/netns/$1

}


case $2 in
    start)
            prelim "$1"
            start_nns $NNSNAME
            ;;
    stop)
            prelim "$1"
            stop_nns $NNSNAME
            ;;
    reload)
            prelim "$1"
            stop_nns $NNSNAME
            prelim "$1"
            start_nns $NNSNAME
            ;;
    *)
 # This removes the absolute path from the command name

            NAME1=$0
            NAMESHORT=${NAME1##*/}

            echo "Usage:" $NAMESHORT "name action,"
            echo "where name is the name of the network namespace,"
            echo "and action is one of start|stop|reload"
            ;;
 esac

如果需要,您甚至可以通过以下方式在新的网络名称空间内启动整个桌面:

            sudo startx -- :2 

然后您可以使用Alt+ Ctrl+搜索它Fn,其中Fn是F1,F2,....-之一

我需要添加一个警告:名称空间内的DNS处理有点麻烦,请耐心等待。

本文收集自互联网,转载请注明来源。

如有侵权,请联系debugcn@gmail.com 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Linux-通过以太网路由特定流量

来自分类Dev

通过VPN容器路由Docker容器流量

来自分类Dev

在Azure VPN中路由流量

来自分类Dev

在Ubuntu Linux上通过VPN路由所有流量

来自分类Dev

无法通过VPN路由某些流量

来自分类Dev

如果Windows 10的目的地是VPN主机,则Windows 10不会通过VPN路由流量

来自分类Dev

通过vpn路由wlan1的流量,并将wlan0的流量路由到eth0

来自分类Dev

偶尔通过VPN将流量路由到某些IP

来自分类Dev

使用PPPoE时流量无法通过VPN路由

来自分类Dev

VPN:登录后,所有流量都通过VPN路由吗?

来自分类Dev

OpenVPN:仅通过vpn路由特定的子网-适用于单个IP地址

来自分类Dev

是否可以仅通过VPN路由特定的应用程序?

来自分类Dev

可以通过配置了我的VPN服务的路由器路由所有LAN流量吗?

来自分类Dev

仅通过PPTP VPN路由某些地址?

来自分类Dev

通过特定网络接口路由特定IP的所有流量

来自分类Dev

Linux-通过以太网路由特定的流量

来自分类Dev

为什么要通过我的网络/ VPN路由流量?

来自分类Dev

如何仅通过OpenVPN客户端路由传出流量?

来自分类Dev

仅允许特定IP范围的流量通过VPN

来自分类Dev

通过VPN路由更多流量

来自分类Dev

如何通过特定的VPN客户端路由特定的VPN流量?

来自分类Dev

通过VPN网关路由特定的IP地址

来自分类Dev

通过特定的接口将流量路由到特定的网络

来自分类Dev

如何通过VPN适配器路由所有流量?

来自分类Dev

通过VPN服务器路由哪些流量?

来自分类Dev

通过VPN网关路由局域网流量

来自分类Dev

networkmanager-strongswan vpn-通过VPN路由特定的IP

来自分类Dev

通过不同的接口路由VPN和Internet流量

来自分类Dev

仅通过 eth0 路由特定的内网流量;其他一切都通过 wlan0

Related 相关文章

  1. 1

    Linux-通过以太网路由特定流量

  2. 2

    通过VPN容器路由Docker容器流量

  3. 3

    在Azure VPN中路由流量

  4. 4

    在Ubuntu Linux上通过VPN路由所有流量

  5. 5

    无法通过VPN路由某些流量

  6. 6

    如果Windows 10的目的地是VPN主机,则Windows 10不会通过VPN路由流量

  7. 7

    通过vpn路由wlan1的流量,并将wlan0的流量路由到eth0

  8. 8

    偶尔通过VPN将流量路由到某些IP

  9. 9

    使用PPPoE时流量无法通过VPN路由

  10. 10

    VPN:登录后,所有流量都通过VPN路由吗?

  11. 11

    OpenVPN:仅通过vpn路由特定的子网-适用于单个IP地址

  12. 12

    是否可以仅通过VPN路由特定的应用程序?

  13. 13

    可以通过配置了我的VPN服务的路由器路由所有LAN流量吗?

  14. 14

    仅通过PPTP VPN路由某些地址?

  15. 15

    通过特定网络接口路由特定IP的所有流量

  16. 16

    Linux-通过以太网路由特定的流量

  17. 17

    为什么要通过我的网络/ VPN路由流量?

  18. 18

    如何仅通过OpenVPN客户端路由传出流量?

  19. 19

    仅允许特定IP范围的流量通过VPN

  20. 20

    通过VPN路由更多流量

  21. 21

    如何通过特定的VPN客户端路由特定的VPN流量?

  22. 22

    通过VPN网关路由特定的IP地址

  23. 23

    通过特定的接口将流量路由到特定的网络

  24. 24

    如何通过VPN适配器路由所有流量?

  25. 25

    通过VPN服务器路由哪些流量?

  26. 26

    通过VPN网关路由局域网流量

  27. 27

    networkmanager-strongswan vpn-通过VPN路由特定的IP

  28. 28

    通过不同的接口路由VPN和Internet流量

  29. 29

    仅通过 eth0 路由特定的内网流量;其他一切都通过 wlan0

热门标签

归档