105 lines
5.1 KiB
PowerShell
105 lines
5.1 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Configura el acceso remoto por SSH (-> PowerShell) en un PC Windows.
|
|
|
|
.DESCRIPTION
|
|
Idempotente. Deja listo el equipo para conectarse desde otro (p. ej. el portatil)
|
|
con `ssh usuario@equipo` y caer directamente en PowerShell.
|
|
|
|
Hace:
|
|
1. Instala la capacidad OpenSSH.Server (si falta).
|
|
2. Pone y arranca los servicios sshd y ssh-agent (Automatico).
|
|
3. Deja PowerShell como shell por defecto de SSH.
|
|
4. Crea una regla de firewall para el puerto 22, restringida a Tailscale y LAN.
|
|
5. Instala la clave publica recibida en authorized_keys (o administrators_authorized_keys).
|
|
|
|
Requiere PowerShell ELEVADO (se auto-eleva si hace falta).
|
|
|
|
.EXAMPLE
|
|
powershell -ExecutionPolicy Bypass -File setup_ssh_server.ps1 -PublicKey "ssh-ed25519 AAAA... juanm@portatil"
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$PublicKey = '',
|
|
[string[]]$AllowedNetworks = @('100.64.0.0/10', '192.168.1.0/24', '192.168.50.0/24')
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# --- Auto-elevacion -------------------------------------------------------
|
|
$esAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
if (-not $esAdmin) {
|
|
Write-Host 'Requiere administrador. Reabriendo elevado...' -ForegroundColor Yellow
|
|
$argsList = @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', "`"$PSCommandPath`"")
|
|
if ($PublicKey) { $argsList += @('-PublicKey', "`"$PublicKey`"") }
|
|
Start-Process powershell -Verb RunAs -ArgumentList $argsList
|
|
exit
|
|
}
|
|
|
|
Write-Host '== Configurando OpenSSH Server (acceso remoto -> PowerShell) ==' -ForegroundColor Cyan
|
|
|
|
# 1) Capacidad OpenSSH.Server ----------------------------------------------
|
|
$cap = Get-WindowsCapability -Online -Name 'OpenSSH.Server*' | Select-Object -First 1
|
|
if ($cap.State -ne 'Installed') {
|
|
Write-Host ' - Instalando OpenSSH.Server...' -ForegroundColor Yellow
|
|
Add-WindowsCapability -Online -Name $cap.Name | Out-Null
|
|
}
|
|
Write-Host ' - OpenSSH.Server instalado.' -ForegroundColor Green
|
|
|
|
# 2) Servicios --------------------------------------------------------------
|
|
foreach ($svc in @('sshd', 'ssh-agent')) {
|
|
if (Get-Service $svc -ErrorAction SilentlyContinue) {
|
|
Set-Service -Name $svc -StartupType Automatic
|
|
if ((Get-Service $svc).Status -ne 'Running') { Start-Service $svc }
|
|
Write-Host " - Servicio '$svc' -> Automatico y en marcha." -ForegroundColor Green
|
|
}
|
|
}
|
|
|
|
# 3) Shell por defecto = PowerShell ----------------------------------------
|
|
if (-not (Test-Path 'HKLM:\SOFTWARE\OpenSSH')) { New-Item -Path 'HKLM:\SOFTWARE\OpenSSH' -Force | Out-Null }
|
|
$pwsh = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
|
|
New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name 'DefaultShell' -Value $pwsh -PropertyType String -Force | Out-Null
|
|
Write-Host " - Shell por defecto: $pwsh" -ForegroundColor Green
|
|
|
|
# 4) Firewall (solo Tailscale + LAN) ---------------------------------------
|
|
$ruleName = 'OpenSSH Server (sshd) - acceso remoto'
|
|
Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue | Remove-NetFirewallRule
|
|
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Protocol TCP -Action Allow `
|
|
-LocalPort 22 -RemoteAddress $AllowedNetworks -Profile Any | Out-Null
|
|
Write-Host " - Firewall: puerto 22 permitido desde $($AllowedNetworks -join ', ')." -ForegroundColor Green
|
|
|
|
# 5) Clave publica ----------------------------------------------------------
|
|
if ($PublicKey) {
|
|
$usuarioEsAdmin = $null -ne (Get-LocalGroupMember -Group (Get-LocalGroup -SID 'S-1-5-32-544').Name |
|
|
Where-Object { $_.Name -like "*\$env:USERNAME" })
|
|
if ($usuarioEsAdmin) {
|
|
$keyFile = Join-Path $env:ProgramData 'ssh\administrators_authorized_keys'
|
|
$dir = Split-Path $keyFile
|
|
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
|
} else {
|
|
$keyFile = Join-Path $env:USERPROFILE '.ssh\authorized_keys'
|
|
$dir = Split-Path $keyFile
|
|
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
|
}
|
|
$contenido = if (Test-Path $keyFile) { Get-Content -LiteralPath $keyFile -ErrorAction SilentlyContinue } else { @() }
|
|
if ($contenido -notcontains $PublicKey.Trim()) {
|
|
Add-Content -LiteralPath $keyFile -Value $PublicKey.Trim() -Encoding ascii
|
|
Write-Host " - Clave publica anadida a $keyFile" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " - La clave publica ya estaba en $keyFile" -ForegroundColor Green
|
|
}
|
|
if ($usuarioEsAdmin) {
|
|
icacls $keyFile /inheritance:r 2>$null | Out-Null
|
|
icacls $keyFile /grant 'SYSTEM:F' 'BUILTIN\Administradores:F' 'BUILTIN\Administrators:F' 2>$null | Out-Null
|
|
}
|
|
Restart-Service sshd
|
|
Write-Host ' - sshd reiniciado para aplicar la clave.' -ForegroundColor Green
|
|
}
|
|
|
|
$ips = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '127.*' }).IPAddress -join ', '
|
|
Write-Host ''
|
|
Write-Host 'Listo. Datos de conexion:' -ForegroundColor Cyan
|
|
Write-Host " Usuario : $env:USERNAME"
|
|
Write-Host " IPs : $ips"
|
|
Write-Host " Prueba : ssh $env:USERNAME@<IP-o-nombre-tailscale>"
|