はじめに
社内に閉じた比較的小規模な開発用途で、仮想マシンを作っては壊すような(それこそインターンシップのような)ケースでは、監査を意識した管理は正直面倒です。
しかし、ふとしたことから「使っているOSやKernelのバージョンはいくつなのか、入っているbashは古くないか、opensshは更新されているか...などを全数チェックせよ」なんてイベントが起きたら、運が悪かったと思って調べることになります。
今回は、払い出す仮想マシンに監査エージェント(salt-minion)を起動時にインストールするようにして、自動的に管理対象にしてみようという話です。
なお、salt-master/salt-minionの設定は紹介程度になりますので、実際に運用する際はユースケースに合わせて詳細を調査しましょう。
なんか他にもあるでしょ?という声も聞こえてきそうですが、今回はSaltを使うんです。そう決めたんです。
ZabbixやNagios...(会社の方を見ながら)...とかHinemos、もしくはPrometheusとかDatadogとかCloudWatchとか、そういうのは今回無しです。
今回使うモノの紹介
- Proxmox VE 7.x: 仮想マシンの管理プラットフォーム
- Salt: ITインフラストラクチャの自動化と構成管理を行うためのオープンソースのソフトウェア
- 公式Doc: https://saltproject.io
- Github: https://github.com/saltstack/salt
- salt-master: 管理サーバーのこと。今回は手動で構築します。
- salt-minion: 各ホストに導入するエージェントのこと。cloud-initで自動インストールします。
大体以下のようなイメージです。
+---------------+---------------+
| VM | VM |
| - salt-master | - salt-minion |
+-------------------------------+
| Proxmox VE |
+-------------------------------+
サンプル用salt-masterの準備
適当なUbuntu 20.04なマシンを準備して、salt-masterをインストールします。
salt-minionが情報を集めてくる、中央の管理サーバーとなります。
sudo mkdir /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/salt-archive-keyring.gpg https://repo.saltproject.io/salt/py3/ubuntu/20.04/amd64/latest/salt-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/salt-archive-keyring.gpg arch=amd64] https://repo.saltproject.io/salt/py3/ubuntu/20.04/amd64/latest focal main" | sudo tee /etc/apt/sources.list.d/salt.list
sudo apt-get update
sudo apt-get install salt-master -y
salt-minionを自動的に登録するため、以下の設定を追加してsalt-masterを再起動します。
echo "auto_accept: True" | sudo tee /etc/salt/master.d/auto_accept.conf
sudo systemctl restart salt-master
上記の設定をしない場合は、以下のように未登録のsalt-minionをsalt-masterで逐一登録する必要があります。
$ sudo salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
salt-master.example.com
Rejected Keys:
$ sudo salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
salt-master.example.com
Proceed? [n/Y] Y
Key for minion salt-master.example.com accepted.
$ sudo salt-key -L
Accepted Keys:
salt-master.example.com
Denied Keys:
Unaccepted Keys:
Rejected Keys:
Proxmox VE上にsalt-minionをインストールするcloud-initファイルを準備する
Proxmox VEは元々仮想マシンの一部設定(ユーザー名(ciuser)、IPアドレス(ifconfig0)など)にcloud-initを使用していますが、その書式はProxmox VE固有のものです。
そこで、Proxmox VEでは独自に作成したcloud-initファイルを cicustom
というオプションで追加することができるようになっています。
まずは、cloud-initで仮想マシンの初回起動時にsalt-minionをインストールし、先ほど作ったsalt-masterに登録されるようにcloud-initファイルを作成します。
cloud-initファイルの置き場所として snippets
が使える必要があるので、無い場合は設定します。今回は local
ストレージに設定しました。
# pvesm set local --content snippets,iso,backup,vztmpl
# pvesm status --content snippets
Name Type Status Total Used Available %
local dir active 98497780 7460732 85987500 7.57%
# cat <<__EOL__ > /var/lib/vz/snippets/ci_salt-minion_ubuntu2204.yml
#cloud-config
salt_minion:
conf:
logging: info
master: 192.168.0.37
__EOL__
192.168.0.37
は先ほど作ったsalt-masterのIPアドレスです。
現在API経由でsnippetsにファイルを格納することは出来ないため、管理者があらかじめProxmox VE上に準備しておく必要があります。
(Proxmox VEはDebianベースで作られているので方法自体はあるかと思いますが、Proxmox VEはその方法をAPIとして提供していない、という意味です)
salt_minion:
にどのような設定が可能なのかは https://cloudinit.readthedocs.io/en/latest/reference/modules.html#salt-minion を参照してください。
Ubuntu 22.04の場合はデフォルトのaptで導入できるので、上記のような記述になりますが、デフォルトのリポジトリでインストール出来ない場合は、リポジトリ登録用の設定も合わせて必要となります。
以下はRHEL9にsalt-3005を導入する場合のcloud-initファイル記述例です。
yum_repos:
salt-3005-repo:
# cloud-init get url: baseurl + /repodata/repomd.xml
baseurl: https://repo.saltproject.io/salt/py3/redhat/9/x86_64/3005
enabled: true
failovermethod: priority
gpgcheck: true
gpgkey: https://repo.saltproject.io/salt/py3/redhat/9/x86_64/3005/SALTSTACK-GPG-KEY2.pub
name: Salt Packages for RHEL/CentOS 9
Proxmox VEで仮想マシンに追加のcloud-initを設定する
それでは、Ubuntu 22.04の仮想マシンに、上記のcloud-initファイルを追加します。
テンプレートは 以前作ったもの を流用して、クローンして作っていきます。(vCPU/Memory/Disk sizeは適当に)
qm clone 9100 1002 --name salt-sample01
qm set 1002 --cores 2 --memory 1024
qm resize 1002 virtio0 20G
qm set 1002 --ipconfig0 ip=192.168.0.12/24,gw=192.168.0.1
qm set 1002 --ciuser sample01 --sshkeys sample01_ed25519.pub
### --cicustom でcloud-initファイルを追加する。今のところ `vendor=...` という形式で記述することに決まっています。
qm set 1002 c vendor=local:snippets/ci_salt-minion_ubuntu2204.yml
qm start 1002
今回は以前作った設定を流用したので、クローンした後の仮想マシンにcloud-initファイルを追加していますが、同じ設定の仮想マシンを作るようであればVM Templateの方に --cicustom
の設定を追加するのが良いと思います。
さて、起動したらsalt-minionが自動的にインストールされて、salt-masterに登録されるはずです。
どうなっているか確認してみましょう。
salt-minionの登録確認
仮想マシンが起動して、少し経つとsalt-masterに自動的に登録されました。
$ sudo salt-key -L
Accepted Keys:
salt-master.example.com
salt-sample01.example.com
Denied Keys:
Unaccepted Keys:
Rejected Keys:
これで、仮想マシンを作っては壊すようなケースでも、自動的に管理対象にしてくれそうです。
salt-masterでsalt-minionの情報を取得する
それでは、唐突に「使っているOSやKernelのバージョンはいくつなのか、入っているbashは古くないか、opensshは更新されているか...」などを聞かれた場合に対応できそうか、確認してみましょう。
試しに使ってみるのはこの辺りのモジュールです。
- 基本情報は salt.modules.grains
- パッケージ周りは salt.modules.pkg
- コマンド実行は salt.modules.cmdmod
ここで紹介するモジュールはほんの一部ですので、他にも必要そうなモジュールがあるかどうかは https://docs.saltproject.io/en/latest/ref/modules/ を探してみてください。
OSのバージョン取得(salt.modules.grains)
Windows/Linuxの違いなどで値の表現が異なりますが、例えば今回準備したLinuxの場合は、以下のように出力されます。
$ sudo salt '*' grains.get os
salt-sample01.example.com:
Ubuntu
salt-master.example.com:
Ubuntu
$ sudo salt '*' grains.get osrelease
salt-sample01.example.com:
22.04
salt-master.example.com:
20.04
今回の手順では準備していませんが、Windowsの場合だと以下のような値が入っています。
os:
Windows
os_family:
Windows
osfinger:
Windows-10
osfullname:
Microsoft Windows 10 Pro
osmanufacturer:
Microsoft Corporation
osrelease:
10
osrelease_info:
- 10
osservicepack:
None
osversion:
10.0.19044
salt.modules.grains
は他にもIPアドレスやCPUモデルなども取得することが可能です。
もし、何を取得するか決まっていない場合は sudo salt '*' grains.items
を実行することで salt.modules.grains
で取得可能な情報が全て出力されます。
OSのバージョン取得(salt.modules.pkg)
次に、パッケージを取得してみます。
これもインストールパッケージの管理方法によって出力パターンは異なるのですが、今回準備した環境では以下のように表示されます。
bashのバージョンを取得した場合:
$ sudo salt '*' pkg.version bash
salt-master.example.com:
5.0-6ubuntu1.2
salt-sample01.example.com:
5.1-6ubuntu1
絞らずに全件を取得する場合は sudo salt '*' pkg.list_pkgs
を実行します。
また、今回の手順では準備していませんが、Windowsの場合の取得例は以下の通りです。
$ sudo salt "WIN-XXX" pkg.version "Google Chrome"
WIN-XXX:
111.0.5563.64
$ sudo salt "WIN-XXX" pkg.version "Slack"
WIN-XXX:
4.29.149
Windowsの場合は一部のパッケージが Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.17
みたいな名前で登録されてしまうので、何も考えずに全件取得しておいた方が簡単な気がします。
(パッケージ名にバージョン入っちゃってるから...)
コマンド実行(salt.modules.cmdmod)
最後の例はコマンド実行です。
salt-master から salt-minion に対して、任意のコマンドを実行することが可能です。
$ sudo salt '*' cmd.run 'uname -a'
salt-sample01.example.com:
Linux salt-sample01 5.15.0-67-generic #74-Ubuntu SMP Wed Feb 22 14:14:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
salt-master.example.com:
Linux salt-master 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
コマンド実行の制限
とはいえ、いくら払い出された環境であっても、管理者が自由にコマンド実行できるというのは心理的な抵抗があるユーザーも多くいると思います。
あくまでOSやパッケージのバージョンを取得する目的でインストールされているものとして、外部から受け付けるコマンドの制限をsalt-minionの設定に追加するのが良いのではないでしょうか。
cmd_whitelist_glob: ["uname -a"]
cmd_whitelist_glob は、一致したコマンド以外の salt または salt-call コマンド実行を拒否します。
上記例の設定を追加した場合は、以下のように uname -a
だけが実行可能になります。
$ sudo salt '*' cmd.run 'uname -a'
salt-sample01.example.com:
Linux salt-sample01 5.15.0-67-generic #74-Ubuntu SMP Wed Feb 22 14:14:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
salt-master.example.com:
Linux salt-master 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
$ sudo salt '*' cmd.run 'uname'
salt-sample01.example.com:
ERROR: The shell command "uname" is not permitted
salt-master.example.com:
Linux
ERROR: Minions returned with non-zero exit code
なお、全てのコマンドを拒否するつもりで以下のように空のリストを渡すと、全て許可という意味になってしまうのでご注意ください。
cmd_whitelist_glob: []
全てのコマンドを拒否したい場合は [""]
としましょう。
salt-minionの登録削除
仮想マシンが削除された場合、登録済みのsalt-minionはsalt-masterに残り続け、コマンド実行してもエラーが返ってきてしまいます。
$ sudo salt '*' pkg.version bash
salt-master.example.com:
5.0-6ubuntu1.2
salt-sample01.example.com:
Minion did not return. [Not connected]
不要になった場合は、ダウンしているノードを登録から削除する salt-run manage.down removekeys=True
を実行することで、salt-masterの管理対象から外せます。
$ sudo salt-run manage.down removekeys=True
- salt-sample01.example.com
$ sudo salt-key -L
Accepted Keys:
salt-master.example.com
Denied Keys:
Unaccepted Keys:
Rejected Keys:
おしまい
今回はcloud-initでsalt-minionをインストールすることで、Proxmox VEの仮想マシンを自動的に管理対象に追加する方法について書いてみました。
Saltを使った方法が良い方法なのかというと、少し大げさというか、それにしては穴だらけと言うか、微妙なところだと思いますが、実現したいことに対するサンプルとしては分かりやすいかなと思います。
今のところ、Proxmox VEに独自のcloud-initファイルを直接設置できるのは管理者だけなので、OpenStackでcloud-initを使用するのとはまた違った使用感になりますが、ある程度利用方法が決まっているような環境では十分活用できるのではないかと思います。