вторник, 9 мая 2017 г.

Логирование использования внешних адресов пользователями в Windows Azure Pack

В одном из проектов облака на базе Windows Azure Pack для государственной организации, в техническом задании было требование - логирование активации внешних IP адресов для клиентов. Изначально данная задача выполнялась с помощью скрипта PowerShell, который запускался один раз в час и отлавливал события в SCVMM. Но, к сожалению, этот вариант имеет много недостатков. Поэтому было принято решение использовать функционал Windows Azure Pack и SMA (Runbook).


Так как решение независимо от других (например, от биллинга), мы создадим новую таблицу в предварительно приготовленной базе данных Microsoft SQL:

USE MyDB

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.iplogDB
(
ID int not null identity(1,1) PRIMARY KEY,
Owner varchar(50) NULL,
Operation varchar(10) NULL,
IP varchar(20) NULL,
Date varchar(20) NULL,
 Name varchar(20) NULL,
Custom varchar(50) NULL
)  
GO
ALTER TABLE dbo.iplogDB SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
select Has_Perms_By_Name(N'dbo.iplogDB', 'Object', 'ALTER') as ALT_Per, Has_Perms_By_Name(N'dbo.iplogDB', 'Object', 'VIEW DEFINITION') as View_def_Per, Has_Perms_By_Name(N'dbo.iplogDB', 'Object', 'CONTROL') as Contr_Per 

Таблица будет выглядеть так:

ID Owner Operation IP  Date Name
Custom
Порядковый номер  Пользователь  ADD/DEL  IP адрес  Date  Имя операции  Резерв

Когда таблица создана, приступаем к написанию Runbook. Основная идея в том, что при его выполнении надо убедиться, что был добавлен или удален IP адрес для подписки. Если так, то заносим информацию в базу данных.

Теперь составим таблицу, в которой укажем, как будем обрабатывать события:


N Событие Объект
1 Включение NAT VMM.NATConnection
2 Добавление правила NAT VMM.NATConnection
3 Отключение NAT VMM.NATConnection 
4 Удаление сети VMM.VMNetworkGateway
5 Удаление подписки VMM.VMNetworkGateway
6 Добавление сети VMM.NATConnection

Далее определим, какие данные мы будем забирать из WAP, какие из VMM JOB:


IDSubscriptionIDOperationIP DateName
Custom
Auto JOB WAP JOB JOB WAP Reserved


Runbook:

workflow IP-Logging
{
param
(
[Parameter(Mandatory=$true)]
[String] $VMMJOBID,
[Parameter(Mandatory=$true)]
[object] $NAME,
[Parameter(Mandatory=$true)]
[object] $OPERATION
)
# Connection to access VMM server
$VmmConnection = Get-AutomationConnection -Name 'VmmConnection'
$VmmServerName = $VmmConnection.ComputerName
$SecurePassword = ConvertTo-SecureString -AsPlainText -String $VmmConnection.Password -Force
$VmmCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $VmmConnection.Username, $SecurePassword
# Connection to access MsSQL server.
$MsSQLCred = Get-AutomationPSCredential -Name 'MsSQL-iploggingDB'
[string] $MsSQLLogin = $MsSQLCred.Username
$MsSQLPassword = $MsSQLCred.Password
[string] $MsSQLDatabase = Get-AutomationVariable -Name 'MsSQL-iplogging-Database'
[string] $MsSQLServer = Get-AutomationVariable -Name 'MsSQL-iplogging-Server'
inlinescript {
# Import VMM module.
Import-Module virtualmachinemanager
# Connect to VMM server.
Get-SCVMMServer -ComputerName $Using:VmmServerName -ForOnBehalfOf
$job = Get-SCJob -ID $USING:vmmjobid
# Check Job Status
$JobStatus=$Job.Status
# Wait Until Task Completed
while ($JobStatus -eq "Running") {
write-output "Start Sleep"
start-sleep 3
$JobStatus=$Job.Status
}
# Break if Job failed
if ($JobStatus -eq "Failed") {
write-output "Job Failed!"
write-output JOBid:$job.ID
break
}
#Get IP
$jobfull = Get-SCJob -Job $job -full
if ($Using:Operation -eq "Delete") {
$IP = (($jobfull.AuditRecords).Previous | ? key -eq "IP address" | Select -First 1).Value
} else {
$IP = (($jobfull.AuditRecords).New | ? key -eq "IP address" | Select -First 1).Value
}
### Get data
$Owner = $job.Owner
$Operation = $Using:Operation
$Date = '{0:s}' -f $job.EndTime
$Name = $Using:name
### Write to Database
### VARS DB Settings
$SQLserver = $USING:MsSQLServer
$SQLDatabase = $USING:MsSQLDatabase
$SQLuser = $USING:MsSQLLogin
$SQLSecurePassword = $USING:MsSQLPassword
# We need unsecure password to connect DB
$SQLBSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SQLSecurePassword)
$SQLUnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($SQLBSTR)
### MsSQL CONNECTION
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "Server = '$SQLServer';database='$SQLDatabase'; User ID = '$SQLuser'; `
Password = '$SQLUnsecurePassword';trusted_connection=true; Integrated Security=false"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
###
$Command.CommandText = "INSERT INTO iplog (Owner, Operation, IP, Date, Name) `
VALUES ('{0}','{1}','{2}','{3}','{4}')" `
-f $Owner, $Operation, $IP, $Date, $Name
$Command.ExecuteNonQuery() | out-null
$Connection.Close()
} -PSComputerName $VmmServerName -PSCredential $VmmCredential
}
view raw wap-ip-logging hosted with ❤ by GitHub


