Debian/NetworkInterfaceName

ネットワークインターフェース(イーサネット)の名前付け

Linux では、ネットワークインターフェース(イーサネット)は認識順に「eth0」「eth1」… という順番に名前が付くことになっている。Debian では、通常はこのイーサネットデバイス名 に対して IP アドレスを割り当てることになる。

※udev によって事情が大きく変わった。MAC アドレスに対してイーサネットデバイス名を 固定することが簡単にできるようになった。

udev を使った解決法

etch 以降はデフォルトで udev を使うようになっているので、udev で解決する。 udev を入れたときには逆に「ネットワークカードひとつしかないのに、eth1 になってしまう」とか 「eth9 とかものすごく大きな数字になってしまう」などの問題が新たに発生しているかも。 ほとんどが、udev の設定によるものと考えられる。

etch のインストーラは、デバイスを発見した順に udev の設定に記述するようになっている。 システムに ieee1394 が付いている場合、eth1394 を先に発見するため、ほとんど使われる ことがない(であろう)ethernet over ieee1394 が eth0 として認識していると思う。

↓認識の例

% ifconfig -a
eth0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-02-00-00-00-00-00-00-00-00
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
eth1      Link encap:Ethernet  HWaddr 00:00:00:00:00:01
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3154480 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4932886 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:682071000 (650.4 MiB)  TX bytes:6029763441 (5.6 GiB)
          Interrupt:19 Base address:0xa000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:7750644 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7750644 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:718668553 (685.3 MiB)  TX bytes:718668553 (685.3 MiB)

通常の用途では問題ないだろうが、なんだか気持ち悪いので、やはり eth0 をメインで使いたい。

udev の設定は、/etc/udev/rules.d 以下にある。インストーラが自動で書いてくれる、ネットワーク 関連設定のファイルは、/etc/udev/rules.d/z25_persistent-net.rules となる。

↓ /etc/udev/rules.d/z25_persistent-net.rules の例

# This file was automatically generated by the /lib/udev/write_net_rules
# program, probably run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single line.
# MAC addresses must be written in lowercase.

# Firewire device 0011d8000106ef37 (ohci1394)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:00:00:00:00:00:00:02", NAME="eth0"

# PCI device 0x10ec:0x8168 (r8169)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:00:00:00:00:01", NAME="eth1"

この設定で、MAC アドレスとイーサネットデバイス名を固定しているので、ここの NAME= を いじってやればよい。

# This file was automatically generated by the /lib/udev/write_net_rules
# program, probably run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single line.
# MAC addresses must be written in lowercase.

# Firewire device 0011d8000106ef37 (ohci1394)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:00:00:00:00:00:00:02", NAME="eth1"

# PCI device 0x10ec:0x8168 (r8169)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:00:00:00:00:01", NAME="eth0"

これで再起動すれば、ファイルに書いたようになっているはず。 /etc/network/interfaces のイーサネットデバイス名の変更を忘れるとネットワーク がつながらなくなるので注意。

以下は古い解説なので、無視するように

問題点

ハードウエアの認識順にデバイス名が振られるので、特定のカードに特定の デバイス名を割り当てたい場合は、チップの種類の異なるカードを用意し、 認識させたい順番でドライバを組み込んでいけばよい。しかし、同一チップ の場合(たとえば内蔵 NIC など)はそうはいかない。ドライバを組み込んだ ときのハードの認識順は、おそらく割り込みの順番等だろうが(このあたりは よく知らない)、プラグアンドプレイ等によって毎回異なる可能性がある。 とくに、ハード構成が変化したとき(デバイスの追加等)は要注意である。 某社のサーバ(e1000 が二つついている)に e1000 の追加カードをつけたところ、 内蔵が eth0 と eth2 で拡張カードの方が eth1 になるというよくわからない 認識の仕方だった。

この問題に関する根本的な解決策はないようだ。 特定の MAC アドレスに対して特定のインターフェース名を割り当てることが とりあえずの解決になる。

