Public/Network/Get-VergeIPSecConnection.ps1
|
function Get-VergeIPSecConnection { <# .SYNOPSIS Retrieves IPSec VPN connections from a VergeOS network. .DESCRIPTION Get-VergeIPSecConnection returns IPSec Phase 1 (IKE) VPN connections configured on a virtual network. These define the IKE security association including remote gateway, authentication, and encryption settings. .PARAMETER Network The name or key of the network to get IPSec connections from. .PARAMETER NetworkObject A network object from Get-VergeNetwork. Accepts pipeline input. .PARAMETER Name Filter by connection name. Supports wildcards. .PARAMETER Key Get a specific connection by its unique key. .PARAMETER IncludePolicies Include Phase 2 policies (traffic selectors) in the output. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Get-VergeIPSecConnection -Network "External" Gets all IPSec connections on the External network. .EXAMPLE Get-VergeNetwork -Name "External" | Get-VergeIPSecConnection -Name "Site-to-Site*" Gets IPSec connections matching the wildcard pattern. .EXAMPLE Get-VergeIPSecConnection -Network "External" -IncludePolicies Gets connections with their Phase 2 traffic selector policies. .OUTPUTS Verge.IPSecConnection .NOTES IPSec connections require an IPSec configuration to exist on the network. #> [CmdletBinding(DefaultParameterSetName = 'ByNetworkName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByNetworkName')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByNetworkNameAndKey')] [string]$Network, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByNetworkObject')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByNetworkObjectAndKey')] [PSTypeName('Verge.Network')] [PSCustomObject]$NetworkObject, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [SupportsWildcards()] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByNetworkNameAndKey')] [Parameter(Mandatory, ParameterSetName = 'ByNetworkObjectAndKey')] [int]$Key, [Parameter()] [switch]$IncludePolicies, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } # Key exchange mapping $keyExchangeMap = @{ 'ike' = 'Auto' 'ikev1' = 'IKEv1' 'ikev2' = 'IKEv2' } # Auth method mapping $authMap = @{ 'psk' = 'Pre-Shared Key' 'pubkey' = 'RSA Certificate' } # Connection behavior mapping $autoMap = @{ 'add' = 'Responder Only' 'route' = 'On-Demand' 'start' = 'Always Start' } # DPD action mapping $dpdMap = @{ 'none' = 'Disabled' 'clear' = 'Clear' 'hold' = 'Hold' 'restart' = 'Restart' } } process { # Resolve network $targetNetwork = $null if ($PSCmdlet.ParameterSetName -like 'ByNetworkObject*') { $targetNetwork = $NetworkObject } else { if ($Network -match '^\d+$') { $targetNetwork = Get-VergeNetwork -Key ([int]$Network) -Server $Server } else { $targetNetwork = Get-VergeNetwork -Name $Network -Server $Server } } if (-not $targetNetwork) { Write-Error -Message "Network '$Network' not found" -ErrorId 'NetworkNotFound' return } Write-Verbose "Querying IPSec connections for network '$($targetNetwork.Name)'" try { # First get the IPSec config for this network $ipsecQuery = @{ filter = "vnet eq $($targetNetwork.Key)" fields = '$key,enabled,mode,uniqueids,compress' } $ipsecConfig = Invoke-VergeAPI -Method GET -Endpoint 'vnet_ipsecs' -Query $ipsecQuery -Connection $Server if (-not $ipsecConfig -or (-not $ipsecConfig.'$key' -and $ipsecConfig.Count -eq 0)) { Write-Verbose "No IPSec configuration found for network '$($targetNetwork.Name)'" return } # Get the IPSec config key $ipsecKey = if ($ipsecConfig -is [array]) { $ipsecConfig[0].'$key' } else { $ipsecConfig.'$key' } if (-not $ipsecKey) { Write-Verbose "No IPSec configuration key found" return } # Build Phase 1 query $phase1Query = @{ fields = @( '$key', 'ipsec', 'enabled', 'name', 'description', 'keyexchange', 'remote_gateway', 'auth', 'negotiation', 'identifier', 'peer_identifier', 'ike', 'ikelifetime', 'auto', 'mobike', 'split_connections', 'forceencaps', 'keyingtries', 'rekey', 'reauth', 'margintime', 'dpdaction', 'dpddelay', 'dpdfailures', 'modified' ) -join ',' sort = 'name' } # Add filters $filters = @("ipsec eq $ipsecKey") if ($PSCmdlet.ParameterSetName -like '*AndKey') { $filters += "`$key eq $Key" } elseif ($Name -and -not [WildcardPattern]::ContainsWildcardCharacters($Name)) { $filters += "name eq '$Name'" } $phase1Query['filter'] = $filters -join ' and ' $response = Invoke-VergeAPI -Method GET -Endpoint 'vnet_ipsec_phase1s' -Query $phase1Query -Connection $Server # Handle response $connections = if ($null -eq $response) { @() } elseif ($response -is [array]) { $response } elseif ($response.'$key') { @($response) } else { @() } # Apply wildcard filter if needed if ($Name -and [WildcardPattern]::ContainsWildcardCharacters($Name)) { $connections = $connections | Where-Object { $_.name -like $Name } } foreach ($conn in $connections) { $output = [PSCustomObject]@{ PSTypeName = 'Verge.IPSecConnection' Key = $conn.'$key' IPSecKey = $conn.ipsec NetworkKey = $targetNetwork.Key NetworkName = $targetNetwork.Name Name = $conn.name Description = $conn.description Enabled = $conn.enabled RemoteGateway = $conn.remote_gateway KeyExchange = if ($keyExchangeMap[$conn.keyexchange]) { $keyExchangeMap[$conn.keyexchange] } else { $conn.keyexchange } KeyExchangeRaw = $conn.keyexchange AuthMethod = if ($authMap[$conn.auth]) { $authMap[$conn.auth] } else { $conn.auth } AuthMethodRaw = $conn.auth Negotiation = $conn.negotiation Identifier = $conn.identifier PeerIdentifier = $conn.peer_identifier Encryption = $conn.ike IKELifetime = $conn.ikelifetime ConnectionMode = if ($autoMap[$conn.auto]) { $autoMap[$conn.auto] } else { $conn.auto } ConnectionModeRaw = $conn.auto MOBIKE = $conn.mobike SplitConnections = $conn.split_connections ForceUDPEncap = $conn.forceencaps KeyingTries = $conn.keyingtries Rekey = $conn.rekey Reauthenticate = $conn.reauth MarginTime = $conn.margintime DPDAction = if ($dpdMap[$conn.dpdaction]) { $dpdMap[$conn.dpdaction] } else { $conn.dpdaction } DPDActionRaw = $conn.dpdaction DPDDelay = $conn.dpddelay DPDFailures = $conn.dpdfailures Modified = if ($conn.modified) { [DateTimeOffset]::FromUnixTimeSeconds($conn.modified).LocalDateTime } else { $null } } # Include Phase 2 policies if requested if ($IncludePolicies) { $phase2Query = @{ filter = "phase1 eq $($conn.'$key')" fields = '$key,enabled,name,description,mode,local,remote,lifetime,protocol,ciphers' sort = 'name' } $phase2Response = Invoke-VergeAPI -Method GET -Endpoint 'vnet_ipsec_phase2s' -Query $phase2Query -Connection $Server $policies = if ($null -eq $phase2Response) { @() } elseif ($phase2Response -is [array]) { $phase2Response } elseif ($phase2Response.'$key') { @($phase2Response) } else { @() } $policyObjects = foreach ($policy in $policies) { [PSCustomObject]@{ PSTypeName = 'Verge.IPSecPolicy' Key = $policy.'$key' Phase1Key = $conn.'$key' Name = $policy.name Description = $policy.description Enabled = $policy.enabled Mode = $policy.mode LocalNetwork = $policy.local RemoteNetwork = $policy.remote Lifetime = $policy.lifetime Protocol = $policy.protocol Ciphers = $policy.ciphers } } $output | Add-Member -MemberType NoteProperty -Name 'Policies' -Value $policyObjects $output | Add-Member -MemberType NoteProperty -Name 'PolicyCount' -Value $policyObjects.Count } Write-Output $output } } catch { Write-Error -Message "Failed to query IPSec connections: $($_.Exception.Message)" -ErrorId 'IPSecQueryFailed' } } } |