Azure Linux VM に Azure AD 認証を使う SSH ログイン拡張機能を追加して複数ユーザー(利用者)管理を簡単便利にする一例

## 背景と目的

Linux 仮想マシンを複数ユーザー(利用者)で使う場合の最も単純な例は、OS 上の一つのユーザーアカウント(azureuserなど)を複数の利用者が SSH ログインして共同利用する事です。この場合、ホームディレクトリ(/home/azureuser)配下のファイルやディレクトリを利用者個人が管理出来なくなります。また、環境変数も共同利用になり、利用者固有の情報も使用出来なくなります。例えば、git config や az cli など利用者固有の情報を扱いたい場合は、adduser して利用者ごとにホームディレクトリを分けるという選択をします。ところが、利用者が増えるたびに adduser と passwd して利用者に通知するのは煩わしいし、何より利用者が部署移動等によりログイン不要になっても adduser したユーザーアカウントに SSH ログインが出来てしまいます。

そこで今回は、Azure Linux VM に Azure AD 認証を使う SSH ログイン拡張機能を追加して、Azure AD のセキュリティグループにユーザーを追加削除するだけで、その他の煩わしい OS 上の管理操作を一切不要にする一例をご紹介します。

## 前提条件

以下のコマンド例を実行するユーザーの権限は、Azure AD のグローバル管理者で、Azure サブスクリプションの所有者です。それぞれの環境においては、組織やチームの役割分担等で全てのコマンドを実行する権限が無い場合があり、それぞれ適切な権限付与にて実施される事を推奨します。

## 検証用の仮想マシンを作成

```bash:bash
# 環境変数をセットします
region=japaneast
prefix=mnraadssh

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region

# SSH キーペアをファイル名を指定して作成します
ssh-keygen -m PEM -t rsa -b 4096 \
  -f ${prefix}

# 検証用の仮想マシンを作成します（メモリ 1GB 以上の VM でマネージド ID を有効にします）
az vm create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --os-disk-name ${prefix}-vmOSDisk \
  --image CentOS \
  --size Standard_A1_v2 \
  --admin-username azureuser \
  --ssh-key-value ${prefix}.pub \
  --assign-identity \
  --nsg-rule NONE \
  --public-ip-address-dns-name ${prefix} \
  --storage-sku Standard_LRS

# NSG に自分の IP アドレスから SSH 接続出来るようにします
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name Allow-SSH \
  --nsg-name ${prefix}-vmNSG \
  --priority 100 \
  --source-address-prefixes $(curl -s inet-ip.info) \
  --destination-port-ranges 22 \
  --access Allow \
  --protocol Tcp

# 仮想マシンに SSH 接続します
ssh -i ${prefix} azureuser@${prefix}.$region.cloudapp.azure.com

# ホームディレクトリには azureuser しか無いことを確認します
ls /home

# 一旦抜けます
exit
```

## Azure AD に SSH ログイン用グループを作成しユーザーを追加

```bash:bash
# セキュリティグループを作成します
az ad group create \
  --display-name ${prefix}-group \
  --mail-nickname ${prefix}-group

# Azure CLI を実行しているユーザーの ID を取得します
memberid=$(az ad user list \
  --upn $(az account show --query user.name --output tsv) \
  --query [].objectId \
  --output tsv)

# セキュリティグループにユーザーを追加します
az ad group member add \
  --group ${prefix}-group \
  --member-id $memberid
```

## Azure AD 認証を使う SSH ログイン拡張機能を追加

```bash:bash
# AADSSHLoginForLinux 拡張機能をインストールします
az vm extension set \
  --resource-group ${prefix}-rg \
  --vm-name ${prefix}-vm \
  --publisher Microsoft.Azure.ActiveDirectory \
  --name AADSSHLoginForLinux

# 検証用仮想マシンに対して Virtual Machine Administrator Login ロールをセキュリティグループに付与します
az role assignment create \
  --role "Virtual Machine Administrator Login" \
  --assignee $(az ad group show \
  --group ${prefix}-group \
  --query objectId \
  --output tsv) \
  --scope $(az vm show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --query id \
  --output tsv)
```

## Azure AD 認証を使う SSH ログインを試す

```bash:bash
# Azure CLI に SSH 拡張機能をインストールします
az extension add --name ssh

# Azure CLI の認証済みユーザーで SSH ログインします
az ssh vm \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm

# カレントディレクトリを確認します
pwd

# ホームディレクトリをを確認します
ls /home

# 一旦抜けます
exit
```

## セキュリティグループからユーザーを削除して SSH ログイン出来なくなる事を確認

```bash:bash
# セキュリティグループからユーザーを削除します
az ad group member remove \
  --group ${prefix}-group \
  --member-id $memberid

# Azure CLI の認証済みユーザーで SSH ログインします
az ssh vm \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm
```

下記のようなメッセージが表示されて SSH ログイン出来なくなりました。

```bash:bash
OpenSSH_8.6p1, LibreSSL 3.3.5
Connection closed by 20.210.241.135 port 22
```

## ホームディレクトリがどうなったかを確認

```bash:bash
# 仮想マシン作成時のユーザーで SSH 接続します
ssh -i ${prefix} azureuser@${prefix}.$region.cloudapp.azure.com

# ホームディレクトリには二つディレクトリがあります
ls /home

# OS から抜けます
exit
```

## 参考

```bash:bash
# リソースグループを削除します
az group delete \
  --name ${prefix}-rg \
  --yes

# 作成した SSH キーペアを削除します
rm -f ${prefix}*
```

<https://docs.microsoft.com/ja-jp/azure/active-directory/devices/howto-vm-sign-in-azure-ad-linux>