0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【付録】Microsoft Sentinel の Syslog フォワーダー / Logstash をオンプレミスに置く場合の注意点と設定手順

0
Posted at

Chapter-0

この記事の付録です。
https://qiita.com/koguchi_takao/items/82dda4952fb49a478b37

付録 A. Syslog フォワーダー / Logstash をオンプレミスに置く場合

本編では検証のために Syslog フォワーダーと Logstash を Azure VM 上に置きました。実際の導入では、ログを出す機器の近く(オンプレミスのデータセンターや拠点)にこれらのサーバーを置く構成がよく使われます。この付録では、そのときに 本編から何が変わるのか、何に注意すべきか、具体的にどう設定するか をまとめます。

この付録は本編の「0. 変数の定義」と「3. Logstash 収集環境」で作成したリソース(ワークスペース、DCE、DCR)があることを前提にしています。オンプレミス側のサーバーは Ubuntu 22.04 を例にしています。

A-1. 本編(Azure VM)との違い

項目 Azure VM に置く場合(本編) オンプレミスに置く場合(付録)
Syslog フォワーダーの AMA 導入 DCR を作ると自動で入る 先に Azure Arc に接続 してから DCR を関連付ける
Logstash の認証 VM のマネージド ID アプリ登録(サービス プリンシパル)+ クライアント シークレット
Azure への通信経路 VNet → NAT Gateway 社内ネットワーク → ファイアウォール / プロキシ → インターネット(または専用線)
プロキシ 不要 Arc エージェント、AMA、Logstash プラグインで それぞれ別に設定
秘密情報 不要(マネージド ID) クライアント シークレットを Logstash キーストアで保護、期限管理が必要
送信できないときの退避 意識しなくてよい Logstash は永続キューを有効にしておくと安心

A-2. 注意点

1. 通信はすべて「オンプレミス → Azure」の HTTPS 443 だけ

Azure からオンプレミスへの受信は不要です。ファイアウォールでは、オンプレミスのサーバーから次の宛先への 送信 TCP 443 を許可します(主なもの)。

用途 宛先
Microsoft Entra ID(認証) login.microsoftonline.com、login.windows.net、*.login.microsoft.com、pas.windows.net
Azure Resource Manager management.azure.com
Azure Arc エージェント *.his.arc.azure.com、*.guestconfiguration.azure.com、guestnotificationservice.azure.com、*.guestnotificationservice.azure.com、azgn*.servicebus.windows.net、*.blob.core.windows.net
Arc エージェントの入手 gbl.his.arc.azure.com、download.microsoft.com、packages.microsoft.com
Azure Monitor Agent global.handler.control.monitor.azure.com、japaneast.handler.control.monitor.azure.com、<ワークスペース ID>.ods.opinsights.azure.com
Logstash(Logs Ingestion API) <DCE 名>.japaneast-1.ingest.monitor.azure.com
Logstash とプラグインの入手 artifacts.elastic.co、rubygems.org(オフライン導入する場合は不要)

Azure Monitor Agent の通信先には HTTPS インスペクション(SSL 復号)をかけない でください。公式ドキュメントでも無効化が求められています。正確な宛先一覧は環境によって変わるため、A-3 の azcmagent check と、末尾の参考リンクの公式ドキュメントで必ず確認してください。

2. Syslog フォワーダーは Azure Arc への接続が必須

Azure Monitor Agent(AMA)は Azure のリソースにしか入れられません。オンプレミスのサーバーは Azure Arc 対応サーバー として登録すると Azure 上のリソースとして扱えるようになり、DCR の関連付けと AMA の導入ができます。

3. Logstash はマネージド ID ではなくアプリ登録で認証する

プラグインの README では、マネージド ID は「Azure VM 上で動かす場合」の方式として説明されています。オンプレミスでは アプリ登録(サービス プリンシパル)とクライアント シークレット を使い、DCR に「Monitoring Metrics Publisher」ロールを付与します。シークレットには有効期限があるので、期限切れで取り込みが止まらないよう更新予定を管理してください。

4. プロキシは 3 か所で別々に設定する

