fix: restore production secrets on kalinamall and repair placeholder settings (2.1.8-SAC)

Real SAC/Telegram tokens and org paths back in example and NETLOGON publish script. Deploy now treats sac.example.com and sac_CHANGE_ME as unconfigured and overwrites from example.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 14:31:53 +10:00
parent 5708e42c66
commit f2bcc6c7df
6 changed files with 61 additions and 36 deletions
+20 -8
View File
@@ -260,11 +260,25 @@ function Copy-RdpMonitorDeployBundle {
} }
} }
function Test-RdpMonitorSettingsHasPlaceholderSecrets {
param([string]$SettingsPath)
$c = Get-RdpMonitorSettingsRaw -Path $SettingsPath
if ([string]::IsNullOrWhiteSpace($c)) { return $true }
if ($c -match '(?m)^\s*\$SacUrl\s*=\s*[''"]https?://[^''"]*example\.com[^''"]*[''"]') { return $true }
if ($c -match '(?m)^\s*\$SacApiKey\s*=\s*[''"]sac_CHANGE_ME[''"]') { return $true }
if ($c -match '(?m)^\s*\$TelegramBotToken\s*=\s*[''"]YOUR_BOT_TOKEN[''"]') { return $true }
if ($c -match '(?m)^\s*\$TelegramChatID\s*=\s*[''"]YOUR_CHAT_ID[''"]') { return $true }
return $false
}
function Test-RdpMonitorSettingsNeedsSacBootstrap { function Test-RdpMonitorSettingsNeedsSacBootstrap {
param([string]$SettingsPath) param([string]$SettingsPath)
$c = Get-RdpMonitorSettingsRaw -Path $SettingsPath $c = Get-RdpMonitorSettingsRaw -Path $SettingsPath
if ([string]::IsNullOrWhiteSpace($c)) { return $true } if ([string]::IsNullOrWhiteSpace($c)) { return $true }
if (Test-RdpMonitorSettingsHasPlaceholderSecrets -SettingsPath $SettingsPath) { return $true }
if ($c -notmatch '(?m)^\s*\$UseSAC\s*=') { return $true } if ($c -notmatch '(?m)^\s*\$UseSAC\s*=') { return $true }
if ($c -match '(?m)^\s*\$UseSAC\s*=\s*[''"]off[''"]') { if ($c -match '(?m)^\s*\$UseSAC\s*=\s*[''"]off[''"]') {
if ($c -notmatch '(?m)^\s*\$SacApiKey\s*=\s*[''"]sac_[^''"]+[''"]') { return $true } if ($c -notmatch '(?m)^\s*\$SacApiKey\s*=\s*[''"]sac_[^''"]+[''"]') { return $true }
@@ -980,12 +994,8 @@ function Get-RdpMonitorSacBlockFromExample {
if ($ex -match '(?ms)(#\s*---\s*Security Alert Center.*?)(?=\r?\n#\s*---|\z)') { if ($ex -match '(?ms)(#\s*---\s*Security Alert Center.*?)(?=\r?\n#\s*---|\z)') {
return $Matches[1].TrimEnd() return $Matches[1].TrimEnd()
} }
return @( Write-DeployLog "Предупреждение: в example нет блока Security Alert Center — patch SAC пропущен."
'# --- Security Alert Center (SAC) ---' return $null
'$UseSAC = ''fallback'''
'$SacUrl = ''https://sac.example.com'''
'$SacApiKey = ''sac_CHANGE_ME'''
) -join "`r`n"
} }
function Sync-RdpMonitorUseSacFallbackMode { function Sync-RdpMonitorUseSacFallbackMode {
@@ -1023,8 +1033,10 @@ function Update-RdpMonitorSettingsSacBlockIfMissing {
if ($c -match '(?m)^\s*\$UseSAC\s*=' -and $c -match '(?m)^\s*\$SacApiKey\s*=\s*[''"]sac_[^''"]+[''"]') { if ($c -match '(?m)^\s*\$UseSAC\s*=' -and $c -match '(?m)^\s*\$SacApiKey\s*=\s*[''"]sac_[^''"]+[''"]') {
if ($c -notmatch '(?m)^\s*\$UseSAC\s*=\s*[''"]off[''"]') { if ($c -notmatch '(?m)^\s*\$UseSAC\s*=\s*[''"]off[''"]') {
Write-DeployLog "login_monitor.settings.ps1: блок SAC уже задан, файл не меняем." if (-not (Test-RdpMonitorSettingsHasPlaceholderSecrets -SettingsPath $LocalSettings)) {
return $false Write-DeployLog "login_monitor.settings.ps1: блок SAC уже задан, файл не меняем."
return $false
}
} }
} }
+1 -1
View File
@@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
$ScriptVersion = "2.1.7-SAC" $ScriptVersion = "2.1.8-SAC"
# Логи (все под InstallRoot) # Логи (все под InstallRoot)
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
+5 -5
View File
@@ -29,11 +29,11 @@ $QueueMessageCountThreshold = 150
# --- Пилот VIP (рекомендуется для первого запуска) --- # --- Пилот VIP (рекомендуется для первого запуска) ---
# $VipMailboxesOnly = $true # $VipMailboxesOnly = $true
# $VipMailboxes = @( # $VipMailboxes = @(
# 'director@example.com', # 'director@kalinamall.ru',
# 'cfo@example.com' # 'cfo@kalinamall.ru'
# ) # )
# $VipMailboxPatterns = @( # $VipMailboxPatterns = @(
# '*@example.com' # опционально: все ящики домена из Get-Mailbox # '*@kalinamall.ru' # опционально: все ящики домена из Get-Mailbox
# ) # )
# Первый ночной скан: не слать сотни алертов по уже существующим пересылкам # Первый ночной скан: не слать сотни алертов по уже существующим пересылкам
@@ -46,9 +46,9 @@ $QueueMessageCountThreshold = 150
# $SendInboxScanSummary = $true # $SendInboxScanSummary = $true
# Удалённый EMS (если скрипт не на Exchange) # Удалённый EMS (если скрипт не на Exchange)
# $ExchangeServerFqdn = 'mail.example.com' # $ExchangeServerFqdn = 'fifth.kalinamall.ru'
# Не сканировать Inbox rules (битое хранилище правил / Watson на Get-InboxRule) # Не сканировать Inbox rules (битое хранилище правил / Watson на Get-InboxRule)
# $SkipInboxScanMailboxes = @( # $SkipInboxScanMailboxes = @(
# 'k.selezneva@example.com' # 'k.selezneva@kalinamall.ru'
# ) # )
+11 -11
View File
@@ -9,8 +9,8 @@
#> #>
# --- Telegram (или DPAPI Base64 через Encrypt-DpapiForRdpMonitor.ps1) --- # --- Telegram (или DPAPI Base64 через Encrypt-DpapiForRdpMonitor.ps1) ---
$TelegramBotToken = 'YOUR_BOT_TOKEN' $TelegramBotToken = '8239219522:AAEyOZX3cwNfgGOMDkf-mgjTIuoaOh5gF7I'
$TelegramChatID = 'YOUR_CHAT_ID' $TelegramChatID = '2843230'
# $TelegramBotTokenProtectedB64 = '' # $TelegramBotTokenProtectedB64 = ''
# $TelegramChatIDProtectedB64 = '' # $TelegramChatIDProtectedB64 = ''
@@ -29,20 +29,20 @@ $NotifyOrder = 'tg'
# --- Подпись сервера в Telegram и SAC (host.display_name); пусто = $env:COMPUTERNAME --- # --- Подпись сервера в Telegram и SAC (host.display_name); пусто = $env:COMPUTERNAME ---
# $ServerDisplayName = 'UNMS Kalina' # $ServerDisplayName = 'UNMS Kalina'
# --- Явный IPv4 хоста для SAC (опционально; иначе автоопределение) --- # --- Явный IPv4 хоста для SAC (опционально; иначе автоопределение) ---
# $ServerIPv4 = '10.0.0.10' # $ServerIPv4 = '192.168.160.57'
# --- Security Alert Center (SAC) --- # --- Security Alert Center (SAC) ---
# off | exclusive | dual | fallback — см. security-alert-center/docs/agent-integration.md # off | exclusive | dual | fallback — см. security-alert-center/docs/agent-integration.md
$UseSAC = 'fallback' $UseSAC = 'fallback'
$SacUrl = 'https://sac.example.com' $SacUrl = 'https://sac.kalinamall.ru'
$SacApiKey = 'sac_CHANGE_ME' $SacApiKey = 'sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8'
# $SacSpoolDir = 'C:\ProgramData\RDP-login-monitor\sac-spool' $SacSpoolDir = 'C:\ProgramData\RDP-login-monitor\sac-spool'
# $SacTimeoutSec = 12 # $SacTimeoutSec = 12
# $SacTlsSkipVerify = $false # $SacTlsSkipVerify = $false
# $SacFallbackFailures = 5 # $SacFallbackFailures = 5
# $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC) # $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC)
# В settings.ps1 используйте 1/0 или $true/$false — не пишите голое false без $ # В settings.ps1 используйте 1/0 или $true/$false — не пишите голое false без $
$DailyReportEnabled = $true # по умолчанию: только SAC; $true или 1 — отчёт с агента $DailyReportEnabled = 1
# --- Heartbeat SAC (agent.heartbeat): интервал в секундах; 14400 = 4 ч --- # --- Heartbeat SAC (agent.heartbeat): интервал в секундах; 14400 = 4 ч ---
$HeartbeatInterval = 14400 $HeartbeatInterval = 14400
@@ -70,7 +70,7 @@ $GetInventory = $true
# --- Узкое исключение шумовых сетевых логонов (LogonType=3, Advapi) --- # --- Узкое исключение шумовых сетевых логонов (LogonType=3, Advapi) ---
$IgnoreAdvapiNetworkLogonSourceIps = @( $IgnoreAdvapiNetworkLogonSourceIps = @(
'10.0.0.1' '192.168.160.57'
) )
# --- Exchange noise filter: 4624 + LogonType=3 + IP='-' (часто Outlook/почтовые клиенты) --- # --- Exchange noise filter: 4624 + LogonType=3 + IP='-' (часто Outlook/почтовые клиенты) ---
# Включайте на почтовом сервере, если нужен только полезный интерактивный сигнал. # Включайте на почтовом сервере, если нужен только полезный интерактивный сигнал.
@@ -83,9 +83,9 @@ $MaxBackupDays = 31
# --- Блокировка учётной записи AD (4740) + IP из IIS ActiveSync --- # --- Блокировка учётной записи AD (4740) + IP из IIS ActiveSync ---
# Мониторинг включается только на КД с именем $LockoutMonitorDomainController. # Мониторинг включается только на КД с именем $LockoutMonitorDomainController.
$LockoutMonitorDomainController = 'DC01' $LockoutMonitorDomainController = 'K6A-DC3'
$NetBiosDomainName = 'CONTOSO' $NetBiosDomainName = 'B26'
$ExchangeIisLogPath = '\\mail.example.com\c$\inetpub\logs\LogFiles\W3SVC1' $ExchangeIisLogPath = '\\fifth.kalinamall.ru\c$\inetpub\logs\LogFiles\W3SVC1'
$ExchangeServerHostForIisExclude = '' $ExchangeServerHostForIisExclude = ''
$ExchangeIisLogTailLines = 5000 $ExchangeIisLogTailLines = 5000
$ExchangeIisLogMinutesBeforeLockout = 30 $ExchangeIisLogMinutesBeforeLockout = 30
+23 -10
View File
@@ -4,7 +4,7 @@
.DESCRIPTION .DESCRIPTION
Dlya servera publikatsii (napr. DC3). Po umolchaniyu GitHub (github.com/PTah). Dlya servera publikatsii (napr. DC3). Po umolchaniyu GitHub (github.com/PTah).
Na zakrytom zerkale ukazhite -GitUrl URL vashego Gitea. Na zakrytom zerkale ukazhite -GitUrl URL vashego Gitea.
Posle fetch: vsegda reset --hard na vetku upstream (bez merge), zatem clean -fd. Posle fetch: vsegda reset --hard na kalinamall/main (bez merge), zatem clean -fd.
Kopiruyutsya: polnyj spisok v Docs/deploy-netlogon-publish.md. Kopiruyutsya: polnyj spisok v Docs/deploy-netlogon-publish.md.
.EXAMPLE .EXAMPLE
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1 powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\soft\update-rdp-monitor.ps1
@@ -14,8 +14,8 @@
[CmdletBinding(SupportsShouldProcess = $true)] [CmdletBinding(SupportsShouldProcess = $true)]
param( param(
[string]$RepoPath = 'C:\Soft\Git\RDP-login-monitor', [string]$RepoPath = 'C:\Soft\Git\RDP-login-monitor',
[string]$NetlogonDest = '\\dc.contoso.local\NETLOGON\RDP-login-monitor', [string]$NetlogonDest = '\\b26\NETLOGON\RDP-login-monitor',
[string]$GitUrl = 'https://github.com/PTah/RDP-login-monitor.git', [string]$GitUrl = 'https://git.kalinamall.ru/PapaTramp/RDP-login-monitor.git',
[string]$GitBranch = 'main', [string]$GitBranch = 'main',
[string]$LogFile = 'C:\soft\Logs\update-rdp-monitor.log', [string]$LogFile = 'C:\soft\Logs\update-rdp-monitor.log',
[switch]$SkipGitClean [switch]$SkipGitClean
@@ -113,25 +113,38 @@ function Ensure-GitRepository {
function Get-ConfiguredGitRemoteName { function Get-ConfiguredGitRemoteName {
$names = @(Invoke-GitCommand -Arguments @('remote') | ForEach-Object { "$_".Trim() } | Where-Object { $_ }) $names = @(Invoke-GitCommand -Arguments @('remote') | ForEach-Object { "$_".Trim() } | Where-Object { $_ })
if ($names.Count -eq 0) { return $null } if ($names.Count -eq 0) { return $null }
if ('kalinamall' -in $names) { return 'kalinamall' }
foreach ($n in $names) {
$url = (& git -C $RepoPath remote get-url $n 2>$null)
if ($url -match 'git\.kalinamall\.ru') { return $n }
}
if ('origin' -in $names) { return 'origin' } if ('origin' -in $names) { return 'origin' }
return $names[0] return $names[0]
} }
function Ensure-GitUpstreamRemote { function Ensure-GitKalinamallRemote {
$name = Get-ConfiguredGitRemoteName $name = Get-ConfiguredGitRemoteName
if ($null -ne $name) { if ($null -ne $name) {
$url = (& git -C $RepoPath remote get-url $name 2>$null) $url = (& git -C $RepoPath remote get-url $name 2>$null)
Write-UpdateLog "Using remote: $name ($url)" if ($url -match 'git\.kalinamall\.ru') {
return $name Write-UpdateLog "Using remote: $name ($url)"
return $name
}
Write-UpdateLog "Remote $name is not kalinamall ($url); adding kalinamall -> $GitUrl"
} else {
Write-UpdateLog "No remotes; adding kalinamall -> $GitUrl"
} }
Write-UpdateLog "No remotes; adding origin -> $GitUrl" if ('kalinamall' -in @(& git -C $RepoPath remote 2>$null)) {
Invoke-GitCommand -Arguments @('remote', 'add', 'origin', $GitUrl) Invoke-GitCommand -Arguments @('remote', 'set-url', 'kalinamall', $GitUrl)
return 'origin' return 'kalinamall'
}
Invoke-GitCommand -Arguments @('remote', 'add', 'kalinamall', $GitUrl)
return 'kalinamall'
} }
function Update-Repository { function Update-Repository {
Ensure-GitRepository Ensure-GitRepository
$remote = Ensure-GitUpstreamRemote $remote = Ensure-GitKalinamallRemote
Invoke-GitCommand -Arguments @('fetch', '--prune', $remote, $GitBranch) Invoke-GitCommand -Arguments @('fetch', '--prune', $remote, $GitBranch)
$upstream = "${remote}/${GitBranch}" $upstream = "${remote}/${GitBranch}"
+1 -1
View File
@@ -1 +1 @@
2.1.7-SAC 2.1.8-SAC