GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

169 lines
7.8 KiB

# Setup SSH key — Administrator@10.100.1.40 (AD LDAP, Windows Server 2012 R2)
# SSOT: server-audit/docs/guide/ssh-access.md
# Usage: .\server-audit\scripts\setup-ssh-ad-ldap.ps1
# Sekali jalan: password Administrator 1–2x (scp + ssh), lalu key-only.
# Wajib PowerShell (bukan CMD).
$ErrorActionPreference = 'Stop'
$hostIp = '10.100.1.40'
$SshUser = 'Administrator'
$key = Join-Path $env:USERPROFILE '.ssh\id_rsa_geonet_laptop'
$pub = "$key.pub"
$aliasName = 'ad-ldap'
if (-not (Test-Path $pub)) {
Write-Host "Generating key $key ..."
ssh-keygen -t rsa -b 4096 -f $key -C 'geonet-laptop' -N '""'
}
Write-Host "Fixing private key ACL..."
icacls $key /inheritance:r 2>$null | Out-Null
icacls $key /grant:r "${env:USERNAME}:(R)" 2>$null | Out-Null
# Pub key LF-only
$tempPub = Join-Path $env:TEMP 'geonet_ad_ldap_key.pub'
$keyLine = (Get-Content $pub -Raw).Trim() -replace "`r", ""
[System.IO.File]::WriteAllText($tempPub, $keyLine + "`n")
# Remote installer (Windows OpenSSH — Administrator)
# FORCE overwrite UTF-8 no BOM; tulis ke administrators_authorized_keys + profile fallback
$remotePs = @'
$ErrorActionPreference = "Stop"
$authFile = "C:\ProgramData\ssh\administrators_authorized_keys"
$userAuthDir = "C:\Users\Administrator\.ssh"
$userAuthFile = Join-Path $userAuthDir "authorized_keys"
$sshDir = "C:\ProgramData\ssh"
$sshdConfig = "C:\ProgramData\ssh\sshd_config"
$pubPath = Join-Path $env:TEMP "geonet_ad_ldap_key.pub"
if (-not (Test-Path $pubPath)) { throw "Missing $pubPath — scp failed?" }
$keyLine = [System.IO.File]::ReadAllText($pubPath).Trim() -replace "`r","" -replace "`0",""
if ($keyLine -notmatch "^ssh-") { throw "Invalid pubkey content" }
if (-not (Test-Path $sshDir)) { New-Item -ItemType Directory -Path $sshDir | Out-Null }
$utf8 = New-Object System.Text.UTF8Encoding $false
# FORCE overwrite — jangan merge file korup UTF-16 lama
[System.IO.File]::WriteAllText($authFile, $keyLine + "`n", $utf8)
Write-Host "FORCE wrote administrators_authorized_keys (UTF-8 no BOM)"
function Fix-AclAdminOnly([string]$path) {
$acl = Get-Acl $path
$acl.SetAccessRuleProtection($true, $false)
@($acl.Access) | ForEach-Object { [void]$acl.RemoveAccessRule($_) }
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","FullControl","Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators","FullControl","Allow")))
Set-Acl -Path $path -AclObject $acl
}
Fix-AclAdminOnly $authFile
Write-Host "ACL ProgramData OK"
# Fallback: profile authorized_keys (jika Match Group di-comment)
if (-not (Test-Path $userAuthDir)) { New-Item -ItemType Directory -Path $userAuthDir | Out-Null }
[System.IO.File]::WriteAllText($userAuthFile, $keyLine + "`n", $utf8)
$uacl = Get-Acl $userAuthFile
$uacl.SetAccessRuleProtection($true, $false)
@($uacl.Access) | ForEach-Object { [void]$uacl.RemoveAccessRule($_) }
$uacl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","FullControl","Allow")))
$uacl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators","FullControl","Allow")))
$uacl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Administrator","FullControl","Allow")))
Set-Acl -Path $userAuthFile -AclObject $uacl
Write-Host "Wrote profile authorized_keys fallback"
if (Test-Path $sshdConfig) {
$cfg = Get-Content $sshdConfig -Raw
# Uncomment Match Group administrators if commented
$cfg = $cfg -replace "(?m)^#\s*Match Group administrators","Match Group administrators"
$cfg = $cfg -replace "(?m)^#\s*AuthorizedKeysFile\s+__PROGRAMDATA__/ssh/administrators_authorized_keys"," AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys"
if ($cfg -match "(?m)^#?\s*PubkeyAuthentication\s+no") {
$cfg = $cfg -replace "(?m)^#?\s*PubkeyAuthentication\s+no","PubkeyAuthentication yes"
Write-Host "Enabled PubkeyAuthentication"
}
if ($cfg -notmatch "(?m)^\s*PubkeyAuthentication\s+yes") {
$cfg = "PubkeyAuthentication yes`r`n" + $cfg
Write-Host "Inserted PubkeyAuthentication yes"
}
# Allow ssh-rsa for older Win32-OpenSSH / mixed client
if ($cfg -notmatch "(?m)^\s*PubkeyAccepted") {
$cfg = $cfg.TrimEnd() + "`r`nPubkeyAcceptedKeyTypes ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa`r`n"
Write-Host "Added PubkeyAcceptedKeyTypes (+ssh-rsa)"
}
if ($cfg -notmatch "(?m)^\s*Match Group administrators") {
$cfg = $cfg.TrimEnd() + "`r`n`r`nMatch Group administrators`r`n AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys`r`n"
Write-Host "Added Match Group administrators block"
}
[System.IO.File]::WriteAllText($sshdConfig, $cfg, $utf8)
Write-Host "sshd_config updated"
}
Write-Host "--- diagnostics ---"
Write-Host ("auth bytes: " + (Get-Item $authFile).Length)
$bytes = [System.IO.File]::ReadAllBytes($authFile)
Write-Host ("first3: " + $bytes[0] + "," + $bytes[1] + "," + $bytes[2] + " (expect 115,115,104 = ssh)")
Select-String -Path $sshdConfig -Pattern "Match Group|AuthorizedKeysFile|PubkeyAuth|PubkeyAccepted" | ForEach-Object { $_.Line }
Get-Service sshd | Format-List Status, Name
Restart-Service sshd -Force
Start-Sleep -Seconds 2
Write-Host "KEY_INSTALLED_OK"
'@
$tempRemote = Join-Path $env:TEMP 'setup-ad-ldap-authorized-keys.ps1'
# Remote script must be CRLF-friendly for Windows PowerShell; keep as-is
[System.IO.File]::WriteAllText($tempRemote, $remotePs)
$commonOpts = @(
'-o', 'PreferredAuthentications=password',
'-o', 'PubkeyAuthentication=no',
'-o', 'StrictHostKeyChecking=accept-new',
'-o', 'MACs=hmac-sha1'
)
# scp: -P (port). ssh: -p (port) + -m hmac-sha1
$scpOpts = $commonOpts + @('-P', '22')
$sshOpts = $commonOpts + @('-m', 'hmac-sha1', '-p', '22')
Write-Host "Upload pub + installer ke ${SshUser}@${hostIp} (password)..."
scp @scpOpts $tempPub "${SshUser}@${hostIp}:C:/Users/Administrator/AppData/Local/Temp/geonet_ad_ldap_key.pub"
scp @scpOpts $tempRemote "${SshUser}@${hostIp}:C:/Users/Administrator/AppData/Local/Temp/setup-ad-ldap-authorized-keys.ps1"
Write-Host "Run installer on server..."
ssh @sshOpts "${SshUser}@${hostIp}" "powershell -NoProfile -ExecutionPolicy Bypass -File C:\Users\Administrator\AppData\Local\Temp\setup-ad-ldap-authorized-keys.ps1"
Remove-Item $tempPub, $tempRemote -Force -ErrorAction SilentlyContinue
# Ensure local ssh config alias
$configPath = Join-Path $env:USERPROFILE '.ssh\config'
$block = @"
Host $aliasName
HostName $hostIp
User $SshUser
Port 22
IdentityFile ~/.ssh/id_rsa_geonet_laptop
IdentitiesOnly yes
MACs hmac-sha1
PubkeyAcceptedAlgorithms +ssh-rsa
"@
if (-not (Test-Path $configPath)) {
Set-Content -Path $configPath -Value $block.TrimStart() -Encoding UTF8
Write-Host "Created ~/.ssh/config with Host $aliasName"
} elseif (-not (Select-String -Path $configPath -Pattern "Host\s+$aliasName" -Quiet)) {
Add-Content -Path $configPath -Value $block
Write-Host "Appended Host $aliasName to ~/.ssh/config"
} else {
Write-Host "Host $aliasName already in ~/.ssh/config"
}
Write-Host ""
Write-Host "Test key-only..."
# Win2012 OpenSSH sering butuh ssh-rsa eksplisit dari client baru
ssh -i $key -o BatchMode=yes -o IdentitiesOnly=yes -o PreferredAuthentications=publickey -o PubkeyAcceptedAlgorithms=+ssh-rsa -m hmac-sha1 "${SshUser}@${hostIp}" -p 22 "echo KEY_AUTH_OK & hostname"
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "Masih gagal. Cek di server (password sekali):"
Write-Host " ssh -m hmac-sha1 ${SshUser}@${hostIp} -p 22 `"powershell -Command Get-Content C:\ProgramData\ssh\administrators_authorized_keys`""
Write-Host " Pastikan OpenSSH Server terpasang & sshd running."
Write-Host " Win2012 R2: Match Group administrators -> administrators_authorized_keys"
exit 1
}
Write-Host "Success. Login: ssh $aliasName"