社内プロキシを経由する場合、設定は共有されません。

  • Azure Arc エージェント:azcmagent config set proxy.url
  • Azure Monitor Agent:拡張機能の設定(settings の proxy)。Arc エージェントの設定は引き継がれません。
  • Logstash プラグイン:出力設定の proxy(必要に応じて proxy_aad、proxy_endpoint)。この設定はプラグインの新しいバージョン(README では v2.5 系で記載)で追加されたものなので、導入したバージョンの README を確認してください。

5. 止まったときにログを失わない工夫

回線やプロキシの障害で Azure に送れない時間帯があっても、ログを失いにくくしておきます。

  • Logstash:永続キュー(queue.type: persisted)を有効にし、ディスクに退避させる。
  • Syslog フォワーダー:ディスクの空き容量を監視する。受信量が多い場合は、Microsoft の「Azure Monitor Agent Performance Benchmark」を参考にサイズを決め、複数台をロードバランサーの後ろに並べる。

6. 時刻同期とタイムゾーン

TimeGenerated がずれると、分析ルールの検知漏れや調査時の混乱につながります。フォワーダー、Logstash、ログを送る機器のすべてで NTP による時刻同期を有効にしてください。

7. 閉域で接続したい場合

ExpressRoute や VPN で Azure とつながっていて、インターネットを経由させたくない場合は、Azure Monitor Private Link Scope(AMPLS)とプライベート エンドポイントで構成できます。この付録では扱いませんが、その場合は DCE もプライベート側を使う必要があります。

A-3. 手順:オンプレミスの Syslog フォワーダー(Azure Arc + AMA)

A-3-1. 追加の変数とリソース プロバイダーの登録

Cloud Shell で、本編の「0. 変数の定義」を貼り付けたうえで次を実行します。ARC_MACHINE は Azure 上での表示名です(オンプレミスのホスト名にそろえるのがおすすめです)。

Cloud Shell
ARC_MACHINE=onprem-syslog01
SUB_ID=$(az account show --query id -o tsv)
TENANT_ID=$(az account show --query tenantId -o tsv)

az provider register --namespace Microsoft.HybridCompute
az provider register --namespace Microsoft.GuestConfiguration
az provider register --namespace Microsoft.HybridConnectivity
az provider register --namespace Microsoft.AzureArcData
az extension add -n connectedmachine --upgrade --yes

A-3-2. 通信先の確認用リストを作る

自分の環境のワークスペース ID を入れた通信先リストを出力します。ネットワーク担当者への申請にそのまま使えます。

Cloud Shell
WS_ID=$(az monitor log-analytics workspace show -g "$RG" -n "$LAW" --query customerId -o tsv)
cat <<EOF
global.handler.control.monitor.azure.com:443
${LOC}.handler.control.monitor.azure.com:443
${WS_ID}.ods.opinsights.azure.com:443
management.azure.com:443
login.microsoftonline.com:443
gbl.his.arc.azure.com:443
EOF

A-3-3. Arc エージェントのインストール(オンプレミスのサーバー)

プロキシなし の場合:

オンプレミス Syslog フォワーダー
wget -O /tmp/install_linux_azcmagent.sh https://gbl.his.arc.azure.com/azcmagent-linux
sudo bash /tmp/install_linux_azcmagent.sh

