概要
普通は気にしないような、nmcliコマンドの挙動を調べてみたので共有します。重箱の隅をつつくような内容なので、面白半分で読んでください。
結論
- nmcli connectionコマンドでIPアドレスを設定したときは、ip address showで本当に変わっているか確認しましょう。 (IPアドレスが変えられない)
- IPアドレスが変わらないときは、余談 その4を試すと確実ですが、オススメしません。connectionの恩恵が受けられないからです。
- connectionはネットワークの設定をコロコロ変えたいときに使うと便利です。 (余談 その2)
問題提起
nmcliコマンドは、
nmcli {general | connection | device} [COMMAND] [ARGUMENTS...]
(man NMCLI(1)より)
のような構文で実行します。
例えば、
nmcli connection modify eth0 ipv4.address 192.168.0.2
で、eth0インターフェースのIPアドレスを192.168.0.2
にすることができます。
というのが、よくある解説ですが、僕は、この解説では説明がつかない状況に出くわしました。あの解説は半分正解で半分間違いだったのです!!
回りくどくなるので、結論から先に書くと、間違っている(or 誤解を招く)のは、**"eth0インターフェースに対して操作をしているのではない"**という点です。
deviceとconnection
ここで、eth0インターフェースとは、
ip address show
# 1: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc pfifo_fast state UP group default qlen 1000
# inet 192.168.0.2/32 brd 192.168.0.255 scope global eth0
# valid_lft forever preferred_lft forever
で出てくるeth0のことを指しています。
実は、nmcli connection ...
で使ったeth0
はこれとは別物なのです。このことをはっきりさせるために、次のコマンドを実行してみます。
nmcli connection show
# NAME UUID TYPE DEVICE
# eth0 bc532b37-088f-3de8-a642-840c85dfd04b 802-3-ethernet eth0
このように表示されると思いますが、ここでNAMEとなっているものがnmcli connection ...
で指定したeth0で、DEVICEとなっているのがip address show
で指定したeth0です。実際、
nmcli connection down eth0
nmcli connection modify eth0 connection.id eth1
nmcli connection up eth1
とすると、
nmcli connection show
# NAME UUID TYPE DEVICE
# eth1 bc553237-088f-3de8-a532-811f7535ea4b 802-3-ethernet eth0
上のようにNAMEが変わります。一方、DEVICEはそのままです。また、eth0のまま先のコマンドを実行すると、
nmcli connection modify eth0 ipv4.address 192.168.0.2
# Error: unknown connection 'eth0'.
と怒られます。
このように、nmcliコマンドにおいてはeth0が二つの物を指しています。ip address show
で出てくるものをdevice、nmcli connection ...
で使うものをconnectionと呼び、区別します。
IPアドレスが変えられない
では、伏線の回収をしていきましょう。さきほど、僕が困った状況に陥ったと書きましたが、これはまさにdeviceとconnectionの微妙な関係によるものでした。
ある日、出来立てほやほやなサーバーのIPアドレスを固定しようと思い、
nmcli connection down eth0
nmcli connection modify eth0 ipv4.method manual
nmcli connection modify eth0 ipv4.address 192.168.0.2
nmcli connection up eth0
service network-manager restart # いらないかも
を実行しました。しかし、この変更がなぜかip address show
に反映されませんでした。理由を調べるために、
nmcli connection show eth0 # eth0 connectionの詳細を見る
を実行すると、
...
ipv4.addresses: 192.168.0.2/32
...
IP4.ADDRESS[1]: 192.168.0.5/32 # 変更前のIP
...
という表示が得られました。なぜか変更前のIPアドレスが表示に残っています。そのIPに対応しているIP4.ADDRESS[1]
とは一体何やねん!?
色々調べまくった結果、nmcli connection show
の表示のうち、大文字のものは、どうやらdeviceに設定されている値のようだとわかりました。
また、上の状態でip address show
に表示されるのは192.168.0.5(device)だけなので、ip address show
に表示されるのはdeviceの設定のみだと分かります。また、192.168.0.2(connectionのみ)にはpingが通らなかったので、実際の通信に使われる設定はdeviceに反映されたものだけだと分かります。
さらに、変更前のIPはdeviceに設定されており、deviceの設定はconnectionの設定で上書きできないということも推測できます(要検証)。
deviceを設定する
ここで注意しないといけないのは、deviceの設定はconnectionの設定でできないわけではなく、単に上書きができないだけということです。
たとえば、DNSの設定を見てみます。IPアドレスを固定したあとやりたいことはDNSの設定ですよね。
まずは、DNSがdeviceに設定されていないことを確認します。deviceの設定の確認は、
nmcli device show eth0
で出来ます。結果の中にIP4.DNS[n]:
のような項目がないことを確認してください。
DNSは、
nmcli connection down eth0
nmcli connection modify eth0 ipv4.ignore-auto-dns yes # dhcpを無視
nmcli connection modify eth0 ipv4.dns 8.8.8.8
nmcli connection up eth0
で設定します。コマンドを実行すると、
nmcli device show eth0
の結果の中にIP4.DNS[1]: 8.8.8.8
という項目が現れるはずです。つまり、connectionの設定によって、deviceの設定が更新されたのです。
複数のconnection
nmcliコマンドでは、自分でconnectionを新たに作ることができます。例えば、
nmcli connection add con-name hoge ifname eth0 type ethernet
で、eth0 deviceに接続されたhogeという名前(connection.id)のconnectionが作られます。
この話を聞いて気になるのは、一つのdeviceに複数のconnectionが接続されたらどうなるのか、ですよね。試してみます。
まず、今のconnectionの状況を確認します。それは、前も出てきた
nmcli connection show
で出来ます。結果は、
NAME UUID TYPE DEVICE
eth0 bc556437-088f-3348-a832-813045dfd04b 802-3-ethernet eth0
hoge 2aca727a-5325-4bdf-bffb-4f1413e89ce6 802-3-ethernet --
となりました。どうやらhoge connectionは有効でないようです。では、有効化して見ましょう。
nmcli connection up hoge
もう一度connectionの状況を確認してみると、
NAME UUID TYPE DEVICE
eth0 bc556437-088f-3348-a832-813045dfd04b 802-3-ethernet --
hoge 2aca727a-5325-4bdf-bffb-4f1413e89ce6 802-3-ethernet eth0
となりました。次はeth0が有効でなくなりました。どうやら、一つのdeviceに対しては一つのconnectionしか有効化出来ないみたいです。
余談
その1
特定の状況では、デフォルトのconnection名がWired connection 1
などのイケてない名前になります。そんなときは、次のコマンドで訂正しましょう。
nmcli connection modify "Wired connection 1" connection.id eth0
覚えていないかもしれませんが、説明の中で名前(connection.id)
という書き方をしたのは、このconnection.id
にまつわる設定変更への伏線でした。
その2
connectionというのは、設定の集まりであって、物理的な何かを指すものではなさそう。
NetworkManager stores all network configuration as "connections", which are collections of data (Layer2 details, IP addressing, etc.) that describe how to create or connect to a network.
(man NMCLI(1) より)
複数のconnectionを一つのdeviceに紐づけるメリットは、以下の引用を参考にしてください。
Consider a machine which is usually connected to a DHCP-enabled network, but sometimes connected to a testing network which uses static IP addressing. Instead of manually reconfiguring eth0 each time the network is changed, the settings can be saved as two connections which both apply to eth0, one for DHCP (called default) and one with the static addressing details (called testing). When connected to the DHCP-enabled network the user would run nmcli con up default , and when connected to the static network the user would run nmcli con up testing.
(man NMCLI(1)より)
要約すると、connectionってネットワークの設定の集まりでしょ。だから、あらかじめ通常用とテスト用で二つのconnectionを作っとけば、テストしたいときはテスト用の、戻したければ通常用のconnectionを付けるだけでネットワークの設定を済ませることができるから便利だよね、という感じです。
その3
最後の説明ではconnectionの作り方だけを説明しましたが、削除の仕方を説明しませんでした。connectionを作るだけ作ってみたけど、処分に困っているそこのあなた!朗報です。これから説明します。
nmcli connection delete hoge
これだけです。ここで終わっても良いのですが、もう少しだけお付き合いください。
hogeというconnectionが複数あって、一方だけ消したい。もう片方を消してしまうとサービスもろともネットから消えてしまう。そんな憂鬱な気分のあなた!朗報です。片方だけ消せます。
まずは、各connectionに付けられたUUID(Universally Unique ID)を確認します。
nmcli connection show
# NAME UUID TYPE DEVICE
# hoge xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 802-3-ethernet eth0
# hoge yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy 802-3-ethernet --
このように表示されたとしましょう。ここで、UUIDがyyy...yyyのconnectionを消したいときは、
nmcli connection delete yyy...yyy
とすればいいだけです。実は、前にも出てきたUUIDはこんな風に使えるのです。
その4
で、結局deviceにIPアドレスが設定されている場合はどないしたらええねん!?という疑問に答えるのを忘れてました。
nmcli device modify eth0 ipv4.address 192.168.0.2
とすればOKです。
<お わ り>