🦔

VNet統合とプライベートエンドポイント、アクセス制御を適用したApp ServiceにSSH接続してみる

2023/03/18に公開

はじめに

VNet統合、プライベートエンドポイントも使用したApp ServiceへSSH接続をしてみる

アクセス制限にも

  • 完全にパブリックアクセスを制限したい場合
  • 一部のパブリックアクセスを許可できる場合

の二つの場合を検証してみようと思います。

検証

リソースの名前などを設定します。

RESOURCE_GROUP_NAME=4kzknt-ssh-rg
LOCATION=japaneast
VNET_NAME=4kzkntVNet
SUBNET_NAME=4kzkntSubnet
SUBNET_B_NAME=4kzkntSubnetB
ADDRESS_PREFIX=10.0.0.0/16
SUBNET_PREFIX=10.0.1.0/24
SUBNET_B_PREFIX=10.0.2.0/24
APPSERVICE_NAME=4kzknt-ssh-webapp
ACR_NAME=4kzkntacr
ACR_SKU=Basic
DOCKER_TAG_NAME=4kzknt-tag-name
ASP_NAME=4kzkntsshPlan
ASP_SKU=B1

App Serviceの作成

今回は python アプリを一応作成します。

ディレクトリ構成

.
  ├── src
    ├── app.py
  ├── Dockerfile
  ├── sshd_config
  ├── init.sh

上記のそれぞれのファイル内容は以下になります。

  • app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return {'message': 'Hello world.'}
  • Dockerfile
FROM python:3.10

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

# ssh setting
ENV SSH_PASSWD "root:Docker!"
RUN apt-get update \
        && apt-get install -y --no-install-recommends dialog \
        && apt-get update \
        && apt-get install -y --no-install-recommends openssh-server \
        && echo "$SSH_PASSWD" | chpasswd
# ssh用ファイルのコピー
COPY sshd_config /etc/ssh/

# プログラム起動用ファイルのコピーと権限付与
COPY init.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/init.sh

EXPOSE 8000 2222

ENTRYPOINT ["init.sh"]
  • sshd_config
Port                    2222
ListenAddress           0.0.0.0
LoginGraceTime          180
X11Forwarding           yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
MACs                    hmac-sha1,hmac-sha1-96
StrictModes             yes
SyslogFacility          DAEMON
PasswordAuthentication  yes
PermitEmptyPasswords    no
PermitRootLogin         yes
  • init.sh
#!/bin/bash
set -e

echo "Starting SSH ..."
service ssh start

gunicorn -w 2 -b 0.0.0.0 src.app:app

以下のコマンドを実行します。

az group create --l $LOCATION -n $RESOURCE_GROUP_NAME
az acr create --resource-group $RESOURCE_GROUP_NAME --name $ACR_NAME --sku $ACR_SKU --admin-enabled true --location $LOCATION
az acr login --name $ACR_NAME
az acr credential show --resource-group $RESOURCE_GROUP_NAME --name $ACR_NAME
docker build -t $ACR_NAME.azurecr.io/$DOCKER_TAG_NAME:latest .
docker tag $DOCKER_TAG_NAME $ACR_NAME.azurecr.io/$DOCKER_TAG_NAME:latest
docker push $ACR_NAME.azurecr.io/$DOCKER_TAG_NAME:latest
az appservice plan create --name $ASP_NAME --resource-group $RESOURCE_GROUP_NAME --sku $ASP_SKU --is-linux
az webapp create --resource-group $RESOURCE_GROUP_NAME --plan $ASP_NAME --name $APPSERVICE_NAME --deployment-container-image-name $ACR_NAME.azurecr.io/$DOCKER_TAG_NAME:latest
az webapp config appsettings set --resource-group $RESOURCE_GROUP_NAME --name $APPSERVICE_NAME --settings WEBSITES_PORT=8000
az webapp identity assign --resource-group $RESOURCE_GROUP_NAME --name $APPSERVICE_NAME --query principalId --output tsv

VNet 構築

App Service が VNet 統合する用のVNetを作成します。
仮想マシンの構築をしていきます。まず、VNetをデプロイし、サブネットを作成します。

# VNet デプロイ
az network vnet create -n $VNET_NAME -g $RESOURCE_GROUP_NAME --address-prefix $ADDRESS_PREFIX --location $LOCATION
# サブネット作成(VNet用)
az network vnet subnet create --address-prefixes $SUBNET_PREFIX --name $SUBNET_NAME --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME
# サブネット作成(Private Endpoint用)
az network vnet subnet create --address-prefixes $SUBNET_B_PREFIX --name $SUBNET_B_NAME --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME

作成した Web App を VNet 統合します。

az webapp vnet-integration add --name $APPSERVICE_NAME --resource-group $RESOURCE_GROUP_NAME --subnet $SUBNET_NAME --vnet $VNET_NAME

プライベートエンドポイントの作成

id=$(az webapp list --resource-group $RESOURCE_GROUP_NAME --query '[].[id]' --output tsv)
az network private-endpoint create --connection-name myConnection --name 4kzkntprivateep --private-connection-resource-id $id --resource-group $RESOURCE_GROUP_NAME --subnet $SUBNET_B_NAME --vnet-name $VNET_NAME --group-id sites

この状態で、SSH接続すると 403 が表示されます。
403

SSH接続

一部アクセス許可する場合

今回はクライアントIPのみを許可したSSH(SCMから)アクセスする場合を想定して、SSHアクセスをしていきます。
まず、App Service -> 設定 -> ネットワーク -> アクセス制限 ページに移動します。
メインサイトタブと高度なツールサイトの「一致しないルールのアクション」で「拒否」を選択し、保存します。
main access

それでは、クライアントIPのみをアクセス許可してみます。
高度なツールサイトの「一致しないルールのアクション」で「拒否」を選択し、クライアントIPを許可して追加します。

scm access

それでは、ポータルから SSH 接続してみます。
scm access

完全にアクセス制御する場合

一部も Internet へのアクセスさせたくない場合に今回の方法でアクセスできます。
閉域環境では、SCMにアクセスできないっぽいので、Windows VM を立てて、そこからアクセスする方法を紹介します。

まず、App Serive でSCMにアクセスするための設定を行います。VMからアクセスする際にベーシック認証をするため、そのユーザー名とパスワードを設定します。
App Service -> デプロイセンター -> FTPS 資格情報 でユーザースコープに ユーザー名パスワードを設定します。

また、アクセス制御で高度なツールサイトで、VNETないのIPのアクセス許可を行います。

scm

次に、VNetに新たにサブネットを作成します。
今回作成するサブネットは、Internet からアクセスを許可します。
create subnet

Windows VMを作成します。
以下のようにwindows VMを作成します。
「管理者アカウント」は適当に入力してください。
create vm
ネットワークの設定等は適当に入力していきます。サブネットは先ほど作成したサブネットを指定します。

それでは作成した VM にアクセスします。
仮想マシン の概要 で接続を選択し、RDPファイルをダウンロードします。
ダウンロードしたら、RDPにアクセスします。
アクセスしたら、Edge等のブラウザを開いていただき、https://<AppService名>.scm.azurewebsites.net/basicauth にアクセスしていただき、先ほど設定したベーシック認証のユーザー名パスワードを入力し、サインインします。

scm

おわりに

閉域網環境での App Service へのSSHアクセスを紹介しました。

Discussion