당신이 요구하는 것은 존재 하지 않습니다 . 그렇기 때문에 발견 한 답변 (일부는 아마도 내 것)에 불만족합니다. 모두 간단한 해결책이나 복잡한 해결책이 아닌 해결책 을 제안했습니다 .
설명하겠습니다. 모든 OS에서의 라우팅은 대상 주소에 따라 결정됩니다. 여러 경로가있을 수 있지만 연결을 호출하는 응용 프로그램이 아니라 단순히 대상 주소에 따라 선택됩니다. 마침표.
사소한 예를 드리겠습니다. VPN 클라이언트가 서버에 연결 한 경우 VPN 외부의 특정 사이트 (예 : example.org)로 연결을 라우팅 할 수 있습니다. 그러나 특정 주소에 도달하려는 모든 응용 프로그램은 VPN 외부로 라우팅됩니다. 다른 응용 프로그램이 VPN 외부를 통과하는 동안 일부 응용 프로그램이 VPN을 통해 example.org로 이동할 수는 없습니다.
소스 라우팅을 허용하는 Linux 커널을 사용하면 상황이 더욱 풍부 해집니다. 즉, 둘 이상의 라우팅 테이블을 가질 수 있으며, 둘 중 하나를 선택하면 대상 주소가 아닌 소스 주소를 기반으로 선택됩니다.
사소한 예 : 내 PC에는 두 개의 외부 공용 회선이 있고 두 개의 다른 공용 IP가 있습니다. 두 인터페이스 중 하나를 통해 연락 할 수 있으며, 주어진 연결에 대한 응답이 연결을 통해 온 동일한 인터페이스를 통해 전달되어야합니다. 그렇지 않으면 연결을 시작한 사람에게 도달하면 관련이없는 것으로 폐기됩니다. 이것은 소스 라우팅입니다.
충분합니다. 우리가 시작한 연결은 어떻습니까? 일부 앱에서는 openssh 클라이언트 와 같이 바인드 주소를 지정할 수 있습니다 .
-b bind_address
로컬 시스템에서 bind_address를 연결의 소스 주소로 사용하십시오. 주소가 둘 이상인 시스템에서만 유용합니다.
그들에게는 하나의 인스턴스가 VPN을 통해 (예 : 라우팅 테이블 1) 나가는 반면 다른 인스턴스가 VPN을 통해 (라우팅 테이블 2)하는 데에는 문제가 없습니다. 그러나 Firefox와 같은 다른 응용 프로그램은 특정 소스 IP 주소에 바인딩하는 것이 매우 어려울뿐만 아니라 ( 매우 현명한 해결 방법 은 여기 참조 ), 두 개의 사본을 가질 수 없다는 의미에서 불쾌 합니다. 각각 다른 소스 주소에 바인딩되어 동시에 실행됩니다. 즉, 위에서 언급 한 트릭으로 인해 하나의 인스턴스가 선택한 소스 주소에 바인딩하도록 강요 할 수 있지만 다른 버전의 인스턴스를 다른 소스 주소에 바인딩 할 수 없습니다.
이것은 우리가 대안을 사용하는 이유를 설명합니다. 그것들은 모두 같은 아이디어를 기반으로하며 나머지 PC와는 별도의 네트워크 스택으로 작동한다는 것입니다. 따라서 대략적인 복잡성, VM, 도커, 컨테이너, 네임 스페이스 순서를 줄일 수 있습니다. 각각에는 하나 이상의 라우팅 테이블이 있지만 각각의 인스턴스 (VM / dockers / containers / namespaces)를 여러 개 가질 수 있으며 자유롭게 자유롭게 혼합 할 수 있습니다. 각 인스턴스는 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 개의 다른 NNS 및 다른 연결로 최대 254 개의 xterm을 열 수 있습니다.
#!/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 처리는 약간 버그가 있습니다. 인내심을 가지십시오.