Những gì bạn đang yêu cầu không tồn tại. Đây là lý do tại sao bạn không hài lòng với câu trả lời bạn tìm thấy (một số trong số chúng, có thể là của tôi): tất cả chúng đều có đề xuất giải pháp , không phải là giải pháp chính hãng, đơn giản hoặc phức tạp.
Hãy để tôi giải thích. Định tuyến trong tất cả các hệ điều hành được xác định theo địa chỉ đích: bạn rất có thể có một số tuyến, nhưng sự lựa chọn giữa chúng không dựa trên ứng dụng gọi kết nối, mà chỉ dựa trên địa chỉ đích. Dấu chấm.
Hãy để tôi cho bạn một ví dụ không tầm thường. Khi máy khách VPN đã thiết lập kết nối đến máy chủ của nó, vẫn có thể định tuyến kết nối đến một trang web nhất định, ví dụ example.org, bên ngoài VPN. Nhưng tất cả các ứng dụng cố gắng truy cập địa chỉ đặc biệt đó sẽ được định tuyến bên ngoài VPN: bạn không thể có một số ứng dụng truy cập example.org thông qua VPN trong khi các ứng dụng khác vượt ra ngoài VPN.
Tình hình trở nên phong phú hơn với nhân Linux, cho phép định tuyến nguồn: điều này có nghĩa là bạn có thể có hai hoặc nhiều bảng định tuyến và sự lựa chọn giữa chúng dựa trên địa chỉ nguồn chứ không phải địa chỉ đích.
Một ví dụ không tầm thường: máy tính của tôi có hai dòng bên ngoài, với hai IP công khai riêng biệt. Nó có thể được liên lạc qua một trong hai giao diện, và điều quan trọng là các câu trả lời của tôi cho một kết nối nhất định sẽ chuyển qua cùng một giao diện mà kết nối được đưa ra: nếu không chúng sẽ bị loại bỏ vì không liên quan khi chúng đến người bắt đầu kết nối. Đây là định tuyến nguồn.
Đủ công bằng, những gì về kết nối mà chúng ta bắt đầu? Một số ứng dụng cho phép bạn chỉ định địa chỉ liên kết, như ứng dụng khách openssh :
-b bind_address
Sử dụng bind_address trên máy cục bộ làm địa chỉ nguồn của kết nối. Chỉ hữu ích trên các hệ thống có nhiều hơn một địa chỉ.
Đối với họ, không có vấn đề gì khi có một cá thể đi qua VPN (giả sử, bảng định tuyến 1) trong khi một phiên bản khác sẽ đi ra ngoài VPN (giả sử bảng định tuyến 2). Nhưng các ứng dụng khác, như Firefox, không chỉ khó liên kết với một địa chỉ IP nguồn cụ thể (mà hãy xem ở đây để có cách giải quyết rất thông minh), mà còn có ý nghĩa và khó chịu ở chỗ chúng sẽ không cho phép bạn có hai bản sao của chúng chạy đồng thời, mỗi ràng buộc với một địa chỉ nguồn khác nhau. Nói cách khác, nhờ vào thủ thuật được tham chiếu ở trên, bạn có thể bắt buộc một trường hợp phải liên kết với một địa chỉ nguồn bạn chọn, sau đó bạn không thể có một phiên bản khác của nó liên kết với địa chỉ nguồn khác.
Điều này giải thích tại sao chúng tôi sử dụng cách giải quyết: tất cả chúng đều dựa trên cùng một ý tưởng, rằng chúng hoạt động với một ngăn xếp mạng riêng biệt so với phần còn lại của máy tính. Vì vậy, bạn có thể có, theo thứ tự gần đúng về độ phức tạp, VM, docker, container, không gian tên. Trong mỗi bảng, bạn sẽ có một hoặc nhiều bảng định tuyến, nhưng bạn có thể có một vài phiên bản của mỗi (VM / docker / container / tên không gian) và bạn cũng có thể trộn chúng một cách tự do, mỗi bảng chạy ứng dụng riêng như Firefox vui vẻ tách ra từ những người khác.
Có lẽ bạn vẫn quan tâm đến một trong những cách giải quyết?
BIÊN TẬP:
Cách làm việc đơn giản nhất là một không gian tên mạng. Kịch bản bên dưới xử lý tất cả các khía cạnh cần thiết của NNS: đặt nó vào một tệp (bạn chọn tên của mình, tôi thường sử dụng newns
, nhưng bạn làm bất cứ điều gì bạn thích) /usr/local/bin
, sau đó chmod 755 FILE_NAME
, và bạn có thể sử dụng nó như sau:
newns NAMESPACE_NAME start
newns NAMESPACE_NAME stop
Nó sẽ mở ra xterm
cho bạn (đó là vì tôi thích xterm hoạt động, nhưng bạn có thể thay đổi nó nếu bạn muốn sử dụng bất cứ thứ gì khác), thuộc về không gian tên mới. Từ bên trong xterm bạn có thể, nếu bạn muốn, bắt đầu vpn của bạn, và sau đó bắt đầu trò chơi của bạn. Bạn có thể dễ dàng kiểm tra xem bạn có đang sử dụng VPN thông qua lệnh sau không:
wget 216.146.38.70:80 -O - -o /dev/null | cut -d" " -f6 | sed 's/<\/body><\/html>//'
trả về cho bạn IP công cộng của bạn. Sau khi thiết lập VPN trong xterm, bạn có thể kiểm tra xem IP công khai của bạn có khác trong các cửa sổ khác không. Bạn có thể mở tối đa 254 xterms, với 254 NNS khác nhau và các kết nối khác nhau.
#!/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
Nếu bạn muốn, bạn thậm chí có thể bắt đầu toàn bộ máy tính để bàn bên trong không gian tên mạng mới, bằng phương tiện
sudo startx -- :2
sau đó bạn có thể tìm kiếm nó bằng cách sử dụng Alt+ Ctrl+ Fn, trong đó Fn là một trong những F1, F2, ....-
Tôi cần thêm một cảnh báo: Xử lý DNS bên trong không gian tên là một lỗi nhỏ, hãy kiên nhẫn.