プロキシあり の場合(http://proxy.example.local:8080 は自社のプロキシに置き換え):

オンプレミス Syslog フォワーダー
export https_proxy=http://proxy.example.local:8080
wget -O /tmp/install_linux_azcmagent.sh https://gbl.his.arc.azure.com/azcmagent-linux
sudo bash /tmp/install_linux_azcmagent.sh --proxy "http://proxy.example.local:8080"
sudo azcmagent config set proxy.url "http://proxy.example.local:8080"

A-3-4. Azure Arc への接続

Cloud Shell で、オンプレミスのサーバーに貼り付ける接続コマンドを生成します。

Cloud Shell
cat <<EOF

===== ここから下をオンプレミス Syslog フォワーダーに貼り付け =====
sudo azcmagent connect --resource-group "${RG}" --tenant-id "${TENANT_ID}" --subscription-id "${SUB_ID}" --location "${LOC}" --resource-name "${ARC_MACHINE}" --cloud AzureCloud --use-device-code
===== ここまで =====
EOF

罫線の間の行をオンプレミスのサーバーで実行すると、ブラウザーで開く URL とコードが表示されます。作業端末のブラウザーでサインインすると接続が完了します。

接続に使うアカウントには、リソースグループに対する「Azure Connected Machine Onboarding」以上の権限が必要です。複数台をまとめて登録する場合は、サービス プリンシパルを使ったスクリプト登録が便利です(Azure ポータルの Azure Arc > マシン > 追加 から生成できます)。

接続できたかと、必要な通信先に届くかを確認します。

オンプレミス Syslog フォワーダー
sudo azcmagent show
sudo azcmagent check --location japaneast

azcmagent show の Agent Status が Connected になっていれば OK です。

A-3-5. AMA のインストール(プロキシありの場合のみ)

プロキシを使わない場合は、この手順を飛ばして A-3-6 に進んでください(DCR を関連付けると AMA が自動で入ります)。

プロキシを使う場合は、DCR を関連付ける前に、プロキシ設定付きで AMA を入れておきます。

Cloud Shell
az connectedmachine extension create \
  --resource-group "$RG" \
  --machine-name "$ARC_MACHINE" \
  --location "$LOC" \
  --name AzureMonitorLinuxAgent \
  --publisher Microsoft.Azure.Monitor \
  --type AzureMonitorLinuxAgent \
  --enable-auto-upgrade true \
  --settings '{"proxy":{"mode":"application","address":"http://proxy.example.local:8080","auth":"false"}}'

プロキシに認証が必要な場合は、"auth":"true" にしたうえで --protected-settings '{"proxy":{"username":"<ユーザー名>","password":"<パスワード>"}}' を追加します。

A-3-6. DCR にオンプレミスのサーバーを関連付ける

本編で作った Syslog 用 DCR(dcr-syslog-demo)と CEF 用 DCR(dcr-cef-demo)に、Arc サーバーを追加します。

Cloud Shell
ARC_ID=$(az connectedmachine show -g "$RG" -n "$ARC_MACHINE" --query id -o tsv)

for DCR_NAME in dcr-syslog-demo dcr-cef-demo; do
  DCR_RID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_NAME" --query id -o tsv)
  az monitor data-collection rule association create \
    --name "assoc-${ARC_MACHINE}-${DCR_NAME}" \
    --rule-id "$DCR_RID" \
    --resource "$ARC_ID"
done

CEF 用の DCR を作っていない場合、dcr-cef-demo の行はエラーになりますが問題ありません。ポータルで行う場合は、データ コネクタ > Syslog via AMA > コネクタ ページを開く で対象の DCR を編集し、リソース タブでオンプレミスのサーバー(種類が Azure Arc のマシン)を追加します。

数分後、AMA が入ったことを確認します。

Cloud Shell
az connectedmachine extension list -g "$RG" --machine-name "$ARC_MACHINE" --query "[].{name:name, state:provisioningState}" -o table

A-3-7. フォワーダーの構成と OS ファイアウォール

本編の 2-4 と同じスクリプトを、オンプレミスのサーバーで実行します。

オンプレミス Syslog フォワーダー
cd ~
wget -O Forwarder_AMA_installer.py https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/Syslog/Forwarder_AMA_installer.py
sudo python3 Forwarder_AMA_installer.py

OS のファイアウォールが有効な場合は、514 番ポートの受信を許可します。

オンプレミス Syslog フォワーダー(Ubuntu / ufw)
sudo ufw allow 514/tcp
sudo ufw allow 514/udp
オンプレミス Syslog フォワーダー(RHEL 系 / firewalld)
sudo firewall-cmd --permanent --add-port=514/tcp
sudo firewall-cmd --permanent --add-port=514/udp
sudo firewall-cmd --reload

時刻同期ができているかも確認します。System clock synchronized: yes なら OK です。

オンプレミス Syslog フォワーダー
timedatectl status

A-3-8. 機器側の送信先を変更して確認する

ネットワーク機器やセキュリティ製品の Syslog 送信先を、オンプレミスのフォワーダーの IP アドレス(TCP または UDP 514)に変更します。Linux サーバーから試す場合は次のとおりです(192.0.2.10 はフォワーダーの IP に置き換え)。

オンプレミスのログ送信元(テスト用 Linux)
logger -n 192.0.2.10 -P 514 -T -p auth.warning -t sshd "Failed password for invalid user demo from 192.0.2.50 port 50001 ssh2"

数分後、ログ画面で確認します(onprem-syslog01 は自分のホスト名に置き換え)。

KQL
Syslog
| where TimeGenerated > ago(30m)
| where Computer has "onprem-syslog01"
| summarize Count = count() by Computer, Facility, SeverityLevel

A-4. 手順:オンプレミスの Logstash(アプリ登録で認証)

A-4-1. アプリ登録の作成と権限付与

Cloud Shell で、Logstash 用のサービス プリンシパルを作り、DCR に「Monitoring Metrics Publisher」ロールを同時に付与します。シークレットの有効期間は 1 年にしています。

Cloud Shell
DCR_RESOURCE_ID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query id -o tsv)

