
sudoを使用してTapを作成し、ここにユーザースペースプログラム(ssh)をリンクしたいと思います。
複数のユーザーがインターフェイス名を使用しているため、インターフェイス名をハードコードしたくないので、インターフェイス名を動的に生成したいと思います。
だから私は次のように蛇口を作ります。
sudo ip tuntap add mode tap user $USER
sshに渡すために使用できるように生成されたインターフェイスの名前を返すipコマンドを取得するにはどうすればよいですか?
答え1
このtuntap
デバイスのLinuxプログラミングインタフェースはここに文書化されています(サンプルコードを含む)。tuntap.rst。インターフェイス名を要求してから、最初の呼び出しに渡された構造を使用して取得できますioctl(fd, TUNSETIFF, ...)
。ip tuntap
名前は表示されないため、このコマンドだけでは有益ではありません。
これを行う方法は2つあります。
図書館ラッパー
libcラッパーを追加できます。ioctl()
この特定のターゲットの場合は、実行時に使用できますLD_PRELOAD
これにより、元のツールを変更する必要がなくなります。これはその目的のラッパーで、ioctl()
次に印刷されます。標準出力作成したばかりのインターフェイスの名前です。 OPのip tuntap
例を考えると、3回だけ使用されますioctl()
。蛇口ioctl()
すべての用途に常に同じ数のパラメータがあるわけではありませんが、非常に安全なインタフェースです(ここではパラメータを3つとします)。
wraptuntap.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#define ioctl ioctl_diverted
#include <sys/ioctl.h>
#undef ioctl
#include <stdio.h>
int ioctl(int fd, unsigned long request, void *p) {
int ret;
int (*orig_ioctl)(int, unsigned long, void *)=dlsym(RTLD_NEXT,"ioctl");
if ((ret=orig_ioctl(fd, request, p)) != -1 )
if (request == TUNSETIFF)
printf("%s\n",((struct ifreq *)p)->ifr_name);
return ret;
}
コメント:
<sys/ioctl.h>
正しく定義する必要がありますTUNSETIFF
が、同時にそれを行うことはできませんioctl()
。それ以外の場合は、ラッパー定義が競合します。初期定義は次に送信されます。このSO Q / Aメソッド。ifr_name
保証済みカーネル4.13以降、nullが終了しました。そうでなければ…まあ、それは粗末な包装紙です。
たとえば、次のようにコンパイルします。
gcc -shared -fPIC -o /tmp/wraptuntap.so wraptuntap.c -ldl
次に、次のように使用します。
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000
tap0
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000
tap1
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d
foo0
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d
foo1
またはより便利に:
# mytun=$(LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d)
# ip link show dev "$mytun"
11: foo2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether ae:99:4a:2b:1f:6b brd ff:ff:ff:ff:ff:ff
これらのインターフェイスを作成することはそれほど難しくありません。本番用に使用するには、専用のツールを作成するか、そのインターフェイスの名前を表示できる他のツールを使用することをお勧めします。
長老tunctl
(のみ蛇口相互作用):
UMLユーティリティで提供される以前の(したがって一般的には使用されません)tunctl
ツールは、使用されたインターフェイス名を含む文を表示しますが、パターンのみを生成します。蛇口(レイヤ2)インタフェース(OPが探しているもの)の代わりにトゥエン(レイヤ3)インターフェイス。
例:
# tunctl -u 1000 -t foo%d
Set 'foo3' persistent and owned by uid 1000
# tunctl -u 1000 -t foo%d | sed -E "s/^Set '([^']+)' .*\$/\1/"
foo4
# ip -d link show dev foo4 # this is a "type tap" interface
13: foo4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether c2:05:de:78:16:a3 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65521
tun type tap pi off vnet_hdr off persist on user 1000 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536