Когда Runbook создан и импортирован, необходимо создать Assets. В них мы укажем данные для соединения с базой данных и сервером VMM:


NameTypeData
VmmConnection
VirtualMachineManager
CONTOSO\Rbuser,
Password,
VMMclusterName
MsSQL-iploggingDB
PowerShell Credential
IploggingDBsa,
Password
MsSQL-iplogging-Server
String
SQlServerName
MsSQL-iplogging-Database
String
IploggingDB

Теперь надо для Runbook установить тег SPF, опубликовать его и привязать к событиям:

OBJECTACTION
VMM NATConnectionCreate
VMM NATConnectionDelete
VMM VMNetworkGateway

Delete


На этом настройка логирования закончена. Теперь представим, что у нас уже есть активные подписки, поэтому надо добавить их IP адреса в базу данных. Для этого сделаем скрипт, который внесет текущую информацию:

$VmmServerName = "VMM01"
$SQLserver = "VMMDB"
$SQLDatabase = "IploggingDB"
$SQLuser = "MyUser"
$SQLPassword = "SecretPWD"
# Import VMM module.
Import-Module virtualmachinemanager
# Connect to VMM server.
Get-SCVMMServer -ComputerName $VmmServerName -ForOnBehalfOf
$Operation = "Create"
$date = get-date
$Date = '{0:s}' -f $date
$Name = "Manual"
### MsSQL CONNECTION
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "Server = '$SQLServer';database='$SQLDatabase'; User ID = '$SQLuser'; `
Password = '$SQLPassword';trusted_connection=true; Integrated Security=false"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
###
$VMnetworks = Get-SCVMNetwork
foreach ($VMnetwork in $VMnetworks) {
$owner = $VMnetwork.Owner
if ($owner) {
$Gateways = Get-SCVMNetworkGateway -VMNetwork $VMnetwork
foreach ($Gateway in $Gateways) {
$IPs = ((Get-SCNATConnection -VMNetworkGateway $Gateway).Rules | ? ExternalPort -eq 0).Name
foreach ($IP in $IPs) {
$Command.CommandText = "INSERT INTO iplog (Owner, Operation, IP, Date, Name) `
VALUES ('{0}','{1}','{2}','{3}','{4}')" `
-f $Owner, $Operation, $IP, $Date, $Name
$Command.ExecuteNonQuery() | out-null
}
}
}
}
$Connection.Close()


На этом этапе решение является вполне работоспособным, но с одним "но" - при удалении подписки, Windows Azure Pack не создает задачу по удалению сетей. Поэтому, при поиске владельца адреса, необходимо учитывать, что подписка могла быть удалена. В следующей статье мы внесем изменения в решение - расширим его функционал, научив удалять сети для удаленных пользователей и вносить данную информацию в базу данных.


Комментариев нет:

Отправить комментарий