SP_JSON=$(az ad sp create-for-rbac \
  --name sp-logstash-sentinel-poc \
  --role "Monitoring Metrics Publisher" \
  --scopes "$DCR_RESOURCE_ID" \
  --years 1 -o json)

AZ_CLIENT_ID=$(echo "$SP_JSON" | jq -r .appId)
AZ_CLIENT_SECRET=$(echo "$SP_JSON" | jq -r .password)
AZ_TENANT_ID=$(echo "$SP_JSON" | jq -r .tenant)
echo "client_id: $AZ_CLIENT_ID"

ロールの反映には最大 30 分程度かかることがあります。反映前に送信すると 403 エラーになります。

A-4-2. Logstash と出力プラグインのインストール

インターネットに出られる場合は、本編の 3-1(Logstash のインストール)と 3-2(プラグインのインストール)を オンプレミスの Logstash サーバーで そのまま実行します。プロキシ経由の場合は、先に次を実行してから同じ手順を行います。

オンプレミス Logstash
export http_proxy=http://proxy.example.local:8080
export https_proxy=http://proxy.example.local:8080
echo 'Acquire::http::Proxy "http://proxy.example.local:8080";' | sudo tee /etc/apt/apt.conf.d/95proxy
echo 'Acquire::https::Proxy "http://proxy.example.local:8080";' | sudo tee -a /etc/apt/apt.conf.d/95proxy

プラグインのインストール(logstash-plugin install)は sudo で実行するため、export した変数が引き継がれないことがあります。その場合は sudo -E /usr/share/logstash/bin/logstash-plugin install microsoft-sentinel-log-analytics-logstash-output-plugin のように -E を付けて実行してください。

インターネットに出られない(閉域) 場合は、インターネットに出られる別の Logstash 環境(同じバージョン)でオフライン パックを作り、ファイルを持ち込んでインストールします。

インターネットに出られる Logstash 環境
sudo /usr/share/logstash/bin/logstash-plugin install microsoft-sentinel-log-analytics-logstash-output-plugin
sudo /usr/share/logstash/bin/logstash-plugin prepare-offline-pack --output /tmp/sentinel-plugin.zip microsoft-sentinel-log-analytics-logstash-output-plugin

/tmp/sentinel-plugin.zip をオンプレミスの Logstash サーバーの /tmp にコピーしてから実行します。

オンプレミス Logstash
sudo /usr/share/logstash/bin/logstash-plugin install file:///tmp/sentinel-plugin.zip
sudo /usr/share/logstash/bin/logstash-plugin list --verbose | grep microsoft

A-4-3. 接続情報を渡す(貼り付け用コマンドの生成)

本編の 3-7 と同じ考え方で、Cloud Shell から貼り付け用コマンドを生成します。秘密情報ではない値は環境変数ファイルに入れ、クライアント シークレットだけは次の A-4-4 でキーストアに入れます。

Cloud Shell
DCE_URI=$(az monitor data-collection endpoint show -g "$RG" -n "$DCE" --query logsIngestion.endpoint -o tsv)
DCR_IMMUTABLE_ID=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query immutableId -o tsv)
STREAM_NAME=$(az monitor data-collection rule show -g "$RG" -n "$DCR_LOGSTASH" --query "keys(streamDeclarations)[0]" -o tsv)

