CentOS 8(7以降)のネットワーク周りの設定について

CenOS6でネットワーク周りの設定を行うには、当然のように /etc/sysconfig/network-scripts/* をいじっていましたが、CentOS7以降はNetwork Managerのコマンドを利用することが推奨されているようです。
いろいろググったり、Redhatのサイトで公開されているドキュメントを読み、なんとなくでコマンドを操作をしていたものをある程度理解できるようになってきました。

その備忘録として未来の自分のために残しておくエントリです。

ネットワーク周りの設定は究極的にいえば、素人的な使い方をしている限り、nmcli コマンドだけで十分かな、と思います。ホスト名もIPアドレスの設定も全部nmcliコマンドを叩けば殆どのケースでOKです。
あ、firewall関連は別ですけどね。firewall関連も firewall-cmd に集約され、バックエンドがiptablesであろうがnftablesだろうが設定方法自体(インターフェイス)は統一されている。
今後こういうフロントエンドとバックエンドを別々にしてフロントエンドは固定し、バックエンドをどんどん改良していく、というのが今風なんだろうな、と思います。

それはさておき。

大前提として、NetworkManagerをデフォルトで有効になっている環境です。そもそもNetworkManagerをsystemctlでenableにしていない環境は想定していません。
あしからず。ご了承のほど。

NetworkManagerの説明はRedHatのドキュメントを読め進めれば他にググって怪しげな情報に振り回される必要はありません。現に僕は思いっきり振り回された側の人間です💦

CentOSは RedHat Enterprise Linux のクローンなので大部分のドキュメントはCentOSにも当てはまるはずです。

第4章 NETWORKMANAGER によるネットワーク管理の開始

最初ネットで情報を探していろいろ試してみましたが、書いていることがバラバラで全く要領がつかめず、頭の中が???状態でコマンドだけコピペしてきました。
その中で一番わからなくなったのは、nmcli コマンドでよく出てくる、インターフェイス名、デバイス名と接続名の関係が一体どいうことなのか全く理解できていませんでした。
ほとんどの記事でインターフェイス名と接続名を一緒にしているので全く???だったんです。

が、上記RedHatサイトの説明を読むと明快に説明されておりました。やっぱり公式のドキュメントをまず読むべきでした。

そして、nmcliコマンドで指定する device と connection の関係をまず理解することがはじめの第一歩です。
deviceは文字通りデバイス、ネットワークインターフェイスを指す。そしてconnectionは、このdeviceに適用するプロファイルのようなもの、と僕は理解した。
そして特定のdeviceに適切に設定されたプロファイルを適用することで通信ができるようになります。

基本的には一つのネットワークインターフェイス(通常はNICとかWiFiとか)に対して、複数のプロファイルを作り、その時々の環境によってプロファイルを切り替えてネットワークインターフェイスに適用する、という形になっているようです。

このプロファイルの名前こそ、接続名(connection.id)であり、con-nameというのは connection.id の別名であり、正式には connection.idというプロパティ、そしてconnection.idというプロパティ名を使うのが推奨されている、らしいです。

(追記:接続名とかいうとワケワカンネーし僕は混乱するので、接続名(con-name/connection.id)のことをプロファイル名と呼ぶようにしています。このエントリでも接続名の事をプロファイル名と書くようにしました。あしからず。)

ググると、LAN I/Fの設定のコマンドは以下のようになっていることが多いです。

# nmcli c add type ethernet con-name eth0 ifname eth0 

これは非常に分かりにくい、と思います。まず eth0 が2回も出てきてますが、この二つは全く別物です。分かっている人は分かるけど、NetworkManager自体よく知らない人が見てもこの2つのeth0が別物である、なんて知りようがありませんし、大抵の記事ではこの辺の説明がサラッと流されていることが多いです。(eth0のところはens01とかNICの命名規則によります)

あえてこれを正しく書き直すと、

# nmcli connection add connection.type ethernet connection.id eth0 connection.interface-name eth0

ここでこの二つのeth0が何を示すのか? を説明されている記事がほとんどなく、ググって検索下位の方に出てくる記事を辿るとやっと出てくる程度です。こんなの分かってて当然なんでしょうね・・・。
connection.type(別名 type)は、ethernetとかwifiとかvpnとかadslとかの文字通りの意味。ethernetやwifiもまた別名なんですけど、これは上記ドキュメントを参照。
connection.interface-name(別名 ifname)は、下記コマンドで確認できるDEVICE名のこと。

# nmcli device
DEVICE  TYPE      STATE     CONNECTION
eth0    ethernet  接続済み  xxxxxxx
lo      loopback  管理無し  --

ここで CONNECTIONを xxxxxx で伏字にしたのはワケがあります。大抵の記事ではこのCONNECTION名を DEVICE名と同じものにしていることが多いです。
コレ、たぶんOSインストール時に自動設定された情報なんでしょうね。おそらく。だけど、これが結局僕が理解する上で邪魔だった。なまじDEVICE名とCONNECTION名が同じになっているのでワケワカンネー状態に陥った原因だと思う。xxxxxxxは自分で任意の名前をつけるべきところです。
CONNECTION名は、上で何度も言ってきた プロファイル名と同じです。NetworkMangerではプロファイルを複数用意できる。
理由は、環境が変わる毎に設定ファイルをいじるのではなく、環境ごとに複数のプロファイルを用意しておき、その都度DEVICE(インターフェイス)に適切なプロファイルを適用することでラクしよう、ということだと思います。バックアップファイルをパカパカ作るより効率的ですし。
(まぁ、最終的には /etc/sysconfig/network-scripts/ 以下のファイル、その他が書き換わるんですけどね。。。精通しているパワーユーザーにとっては昔ながらのファイル修正とかの方がいいのかも?)

これが一番効率的だなと思うのは、無線LAN(wifi)を利用するときだと思います。無線接続時、接続ポイントによってSSIDとかパスワードとか暗号化方法とか、そういった無線LANの接続ポイント毎にプロファイルを用意しておくと、あとは nmcli コマンドで切り替えるだけで済むようになりますよねぇ。

そしてそのプロファイルは、connection.id(別名con-name)で指定するプロパティ、これは自分で勝手に名前をつけるべきもの。デフォルトでDEVICE名が使われています。分かっている人は別にいいんですけどね。。。僕は分かんなかったです。。。。

僕は HyperVでCentOS8を稼働していますが、この接続(プロファイル)の一覧を表示すると・・・

# nmcli connection
NAME      UUID                                  TYPE      DEVICE
external  fdfa3402-1a88-4e49-8877-ee44480fd405  ethernet  eth0
internal  c541d202-e756-4680-af82-fe9343de6b8c  ethernet  --

と、二つのプロファイルを用意しておいて、ケースに応じて切り替えて使ってます。
上記では externalが eth0 に適用されています。

internalプロファイルをeth0に適用するには、

# nmcli connection up internal connection.interface-name eth0
もしくは省略形を使うと・・・
# nmcli c up internal ifname eth0

と、するだけで再起動してもinternalが適用されます。いちいち down する必要もない。ただし、一つのデバイスに適用できるのは当然だけど一つのプロファイルだけ。
複数のデバイスがある場合で、プロファイルをスワップしたいときも nmcli connection up コマンドを二つ叩けば済みますしね。

nmcliで殆どのネットワーク設定が可能なので、複数のプロファイルを作ってDEVICEに適用する、というのは、以前のような/etc/sysconfig/network-scripts/*の各ファイルをいちいち編集するより非常に効率的な方法だと思います。

たとえば、違うdnsを切り替えたいとき、dnsの設定だけ違う別プロファイルを作っておき、nmcli connection up コマンドで切り替える。
たとえば、インターフェイスのゾーンを切り替えたいときもfirewall-cmdでもいいですけど、nmcliで切り替えたほうがカンタンなような気もします。

まぁ、素人考えですけどね。

プロファイルの各プロパティの値を変更するには・・・(めんどくさいので省略表記を利用します connection ⇒ c , modify ⇒ mod 等)

# nmcli c mod プロファイル名 プロパティー名 値

というように修正していく。具体的なプロパティー名は、show サブコマンドで確認できる。たとえば僕のテスト環境だと・・・

# nmcli c show external
connection.id:                          external
connection.uuid:                        fdfa3402-1a88-4e49-8877-ee44480fd405
connection.stable-id:                   --
connection.type:                        802-3-ethernet
connection.interface-name:              eth0
connection.autoconnect:                 はい
connection.autoconnect-priority:        0
connection.autoconnect-retries:         -1 (default)
connection.multi-connect:               0 (default)
connection.auth-retries:                -1
connection.timestamp:                   1584863103
connection.read-only:                   いいえ
connection.permissions:                 --
connection.zone:                        trusted
connection.master:                      --
connection.slave-type:                  --
connection.autoconnect-slaves:          -1 (default)
connection.secondaries:                 --
connection.gateway-ping-timeout:        0
connection.metered:                     不明
connection.lldp:                        default
connection.mdns:                        -1 (default)
connection.llmnr:                       -1 (default)
connection.wait-device-timeout:         -1
802-3-ethernet.port:                    --
802-3-ethernet.speed:                   0
802-3-ethernet.duplex:                  --
802-3-ethernet.auto-negotiate:          いいえ
802-3-ethernet.mac-address:             --
802-3-ethernet.cloned-mac-address:      --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-blacklist:   --
802-3-ethernet.mtu:                     自動
802-3-ethernet.s390-subchannels:        --
802-3-ethernet.s390-nettype:            --
802-3-ethernet.s390-options:            --
802-3-ethernet.wake-on-lan:             default
802-3-ethernet.wake-on-lan-password:    --
ipv4.method:                            manual
ipv4.dns:                               8.8.8.8,8.8.4.4
ipv4.dns-search:                        --
ipv4.dns-options:                       --
ipv4.dns-priority:                      0
ipv4.addresses:                         10.0.0.153/24
ipv4.gateway:                           10.0.0.1
ipv4.routes:                            --
ipv4.route-metric:                      -1
ipv4.route-table:                       0 (unspec)
ipv4.routing-rules:                     --
ipv4.ignore-auto-routes:                いいえ
ipv4.ignore-auto-dns:                   いいえ
ipv4.dhcp-client-id:                    --
ipv4.dhcp-timeout:                      0 (default)
ipv4.dhcp-send-hostname:                はい
ipv4.dhcp-hostname:                     --
ipv4.dhcp-fqdn:                         --
ipv4.never-default:                     いいえ
ipv4.may-fail:                          いいえ
ipv4.dad-timeout:                       -1 (default)
ipv6.method:                            ignore
ipv6.dns:                               --
ipv6.dns-search:                        --
ipv6.dns-options:                       --
ipv6.dns-priority:                      0
ipv6.addresses:                         --
ipv6.gateway:                           --
ipv6.routes:                            --
ipv6.route-metric:                      -1
ipv6.route-table:                       0 (unspec)
ipv6.routing-rules:                     --
ipv6.ignore-auto-routes:                いいえ
ipv6.ignore-auto-dns:                   いいえ
ipv6.never-default:                     いいえ
ipv6.may-fail:                          はい
ipv6.ip6-privacy:                       -1 (unknown)
ipv6.addr-gen-mode:                     stable-privacy
ipv6.dhcp-duid:                         --
ipv6.dhcp-send-hostname:                はい
ipv6.dhcp-hostname:                     --
ipv6.token:                             --
proxy.method:                           none
proxy.browser-only:                     いいえ
proxy.pac-url:                          --
proxy.pac-script:                       --
GENERAL.NAME:                           external
GENERAL.UUID:                           fdfa3402-1a88-4e49-8877-ee44480fd405
GENERAL.DEVICES:                        eth0
GENERAL.STATE:                          アクティベート済み
GENERAL.DEFAULT:                        はい
GENERAL.DEFAULT6:                       いいえ
GENERAL.SPEC-OBJECT:                    --
GENERAL.VPN:                            いいえ
GENERAL.DBUS-PATH:                      /org/freedesktop/NetworkManager/ActiveConnection/2
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/Settings/1
GENERAL.ZONE:                           trusted
GENERAL.MASTER-PATH:                    --
IP4.ADDRESS[1]:                         10.0.0.153/24
IP4.GATEWAY:                            10.0.0.1
IP4.ROUTE[1]:                           dst = 10.0.0.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 0.0.0.0/0, nh = 10.0.0.1, mt = 100
IP4.DNS[1]:                             8.8.8.8
IP4.DNS[2]:                             8.8.4.4

ってな感じになります。

externalプロファイルのdnsを変更するには・・・

# nmcli c mod external ipv4.dns 1.1.1.1
# nmcli c up external
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/3)
# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 1.1.1.1

upサブコマンドでexternal を up すると、即座に/etc/resolveが更新されていることが確認できます。
ほとんどの場合 プロパティーを変更してup すると更新されるみたい。

dnsを一時的に変更したい、というようなときは上記のようにプロファイルを修正すればいいけど、それにともなって gatewayも変更したい、ゾーンも変更したい・・・とかいう場合はプロファイルを修正するのではなく、新しいプロファイルを別につくってそれをdeviceに適用した方が断然効率的です。
その場合、既存のプロファイルをコピーするとラクかな、と思います。上記の例でexternal をコピーしてexternal2 としてそのプロファイルを修正していきます。

# nmcli c clone external external2
# nmcli c mod external2 connection.zone public ipv4.dns "8.8.8.8 8.8.4.4"
# nmcli c up external2
# nmcli d
DEVICE  TYPE      STATE     CONNECTION
eth0    ethernet  接続済み  external2
lo      loopback  管理無し  --

仮想マシンを違うPCから持ってきてインポートしたとき、大概ネットワーク関連を再設定するはめになるんですが、その都度ネットで調べて・・・という風にしてたんですが、NetworkManagerの仕組みをおおよそ理解することで、仮想マシンの引っ越しが躓かずにできるようになった。