특정 프로세스 에 대한 모든 트래픽과 트래픽 만 VPN을 통과하도록 VPN (OpenVPN 사용)을 설정하려고합니다 . 다른 프로세스는 물리적 장치를 계속 직접 사용해야합니다. Linux 에서이 작업을 수행하는 방법은 네트워크 네임 스페이스를 사용하는 것입니다.
OpenVPN을 정상적으로 사용하면 (즉 , VPN을 통해 클라이언트의 모든 트래픽을 유입) 제대로 작동합니다. 구체적으로 다음과 같이 OpenVPN을 시작합니다.
# openvpn --config destination.ovpn --auth-user-pass credentials.txt
(편집 된 destination.ovpn 버전이이 질문의 끝에 있습니다.)
다음 단계에서는 터널 장치를 네임 스페이스로 제한하는 스크립트를 작성하는 중입니다. 나는 시도했다 :
다음과 같이 네임 스페이스에 터널 장치를 직접 넣습니다.
# ip netns add tns0 # ip link set dev tun0 netns tns0 # ip netns exec tns0 ( ... commands to bring up tun0 as usual ... )
이러한 명령은 성공적으로 실행되지만 네임 스페이스 내에서 생성 된 트래픽 (예
ip netns exec tns0 traceroute -n 8.8.8.8
:)은 블랙홀에 빠집니다." 여전히 가상 이더넷 (veth) 인터페이스를 네트워크 네임 스페이스에만 할당 할 수 있다"는 가정하에 ( 사실, 가장 엄청나게 불필요한 API 제한으로 올해의 상을 받음) veth pair와 bridge를 만들고 이름 공간에 veth 쌍의 한쪽 끝을 넣습니다. 이것은 심지어 바닥에 교통량이 떨어지지 않는 한도 : 터널에 다리를 놓을 수는 없습니다! [편집 : 탭 장치 만 브리지에 연결할 수 있기 때문 입니다. 임의의 장치를 네트워크 네임 스페이스에 넣을 수없는 것과 달리 실제로는 이것이 의미가 있습니다. 브리지는 이더넷 계층 개념입니다. 불행히도 내 VPN 제공 업체는 탭 모드에서 OpenVPN을 지원하지 않으므로 해결 방법이 필요합니다.]
# ip addr add dev tun0 local 0.0.0.0/0 scope link # ip link set tun0 up # ip link add name teo0 type veth peer name tei0 # ip link set teo0 up # brctl addbr tbr0 # brctl addif tbr0 teo0 # brctl addif tbr0 tun0 can't add tun0 to bridge tbr0: Invalid argument
이 질문의 끝에서 스크립트는 veth 접근을위한 것입니다. 직접 접근을위한 스크립트는 편집 히스토리에서 찾을 수 있습니다. 변수를 먼저 설정하지 않고 사용되는 것으로 보이는 스크립트의 변수는 openvpn
프로그램에 의해 환경에서 설정됩니다. 그렇습니다.
이 작업을 수행하는 방법에 대한 구체적인 조언을 제공하십시오. 나는 여기에화물 숭배에 의해 프로그래밍하고있어 것을 고통스럽게 알고 있어요 - 한 사람 이 물건에 대한 포괄적 인 문서를 작성? 찾을 수 없으므로 스크립트에 대한 일반적인 코드 검토도 감사합니다.
중요한 경우 :
# uname -srvm
Linux 3.14.5-x86_64-linode42 #1 SMP Thu Jun 5 15:22:13 EDT 2014 x86_64
# openvpn --version | head -1
OpenVPN 2.3.2 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Mar 17 2014
# ip -V
ip utility, iproute2-ss140804
# brctl --version
bridge-utils, 1.5
커널은 내 가상 호스팅 제공 업체 (에 의해 만들어진 Linode )와, 컴파일하지만 CONFIG_MODULES=y
, 실제 모듈이 없습니다 - 만 CONFIG_*
에 변수 설정 m
에 따라 /proc/config.gz
되었다 CONFIG_XEN_TMEM
, 나는 실제로하지 않는 이 해당 모듈을 (커널이 내 파일 시스템 외부에 저장되며, /lib/modules
비어 있고 /proc/modules
어떻게 든 마술처럼로드되지 않았 음을 나타냅니다. /proc/config.gz
요청시 제공에서 발췌 했지만 전체 내용을 여기에 붙여 넣고 싶지 않습니다.
netns-up.sh
#! /bin/sh
mask2cidr () {
local nbits dec
nbits=0
for dec in $(echo $1 | sed 's/\./ /g') ; do
case "$dec" in
(255) nbits=$(($nbits + 8)) ;;
(254) nbits=$(($nbits + 7)) ;;
(252) nbits=$(($nbits + 6)) ;;
(248) nbits=$(($nbits + 5)) ;;
(240) nbits=$(($nbits + 4)) ;;
(224) nbits=$(($nbits + 3)) ;;
(192) nbits=$(($nbits + 2)) ;;
(128) nbits=$(($nbits + 1)) ;;
(0) ;;
(*) echo "Error: $dec is not a valid netmask component" >&2
exit 1
;;
esac
done
echo "$nbits"
}
mask2network () {
local host mask h m result
host="$1."
mask="$2."
result=""
while [ -n "$host" ]; do
h="${host%%.*}"
m="${mask%%.*}"
host="${host#*.}"
mask="${mask#*.}"
result="$result.$(($h & $m))"
done
echo "${result#.}"
}
maybe_config_dns () {
local n option servers
n=1
servers=""
while [ $n -lt 100 ]; do
eval option="\$foreign_option_$n"
[ -n "$option" ] || break
case "$option" in
(*DNS*)
set -- $option
servers="$servers
nameserver $3"
;;
(*) ;;
esac
n=$(($n + 1))
done
if [ -n "$servers" ]; then
cat > /etc/netns/$tun_netns/resolv.conf <<EOF
# name servers for $tun_netns
$servers
EOF
fi
}
config_inside_netns () {
local ifconfig_cidr ifconfig_network
ifconfig_cidr=$(mask2cidr $ifconfig_netmask)
ifconfig_network=$(mask2network $ifconfig_local $ifconfig_netmask)
ip link set dev lo up
ip addr add dev $tun_vethI \
local $ifconfig_local/$ifconfig_cidr \
broadcast $ifconfig_broadcast \
scope link
ip route add default via $route_vpn_gateway dev $tun_vethI
ip link set dev $tun_vethI mtu $tun_mtu up
}
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
set -ex
# For no good reason, we can't just put the tunnel device in the
# subsidiary namespace; we have to create a "virtual Ethernet"
# device pair, put one of its ends in the subsidiary namespace,
# and put the other end in a "bridge" with the tunnel device.
tun_tundv=$dev
tun_netns=tns${dev#tun}
tun_bridg=tbr${dev#tun}
tun_vethI=tei${dev#tun}
tun_vethO=teo${dev#tun}
case "$tun_netns" in
(tns[0-9] | tns[0-9][0-9] | tns[0-9][0-9][0-9]) ;;
(*) exit 1;;
esac
if [ $# -eq 1 ] && [ $1 = "INSIDE_NETNS" ]; then
[ $(ip netns identify $$) = $tun_netns ] || exit 1
config_inside_netns
else
trap "rm -rf /etc/netns/$tun_netns ||:
ip netns del $tun_netns ||:
ip link del $tun_vethO ||:
ip link set $tun_tundv down ||:
brctl delbr $tun_bridg ||:
" 0
mkdir /etc/netns/$tun_netns
maybe_config_dns
ip addr add dev $tun_tundv local 0.0.0.0/0 scope link
ip link set $tun_tundv mtu $tun_mtu up
ip link add name $tun_vethO type veth peer name $tun_vethI
ip link set $tun_vethO mtu $tun_mtu up
brctl addbr $tun_bridg
brctl setfd $tun_bridg 0
#brctl sethello $tun_bridg 0
brctl stp $tun_bridg off
brctl addif $tun_bridg $tun_vethO
brctl addif $tun_bridg $tun_tundv
ip link set $tun_bridg up
ip netns add $tun_netns
ip link set dev $tun_vethI netns $tun_netns
ip netns exec $tun_netns $0 INSIDE_NETNS
trap "" 0
fi
netns-down.sh
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
set -ex
tun_netns=tns${dev#tun}
tun_bridg=tbr${dev#tun}
case "$tun_netns" in
(tns[0-9] | tns[0-9][0-9] | tns[0-9][0-9][0-9]) ;;
(*) exit 1;;
esac
[ -d /etc/netns/$tun_netns ] || exit 1
pids=$(ip netns pids $tun_netns)
if [ -n "$pids" ]; then
kill $pids
sleep 5
pids=$(ip netns pids $tun_netns)
if [ -n "$pids" ]; then
kill -9 $pids
fi
fi
# this automatically cleans up the the routes and the veth device pair
ip netns delete "$tun_netns"
rm -rf /etc/netns/$tun_netns
# the bridge and the tunnel device must be torn down separately
ip link set $dev down
brctl delbr $tun_bridg
destination.ovpn
client
auth-user-pass
ping 5
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
verb 3
route-metric 1
proto tcp
ping-exit 90
remote [REDACTED]
<ca>
[REDACTED]
</ca>
<cert>
[REDACTED]
</cert>
<key>
[REDACTED]
</key>
grep veth /proc/modules
는 아무것도 나열하지 않지만 그것이 결정적인지 모르겠습니다. Linode 인스턴스에는 OS 파티션 내에 커널이 설치되어 있지 않으므로 누락 된 모듈을로드 할 수 있는지 잘 모르겠습니다.
lsmod
전혀 출력을 생성? 디렉토리가 /lib/modules
있습니까?
lsmod: command not found
. 이 /lib/modules
있지만 모듈 이 없으며 빈 modules.dep
파일이 들어있는 커널 당 디렉토리 만 있습니다. Linode 관련 도움말을 살펴보고 그것이 어떻게되어 있는지 알아 보겠습니다.