cat <<EOF

===== ここから下をオンプレミス Logstash に貼り付け =====
sudo tee /etc/default/logstash > /dev/null <<'EOT'
DCE_URI="${DCE_URI}"
DCR_ID="${DCR_IMMUTABLE_ID}"
STREAM_NAME="${STREAM_NAME}"
AZ_TENANT_ID="${AZ_TENANT_ID}"
AZ_CLIENT_ID="${AZ_CLIENT_ID}"
EOT
sudo chmod 600 /etc/default/logstash
===== ここまで =====

次の手順でキーストアに入力するクライアント シークレット:
${AZ_CLIENT_SECRET}
EOF

罫線の間の行をオンプレミスの Logstash サーバーに貼り付けて実行します。表示されたクライアント シークレットは、次の手順で使ったら画面から消し、どこにも保存しないでください。

Cloud Shell のセッションが切れて AZ_CLIENT_SECRET などが消えた場合は、AZ_CLIENT_ID に client_id を設定してから az ad app credential reset --id "$AZ_CLIENT_ID" --years 1 でシークレットを再発行します。

A-4-4. クライアント シークレットをキーストアに保存

オンプレミス Logstash
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash create

パスワードなしで続けるか聞かれたら y を入力します(キーストアにパスワードを付ける場合は、そのパスワードを /etc/default/logstash に LOGSTASH_KEYSTORE_PASS="..." として追記します)。続けてシークレットを登録します。

オンプレミス Logstash
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add AZ_CLIENT_SECRET

Enter value for AZ_CLIENT_SECRET: と表示されたら、A-4-3 で表示されたシークレットを貼り付けます。最後に、Logstash サービスが読めるよう所有者を変更します。

オンプレミス Logstash
sudo chown logstash:logstash /etc/logstash/logstash.keystore
sudo chmod 600 /etc/logstash/logstash.keystore
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash list

A-4-5. 永続キューの有効化

Azure に送れない間のイベントをディスクに退避させます。4gb は退避に使う最大サイズで、ディスクの空きに合わせて調整してください。

オンプレミス Logstash
sudo tee -a /etc/logstash/logstash.yml > /dev/null <<'EOF'
pipeline.ecs_compatibility: disabled
queue.type: persisted
queue.max_bytes: 4gb
EOF
grep -E 'ecs_compatibility|queue\.' /etc/logstash/logstash.yml

本編の 3-1 で pipeline.ecs_compatibility: disabled を追記済みの場合は、同じ行が 2 回入りますが動作に問題はありません。気になる場合は /etc/logstash/logstash.yml から重複行を削除してください。

A-4-6. 出力設定

プロキシなし の場合:

オンプレミス Logstash
sudo tee /etc/logstash/conf.d/sentinel.conf > /dev/null <<'EOF'
input {
  tcp {
    port  => 5000
    codec => json_lines
  }
}
output {
  microsoft-sentinel-log-analytics-logstash-output-plugin {
    data_collection_endpoint => "${DCE_URI}"
    dcr_id                   => "${DCR_ID}"
    stream_name              => "${STREAM_NAME}"
    tenant_id                => "${AZ_TENANT_ID}"
    client_id                => "${AZ_CLIENT_ID}"
    client_secret            => "${AZ_CLIENT_SECRET}"
  }
}
EOF