interfaces(5) を見てみると、/etc/network/interfaces のオプションで hwaddress で MAC アドレスを指定できることがわかった。しかし、この指定がどういった意味を なすのかがわからない。とりあえず書いてはみたものの、変化はなかった。

ifrename ユーティリティ

まず始めに考えたのが、ifrename を使う方法である。 ifrename は wireless-tools のコマンドで、eth* として認識するデバイスを wlan* 等に変えることができる。しかし、実際にトライしてみたところ、 eth0 eth1 eth2 として認識されているデバイスの順番を変えることはできなかった。 すでに使われているデバイス名にはできないようだ。

nameif コマンド

wireless-tools に頼らなくとも、net-tools パッケージに nameif というコマンドが あった。しかしこれも同様に、認識されているデバイスの順番を変えるという動作は できなかった。理由も同じ。

RedHat? での解決法

RedHat? は、MAC アドレスとインターフェース名を関連づけている。 どうやっているかを見てみたところ、/etc/sysconfig/network-scripts/network-functions 内で、以下のようにしていた。

# rename_device() - Rename a network device to something else
# $1 - desired name
# $2 - hardware address to name
# $3 - list of devices that are already in use
#      (for general calls, use the current device you're trying to
#       change to $1)

rename_device()
{
    /sbin/nameif "$1" "$2" || {
      local hw2=`get_hwaddr ${1}`
      local nconfig=`fgrep -il "HWADDR=$hw2" /etc/sysconfig/network-scripts/ifcf
g-*`
      local dev=
      if [ -n "$nconfig"  ]; then
         dev=$(. $nconfig ; echo $DEVICE)
         for device in $3 ; do
            [ "$dev" = "$device" ] && unset dev
         done
      fi 
      [ -z "$dev" ] && dev=dev$RANDOM
      rename_device $dev $hw2 "$3 $1"
      /sbin/nameif "$1" "$2"
    }
}

再帰でわかりにくいかもしれないが、変更しようとしている先のデバイス名が使われていたら、 それを別の(ランダム)に変更してから、望みの名前に変更している。debian にはこの仕組みはない。

Debian での解決法

しかし、interfaces(5) や /usr/share/doc/ifupdown/examples/network-interfaces.gz を 見ていると、以下のような興味深い記述がある。

# Two ethernet interfaces, one connected to a trusted LAN, the other to
# the untrusted Internet, identified by MAC address rather than interface
# name:
#
# auto eth0 eth1
# mapping eth0 eth1
#     script /path/to/get-mac-address.sh
#     map 11:22:33:44:55:66 lan
#     map AA:BB:CC:DD:EE:FF internet
# iface lan inet static
#     address 192.168.42.1
#     netmask 255.255.255.0
#     pre-up /usr/local/sbin/enable-masq $IFACE
# iface internet inet dhcp
#     pre-up /usr/local/sbin/firewall $IFACE

この仕組みを使えば、MAC アドレスとインターフェース名の対応付けはできないけれど、 MAC アドレスと IP アドレスの対応付けはできる。get-mac-address.sh は /usr/share/doc/ifupdown/examples/get-mac-address.sh にある。トライしてみたところ、 きちんと特定の MAC アドレスのインターフェースに IP アドレスをつけることができた。

しかし、これには問題がある。たとえば、heartbeat では設定ファイルにインターフェース 名を書くようになっている。IP アドレスが変わらなくてもインターフェース名が変わって しまったら、このようなソフトはただしく動かなくなってしまう。解決策としては、 起動時に IP アドレスに対するインターフェース名を見つけて、設定ファイルを置換 する、ということが考えられる。

結論

Debian の仕組みはかっこいい(インターフェース名ではなく、機能に対して IP アドレスを 振るという感じ?)が、ネットワークインターフェース名が重要(設定に書くとか)となる ソフトとの相性が悪い。RedHat? 方式の方が現実にはよくマッチしているので、この方式 での実装を行った方がよい。