Fedora CoreOSのインストール練習 4 〜ネットワーク設定〜
前回までに引き続きFedora CoreOSで、ネットワークの設定をしてみる。
今回は、2個のネットワークインタフェースを持ち、1個目がDHCPでアドレスを取ってきてホスト名をcoreos
に設定し、2個目は静的にIPアドレスを設定する構成にする。
Fedora CoreOSでインストール時にネットワークを設定するには、NetworkManagerのkeyfileを手動で配置してやる必要があるので、そのようなIgnition configを作成する。
まずはButaneファイルを書く。
Network Manager keyfileの書式はGnome公式ドキュメントを参照。
なお今回はコンソールでログインするようにpassword_hashを設定した。
variant: fcos version: 1.3.0 passwd: users: - name: core password_hash: (mkpasswdで出力したハッシュ) storage: files: - path: /etc/NetworkManager/system-connections/enp1s0.nmconnection mode: 0600 contents: inline: | [connection] id=enp1s0 type=ethernet interface-name=enp1s0 [ipv4] method=auto dhcp-hostname=coreos - path: /etc/NetworkManager/system-connections/enp2s0.nmconnection mode: 0600 contents: inline: | [connection] id=enp2s0 type=ethernet interface-name=enp2s0 [ipv4] address1=192.168.152.2/24 method=manual
次に、Butane configをIgnition configに変換する。
$ docker run -i --rm quay.io/coreos/butane:release < netconfig.bu > netconfig.ign
そして、ネットワークインタフェースを2個指定してVMを作成してインストールする。
$ virt-install --connect qemu:///system --name coreos --vcpus 1 --memory 2048 --os-variant fedora31 --import --graphics=none --disk path=coreos.img,size=10,backing_store=$PWD/fedora-coreos-34.20210518.3.0-qemu.x86_64.qcow2 --network network=default --network network=private --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/netconfig.ign"
インストールが終わったら、ログインして設定を確認する。
[core@coreos ~]$ nmcli con show NAME UUID TYPE DEVICE enp1s0 360d1330-11cf-3a91-ae05-590058fc3e82 ethernet enp1s0 enp2s0 08862f9c-09fb-396b-ba92-ff582dfe1839 ethernet enp2s0 [core@coreos ~]$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:44:6a:cb brd ff:ff:ff:ff:ff:ff inet 192.168.122.159/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0 valid_lft 3224sec preferred_lft 3224sec inet6 fe80::1ce2:98a4:a6fa:2965/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:40:bd:8e brd ff:ff:ff:ff:ff:ff inet 192.168.152.2/24 brd 192.168.152.255 scope global noprefixroute enp2s0 valid_lft forever preferred_lft forever inet6 fe80::767:ae67:5c75:d25a/64 scope link noprefixroute valid_lft forever preferred_lft forever
enp2s0
に指定したIPアドレスが設定されており、コマンドプロンプトからホスト名がcoreos
に設定されていることがわかる。
Ignitionを使ってFedora CoreOSのネットワークが設定できた!
Fedora CoreOSのインストール練習 3 〜CDからのスタンドアロンインストール〜
前回の続き。
今回は、ISOイメージをカスタマイズして、スタンドアロンインストールを試してみる。
まずは、docker上でcoreos-installerを使ってisoイメージをダウンロードする。
$ docker run --rm -v $PWD:/data -w /data quay.io/coreos/coreos-installer:release download -s stable -p metal -f iso
次に、Live CDを構成するためのButane config liveiso.bu
を準備する。
インストール先用のIgnition configをLive CDシステム上に配置し、
coreos-installerのドキュメントを参考に、coreos-installerを自動実行するsystemdサービスを定義する。
variant: fcos version: 1.3.0 storage: files: - path: /var/tmp/simple.ign contents: local: simple.ign systemd: units: - name: install.service enabled: true contents: | [Unit] Description=Run CoreOS Installer Requires=coreos-installer-pre.target After=coreos-installer-pre.target OnFailure=emergency.target OnFailureJobMode=replace-irreversibly [Service] Type=oneshot ExecStart=/usr/bin/coreos-installer install --ignition-file /var/tmp/simple.ign /dev/vda ExecStart=/usr/bin/systemctl --no-block reboot StandardOutput=kmsg+console StandardError=kmsg+console [Install] RequiredBy=default.target
そして、Ignition config liveiso.ign
に変換する。
$ docker run -i -v $PWD:/data --rm quay.io/coreos/butane:release --files-dir /data < liveiso.bu > liveiso.ign
準備したliveiso.ign
をLive CDのISOイメージに追加する。
ここでは、ダウンロードしたisoファイルをコピーして書き込んでいる。
$ cp fedora-coreos-34.20210518.3.0-live.x86_64.iso fedora-coreos-34.20210518.3.0-live-mod.x86_64.iso $ docker run -i --rm -v $PWD:/data -w /data quay.io/coreos/coreos-installer:release iso ignition embed fedora-coreos-34.20210518.3.0-live-mod.x86_64.iso < liveiso.ign
今回はKVMにインストールするので、コンソールがシリアルに表示されるように、Live CDのkernel引数も変更しておく。
$ docker run --rm -v $PWD:/data -w /data quay.io/coreos/coreos-installer:release iso kargs modify fedora-coreos-34.20210518.3.0-live-mod.x86_64.iso --append "console=ttyS0,115200n8"
出来上がったISOイメージを使ってKVMにインストールする。
$ virt-install --name coreos --vcpus 1 --memory 2048 --os-variant fedora31 --cdrom fedora-coreos-34.20210518.3.0-live-mod.x86_64.iso --disk path=coreos.img,size=10 --network network=default --graphics none --console pty,target_type=serial
無事インストールが完了。
Ignitionファイルを格納したISOイメージを作って、スタンドアロンでインストールできた!
Fedora CoreOSのインストール練習 2 〜自動アップデートの設定〜
前回の続き。
現在のFedora CoreOSでは、Zincatiを使って自動アップデートするように設定されていて、そのデフォルト設定では、アップデートの準備が出来ると自動でリブートするようになっている。
そこで、特定の曜日・時間にだけリブートするように設定してみる。
公式ドキュメントを参考にして、Zincatiの設定ファイルの内容を決める。
今回は、土日の朝4時〜6時の間だけリブートするように設定してみる。
[updates] strategy = "periodic" [updates.periodic] time_zone = "Asia/Tokyo" [[updates.periodic.window]] days = [ "Sat", "Sun" ] start_time = "4:00" length_minutes = 120
まず、strategy
に periodic
を選ぶ。
time_zone
を日本に設定して、days
に曜日 Sat
, Sun
を指定し、リブート可能区間 (window) を 4:00
から 120
分に設定している。
この設定ファイルを /etc/zincati/config.d/
の下に適当なファイル名で置けば良い。
Fedora CoreOSなので、Ignitionで配置するようにする。
Butan configを前回のものに書き足して作る。
variant: fcos version: 1.3.0 passwd: users: - name: core ssh_authorized_keys: - (ssh公開鍵) storage: files: - path: /etc/zincati/config.d/55-updates-strategy.toml contents: inline: | [updates] strategy = "periodic" [[updates.periodic.window]] days = [ "Sat", "Sun" ] start_time = "4:00" length_minutes = 120
前回同様にVMを作成する。
sshでログインして確認してみる。
host$ ssh core@coreos_ip_address coreos$ cat /etc/zincati/config.d/55-updates-strategy.toml [updates] strategy = "periodic" [updates.periodic] time_zone = "Asia/Tokyo" [[updates.periodic.window]] days = [ "Sat", "Sun" ] start_time = "4:00" length_minutes = 120
Zincatiのログでも確認する。
$ sudo journalctl -b 0 -e -u zincati.service | grep strategy Jun 09 08:53:49 localhost zincati[925]: [INFO ] update strategy: periodic, total schedule length 240 minutes; next window at 4:0 on Sat (Asia/Tokyo), subject to time zone caveats.
特定の曜日・時間にだけリブートするようにZincatiが設定できた!
Fedora CoreOSのインストール練習 1
KVM上にFedora CoreOSをインストールしてみる。
公式ドキュメントを参考に作業を進める。
最初に、公式ダウンロードページから、QEMU用のイメージファイルをダウンロードして展開する。
$ curl -O 'https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/34.20210518.3.0/x86_64/fedora-coreos-34.20210518.3.0-qemu.x86_64.qcow2.xz' $ unxz fedora-coreos-34.20210518.3.0-qemu.x86_64.qcow2.xz
次に、公式ドキュメントを参考に、Ignitionファイルを準備する。
まずはButaneのDockerイメージを取得する。
$ docker pull quay.io/coreos/butane:release
次に、YAML形式のButan configファイル simple.bu
を作成する。
ここではユーザcore
を作るだけの設定にする。
variant: fcos version: 1.3.0 passwd: users: - name: core ssh_authorized_keys: - (ssh公開鍵)
ここで(ssh公開鍵)
は実際のSSH公開鍵を入力する。
Butan configファイル simple.bu
からJSON形式のIgnition configファイル simple.ign
に変換する。
$ docker run -i --rm quay.io/coreos/butane:release < simple.bu > simple.ign
出力されたsimple.ign
の中身はこれ。
{"ignition":{"version":"3.2.0"},"passwd":{"users":[{"name":"core","sshAuthorizedKeys":["(ssh公開鍵)"]}]}}
ここまででFedora CoreOSのインストールに必要なものは準備できたが、
Debian系ではAppArmorが有効になっており、そのままvirt-install
すると
can't load /path/to/simple.ign: Failed to open file “/path/to/simple.ign”: Permission denied
といって怒られる。
そこで、libvirtがsimple.ign
ファイルを読めるように、AppArmorの設定を変更する。
$ sudo vi /etc/apparmor.d/libvirt/TEMPLATE.qemu
profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
#include <abstractions/libvirt-qemu>
+ /path/to/simple.ign rk,
}
準備が整ったので、VMを作成する。
手元のホストでは、os-variantでfedora-coreos-stable
が認識してもらえなかったので、fedora31
を指定している。
$ virt-install --name coreos --vcpus 1 --memory 2048 --os-variant fedora31 --import --graphics=none --disk path=coreos.img,size=10,backing_store=$PWD/fedora-coreos-34.20210518.3.0-qemu.x86_64.qcow2 --network network=default --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/simple.ign"
インストールが終了したら、sshで接続してみる。
IPアドレスはインストール時のコンソールの最後の方に次のように表示されている。
enp1s0: 192.168.122.22 fe80::ba1b:5f86:aa42:280f
coreユーザでssh接続できることを確認する。
$ ssh core@192.168.122.22
無事Fedora CoreOSがKVM上にインストールできた!
nftablesでブリッジにフィルタ設定
前回はVMごとにネットワークフィルタを設定したが、共通のフィルタはホスト環境で設定した方が間違いがない。
そこで、ホスト環境のネットワークインタフェースに接続したブリッジに対してnftablesでフィルタを設定してみる。
ここでは、ホスト環境のネットワークインタフェースenp1s0
に接続されたブリッジに対してフィルタを設定する。
まずはnftで手動で設定してみる。
bridge filterテーブルとfowardチェインを(なければ)作る。
# nft add table bridge filter # nft add chain bridge filter forward '{type filter hook forward priority filter; policy accept; }'
次にルールを設定する。
ここでは、VMから x.y.z.0/24 への通信を禁止してみる。
# nft add rule bridge filter ct state established,related accept # nft add rule bridge filter oif "enp1s0" ip daddr x.y.z.0/24 counter drop
VM内部からx.y.z.0/24にpingを打っても返ってこない。 なお、先に x.y.z.0/24 のどこかにpingを打って返ってくることを確認してある。
nftでも確認する。
# nft list ruleset bridge table bridge filter { chain forward { type filter hook forward priority filter; policy accept; ct state established,related accept oif "enp1s0" ip daddr x.y.z.0/24 counter packets 3 bytes 252 drop } }
確かにdropルールに引っ掛かっている。
手動で設定したフィルタを永続化する。
# cat <<EOF >> /etc/nftables.conf table bridge filter { chain forward { type filter hook forward priority filter; policy accept; ct state established,related accept oif "enp1s0" ip daddr x.y.z.0/24 counter drop } }
なお/etc/nftables.conf
はDebian系の場合。
設定を反映する。
# systemctl restart nftables # nft list ruleset bridge table bridge filter { chain forward { type filter hook forward priority filter; policy accept; ct state established,related accept oif "enp1s0" ip daddr x.y.z.0/24 counter packets 0 bytes 0 drop } }
nftablesを使ってホストブリッジにフィルタを設定できた!
KVMのネットワークフィルタ設定
libvirtに備わっているネットワークフィルタ機能 (nwfilter) をVMに適用してみる。
libvirtの公式ドキュメントを参考に作業を進める。
nwfilterは(バックエンドがnftablesであっても)iptablesを使ってフィルタリングを行うので、まずはnwfilter未設定時のiptables設定を確認する。
# iptables -nvL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 161 14807 LIBVIRT_INP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 LIBVIRT_FWX all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 LIBVIRT_FWI all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 LIBVIRT_FWO all -- * * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 122 11453 LIBVIRT_OUT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain LIBVIRT_FWI (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED 0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain LIBVIRT_FWO (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0 0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain LIBVIRT_FWX (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 Chain LIBVIRT_INP (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67 Chain LIBVIRT_OUT (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68 0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:68
既にlibvirtによってDNSやDHCPを通すフィルタリングなどが設定されている。
まずはフィルタtest-filter
を定義する。
ここではホスト環境のIPアドレス192.168.122.1
へのsshをブロックするルールを書いてみる。
ルールの詳細は公式ドキュメントを参考にする。
$ virsh nwfilter-define <(cat <<EOF <filter name='test-filter'> <rule action='drop' direction='out'> <tcp dstipaddr='192.168.122.1' dstportstart='22'/> </rule> </filter> EOF ) $ virsh nwfilter-dumpxml test-filter <filter name='test-filter' chain='root'> <uuid>49978302-912f-45b2-8298-af957757177e</uuid> <rule action='drop' direction='out' priority='500'> <tcp dstipaddr='192.168.122.1' dstportstart='22'/> </rule> </filter>
いま定義したフィルタtest-filter
をVM kvmdom
に設定する。
$ virsh edit kvmdom
<interface type='network'>
<mac address='52:54:00:fa:68:d9'/>
<source network='default'/>
<model type='virtio'/>
+ <filterref filter='test-filter'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
Domain kvmdom XML configuration edited.
VM kvmdom
を起動する。
$ virsh start kvmdom
iptables設定を確認してみる。
# iptables -nvL
追加された部分
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 21 2032 libvirt-host-in all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 libvirt-in all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 libvirt-out all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 libvirt-in-post all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FI-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 0.0.0.0/0 192.168.122.1 tcp dpt:22 Chain FO-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 192.168.122.1 0.0.0.0/0 tcp spt:22 Chain HI-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 0.0.0.0/0 192.168.122.1 tcp dpt:22 Chain libvirt-host-in (1 references) pkts bytes target prot opt in out source destination 2 656 HI-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet2 Chain libvirt-in (1 references) pkts bytes target prot opt in out source destination 0 0 FI-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet2 Chain libvirt-in-post (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vnet2 Chain libvirt-out (1 references) pkts bytes target prot opt in out source destination 0 0 FO-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-out vnet2 --physdev-is-bridged
先ほど定義したルールはChain FI-vnet2
, FO-vnet2
, HI-vnet2
に定義されている。
実際にVM kvmdom
から192.168.122.1
にsshしてみても接続できない。
KVMのデフォルトネットワークをブリッジへ変更
KVMのデフォルトネットワークは通常、ブリッジでプライベートアドレスのサブネットを作ってNATで外部に出ていくものになっているが、これをホスト環境のネットワークインタフェースに直接ブリッジするもの(ホストブリッジ)に変えてみる。
まずは現状の確認。
$ export LIBVIRT_DEFAULT_URI='qemu:///system' $ virsh net-list --all Name State Autostart Persistent ---------------------------------------------- default inactive no yes
デフォルトのネットワークが定義されている。
いったんdefault
ネットワークの定義を削除する。
$ virsh net-undefine default $ virsh net-list --all Name State Autostart Persistent ----------------------------------------
続いて、ブリッジbr0
を使うホストブリッジ用ネットワークを定義する。
ブリッジを作成する方法は各ディストリビューションのドキュメントを参照のこと。
default
ネットワークをXMLを使って定義する。
なお <( ... )
の部分はbashのprocess substitution(プロセス置換)という機能。
$ virsh net-define <(cat <<EOF <network> <name>default</name> <forward mode="bridge"/> <bridge name="br0"/> </network> EOF ) Network default defined from /tmp/br0.xml $ virsh net-list --all Name State Autostart Persistent ---------------------------------------------- default inactive no yes
最後に、default
ネットワークを開始し、自動開始を設定する。
$ virsh net-start default Network default started $ virsh net-autostart default Network default marked as autostarted $ virsh net-list --all Name State Autostart Persistent -------------------------------------------- default active yes yes
KVMのデフォルトネットワークをホストブリッジに変更できた!