一部のアプリケーションがOpenVPNを介してインターネットにアクセスしたいと考えています。この質問/スレッドの下部の最終回答/コメントで解決策を見つけました。 特定のネットワーク名前空間に対してOpenVPNを介してのみすべてのトラフィックを提供します。
私はその記事を引用していますが、私が経験している問題は一番下に記載されています。
名前空間内でOpenVPNリンクを開始し、名前空間内で対応するOpenVPNリンクを使用する各コマンドを実行できます。これを行う方法(私の仕事ではない)の詳細は次のとおりです。
http://www.naju.se/articles/openvpn-netns.html
試してみましたが効果がありました。 (グローバルネームスペースではなく)特定のネームスペース内でOpenVPN接続の開始およびルーティングステップを実行するカスタムスクリプトを提供することがアイデアでした。後でオフラインになる場合に備えて、上記のリンクを引用します。
First create an --up script for OpenVPN. This script will create the VPN tunnel interface inside a network namespace called vpn, instead of the default namespace.
$ cat > netns-up << EOF
#!/bin/sh
case $script_type in
up)
ip netns add vpn
ip netns exec vpn ip link set dev lo up
mkdir -p /etc/netns/vpn
echo "nameserver 8.8.8.8" > /etc/netns/vpn/resolv.conf
ip link set dev "$1" up netns vpn mtu "$2"
ip netns exec vpn ip addr add dev "$1" \
"$4/${ifconfig_netmask:-30}" \
${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"}
test -n "$ifconfig_ipv6_local" && \
ip netns exec vpn ip addr add dev "$1" \
"$ifconfig_ipv6_local"/112
;;
route-up)
ip netns exec vpn ip route add default via "$route_vpn_gateway"
test -n "$ifconfig_ipv6_remote" && \
ip netns exec vpn ip route add default via \
"$ifconfig_ipv6_remote"
;;
down)
ip netns delete vpn
;;
esac
次に、OpenVPNを起動し、ifconfigとルーティングを実行するのではなく、--upスクリプトを使用するように指示します。
openvpn --ifconfig-noexec --route-noexec --up netns-up --route-up netns-up --down netns-up
これで、トンネリングしたいプログラムを次のように起動できます。
ip netns exec vpn command
唯一の問題は、ip netns execを呼び出すにはrootでなければならず、アプリケーションがrootとして実行されたくない場合があることです。解決策は簡単です。
sudo ip netns exec vpn sudo -u $(whoami) command
私の質問:
netns-upスクリプトを呼び出すopenvpnコマンドを実行しようとすると、次の2つのエラーが発生します。
:/etc/openvpn$ sudo openvpn --ifconfig-noexec --route-noexec --up netns-up --route-up netns-up --down netns-up --config za1.nordvpn.com.tcp443.ovpn
(..)
Tue Mar 22 00:10:56 2016 [vpn-za.nordvpn.com] Peer Connection Initiated with [AF_INET]154.127.61.142:443
Tue Mar 22 00:10:59 2016 SENT CONTROL [vpn-za.nordvpn.com]: 'PUSH_REQUEST' (status=1)
Tue Mar 22 00:10:59 2016 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,dhcp-option DNS 78.46.223.24,dhcp-option DNS 162.242.211.137,route 10.7.7.1,topology net30,ping 5,ping-restart 30,ifconfig 10.7.7.102 10.7.7.101'
Tue Mar 22 00:10:59 2016 OPTIONS IMPORT: timers and/or timeouts modified
Tue Mar 22 00:10:59 2016 OPTIONS IMPORT: --ifconfig/up options modified
Tue Mar 22 00:10:59 2016 OPTIONS IMPORT: route options modified
Tue Mar 22 00:10:59 2016 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
Tue Mar 22 00:10:59 2016 ROUTE_GATEWAY 192.168.1.254/255.255.255.0 IFACE=eth0 HWADDR=b8:27:eb:39:7e:46
Tue Mar 22 00:10:59 2016 TUN/TAP device tun0 opened
Tue Mar 22 00:10:59 2016 TUN/TAP TX queue length set to 100
Tue Mar 22 00:10:59 2016 netns-up tun0 1500 1592 10.7.7.102 10.7.7.101 init
Tue Mar 22 00:10:59 2016 WARNING: Failed running command (--up/--down): external program exited with error status: 1
Tue Mar 22 00:10:59 2016 Exiting due to fatal error
sudoを使用または使用せずにnetns-upスクリプトを再構築してみましたが、役に立ちませんでした。私は何が間違っていましたか?
ベストアンサー1
ネットワークネームスペース内でopenvpnを起動する方が安全です。次のスクリプト(Schnoukiのフォーク)を使用して名前空間を作成し、ファイアウォール、DNSを設定し、接続をテストし、openvpnを起動し、最後に急流クライアントを起動しました。 TODOをスクリプトに入れたので、必要に応じて調整する必要があります。
#!/bin/sh
# start openvpn tunnel and torrent client inside Linux network namespace
#
# this is a fork of schnouki's script, see original blog post
# https://schnouki.net/posts/2014/12/12/openvpn-for-a-single-application-on-linux/
#
# original script can be found here
# https://gist.github.com/Schnouki/fd171bcb2d8c556e8fdf
# ------------ adjust values below ------------
# network namespace
NS_NAME=myVPN
NS_EXEC="ip netns exec $NS_NAME"
# user for starting the torrent client
REGULAR_USER=heinzwurst
# ---------------------------------------------
# exit on unbound variable
set -u
# exit on error
set -e
set -o pipefail
# trace option
#set -x
if [ $USER != "root" ]; then
echo "This must be run as root."
exit 1
fi
start_vpn() {
echo "Add network interface"
# Create the network namespace
ip netns add $NS_NAME
# Start the loopback interface in the namespace
$NS_EXEC ip addr add 127.0.0.1/8 dev lo
$NS_EXEC ip link set lo up
# Create virtual network interfaces that will let OpenVPN (in the
# namespace) access the real network, and configure the interface in the
# namespace (vpn1) to use the interface out of the namespace (vpn0) as its
# default gateway
ip link add vpn0 type veth peer name vpn1
ip link set vpn0 up
ip link set vpn1 netns $NS_NAME up
ip addr add 10.200.200.1/24 dev vpn0
$NS_EXEC ip addr add 10.200.200.2/24 dev vpn1
$NS_EXEC ip link set dev vpn1 mtu 1492
$NS_EXEC ip route add default via 10.200.200.1 dev vpn1
# Configure the nameserver to use inside the namespace
# TODO use VPN-provided DNS servers in order to prevent leaks
mkdir -p /etc/netns/$NS_NAME
cat >/etc/netns/$NS_NAME/resolv.conf <<EOF || exit 1
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF
# IPv4 NAT, you may need to adjust the interface name prefixes 'eth' 'wlan'
iptables -t nat -A POSTROUTING -o eth+ -m mark --mark 0x29a -j MASQUERADE
iptables -t nat -A POSTROUTING -o wlan+ -m mark --mark 0x29a -j MASQUERADE
iptables -t mangle -A PREROUTING -i vpn0 -j MARK --set-xmark 0x29a/0xffffffff
# TODO create firewall rules for your specific application (torrent)
# or just comment the line below
$NS_EXEC iptables-restore < /etc/iptables/iptables-$NS_NAME.rules
# we should have full network access in the namespace
$NS_EXEC ping -c 3 www.google.com
# start OpenVPN in the namespace
echo "Starting VPN"
cd /etc/openvpn
# TODO create openvpn configuration in /etc/openvpn/$NS_NAME.conf
$NS_EXEC openvpn --config $NS_NAME.conf &
# wait for the tunnel interface to come up
while ! $NS_EXEC ip link show dev tun0 >/dev/null 2>&1 ; do sleep .5 ; done
}
stop_vpn() {
echo "Stopping VPN"
ip netns pids $NS_NAME | xargs -rd'\n' kill
# TODO wait for terminate
# clear NAT
iptables -t nat -D POSTROUTING -o eth+ -m mark --mark 0x29a -j MASQUERADE
iptables -t nat -D POSTROUTING -o wlan+ -m mark --mark 0x29a -j MASQUERADE
iptables -t mangle -D PREROUTING -i vpn0 -j MARK --set-xmark 0x29a/0xffffffff
echo "Delete network interface"
rm -rf /etc/netns/$NS_NAME
ip netns delete $NS_NAME
ip link delete vpn0
}
# stop VPN on exit (even when error occured)
trap stop_vpn EXIT
start_vpn
# TODO start your favorite torrent client
$NS_EXEC sudo -u $REGULAR_USER transmission-gtk