AzureにWindowsのポート転送サーバ構築

AzureにWindows Serverのポート転送サーバを構築します。
Azure Automation(Runbook)でWindows Serverの仮想マシンを作成し、ポート転送設定までを自動化します。
必要な時だけ仮想マシンを生成する形態とすることで、使用しない時は利用料のかからないようにするということです。
作成する仮想マシンは、インスタンスタイプ「B2s」(2core 4GiB)、ディスク「32GiB」のHDDとします。
課金は10円/時間未満でしょう。インスタンスタイプで「1core 2GiB」のものにすれば半減できます。
課金を抑えるには、LINUXサーバの方がよいのですが、今回は、GUIになれているWindows Serverとしました。

構築用のRunbook

例として、ポート80番で受けたHTTP通信を別のWEBサーバへ転送します。
管理者のパスワードはランダムな英大小文字、数字としていますが、あくまでも必要な時だけ稼働する踏み台ということでサーバにログインできなくても問題ありません。

# ポート転送用VM作成
#
try
{
    Write-Output "Logging in to Azure..."
    $null = Connect-AzAccount -Identity
}
catch {
    Write-Error -Message $_.Exception
    throw $_.Exception
}

# 管理者ユーザ、パスワード(自動生成)
$AdminUsername = "LocalAdminUser"
$AdminPassword = -join((65..90 | Get-Random -Count 4) + `
    (97..122 | Get-Random -Count 4) + `
    (48..57 | Get-Random -Count 4) `
    | Get-Random -Count 12 | ForEach-Object {[char]$_})

# リソース配置
$ResourceGroupName = "(リソースグループ名)"
$Location = "Japan East"

# 仮想マシン名、サイズ
$VMName = "(サーバ名)"
$VMSize = "Standard_B2s"

# 仮想ネットワーク、サブネット名
$VNetName = "(VNet名)"
$SubnetName = "(サブネット名)"

$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName
If (-not $vm) {
    Write-Output "仮想マシン($VMName)の作成"
    # NetworkInterface作成
    $Vnet = Get-AzVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName
    $subnet = Get-AzVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $Vnet
    $NIC = New-AzNetworkInterface -Name "${VMName}-nic" `
        -ResourceGroupName $ResourceGroupName `
        -Location $Location `
        -SubnetId $subnet.Id

    # Credential作成
    $pass = ConvertTo-SecureString -String $AdminPassword -AsPlainText -Force
    $Credential = New-Object System.Management.Automation.PSCredential($AdminUsername, $pass);

    # VirtualMachine準備
    $vmConfig = New-AzVMConfig -VMName $VMName `
        -VMSize $VMSize
    $vmConfig = Set-AzVMOSDisk -VM $vmConfig `
        -Name "${VMName}-OsDisk" `
        -StorageAccountType "Standard_LRS" `
        -CreateOption FromImage `
        -DiskSizeInGB 32
    $vmConfig = Set-AzVMSourceImage -VM $vmConfig `
        -PublisherName 'MicrosoftWindowsServer' `
        -Offer 'WindowsServer' `
        -Skus '2022-datacenter-smalldisk-g2' `
        -Version latest
    $vmConfig = Add-AzVMNetworkInterface -VM $vmConfig `
        -Id $NIC.Id
    $vmConfig = Set-AzVMOperatingSystem -VM $vmConfig `
        -Windows `
        -ComputerName $VMName `
        -Credential $Credential `
        -ProvisionVMAgent `
        -EnableAutoUpdate
    $vmConfig.DiagnosticsProfile = New-Object Microsoft.Azure.Management.Compute.Models.DiagnosticsProfile
    $vmConfig.DiagnosticsProfile.BootDiagnostics = New-Object Microsoft.Azure.Management.Compute.Models.BootDiagnostics
    $vmConfig.DiagnosticsProfile.BootDiagnostics.Enabled = $true

    # VirtualMachine作成
    Write-Output "Create Virtual Machine"
    New-AzVM -VM $vmConfig  `
        -ResourceGroupName $ResourceGroupName `
        -Location $Location `
        -WarningAction Ignore

    # VM作成後コマンド実行
    $IpAddr = $nic.IpConfigurations.PrivateIpAddress

    $cmd1 = 'netsh advfirewall firewall add rule ' +`
            'name=OpenPort80 dir=in action=allow ' +`
            'protocol=TCP localport=80'
    $cmd2 = "netsh.exe interface portproxy add v4tov4 " +`
            "listenaddress=$IpAddr listenport=80 " +`
            "connectaddress=(転送先IPアドレス)  connectport=80"

    Set-AzVMExtension -ResourceGroupName $ResourceGroupName `
        -ExtensionName "HttpPortForwarding" `
        -VMName $VMName `
        -Location $Location `
        -Publisher Microsoft.Compute `
        -ExtensionType CustomScriptExtension `
        -TypeHandlerVersion 1.8 `
        -SettingString "{""commandToExecute"":""$cmd1 && $cmd2""}"
    # 終了
    Write-Output "Generated Password: $AdminPassword"
}
else {
    Write-Output "仮想マシン($VMName)が既に存在しているため処理スキップ"
}

Windows Firewallの受信ルールの除外設定を行っていますが、以下のようにFirewall自体を無効化する方法もあります。この場合はNSGで適切な設定を行ってください。

$cmd1 = "netsh advfirewall set allprofiles state off"

削除用のRunbook

使用が終わったら速やかにリソースを削除します。
仮想マシン、ディスク、NICを削除します。
順番に削除していくだけです。

try
{
    "Logging in to Azure..."
    Connect-AzAccount -Identity
}
catch {
    Write-Error -Message $_.Exception
    throw $_.Exception
}

$ResourceGroupName = "(リソースグループ名)"
$VMName = "(サーバ名)"
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName
If ($vm) {
    Write-Output "Remove Virtual machine, Disk, NIC"
    Remove-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName -Force
    Remove-AzDisk -ResourceGroupName $ResourceGroupName -DiskName $vm.StorageProfile.OsDisk.Name -Force
    Remove-AzNetworkInterface -ResourceGroupName $ResourceGroupName -Name $vm.NetworkProfile.NetworkInterfaces[0].Id.Split('/')[-1] -Force
}

コメント