プロキシあり の場合(http://proxy.example.local:8080 は自社のプロキシに置き換え):

オンプレミス Logstash
sudo tee /etc/logstash/conf.d/sentinel.conf > /dev/null <<'EOF'
input {
  tcp {
    port  => 5000
    codec => json_lines
  }
}
output {
  microsoft-sentinel-log-analytics-logstash-output-plugin {
    data_collection_endpoint => "${DCE_URI}"
    dcr_id                   => "${DCR_ID}"
    stream_name              => "${STREAM_NAME}"
    tenant_id                => "${AZ_TENANT_ID}"
    client_id                => "${AZ_CLIENT_ID}"
    client_secret            => "${AZ_CLIENT_SECRET}"
    proxy                    => "http://proxy.example.local:8080"
  }
}
EOF

構文をチェックしてから起動します。Configuration OK と表示されれば構文は正しいです。

オンプレミス Logstash
sudo -u logstash bash -c 'set -a; . /etc/default/logstash; /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t'
sudo systemctl enable logstash
sudo systemctl restart logstash

/etc/logstash/conf.d/ にある .conf ファイルはすべて 1 つのパイプラインとして読み込まれます。本編で作った demo.conf などが残っていると、同じポートを二重に待ち受けて起動に失敗するため、不要なファイルは削除してください。

OS のファイアウォールが有効な場合は、5000 番ポートの受信を許可します。

オンプレミス Logstash(Ubuntu / ufw)
sudo ufw allow 5000/tcp

A-4-7. 疎通と取り込みの確認

DCE に届くかを確認します。000 以外の HTTP ステータス(404 など)が返れば通信は届いています。000 の場合は、ファイアウォールかプロキシで止まっています。

オンプレミス Logstash
sudo bash -c '. /etc/default/logstash; curl -sS -o /dev/null -w "%{http_code}\n" "$DCE_URI"'

プロキシ経由の場合:

オンプレミス Logstash
sudo bash -c '. /etc/default/logstash; curl -sS -x http://proxy.example.local:8080 -o /dev/null -w "%{http_code}\n" "$DCE_URI"'

テストイベントを 10 件送ります。

オンプレミス Logstash
for i in $(seq 1 10); do
  echo '{"EventType":"LoginFailed","UserName":"alice","SrcIp":"192.0.2.50","App":"demo-web","Severity":"High"}' | nc -q 1 127.0.0.1 5000
done
sudo tail -n 50 /var/log/logstash/logstash-plain.log

数分後、ログ画面で確認します。

KQL
LogstashDemo_CL
| where TimeGenerated > ago(30m)
| where SrcIp == "192.0.2.50"
| project TimeGenerated, EventType, UserName, SrcIp, App, Severity

A-5. トラブルシューティング(オンプレミス特有)

事象 主な原因 確認・対処
azcmagent connect が失敗する 通信先がブロックされている、プロキシ未設定、権限不足 sudo azcmagent check --location japaneast で届かない宛先を確認。azcmagent show でプロキシ設定を確認。接続ユーザーの権限を確認
Arc は接続済みだが AMA が Failed AMA の通信先がブロック、プロキシが AMA に設定されていない A-3-5 のプロキシ設定付きで AMA を入れ直す。HTTPS インスペクションの対象から外す
Syslog テーブルにオンプレミスのデータが出ない DCR の関連付け漏れ、OS ファイアウォールで 514 番が閉じている A-3-6 の関連付けを確認。sudo ss -lntup | grep ':514' と ufw / firewalld の設定を確認
Logstash の送信で 401 / 403 シークレットの誤り・期限切れ、ロール未反映 キーストアの値を登録し直す。az ad app credential list --id "$AZ_CLIENT_ID" で期限を確認。ロール反映まで最大 30 分待つ
Logstash の送信でタイムアウト DCE やログイン先への通信がブロック、プロキシ未設定 A-4-7 の curl で疎通確認。出力設定の proxy を確認
TimeGenerated がずれる サーバーや機器の時刻ずれ timedatectl status で同期状態を確認し、NTP を設定
回線障害後にイベントが欠ける 永続キュー未設定、キュー容量不足 A-4-5 の永続キューを有効化し、queue.max_bytes を見直す

A-6. 後片付け(オンプレミス側)

オンプレミスのサーバーを Azure Arc から外し、エージェントを削除します。disconnect を実行すると Azure 上の Arc リソースも削除されます。

オンプレミス Syslog フォワーダー
sudo azcmagent disconnect --use-device-code
sudo apt-get remove -y azcmagent

Logstash 用のアプリ登録を削除します。1 行目の値は A-4-1 で表示された client_id に置き換えてください(同じ Cloud Shell セッションが続いている場合は 1 行目は不要です)。

Cloud Shell
AZ_CLIENT_ID=00000000-0000-0000-0000-000000000000
az ad app delete --id "$AZ_CLIENT_ID"

A-7. 参考(付録)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?