Add port forwarding support, improve XML documentation, and add unit tests

This commit is contained in:
GraceSolutions
2025-04-14 22:48:53 -04:00
commit afcb6dbbfa
203 changed files with 30165 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
name: Build and Release
on:
push:
branches: [ main ]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'
- '!.github/workflows/build-and-release.yml'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
release:
description: 'Create a release'
required: false
default: false
type: boolean
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '6.0.x'
- name: Setup PowerShell
uses: actions/setup-powershell@v1
with:
powershell-version: '7.2'
- name: Restore dependencies
run: dotnet restore src/PSOPNSenseAPI.sln
- name: Run tests
run: pwsh -Command "./build/test.ps1 -Configuration Release"
- name: Build and package
run: |
pwsh -Command "./build/build-release.ps1 -Clean -Package"
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: PSOPNSenseAPI
path: output/PSOPNSenseAPI/
- name: Upload package artifacts
uses: actions/upload-artifact@v3
with:
name: PSOPNSenseAPI-Package
path: packages/*.zip
release:
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.event.inputs.release == 'true'
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup PowerShell
uses: actions/setup-powershell@v1
with:
powershell-version: '7.2'
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: PSOPNSenseAPI
path: output/PSOPNSenseAPI/
- name: Download package artifacts
uses: actions/download-artifact@v3
with:
name: PSOPNSenseAPI-Package
path: packages/
- name: Configure Git
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
- name: Create Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$version = Get-Date -Format "yyyy.MM.dd.HHmm"
# Update version in project file
$projectFile = "src/PSOPNSenseAPI/PSOPNSenseAPI.csproj"
$projectXml = [xml](Get-Content $projectFile)
$versionNode = $projectXml.Project.PropertyGroup.Version
$versionNode.InnerText = $version
$projectXml.Save($projectFile)
# Update version in module manifest
$manifestFile = "PSOPNSenseAPI/PSOPNSenseAPI.psd1"
$manifestContent = Get-Content -Path $manifestFile -Raw
$manifestContent = $manifestContent -replace "ModuleVersion\s*=\s*['`"].*['`"]", "ModuleVersion = '$version'"
Set-Content -Path $manifestFile -Value $manifestContent
# Commit changes
git add $projectFile
git add $manifestFile
git commit -m "Release version $version [skip ci]"
git push
# Create release
$packagePath = Get-ChildItem -Path "packages/*.zip" | Select-Object -First 1 -ExpandProperty FullName
gh release create "v$version" `
--title "Release v$version" `
--notes "Release version $version - $(Get-Date -Format 'yyyy-MM-dd')" `
$packagePath
shell: pwsh
+3
View File
@@ -0,0 +1,3 @@
.vs/
bin/
obj/
+69
View File
@@ -0,0 +1,69 @@
# Changelog
All notable changes to the PSOPNSenseAPI module will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.6.0] - 2025-04-14
### Added
- Port forwarding management (Get, New, Set, Remove)
- Added unit tests for interface management
### Changed
- Updated IPNetwork2 library from version 2.6.618 to 3.1.764
- Updated code to use the new namespace (System.Net) for IPNetwork2
- Added support for .NET 8.0 and .NET 9.0
- Improved XML documentation for all classes and methods
- Made OPNSenseApiClient more testable by introducing an interface
## [0.5.0] - 2025-04-16
### Added
- Tailscale VPN management (Get, Enable, Disable, Connect, Disconnect)
- Auto-installation of Tailscale plugin if not present
- Support for configuring Tailscale settings
- Subnet route advertising for Tailscale networks
## [0.4.0] - 2025-04-15
### Added
- DHCP server management (Get, Set)
- DHCP static mapping management (Get, New, Set, Remove)
- Cron job management (Get, New, Set, Remove, Enable, Disable)
- Improved credential handling in Restart-OPNSenseFirewall
- Switched from IPNetwork to IPNetwork2 for better subnet handling
- Implemented DHCP configuration in New-OPNSenseSubnetVLANs
## [0.3.0] - 2025-04-14
### Added
- Plugin management (Get, Enable, Disable, Install, Uninstall)
- User management (Get, New, Set, Remove)
- Firmware management (Get, Update, Upgrade)
- Firewall reboot functionality with wait for reconnection
- Subnet division and VLAN creation utility
- Completed all firewall rule, alias, and NAT rule management cmdlets
## [0.2.0] - 2025-04-14
### Added
- Interface management (Get, Set, Restart, Statistics)
- VLAN management (Get, New, Set, Remove)
- DNS configuration (Servers, Domains, Overrides)
- Configuration backup and restore functionality
## [0.1.0] - 2025-04-14
### Added
- Initial release
- Basic connection management (Connect-OPNSense, Disconnect-OPNSense)
- Firewall rule management (Get, New, Set, Remove, Enable, Disable)
- Alias management (Get, New, Set, Remove)
- NAT rule management (Get, New, Set, Remove)
- Comprehensive logging system
- Error handling and retry logic
- Support for both PowerShell 5.1 and PowerShell 7
+179
View File
@@ -0,0 +1,179 @@
# Contributing to PSOPNSenseAPI
Thank you for your interest in contributing to the PSOPNSenseAPI module! This document provides guidelines and instructions for contributing to the project.
## Code of Conduct
This project adheres to a Code of Conduct that all contributors are expected to follow. Please read and understand the [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
## How Can I Contribute?
There are many ways to contribute to the PSOPNSenseAPI module:
- Reporting bugs
- Suggesting enhancements
- Writing documentation
- Submitting code changes
- Reviewing pull requests
- Helping other users
### Reporting Bugs
Before reporting a bug, please check the [issue tracker](https://github.com/freedbygrace/PSOPNSenseAPI/issues) to see if the bug has already been reported. If it has, you can add additional information to the existing issue.
When reporting a bug, please include:
- A clear and descriptive title
- A detailed description of the issue
- Steps to reproduce the bug
- Expected behavior
- Actual behavior
- Screenshots or error messages (if applicable)
- Your environment (PowerShell version, OPNSense version, module version)
### Suggesting Enhancements
Enhancement suggestions are welcome! Please include:
- A clear and descriptive title
- A detailed description of the enhancement
- The motivation for the enhancement
- Any potential implementation details
- Examples of how the enhancement would be used
### Writing Documentation
Documentation improvements are always welcome. You can contribute by:
- Fixing typos or errors in existing documentation
- Adding missing documentation
- Improving examples or explanations
- Adding tutorials or guides
### Submitting Code Changes
1. Fork the repository
2. Create a new branch for your changes
3. Make your changes
4. Write or update tests for your changes
5. Ensure all tests pass
6. Submit a pull request
#### Coding Standards
- Follow the existing code style and conventions
- Use meaningful variable and function names
- Write clear and concise comments
- Include XML documentation for all public members
- Follow PowerShell best practices
#### Testing
- Write tests for all new functionality
- Ensure all existing tests pass
- Test your changes on both PowerShell 5.1 and PowerShell 7
- Test your changes on different OPNSense versions if possible
### Pull Request Process
1. Update the README.md and documentation with details of your changes
2. Update the CHANGELOG.md with details of your changes
3. Ensure all tests pass
4. Submit the pull request with a clear description of the changes
## Development Environment Setup
### Prerequisites
- Visual Studio 2019 or later
- PowerShell 5.1 or PowerShell 7+
- .NET Framework 4.7.2 SDK (for Windows PowerShell 5.1 compatibility)
- .NET Core 3.1 SDK or later (for PowerShell 7+ compatibility)
- Git
### Setting Up the Development Environment
1. Clone the repository:
```
git clone https://github.com/freedbygrace/PSOPNSenseAPI.git
cd PSOPNSenseAPI
```
2. Open the solution in Visual Studio:
```
start PSOPNSenseAPI.sln
```
3. Restore NuGet packages:
```
dotnet restore
```
4. Build the solution:
```
dotnet build
```
### Building and Testing
To build the module:
```powershell
.\build\build.ps1
```
To run tests:
```powershell
.\build\test.ps1
```
To build a release version:
```powershell
.\build\build-release.ps1 -Clean -Test -Package
```
## Project Structure
The project follows this structure:
- **src/PSOPNSenseAPI**: Main source code
- **Cmdlets**: PowerShell cmdlets
- **Models**: Data models
- **Services**: Service classes for API communication
- **Utilities**: Utility classes
- **Logging**: Logging infrastructure
- **tests**: Unit and integration tests
- **docs**: Documentation
- **build**: Build scripts
- **output**: Build output (not in source control)
## Versioning
The module uses a versioning scheme of `yyyy.MM.dd.HHmm` for releases, which is automatically generated during the build process.
## Release Process
1. Update the CHANGELOG.md file
2. Build a release package:
```
.\build\build-release.ps1 -Clean -Test -Package
```
3. Create a new release on GitHub with the generated package
## Getting Help
If you need help with contributing:
- Open an issue on GitHub
- Reach out to the maintainers
- Check the documentation and existing issues
## License
By contributing to this project, you agree that your contributions will be licensed under the project's [MIT License](LICENSE).
## Acknowledgments
Thank you to all contributors who have helped improve this module!
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 PSOPNSenseAPI Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+35
View File
@@ -0,0 +1,35 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSOPNSenseAPI", "src\PSOPNSenseAPI\PSOPNSenseAPI.csproj", "{B5FF021D-65A9-4E5A-A661-152CB7549ED2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{17CE58CD-B605-49EA-8AD4-6D034E0330E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PSOPNSenseAPI.Tests", "tests\PSOPNSenseAPI.Tests\PSOPNSenseAPI.Tests.csproj", "{D1BF04F2-AD6E-419B-9160-C0CB328594E4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B5FF021D-65A9-4E5A-A661-152CB7549ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5FF021D-65A9-4E5A-A661-152CB7549ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5FF021D-65A9-4E5A-A661-152CB7549ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5FF021D-65A9-4E5A-A661-152CB7549ED2}.Release|Any CPU.Build.0 = Release|Any CPU
{D1BF04F2-AD6E-419B-9160-C0CB328594E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1BF04F2-AD6E-419B-9160-C0CB328594E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1BF04F2-AD6E-419B-9160-C0CB328594E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1BF04F2-AD6E-419B-9160-C0CB328594E4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F1E2D3C4-B5A6-9876-5432-1098F7E6D5C4}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D1BF04F2-AD6E-419B-9160-C0CB328594E4} = {17CE58CD-B605-49EA-8AD4-6D034E0330E8}
EndGlobalSection
EndGlobal
+208
View File
@@ -0,0 +1,208 @@
@{
# Script module or binary module file associated with this manifest.
RootModule = 'PSOPNSenseAPI.psm1'
# Version number of this module.
ModuleVersion = '2025.04.14.1839'
# Supported PSEditions
CompatiblePSEditions = @('Desktop', 'Core')
# ID used to uniquely identify this module
GUID = '8f7a3d7a-0e5a-4b7c-9b5a-9c5b3a5a8e7a'
# Author of this module
Author = 'PSOPNSenseAPI Contributors'
# Company or vendor of this module
CompanyName = 'PSOPNSenseAPI'
# Copyright statement for this module
Copyright = '(c) 2025 PSOPNSenseAPI Contributors. All rights reserved.'
# Description of the functionality provided by this module
Description = 'PowerShell module for interacting with the OPNSense API to configure firewalls'
# Minimum version of the PowerShell engine required by this module
PowerShellVersion = '5.1'
# Name of the PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
DotNetFrameworkVersion = '4.7.2'
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# ClrVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @('bin\PSOPNSenseAPI.dll')
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = @('bin\PSOPNSenseAPI.dll')
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @()
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @(
# Connection Management
'Connect-OPNSense',
'Disconnect-OPNSense',
'Get-OPNSenseConnection',
# Firewall Rule Management
'Get-OPNSenseFirewallRule',
'New-OPNSenseFirewallRule',
'Set-OPNSenseFirewallRule',
'Remove-OPNSenseFirewallRule',
'Enable-OPNSenseFirewallRule',
'Disable-OPNSenseFirewallRule',
'Apply-OPNSenseFirewallChanges',
# Alias Management
'Get-OPNSenseAlias',
'New-OPNSenseAlias',
'Set-OPNSenseAlias',
'Remove-OPNSenseAlias',
# NAT Rule Management
'Get-OPNSenseNATRule',
'New-OPNSenseNATRule',
'Set-OPNSenseNATRule',
'Remove-OPNSenseNATRule',
# Interface Management
'Get-OPNSenseInterface',
'Set-OPNSenseInterface',
'Restart-OPNSenseInterface',
'Get-OPNSenseInterfaceStatistics',
'New-OPNSenseSubnetVLANs',
# VLAN Management
'Get-OPNSenseVLAN',
'New-OPNSenseVLAN',
'Set-OPNSenseVLAN',
'Remove-OPNSenseVLAN',
# DNS Configuration
'Get-OPNSenseDNSServer',
'Set-OPNSenseDNSServer',
'Get-OPNSenseDNSDomain',
'Set-OPNSenseDNSDomain',
'Get-OPNSenseDNSOverride',
'New-OPNSenseDNSOverride',
'Remove-OPNSenseDNSOverride',
# Configuration Management
'Backup-OPNSenseConfig',
'Restore-OPNSenseConfig',
'Export-OPNSenseConfig',
'Import-OPNSenseConfig',
'Get-OPNSenseConfigBackup',
# Plugin Management
'Get-OPNSensePlugin',
'Install-OPNSensePlugin',
'Uninstall-OPNSensePlugin',
'Enable-OPNSensePlugin',
'Disable-OPNSensePlugin',
# User Management
'Get-OPNSenseUser',
'New-OPNSenseUser',
'Set-OPNSenseUser',
'Remove-OPNSenseUser',
# Firmware Management
'Get-OPNSenseFirmware',
'Update-OPNSenseFirmware',
'Upgrade-OPNSenseFirmware',
# System Management
'Restart-OPNSenseFirewall'
)
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('OPNSense', 'Firewall', 'API', 'Network', 'Security')
# A URL to the license for this module.
LicenseUri = 'https://github.com/freedbygrace/PSOPNSenseAPI/blob/main/LICENSE'
# A URL to the main website for this project.
ProjectUri = 'https://github.com/freedbygrace/PSOPNSenseAPI'
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
ReleaseNotes = 'Initial release of the PSOPNSenseAPI module'
# Prerelease string of this module
# Prerelease = ''
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
# RequireLicenseAcceptance = $false
# External dependent modules of this module
# ExternalModuleDependencies = @()
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}
+3
View File
@@ -0,0 +1,3 @@
# This file is intentionally left empty.
# The module functionality is provided by the binary module (DLL).
# This file exists to allow for future PowerShell script functions if needed.
+197
View File
@@ -0,0 +1,197 @@
# PSOPNSenseAPI
PowerShell module for interacting with the OPNSense API to configure firewalls.
## Overview
PSOPNSenseAPI is a PowerShell module that provides cmdlets for managing OPNSense firewalls through their API. The module is built as a binary module in C# and is compatible with both PowerShell 5.1 and PowerShell 7.
## Features
- Connect to OPNSense firewalls using API credentials
- Manage firewall rules (create, read, update, delete)
- Configure NAT rules and port forwarding
- Manage aliases (host, network, port, URL, etc.)
- Manage network interfaces and VLANs
- Configure DNS settings, overrides, and forwarding
- Configure system DNS servers
- Backup, restore, export, and import configurations
- Manage plugins (install, uninstall, enable, disable)
- Manage users and permissions
- Update and upgrade firmware
- Reboot firewall with wait for reconnection
- Create VLANs from subnet divisions
- Configure DHCP servers, static mappings, leases, and options
- Manage cron jobs
- Configure and manage Tailscale VPN (with auto-installation)
- Manage gateways and static routes
- Network calculation utilities (subnet, supernet, CIDR conversion)
- Apply and revert configuration changes
- Extensive logging and error handling
- Compatible with both PowerShell 5.1 and PowerShell 7
## Requirements
- PowerShell 5.1 or PowerShell 7+
- .NET Framework 4.7.2+ (for PowerShell 5.1)
- .NET Core 3.1+ (for PowerShell 7)
## Installation
```powershell
# Install from PowerShell Gallery (when published)
Install-Module -Name PSOPNSenseAPI
# Or install manually
# 1. Download the module
# 2. Extract to a directory in your PSModulePath
# 3. Import the module
Import-Module PSOPNSenseAPI
```
## Quick Start
```powershell
# Connect to an OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all firewall rules
Get-OPNSenseFirewallRule
# Create a new firewall rule
New-OPNSenseFirewallRule -Description "Allow HTTP" -Protocol TCP -SourceNet "192.168.1.0/24" -DestinationPort 80 -Action Pass
# Apply changes
Apply-OPNSenseFirewallChanges
# Manage aliases
Get-OPNSenseAlias
New-OPNSenseAlias -Name "WebServers" -Type host -Content "192.168.1.10,192.168.1.11" -Description "Web Servers" -Apply
New-OPNSenseAlias -Name "WebPorts" -Type port -Content "80,443" -Protocol TCP -Description "Web Ports" -Apply
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Content "192.168.1.10,192.168.1.11,192.168.1.12" -Apply
# Manage interfaces
Get-OPNSenseInterface
Set-OPNSenseInterface -Name "lan" -Description "Local Network" -IpAddress "192.168.1.1" -SubnetMask "24"
# Create VLANs from subnet divisions
New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 10 -EnableDHCP
# Configure DNS
Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4" -Apply
New-OPNSenseDNSOverride -Hostname "server" -Domain "local" -IpAddress "192.168.1.10"
# Manage plugins
Get-OPNSensePlugin -Installed
Install-OPNSensePlugin -Name "os-acme-client" -Wait
# Manage users
New-OPNSenseUser -Username "john" -Password "P@ssw0rd" -FullName "John Doe" -Groups "admins"
# Configure DHCP
Get-OPNSenseDHCPServer
Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Apply
New-OPNSenseDHCPStaticMapping -Interface "lan" -MacAddress "00:11:22:33:44:55" -IpAddress "192.168.1.50" -Hostname "printer"
Get-OPNSenseDHCPLease
Remove-OPNSenseDHCPLease -MacAddress "00:11:22:33:44:55" -Apply
Get-OPNSenseDHCPOption -Interface "lan"
New-OPNSenseDHCPOption -Interface "lan" -Number 66 -Value "192.168.1.10" -Description "TFTP Server" -Apply
# Manage cron jobs
Get-OPNSenseCronJob
New-OPNSenseCronJob -Description "Daily backup" -Command "/usr/local/bin/backup.sh" -Minutes "0" -Hours "2" -Apply
# Configure and manage Tailscale
Get-OPNSenseTailscaleStatus -IncludeInterfaces
Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Force
# Advertise subnet routes to Tailscale network
Enable-OPNSenseTailscale -AdvertiseRoutes -SubnetRoutes "192.168.1.0/24","10.0.0.0/8" -Force
Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing -Force
# Manage DNS forwarding
Get-OPNSenseDNSForwarding
Set-OPNSenseDNSForwarding -Enabled -DnsServers "8.8.8.8","8.8.4.4" -Apply
New-OPNSenseDNSForwardingHost -Domain "example.com" -Server "192.168.1.10" -Apply
# Configure system DNS
Get-OPNSenseSystemDNS
Set-OPNSenseSystemDNS -Hostname "firewall" -Domain "example.com" -DnsServers "1.1.1.1","1.0.0.1" -Apply
# Manage gateways and routes
Get-OPNSenseGateway -IncludeStatus
New-OPNSenseGateway -Name "WAN2_GW" -Interface "opt1" -IpAddress "203.0.113.1" -Description "Secondary WAN" -Apply
Get-OPNSenseRoute
New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN2_GW" -Description "Remote Office" -Apply
# Network utilities
Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Subnet -PrefixLength 24
ConvertTo-OPNSenseNetworkNotation -CIDR 24 # Returns "255.255.255.0"
# Advanced supernetting
Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Supernet -AdditionalNetworks "192.168.2.0/24"
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "10.0.1.0/24","10.0.2.0/24"
# Firmware management
Update-OPNSenseFirmware -Wait
# Reboot firewall
Restart-OPNSenseFirewall -Wait -Timeout 300
# Backup and restore configuration
Backup-OPNSenseConfig -Filename "pre-upgrade-backup"
Export-OPNSenseConfig -Path "C:\Backups\opnsense-config.xml"
```
## Documentation
For detailed documentation, see the [docs](./docs) directory or use PowerShell's built-in help:
```powershell
Get-Help Connect-OPNSense -Full
```
## Development
### Build and Test
To build and test the module locally:
```powershell
# Run tests
.\build\test.ps1
# Build the module
.\build\build.ps1
# Build a release version with automatic versioning
.\build\build-release.ps1 -Clean -Test -Package
```
### Versioning
The module uses a versioning scheme of `yyyy.MM.dd.HHmm` for releases, which is automatically generated during the build process.
### CI/CD
The project uses GitHub Actions for continuous integration and deployment:
- Builds and tests are run on every push to the main branch
- Release packages are automatically created with the versioning scheme
- Release artifacts are uploaded to GitHub Releases
## Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Run tests to ensure they pass
5. Commit your changes (`git commit -m 'Add some amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request
## License
This project is licensed under the MIT License - see the LICENSE file for details.
+201
View File
@@ -0,0 +1,201 @@
[CmdletBinding()]
param (
[Parameter()]
[switch]
$Clean,
[Parameter()]
[switch]
$Test,
[Parameter()]
[switch]
$Package,
[Parameter()]
[switch]
$Push,
[Parameter()]
[string]
$GitHubToken
)
$ErrorActionPreference = 'Stop'
# Define paths
$rootDir = Split-Path -Parent $PSScriptRoot
$srcDir = Join-Path -Path $rootDir -ChildPath "src"
$testDir = Join-Path -Path $srcDir -ChildPath "PSOPNSenseAPI.Tests"
$projectDir = Join-Path -Path $srcDir -ChildPath "PSOPNSenseAPI"
$outputDir = Join-Path -Path $rootDir -ChildPath "output\PSOPNSenseAPI"
$moduleDir = Join-Path -Path $rootDir -ChildPath "PSOPNSenseAPI"
# Generate version number based on current date and time
$version = Get-Date -Format "yyyy.MM.dd.HHmm"
Write-Output "Building version: $version"
# Clean output directory if requested
if ($Clean -and (Test-Path -Path $outputDir)) {
Write-Verbose "Cleaning output directory: $outputDir"
Remove-Item -Path $outputDir -Recurse -Force
}
# Create output directory if it doesn't exist
if (-not (Test-Path -Path $outputDir)) {
Write-Verbose "Creating output directory: $outputDir"
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
# Update version in project file
$projectFile = Join-Path -Path $projectDir -ChildPath "PSOPNSenseAPI.csproj"
# Update the version using XML manipulation
Write-Output "Updating version in project file to $version"
$projectContent = Get-Content -Path $projectFile -Raw
$updatedContent = $projectContent -replace '<Version>[^<]+</Version>', "<Version>$version</Version>"
Set-Content -Path $projectFile -Value $updatedContent
# Verify the update
$newContent = Get-Content -Path $projectFile -Raw
if ($newContent -match "<Version>$version</Version>") {
Write-Output "Successfully updated version in project file"
} else {
Write-Warning "Failed to update version in project file"
}
# Project file has been updated
# Update version in module manifest
$manifestFile = Join-Path -Path $moduleDir -ChildPath "PSOPNSenseAPI.psd1"
if (Test-Path $manifestFile) {
Write-Output "Updating module manifest version to $version"
$manifestContent = Get-Content -Path $manifestFile -Raw
# Use a more flexible regex pattern to match the ModuleVersion line
if ($manifestContent -match "ModuleVersion\s*=\s*['`"].*['`"]") {
$newManifestContent = $manifestContent -replace "ModuleVersion\s*=\s*['`"].*['`"]", "ModuleVersion = '$version'"
Set-Content -Path $manifestFile -Value $newManifestContent
Write-Output "Successfully updated module manifest version"
} else {
# Try a different approach if the regex doesn't match
$lines = Get-Content -Path $manifestFile
$versionLineIndex = $lines | Select-String -Pattern "ModuleVersion" | Select-Object -First 1 -ExpandProperty LineNumber
if ($versionLineIndex) {
$lines[$versionLineIndex - 1] = " ModuleVersion = '$version'"
Set-Content -Path $manifestFile -Value $lines
Write-Output "Successfully updated module manifest version using line replacement"
} else {
Write-Warning "Failed to update module version in manifest. ModuleVersion line not found."
}
}
} else {
Write-Warning "Module manifest file not found at $manifestFile"
}
# Run tests if requested
if ($Test) {
Write-Output "Running tests..."
& "$PSScriptRoot\test.ps1" -Configuration "Release"
if ($LASTEXITCODE -ne 0) {
throw "Tests failed with exit code $LASTEXITCODE"
}
}
# Build the solution
Write-Output "Building solution in Release configuration..."
# Create bin directory if it doesn't exist
$binDir = Join-Path -Path $outputDir -ChildPath "bin"
if (-not (Test-Path -Path $binDir)) {
Write-Output "Creating bin directory: $binDir"
New-Item -Path $binDir -ItemType Directory -Force | Out-Null
}
# Build the project
dotnet build "$projectDir" -c Release -o "$binDir"
if ($LASTEXITCODE -ne 0) {
throw "Build failed with exit code $LASTEXITCODE"
}
Write-Output "DLLs built successfully to: $binDir"
# Copy module files
Write-Output "Copying module files to output directory"
Copy-Item -Path "$moduleDir\*" -Destination $outputDir -Recurse -Force
# Verify DLLs were built
$dllPath = Join-Path -Path $binDir -ChildPath "PSOPNSenseAPI.dll"
if (Test-Path $dllPath) {
Write-Output "Verified DLL was built: $dllPath"
} else {
Write-Warning "DLL was not found at expected location: $dllPath"
}
# Create a zip package if requested
if ($Package) {
$packageDir = Join-Path -Path $rootDir -ChildPath "packages"
if (-not (Test-Path -Path $packageDir)) {
New-Item -Path $packageDir -ItemType Directory -Force | Out-Null
}
$zipFile = Join-Path -Path $packageDir -ChildPath "PSOPNSenseAPI-$version.zip"
if (Test-Path -Path $zipFile) {
Remove-Item -Path $zipFile -Force
}
Write-Output "Creating package: $zipFile"
Compress-Archive -Path "$outputDir\*" -DestinationPath $zipFile
}
# Push to GitHub and create a release if requested
if ($Push) {
if ([string]::IsNullOrEmpty($GitHubToken)) {
throw "GitHubToken parameter is required for pushing to GitHub"
}
Write-Output "Committing changes to Git..."
git add "$projectFile"
git add "$manifestFile"
git commit -m "Release version $version"
Write-Output "Pushing changes to GitHub..."
git push
Write-Output "Creating GitHub release..."
$releaseNotes = "Release version $version - $(Get-Date -Format 'yyyy-MM-dd')"
# Create the release using GitHub CLI or REST API
$headers = @{
"Authorization" = "token $GitHubToken"
"Accept" = "application/vnd.github.v3+json"
}
$releaseData = @{
tag_name = "v$version"
name = "Release v$version"
body = $releaseNotes
draft = $false
prerelease = $false
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/freedbygrace/PSOPNSenseAPI/releases" -Method Post -Headers $headers -Body $releaseData
if ($Package) {
Write-Output "Uploading package to GitHub release..."
$uploadUrl = $response.upload_url -replace "{.*}", ""
$fileName = Split-Path -Path $zipFile -Leaf
Invoke-RestMethod -Uri "$uploadUrl?name=$fileName" -Method Post -Headers $headers -InFile $zipFile -ContentType "application/zip"
}
}
Write-Output "Build completed successfully!"
Write-Output "Module output is available at: $outputDir"
if ($Package) {
Write-Output "Package is available at: $zipFile"
}
+91
View File
@@ -0,0 +1,91 @@
[CmdletBinding()]
param (
[Parameter()]
[string]
$Configuration = "Release",
[Parameter()]
[switch]
$Clean,
[Parameter()]
[switch]
$UpdateVersion
)
$ErrorActionPreference = 'Stop'
# Define paths
$rootDir = Split-Path -Parent $PSScriptRoot
$srcDir = Join-Path -Path $rootDir -ChildPath "src"
$outputDir = Join-Path -Path $rootDir -ChildPath "output\PSOPNSenseAPI"
$moduleDir = Join-Path -Path $rootDir -ChildPath "PSOPNSenseAPI"
# Clean output directory if requested
if ($Clean -and (Test-Path -Path $outputDir)) {
Write-Verbose "Cleaning output directory: $outputDir"
Remove-Item -Path $outputDir -Recurse -Force
}
# Create output directory if it doesn't exist
if (-not (Test-Path -Path $outputDir)) {
Write-Verbose "Creating output directory: $outputDir"
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
# Update version if requested
if ($UpdateVersion) {
$version = Get-Date -Format "yyyy.MM.dd.HHmm"
Write-Output "Updating version to: $version"
# Update version in project file
$projectFile = Join-Path -Path "$srcDir\PSOPNSenseAPI" -ChildPath "PSOPNSenseAPI.csproj"
if (Test-Path $projectFile) {
$projectXml = [xml](Get-Content $projectFile)
$versionNodes = $projectXml.SelectNodes("//Version")
if ($versionNodes.Count -gt 0) {
foreach ($node in $versionNodes) {
$node.InnerText = $version
}
$projectXml.Save($projectFile)
Write-Output "Updated version in project file to $version"
} else {
Write-Warning "Could not find Version node in project file"
}
} else {
Write-Warning "Project file not found at $projectFile"
}
# Update version in module manifest
$manifestFile = Join-Path -Path $moduleDir -ChildPath "PSOPNSenseAPI.psd1"
if (Test-Path $manifestFile) {
$manifestContent = Get-Content -Path $manifestFile -Raw
$newManifestContent = $manifestContent -replace "ModuleVersion\s*=\s*['`"].*['`"]", "ModuleVersion = '$version'"
Set-Content -Path $manifestFile -Value $newManifestContent
Write-Output "Updated version in module manifest to $version"
} else {
Write-Warning "Module manifest file not found at $manifestFile"
}
}
# Build the solution
Write-Output "Building solution in $Configuration configuration..."
dotnet build "$srcDir\PSOPNSenseAPI" -c $Configuration -o "$outputDir\bin"
if ($LASTEXITCODE -ne 0) {
throw "Build failed with exit code $LASTEXITCODE"
}
# Copy module files
Write-Verbose "Copying module files to output directory"
Copy-Item -Path "$moduleDir\*" -Destination $outputDir -Recurse -Force
# Create module directory in PSModulePath if it doesn't exist
$modulePath = $env:PSModulePath -split ';' | Select-Object -First 1
$installPath = Join-Path -Path $modulePath -ChildPath "PSOPNSenseAPI"
Write-Verbose "Module can be installed to: $installPath"
Write-Verbose "To install, run: Copy-Item -Path '$outputDir\*' -Destination '$installPath' -Recurse -Force"
Write-Output "Build completed successfully!"
Write-Output "Module output is available at: $outputDir"
+23
View File
@@ -0,0 +1,23 @@
[CmdletBinding()]
param (
[Parameter()]
[string]
$Configuration = "Debug"
)
$ErrorActionPreference = 'Stop'
# Define paths
$rootDir = Split-Path -Parent $PSScriptRoot
$srcDir = Join-Path -Path $rootDir -ChildPath "src"
$testDir = Join-Path -Path $srcDir -ChildPath "PSOPNSenseAPI.Tests"
# Run the tests
Write-Verbose "Running tests in $Configuration configuration"
dotnet test "$testDir" -c $Configuration
if ($LASTEXITCODE -ne 0) {
throw "Tests failed with exit code $LASTEXITCODE"
}
Write-Output "Tests completed successfully!"
File diff suppressed because it is too large Load Diff
+120
View File
@@ -0,0 +1,120 @@
# Alias Management
This document describes how to use the alias management cmdlets in the PSOPNSenseAPI module.
## Overview
Aliases in OPNSense are named lists of networks, hosts, ports, or URLs that can be used in firewall rules. Using aliases makes it easier to manage firewall rules, as you can update the alias content without having to modify the rules that use it.
The PSOPNSenseAPI module provides cmdlets for managing aliases:
- `Get-OPNSenseAlias`: Retrieves aliases from an OPNSense firewall
- `New-OPNSenseAlias`: Creates a new alias on an OPNSense firewall
- `Set-OPNSenseAlias`: Updates an alias on an OPNSense firewall
- `Remove-OPNSenseAlias`: Removes an alias from an OPNSense firewall
## Alias Types
OPNSense supports several types of aliases:
- `host`: A list of IP addresses
- `network`: A list of networks in CIDR notation
- `port`: A list of port numbers
- `url`: A URL that points to a list of IPs or networks
- `urltable`: A URL that points to a table of IPs or networks
- `geoip`: A list of country codes for GeoIP filtering
- `networkgroup`: A group of networks
- `mac`: A list of MAC addresses
- `interface`: A list of network interfaces
- `dynipv6host`: A list of dynamic IPv6 hosts
- `internal`: Special internal aliases
- `external`: Special external aliases
## Examples
### Getting Aliases
```powershell
# Get all aliases
Get-OPNSenseAlias
# Get a specific alias by UUID
Get-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"
# Get a specific alias by name
Get-OPNSenseAlias -Name "WebServers"
# Get all host aliases
Get-OPNSenseAlias -Type host
# Get all port aliases
Get-OPNSenseAlias -Type port
```
### Creating Aliases
```powershell
# Create a host alias
New-OPNSenseAlias -Name "WebServers" -Type host -Content "192.168.1.10,192.168.1.11" -Description "Web Servers" -Apply
# Create a network alias
New-OPNSenseAlias -Name "InternalNetworks" -Type network -Content "192.168.1.0/24,192.168.2.0/24" -Description "Internal Networks" -Apply
# Create a port alias
New-OPNSenseAlias -Name "WebPorts" -Type port -Content "80,443" -Protocol TCP -Description "Web Ports" -Apply
# Create a URL alias
New-OPNSenseAlias -Name "BlockList" -Type url -Content "https://example.com/blocklist.txt" -UpdateFrequency 1 -Description "Block List" -Apply
```
### Updating Aliases
```powershell
# Update an alias's content
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Content "192.168.1.10,192.168.1.11,192.168.1.12" -Apply
# Update an alias's description
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Description "Updated description" -Apply
# Disable an alias
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Disabled -Apply
# Enable an alias
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Enabled -Apply
# Enable counters for an alias
Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -EnableCounters -Apply
```
### Removing Aliases
```powershell
# Remove an alias by UUID
Remove-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply
# Remove an alias with confirmation
Remove-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply
# Remove an alias without confirmation
Remove-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Force -Apply
# Remove aliases by pipeline
Get-OPNSenseAlias -Type host | Remove-OPNSenseAlias -Force -Apply
```
## Using Aliases in Firewall Rules
Once you have created aliases, you can use them in firewall rules:
```powershell
# Create a firewall rule using aliases
New-OPNSenseFirewallRule -Description "Allow Web Traffic" -Protocol TCP -SourceNet "InternalNetworks" -DestinationPort "WebPorts" -Action pass -Apply
```
## Best Practices
1. **Use descriptive names**: Choose alias names that clearly indicate their purpose.
2. **Use aliases for groups of objects**: Aliases are most useful when they group related objects.
3. **Keep aliases organized**: Use a consistent naming convention for aliases.
4. **Document aliases**: Use the description field to document the purpose of the alias.
5. **Apply changes**: Always use the `-Apply` parameter to apply changes immediately, or apply them later using `Apply-OPNSenseFirewallChanges`.
+326
View File
@@ -0,0 +1,326 @@
# Cron Job Management
This component provides cmdlets for managing cron jobs on OPNSense firewalls.
## Overview
The Cron Job Management component allows you to configure and manage scheduled tasks (cron jobs) on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting cron jobs.
## Cmdlets
### Get-OPNSenseCronJob
Retrieves cron jobs from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific cron job to retrieve. If not specified, all cron jobs are returned.
- **Description** - Filter cron jobs by description.
- **Command** - Filter cron jobs by command.
#### Examples
```powershell
# Get all cron jobs
Get-OPNSenseCronJob
# Get a specific cron job by UUID
Get-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Get cron jobs with a specific description
Get-OPNSenseCronJob -Description "Backup"
# Get cron jobs with a specific command
Get-OPNSenseCronJob -Command "configctl"
```
### New-OPNSenseCronJob
Creates a new cron job on an OPNSense firewall.
#### Parameters
- **Description** - A description for the cron job.
- **Command** - The command to execute.
- **Parameters** - The parameters for the command.
- **Minute** - The minute(s) when the job should run (0-59, *, */5, etc.).
- **Hour** - The hour(s) when the job should run (0-23, *, */2, etc.).
- **Day** - The day(s) of the month when the job should run (1-31, *, */2, etc.).
- **Month** - The month(s) when the job should run (1-12, *, */2, etc.).
- **Weekday** - The weekday(s) when the job should run (0-7, *, etc., where 0 and 7 are Sunday).
- **Enabled** - Whether the cron job is enabled. Default is true.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a daily backup cron job
New-OPNSenseCronJob -Description "Daily Backup" -Command "configctl" -Parameters "system backup" -Minute "0" -Hour "2" -Day "*" -Month "*" -Weekday "*"
# Create a weekly update cron job
New-OPNSenseCronJob -Description "Weekly Update" -Command "configctl" -Parameters "firmware update" -Minute "0" -Hour "3" -Day "*" -Month "*" -Weekday "0"
# Create a monthly log rotation cron job
New-OPNSenseCronJob -Description "Monthly Log Rotation" -Command "configctl" -Parameters "system rotate" -Minute "0" -Hour "4" -Day "1" -Month "*" -Weekday "*"
# Create a disabled cron job
New-OPNSenseCronJob -Description "Temporary Job" -Command "configctl" -Parameters "system reboot" -Minute "0" -Hour "5" -Day "*" -Month "*" -Weekday "*" -Enabled:$false
```
### Set-OPNSenseCronJob
Updates an existing cron job on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the cron job to update.
- **Description** - A description for the cron job.
- **Command** - The command to execute.
- **Parameters** - The parameters for the command.
- **Minute** - The minute(s) when the job should run (0-59, *, */5, etc.).
- **Hour** - The hour(s) when the job should run (0-23, *, */2, etc.).
- **Day** - The day(s) of the month when the job should run (1-31, *, */2, etc.).
- **Month** - The month(s) when the job should run (1-12, *, */2, etc.).
- **Weekday** - The weekday(s) when the job should run (0-7, *, etc., where 0 and 7 are Sunday).
- **Enabled** - Whether the cron job is enabled.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated cron job.
#### Examples
```powershell
# Update a cron job's description
Set-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated Backup Job"
# Update a cron job's schedule
Set-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Minute "30" -Hour "3"
# Update a cron job's command and parameters
Set-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Command "configctl" -Parameters "system backup full"
# Disable a cron job
Set-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Enabled:$false
# Update multiple properties of a cron job
Set-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Full Backup" -Command "configctl" -Parameters "system backup full" -Minute "0" -Hour "1" -PassThru
```
### Remove-OPNSenseCronJob
Removes a cron job from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the cron job to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a cron job
Remove-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a cron job without confirmation
Remove-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Enable-OPNSenseCronJob
Enables a cron job on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the cron job to enable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated cron job.
#### Examples
```powershell
# Enable a cron job
Enable-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Enable a cron job and return the updated job
Enable-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Disable-OPNSenseCronJob
Disables a cron job on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the cron job to disable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated cron job.
#### Examples
```powershell
# Disable a cron job
Disable-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Disable a cron job and return the updated job
Disable-OPNSenseCronJob -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Apply-OPNSenseCronJobChanges
Applies pending cron job changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply cron job changes
Apply-OPNSenseCronJobChanges
# Apply cron job changes without confirmation
Apply-OPNSenseCronJobChanges -Force
```
## Common Scenarios
### Basic Backup Schedule
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a daily backup cron job
New-OPNSenseCronJob -Description "Daily Configuration Backup" -Command "configctl" -Parameters "system backup" -Minute "0" -Hour "2" -Day "*" -Month "*" -Weekday "*" -Force
# Apply the changes
Apply-OPNSenseCronJobChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Comprehensive Maintenance Schedule
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define maintenance jobs
$cronJobs = @(
@{ Description = "Daily Backup"; Command = "configctl"; Parameters = "system backup"; Minute = "0"; Hour = "2"; Day = "*"; Month = "*"; Weekday = "*" },
@{ Description = "Weekly Full Backup"; Command = "configctl"; Parameters = "system backup full"; Minute = "0"; Hour = "3"; Day = "*"; Month = "*"; Weekday = "0" },
@{ Description = "Daily Log Rotation"; Command = "configctl"; Parameters = "system rotate"; Minute = "30"; Hour = "2"; Day = "*"; Month = "*"; Weekday = "*" },
@{ Description = "Weekly Update Check"; Command = "configctl"; Parameters = "firmware check"; Minute = "0"; Hour = "4"; Day = "*"; Month = "*"; Weekday = "1" },
@{ Description = "Monthly Cleanup"; Command = "configctl"; Parameters = "system cleanup"; Minute = "0"; Hour = "5"; Day = "1"; Month = "*"; Weekday = "*" }
)
# Create cron jobs
foreach ($job in $cronJobs) {
New-OPNSenseCronJob -Description $job.Description -Command $job.Command -Parameters $job.Parameters -Minute $job.Minute -Hour $job.Hour -Day $job.Day -Month $job.Month -Weekday $job.Weekday -Force
}
# Apply the changes
Apply-OPNSenseCronJobChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Existing Cron Jobs
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all cron jobs
$cronJobs = Get-OPNSenseCronJob
# Update backup jobs to run at a different time
$backupJobs = $cronJobs | Where-Object { $_.Description -like "*Backup*" }
foreach ($job in $backupJobs) {
Set-OPNSenseCronJob -Uuid $job.Uuid -Hour "4" -Force
Write-Output "Updated job: $($job.Description) to run at 4:00 AM"
}
# Disable temporary jobs
$tempJobs = $cronJobs | Where-Object { $_.Description -like "*Temporary*" }
foreach ($job in $tempJobs) {
Disable-OPNSenseCronJob -Uuid $job.Uuid -Force
Write-Output "Disabled job: $($job.Description)"
}
# Remove obsolete jobs
$obsoleteJobs = $cronJobs | Where-Object { $_.Description -like "*Obsolete*" }
foreach ($job in $obsoleteJobs) {
Remove-OPNSenseCronJob -Uuid $job.Uuid -Force
Write-Output "Removed job: $($job.Description)"
}
# Apply the changes
Apply-OPNSenseCronJobChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Scheduling Network Tests
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define network test jobs
$testJobs = @(
@{ Description = "Hourly Gateway Ping"; Command = "configctl"; Parameters = "gateway pingall"; Minute = "0"; Hour = "*"; Day = "*"; Month = "*"; Weekday = "*" },
@{ Description = "Daily DNS Test"; Command = "configctl"; Parameters = "system dns test"; Minute = "15"; Hour = "*/6"; Day = "*"; Month = "*"; Weekday = "*" },
@{ Description = "Weekly Network Diagnostics"; Command = "configctl"; Parameters = "system diagnostics"; Minute = "30"; Hour = "5"; Day = "*"; Month = "*"; Weekday = "0" }
)
# Create cron jobs
foreach ($job in $testJobs) {
New-OPNSenseCronJob -Description $job.Description -Command $job.Command -Parameters $job.Parameters -Minute $job.Minute -Hour $job.Hour -Day $job.Day -Month $job.Month -Weekday $job.Weekday -Force
}
# Apply the changes
Apply-OPNSenseCronJobChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Scheduling Firewall Reboots
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a monthly reboot cron job
New-OPNSenseCronJob -Description "Monthly Maintenance Reboot" -Command "configctl" -Parameters "system reboot" -Minute "0" -Hour "3" -Day "15" -Month "*" -Weekday "*" -Force
# Apply the changes
Apply-OPNSenseCronJobChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Cron job changes are not applied until you call `Apply-OPNSenseCronJobChanges`.
- The cron job schedule uses the standard cron format:
- **Minute**: 0-59, *, */5 (every 5 minutes), etc.
- **Hour**: 0-23, *, */2 (every 2 hours), etc.
- **Day**: 1-31, *, */2 (every 2 days), etc.
- **Month**: 1-12, *, */2 (every 2 months), etc.
- **Weekday**: 0-7, * (where 0 and 7 are Sunday), etc.
- The `*` character means "every" (e.g., every minute, every hour, etc.).
- The `*/n` format means "every n" (e.g., every 5 minutes, every 2 hours, etc.).
- Multiple values can be specified with commas (e.g., "1,3,5" for 1st, 3rd, and 5th).
- Ranges can be specified with hyphens (e.g., "1-5" for 1st through 5th).
- The `Command` parameter typically uses `configctl` for OPNSense system commands.
- Consider using the `-PassThru` parameter when updating cron jobs to verify the changes.
- Cron job descriptions should be descriptive and follow a consistent naming convention.
- Be careful when scheduling system reboots, as they will interrupt all services.
- Cron jobs run with system privileges, so they can execute any command available to the system.
- For complex schedules, consider using multiple cron jobs instead of a single job with a complex schedule.
+393
View File
@@ -0,0 +1,393 @@
# DHCP Management
This component provides cmdlets for managing DHCP servers and leases on OPNSense firewalls.
## Overview
The DHCP Management component allows you to configure and manage DHCP servers on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting DHCP servers, as well as managing DHCP leases and static mappings.
## Cmdlets
### Get-OPNSenseDHCPServer
Retrieves DHCP server configurations from an OPNSense firewall.
#### Parameters
- **Interface** - The interface to get the DHCP server configuration for. If not specified, all DHCP servers are returned.
#### Examples
```powershell
# Get all DHCP servers
Get-OPNSenseDHCPServer
# Get the DHCP server for a specific interface
Get-OPNSenseDHCPServer -Interface "lan"
```
### New-OPNSenseDHCPServer
Creates a new DHCP server on an OPNSense firewall.
#### Parameters
- **Interface** - The interface to create the DHCP server on.
- **Enabled** - Whether the DHCP server is enabled. Default is true.
- **RangeFrom** - The starting IP address of the DHCP range.
- **RangeTo** - The ending IP address of the DHCP range.
- **Domain** - The domain name to provide to DHCP clients.
- **DnsServers** - The DNS servers to provide to DHCP clients.
- **GatewayIP** - The gateway IP address to provide to DHCP clients.
- **LeaseTime** - The lease time in seconds. Default is 86400 (1 day).
- **DenyUnknownClients** - Whether to deny unknown clients. Default is false.
- **IgnoreClientIdentifiers** - Whether to ignore client identifiers. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic DHCP server
New-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Domain "example.com" -DnsServers "192.168.1.1","8.8.8.8" -GatewayIP "192.168.1.1"
# Create a DHCP server with advanced options
New-OPNSenseDHCPServer -Interface "opt1" -RangeFrom "10.0.0.100" -RangeTo "10.0.0.200" -Domain "internal.example.com" -DnsServers "10.0.0.1","8.8.4.4" -GatewayIP "10.0.0.1" -LeaseTime 43200 -DenyUnknownClients -Force
```
### Set-OPNSenseDHCPServer
Updates an existing DHCP server on an OPNSense firewall.
#### Parameters
- **Interface** - The interface of the DHCP server to update.
- **Enabled** - Whether the DHCP server is enabled.
- **RangeFrom** - The starting IP address of the DHCP range.
- **RangeTo** - The ending IP address of the DHCP range.
- **Domain** - The domain name to provide to DHCP clients.
- **DnsServers** - The DNS servers to provide to DHCP clients.
- **GatewayIP** - The gateway IP address to provide to DHCP clients.
- **LeaseTime** - The lease time in seconds.
- **DenyUnknownClients** - Whether to deny unknown clients.
- **IgnoreClientIdentifiers** - Whether to ignore client identifiers.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated DHCP server.
#### Examples
```powershell
# Update a DHCP server's range
Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.50" -RangeTo "192.168.1.150"
# Update a DHCP server's DNS servers
Set-OPNSenseDHCPServer -Interface "opt1" -DnsServers "10.0.0.1","1.1.1.1"
# Update multiple properties of a DHCP server
Set-OPNSenseDHCPServer -Interface "lan" -Domain "updated.example.com" -LeaseTime 43200 -DenyUnknownClients -PassThru
```
### Remove-OPNSenseDHCPServer
Removes a DHCP server from an OPNSense firewall.
#### Parameters
- **Interface** - The interface of the DHCP server to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a DHCP server
Remove-OPNSenseDHCPServer -Interface "opt1"
# Remove a DHCP server without confirmation
Remove-OPNSenseDHCPServer -Interface "opt1" -Force
```
### Get-OPNSenseDHCPLease
Retrieves DHCP leases from an OPNSense firewall.
#### Parameters
- **Interface** - The interface to get DHCP leases for. If not specified, leases for all interfaces are returned.
- **MACAddress** - Filter leases by MAC address.
- **IPAddress** - Filter leases by IP address.
- **Hostname** - Filter leases by hostname.
- **Status** - Filter leases by status (active, expired, etc.).
#### Examples
```powershell
# Get all DHCP leases
Get-OPNSenseDHCPLease
# Get DHCP leases for a specific interface
Get-OPNSenseDHCPLease -Interface "lan"
# Get DHCP leases for a specific MAC address
Get-OPNSenseDHCPLease -MACAddress "00:11:22:33:44:55"
# Get active DHCP leases
Get-OPNSenseDHCPLease -Status "active"
```
### New-OPNSenseDHCPStaticMapping
Creates a new DHCP static mapping on an OPNSense firewall.
#### Parameters
- **Interface** - The interface to create the static mapping on.
- **MACAddress** - The MAC address of the client.
- **IPAddress** - The IP address to assign to the client.
- **Hostname** - The hostname of the client.
- **Description** - A description for the static mapping.
- **Enabled** - Whether the static mapping is enabled. Default is true.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic static mapping
New-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress "00:11:22:33:44:55" -IPAddress "192.168.1.50" -Hostname "printer" -Description "Office Printer"
# Create a static mapping without confirmation
New-OPNSenseDHCPStaticMapping -Interface "opt1" -MACAddress "AA:BB:CC:DD:EE:FF" -IPAddress "10.0.0.10" -Hostname "server" -Description "File Server" -Force
```
### Set-OPNSenseDHCPStaticMapping
Updates an existing DHCP static mapping on an OPNSense firewall.
#### Parameters
- **Interface** - The interface of the static mapping to update.
- **MACAddress** - The MAC address of the static mapping to update.
- **IPAddress** - The IP address to assign to the client.
- **Hostname** - The hostname of the client.
- **Description** - A description for the static mapping.
- **Enabled** - Whether the static mapping is enabled.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated static mapping.
#### Examples
```powershell
# Update a static mapping's IP address
Set-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress "00:11:22:33:44:55" -IPAddress "192.168.1.60"
# Update a static mapping's description
Set-OPNSenseDHCPStaticMapping -Interface "opt1" -MACAddress "AA:BB:CC:DD:EE:FF" -Description "Updated File Server"
# Update multiple properties of a static mapping
Set-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress "00:11:22:33:44:55" -IPAddress "192.168.1.70" -Hostname "new-printer" -Description "New Office Printer" -PassThru
```
### Remove-OPNSenseDHCPStaticMapping
Removes a DHCP static mapping from an OPNSense firewall.
#### Parameters
- **Interface** - The interface of the static mapping to remove.
- **MACAddress** - The MAC address of the static mapping to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a static mapping
Remove-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress "00:11:22:33:44:55"
# Remove a static mapping without confirmation
Remove-OPNSenseDHCPStaticMapping -Interface "opt1" -MACAddress "AA:BB:CC:DD:EE:FF" -Force
```
### Apply-OPNSenseDHCPChanges
Applies pending DHCP changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply DHCP changes
Apply-OPNSenseDHCPChanges
# Apply DHCP changes without confirmation
Apply-OPNSenseDHCPChanges -Force
```
## Common Scenarios
### Basic DHCP Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a DHCP server for the LAN interface
New-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Domain "example.com" -DnsServers "192.168.1.1","8.8.8.8" -GatewayIP "192.168.1.1" -Force
# Apply the changes
Apply-OPNSenseDHCPChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Static Mappings
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create static mappings for important devices
$staticMappings = @(
@{ MACAddress = "00:11:22:33:44:55"; IPAddress = "192.168.1.10"; Hostname = "printer"; Description = "Office Printer" },
@{ MACAddress = "AA:BB:CC:DD:EE:FF"; IPAddress = "192.168.1.20"; Hostname = "fileserver"; Description = "File Server" },
@{ MACAddress = "11:22:33:44:55:66"; IPAddress = "192.168.1.30"; Hostname = "nas"; Description = "Network Storage" }
)
foreach ($mapping in $staticMappings) {
New-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress $mapping.MACAddress -IPAddress $mapping.IPAddress -Hostname $mapping.Hostname -Description $mapping.Description -Force
}
# Apply the changes
Apply-OPNSenseDHCPChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Converting DHCP Leases to Static Mappings
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get active DHCP leases
$leases = Get-OPNSenseDHCPLease -Interface "lan" -Status "active"
# Convert leases to static mappings
foreach ($lease in $leases) {
New-OPNSenseDHCPStaticMapping -Interface "lan" -MACAddress $lease.MACAddress -IPAddress $lease.IPAddress -Hostname $lease.Hostname -Description "Converted from lease on $(Get-Date -Format 'yyyy-MM-dd')" -Force
}
# Apply the changes
Apply-OPNSenseDHCPChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Multiple DHCP Servers
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define DHCP server configurations for different interfaces
$dhcpConfigs = @(
@{
Interface = "lan";
RangeFrom = "192.168.1.100";
RangeTo = "192.168.1.200";
Domain = "internal.example.com";
DnsServers = @("192.168.1.1", "8.8.8.8");
GatewayIP = "192.168.1.1";
LeaseTime = 86400;
},
@{
Interface = "opt1";
RangeFrom = "10.0.0.100";
RangeTo = "10.0.0.200";
Domain = "guest.example.com";
DnsServers = @("10.0.0.1", "8.8.4.4");
GatewayIP = "10.0.0.1";
LeaseTime = 3600;
DenyUnknownClients = $true;
},
@{
Interface = "opt2";
RangeFrom = "172.16.0.100";
RangeTo = "172.16.0.200";
Domain = "iot.example.com";
DnsServers = @("172.16.0.1");
GatewayIP = "172.16.0.1";
LeaseTime = 86400;
}
)
# Create or update DHCP servers
foreach ($config in $dhcpConfigs) {
$existing = Get-OPNSenseDHCPServer -Interface $config.Interface
if ($existing) {
# Update existing DHCP server
$params = @{
Interface = $config.Interface
RangeFrom = $config.RangeFrom
RangeTo = $config.RangeTo
Domain = $config.Domain
DnsServers = $config.DnsServers
GatewayIP = $config.GatewayIP
LeaseTime = $config.LeaseTime
Force = $true
}
if ($config.DenyUnknownClients) {
$params.Add("DenyUnknownClients", $true)
}
Set-OPNSenseDHCPServer @params
Write-Output "Updated DHCP server for interface $($config.Interface)"
}
else {
# Create new DHCP server
$params = @{
Interface = $config.Interface
RangeFrom = $config.RangeFrom
RangeTo = $config.RangeTo
Domain = $config.Domain
DnsServers = $config.DnsServers
GatewayIP = $config.GatewayIP
LeaseTime = $config.LeaseTime
Force = $true
}
if ($config.DenyUnknownClients) {
$params.Add("DenyUnknownClients", $true)
}
New-OPNSenseDHCPServer @params
Write-Output "Created DHCP server for interface $($config.Interface)"
}
}
# Apply the changes
Apply-OPNSenseDHCPChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- DHCP servers are configured per interface on OPNSense firewalls.
- Changes to DHCP servers and static mappings are not applied until you call `Apply-OPNSenseDHCPChanges`.
- When creating a DHCP server, ensure that the range is within the subnet of the interface.
- Static mappings take precedence over dynamic leases.
- The `DenyUnknownClients` option only allows clients with static mappings to receive DHCP leases.
- The `IgnoreClientIdentifiers` option can help with clients that change their identifier between requests.
- DHCP lease times are specified in seconds. Common values are:
- 3600 (1 hour)
- 43200 (12 hours)
- 86400 (1 day)
- 604800 (1 week)
- Consider using the `-PassThru` parameter when updating DHCP servers or static mappings to verify the changes.
+411
View File
@@ -0,0 +1,411 @@
# DNS Management
This component provides cmdlets for managing DNS settings on OPNSense firewalls.
## Overview
The DNS Management component allows you to configure and manage DNS settings on OPNSense firewalls. It provides cmdlets for configuring DNS servers, DNS forwarders, DNS overrides, and DNS forwarding.
## Cmdlets
### Get-OPNSenseDNSServer
Retrieves DNS server configurations from an OPNSense firewall.
#### Examples
```powershell
# Get DNS server configuration
Get-OPNSenseDNSServer
```
### Set-OPNSenseDNSServer
Updates the DNS server configuration on an OPNSense firewall.
#### Parameters
- **Enabled** - Whether the DNS server is enabled.
- **ListenIPs** - The IP addresses to listen on.
- **Port** - The port to listen on. Default is 53.
- **DNSSECEnabled** - Whether DNSSEC is enabled.
- **ForwardingEnabled** - Whether DNS forwarding is enabled.
- **ForwardingServers** - The DNS servers to forward queries to.
- **CacheEnabled** - Whether DNS caching is enabled.
- **CacheSize** - The size of the DNS cache in MB.
- **PrefetchEnabled** - Whether DNS prefetching is enabled.
- **PrefetchDomains** - Whether to prefetch domains.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated DNS server configuration.
#### Examples
```powershell
# Enable the DNS server
Set-OPNSenseDNSServer -Enabled
# Configure DNS forwarding
Set-OPNSenseDNSServer -ForwardingEnabled -ForwardingServers "8.8.8.8","8.8.4.4"
# Configure DNS caching
Set-OPNSenseDNSServer -CacheEnabled -CacheSize 10 -PrefetchEnabled -PrefetchDomains
# Configure DNS server with multiple options
Set-OPNSenseDNSServer -Enabled -ListenIPs "192.168.1.1" -Port 53 -DNSSECEnabled -ForwardingEnabled -ForwardingServers "1.1.1.1","1.0.0.1" -CacheEnabled -CacheSize 20 -PrefetchEnabled -PassThru
```
### Get-OPNSenseDNSOverride
Retrieves DNS overrides from an OPNSense firewall.
#### Parameters
- **Host** - Filter overrides by host.
- **Domain** - Filter overrides by domain.
- **IP** - Filter overrides by IP address.
- **Description** - Filter overrides by description.
#### Examples
```powershell
# Get all DNS overrides
Get-OPNSenseDNSOverride
# Get DNS overrides for a specific host
Get-OPNSenseDNSOverride -Host "server"
# Get DNS overrides for a specific domain
Get-OPNSenseDNSOverride -Domain "example.com"
```
### New-OPNSenseDNSOverride
Creates a new DNS override on an OPNSense firewall.
#### Parameters
- **Host** - The hostname to override.
- **Domain** - The domain to override.
- **IP** - The IP address to resolve to.
- **Description** - A description for the override.
- **Enabled** - Whether the override is enabled. Default is true.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a DNS override for a specific host
New-OPNSenseDNSOverride -Host "server" -Domain "example.com" -IP "192.168.1.10" -Description "Internal Server"
# Create a DNS override for a wildcard domain
New-OPNSenseDNSOverride -Host "*" -Domain "example.com" -IP "192.168.1.20" -Description "All example.com hosts"
# Create a DNS override without confirmation
New-OPNSenseDNSOverride -Host "printer" -Domain "example.com" -IP "192.168.1.30" -Description "Office Printer" -Force
```
### Set-OPNSenseDNSOverride
Updates an existing DNS override on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the DNS override to update.
- **Host** - The hostname to override.
- **Domain** - The domain to override.
- **IP** - The IP address to resolve to.
- **Description** - A description for the override.
- **Enabled** - Whether the override is enabled.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated DNS override.
#### Examples
```powershell
# Update a DNS override's IP address
Set-OPNSenseDNSOverride -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -IP "192.168.1.15"
# Update a DNS override's description
Set-OPNSenseDNSOverride -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated Server"
# Update multiple properties of a DNS override
Set-OPNSenseDNSOverride -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Host "newserver" -Domain "example.com" -IP "192.168.1.20" -Description "New Server" -PassThru
```
### Remove-OPNSenseDNSOverride
Removes a DNS override from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the DNS override to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a DNS override
Remove-OPNSenseDNSOverride -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a DNS override without confirmation
Remove-OPNSenseDNSOverride -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Get-OPNSenseDNSForwarder
Retrieves DNS forwarder configurations from an OPNSense firewall.
#### Examples
```powershell
# Get DNS forwarder configuration
Get-OPNSenseDNSForwarder
```
### Set-OPNSenseDNSForwarder
Updates the DNS forwarder configuration on an OPNSense firewall.
#### Parameters
- **Enabled** - Whether the DNS forwarder is enabled.
- **ListenIPs** - The IP addresses to listen on.
- **Port** - The port to listen on. Default is 53.
- **Interfaces** - The interfaces to listen on.
- **DNSSECEnabled** - Whether DNSSEC is enabled.
- **RegdhcpStatic** - Whether to register DHCP static mappings.
- **RegdhcpDynamic** - Whether to register DHCP leases.
- **StrictBind** - Whether to use strict binding.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated DNS forwarder configuration.
#### Examples
```powershell
# Enable the DNS forwarder
Set-OPNSenseDNSForwarder -Enabled
# Configure DNS forwarder interfaces
Set-OPNSenseDNSForwarder -Interfaces "lan","opt1"
# Configure DNS forwarder with DHCP registration
Set-OPNSenseDNSForwarder -RegdhcpStatic -RegdhcpDynamic
# Configure DNS forwarder with multiple options
Set-OPNSenseDNSForwarder -Enabled -ListenIPs "192.168.1.1" -Port 53 -Interfaces "lan","opt1" -DNSSECEnabled -RegdhcpStatic -RegdhcpDynamic -StrictBind -PassThru
```
### Get-OPNSenseDNSForwarding
Retrieves DNS forwarding configurations from an OPNSense firewall.
#### Parameters
- **Domain** - Filter forwarding by domain.
- **Server** - Filter forwarding by server.
- **Description** - Filter forwarding by description.
#### Examples
```powershell
# Get all DNS forwarding configurations
Get-OPNSenseDNSForwarding
# Get DNS forwarding for a specific domain
Get-OPNSenseDNSForwarding -Domain "example.com"
```
### New-OPNSenseDNSForwarding
Creates a new DNS forwarding configuration on an OPNSense firewall.
#### Parameters
- **Domain** - The domain to forward.
- **Server** - The server to forward to.
- **Description** - A description for the forwarding.
- **Enabled** - Whether the forwarding is enabled. Default is true.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a DNS forwarding for a specific domain
New-OPNSenseDNSForwarding -Domain "example.com" -Server "192.168.1.10" -Description "Internal DNS"
# Create a DNS forwarding for a domain to multiple servers
New-OPNSenseDNSForwarding -Domain "example.org" -Server "192.168.1.10,192.168.1.11" -Description "Redundant DNS"
# Create a DNS forwarding without confirmation
New-OPNSenseDNSForwarding -Domain "example.net" -Server "192.168.1.12" -Description "External DNS" -Force
```
### Set-OPNSenseDNSForwarding
Updates an existing DNS forwarding configuration on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the DNS forwarding to update.
- **Domain** - The domain to forward.
- **Server** - The server to forward to.
- **Description** - A description for the forwarding.
- **Enabled** - Whether the forwarding is enabled.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated DNS forwarding.
#### Examples
```powershell
# Update a DNS forwarding's server
Set-OPNSenseDNSForwarding -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Server "192.168.1.15"
# Update a DNS forwarding's description
Set-OPNSenseDNSForwarding -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated DNS"
# Update multiple properties of a DNS forwarding
Set-OPNSenseDNSForwarding -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Domain "new.example.com" -Server "192.168.1.20" -Description "New DNS" -PassThru
```
### Remove-OPNSenseDNSForwarding
Removes a DNS forwarding configuration from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the DNS forwarding to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a DNS forwarding
Remove-OPNSenseDNSForwarding -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a DNS forwarding without confirmation
Remove-OPNSenseDNSForwarding -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Apply-OPNSenseDNSChanges
Applies pending DNS changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply DNS changes
Apply-OPNSenseDNSChanges
# Apply DNS changes without confirmation
Apply-OPNSenseDNSChanges -Force
```
## Common Scenarios
### Basic DNS Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Configure the DNS server
Set-OPNSenseDNSServer -Enabled -ListenIPs "192.168.1.1" -ForwardingEnabled -ForwardingServers "1.1.1.1","1.0.0.1" -CacheEnabled -CacheSize 10 -Force
# Apply the changes
Apply-OPNSenseDNSChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### DNS Overrides for Internal Services
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create DNS overrides for internal services
$dnsOverrides = @(
@{ Host = "www"; Domain = "example.com"; IP = "192.168.1.10"; Description = "Internal Web Server" },
@{ Host = "mail"; Domain = "example.com"; IP = "192.168.1.11"; Description = "Internal Mail Server" },
@{ Host = "files"; Domain = "example.com"; IP = "192.168.1.12"; Description = "Internal File Server" },
@{ Host = "*"; Domain = "internal.example.com"; IP = "192.168.1.13"; Description = "Internal Services" }
)
foreach ($override in $dnsOverrides) {
New-OPNSenseDNSOverride -Host $override.Host -Domain $override.Domain -IP $override.IP -Description $override.Description -Force
}
# Apply the changes
Apply-OPNSenseDNSChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### DNS Forwarding for Specific Domains
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Configure DNS forwarding for specific domains
$dnsForwarding = @(
@{ Domain = "example.com"; Server = "192.168.1.10"; Description = "Internal Domain" },
@{ Domain = "partner.com"; Server = "10.0.0.10"; Description = "Partner Domain" },
@{ Domain = "vendor.com"; Server = "172.16.0.10"; Description = "Vendor Domain" }
)
foreach ($forwarding in $dnsForwarding) {
New-OPNSenseDNSForwarding -Domain $forwarding.Domain -Server $forwarding.Server -Description $forwarding.Description -Force
}
# Apply the changes
Apply-OPNSenseDNSChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing DNS Overrides
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all DNS overrides
$overrides = Get-OPNSenseDNSOverride
# Update all overrides for a specific domain
$overrides | Where-Object { $_.Domain -eq "example.com" } | ForEach-Object {
Set-OPNSenseDNSOverride -Uuid $_.Uuid -IP "192.168.2.$($_.IP.Split('.')[-1])" -Description "$($_.Description) (Migrated)" -Force
Write-Output "Updated override: $($_.Host).$($_.Domain)"
}
# Remove all overrides with "Temporary" in the description
$overrides | Where-Object { $_.Description -like "*Temporary*" } | ForEach-Object {
Remove-OPNSenseDNSOverride -Uuid $_.Uuid -Force
Write-Output "Removed override: $($_.Host).$($_.Domain)"
}
# Apply the changes
Apply-OPNSenseDNSChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- DNS changes are not applied until you call `Apply-OPNSenseDNSChanges`.
- DNS overrides take precedence over DNS forwarding.
- When using DNS forwarding, ensure that the forwarded domains are accessible from the OPNSense firewall.
- DNS caching can improve performance by reducing the number of external DNS queries.
- DNSSEC provides additional security by validating DNS responses.
- Consider using the `-PassThru` parameter when updating DNS configurations to verify the changes.
- Wildcard DNS overrides (using "*" as the host) can be used to override all subdomains of a domain.
- DNS forwarding can be used to direct queries for specific domains to internal or external DNS servers.
+238
View File
@@ -0,0 +1,238 @@
# Development and Contribution Guidelines
This document provides guidelines for developing and contributing to the PSOPNSenseAPI module.
## Development Environment Setup
### Prerequisites
- Visual Studio 2019 or later
- PowerShell 5.1 or PowerShell 7+
- .NET Framework 4.7.2 SDK (for Windows PowerShell 5.1 compatibility)
- .NET Core 3.1 SDK or later (for PowerShell 7+ compatibility)
- Git
### Setting Up the Development Environment
1. Clone the repository:
```
git clone https://github.com/freedbygrace/PSOPNSenseAPI.git
cd PSOPNSenseAPI
```
2. Open the solution in Visual Studio:
```
start PSOPNSenseAPI.sln
```
3. Restore NuGet packages:
```
dotnet restore
```
4. Build the solution:
```
dotnet build
```
## Coding Standards
### C# Code Style
- Follow Microsoft's C# coding conventions
- Use meaningful names for classes, methods, and variables
- Add XML documentation comments to all public members
- Use proper exception handling
- Write unit tests for all functionality
- Keep methods small and focused on a single responsibility
- Use dependency injection where appropriate
- Avoid static methods except for utility functions
### PowerShell Cmdlet Design
- Follow the PowerShell Verb-Noun naming convention
- Use approved PowerShell verbs (Get, Set, New, Remove, etc.)
- Implement proper parameter validation
- Support pipeline input where appropriate
- Implement ShouldProcess for cmdlets that make changes
- Provide meaningful error messages
- Write detailed help content
- Support common parameters (-Verbose, -Debug, etc.)
- Return appropriate objects, not strings
### Documentation
- Document all public APIs with XML comments
- Include examples in cmdlet help
- Update README.md and other documentation when adding features
- Document breaking changes in CHANGELOG.md
## Project Structure
The project follows this structure:
- **src/PSOPNSenseAPI**: Main source code
- **Cmdlets**: PowerShell cmdlets
- **Models**: Data models
- **Services**: Service classes for API communication
- **Utilities**: Utility classes
- **Logging**: Logging infrastructure
- **tests**: Unit and integration tests
- **docs**: Documentation
- **build**: Build scripts
- **output**: Build output (not in source control)
## Development Workflow
### Feature Development
1. Create a new branch from `main`:
```
git checkout -b feature/my-feature
```
2. Implement the feature:
- Add model classes if needed
- Implement service classes
- Create PowerShell cmdlets
- Add unit tests
- Update documentation
3. Build and test locally:
```
.\build\build.ps1
.\build\test.ps1
```
4. Commit your changes with meaningful commit messages:
```
git commit -m "Add feature: description of the feature"
```
5. Push your branch and create a pull request:
```
git push origin feature/my-feature
```
### Bug Fixes
1. Create a new branch from `main`:
```
git checkout -b fix/bug-description
```
2. Fix the bug:
- Add a test that reproduces the bug
- Fix the bug
- Verify that the test passes
3. Commit your changes:
```
git commit -m "Fix: description of the bug fix"
```
4. Push your branch and create a pull request:
```
git push origin fix/bug-description
```
## Testing
### Unit Testing
- Write unit tests for all functionality
- Use xUnit for testing
- Mock external dependencies
- Aim for high code coverage
- Run tests before submitting pull requests
### Integration Testing
- Write integration tests for API interactions
- Use a test OPNSense instance if possible
- Skip integration tests if no test instance is available
### Running Tests
```powershell
# Run all tests
.\build\test.ps1
# Run specific tests
dotnet test --filter "FullyQualifiedName~PSOPNSenseAPI.Tests.NetworkUtilityTests"
```
## Building and Packaging
### Building the Module
```powershell
# Build the module
.\build\build.ps1
# Build a release version with automatic versioning
.\build\build-release.ps1 -Clean -Test -Package
```
### Versioning
The module uses a versioning scheme of `yyyy.MM.dd.HHmm` for releases, which is automatically generated during the build process.
### Creating a Release
1. Update the CHANGELOG.md file
2. Build a release package:
```
.\build\build-release.ps1 -Clean -Test -Package
```
3. Create a new release on GitHub with the generated package
## Continuous Integration
The project uses GitHub Actions for continuous integration:
- Builds and tests are run on every push to the main branch
- Release packages are automatically created with the versioning scheme
- Release artifacts are uploaded to GitHub Releases
## Pull Request Guidelines
When submitting a pull request:
1. Ensure all tests pass
2. Update documentation if needed
3. Add entries to CHANGELOG.md for new features or bug fixes
4. Follow the coding standards
5. Keep pull requests focused on a single change
6. Provide a clear description of the changes
7. Link to any related issues
## Code Review Process
All pull requests will be reviewed for:
- Code quality and style
- Test coverage
- Documentation
- Performance considerations
- Security implications
## Release Process
1. Merge approved pull requests into the main branch
2. Update the version in the module manifest
3. Update CHANGELOG.md
4. Create a new release on GitHub
5. Publish the module to PowerShell Gallery (if applicable)
## Support
If you need help with development:
- Open an issue on GitHub
- Reach out to the maintainers
- Check the documentation and existing issues
## License
All contributions to this project are subject to the terms of the MIT License.
+268
View File
@@ -0,0 +1,268 @@
# Firewall Rules Management
This component provides cmdlets for managing firewall rules on OPNSense firewalls.
## Overview
The Firewall Rules Management component allows you to create, view, modify, and delete firewall rules on OPNSense firewalls. It provides a comprehensive set of cmdlets to manage all aspects of firewall rules, including enabling, disabling, and applying changes.
## Cmdlets
### Get-OPNSenseFirewallRule
Retrieves firewall rules from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific firewall rule to retrieve. If not specified, all rules are returned.
- **Interface** - Filter rules by interface.
- **Direction** - Filter rules by direction (in, out).
- **Protocol** - Filter rules by protocol.
- **Action** - Filter rules by action (pass, block, reject).
#### Examples
```powershell
# Get all firewall rules
Get-OPNSenseFirewallRule
# Get a specific firewall rule by UUID
Get-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Get all rules for a specific interface
Get-OPNSenseFirewallRule -Interface "lan"
# Get all block rules
Get-OPNSenseFirewallRule -Action "block"
```
### New-OPNSenseFirewallRule
Creates a new firewall rule on an OPNSense firewall.
#### Parameters
- **Enabled** - Whether the rule is enabled. Default is true.
- **Action** - The action to take (pass, block, reject). Default is "pass".
- **Interface** - The interface for the rule.
- **Direction** - The direction for the rule (in, out). Default is "in".
- **Protocol** - The protocol for the rule (tcp, udp, icmp, etc.).
- **Source** - The source address for the rule. Default is "any".
- **SourcePort** - The source port for the rule. Default is "any".
- **Destination** - The destination address for the rule. Default is "any".
- **DestinationPort** - The destination port for the rule.
- **Description** - A description for the rule.
- **Log** - Whether to log matches for this rule. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a rule to allow HTTP traffic
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -Destination "any" -DestinationPort "80" -Description "Allow HTTP"
# Create a rule to block outgoing SMTP traffic
New-OPNSenseFirewallRule -Interface "lan" -Direction "out" -Protocol "tcp" -DestinationPort "25" -Action "block" -Description "Block outgoing SMTP" -Log
# Create a rule to allow traffic from a specific subnet to a specific server
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -Source "192.168.1.0/24" -Destination "192.168.2.10" -DestinationPort "443" -Description "Allow subnet to server"
```
### Set-OPNSenseFirewallRule
Updates an existing firewall rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the firewall rule to update.
- **Enabled** - Whether the rule is enabled.
- **Action** - The action to take (pass, block, reject).
- **Interface** - The interface for the rule.
- **Direction** - The direction for the rule (in, out).
- **Protocol** - The protocol for the rule.
- **Source** - The source address for the rule.
- **SourcePort** - The source port for the rule.
- **Destination** - The destination address for the rule.
- **DestinationPort** - The destination port for the rule.
- **Description** - A description for the rule.
- **Log** - Whether to log matches for this rule.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Update a firewall rule's description
Set-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated HTTP rule"
# Update a firewall rule's destination port
Set-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -DestinationPort "8080"
# Update multiple properties of a firewall rule
Set-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Action "block" -Log -Description "Block traffic" -PassThru
```
### Remove-OPNSenseFirewallRule
Removes a firewall rule from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the firewall rule to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a firewall rule
Remove-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a firewall rule without confirmation
Remove-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Enable-OPNSenseFirewallRule
Enables a firewall rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the firewall rule to enable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Enable a firewall rule
Enable-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Enable a firewall rule and return the updated rule
Enable-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Disable-OPNSenseFirewallRule
Disables a firewall rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the firewall rule to disable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Disable a firewall rule
Disable-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Disable a firewall rule and return the updated rule
Disable-OPNSenseFirewallRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Apply-OPNSenseFirewallChanges
Applies pending firewall changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply firewall changes
Apply-OPNSenseFirewallChanges
# Apply firewall changes without confirmation
Apply-OPNSenseFirewallChanges -Force
```
## Common Scenarios
### Basic Firewall Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create rules for basic web access
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -DestinationPort "80" -Description "Allow HTTP" -Force
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -DestinationPort "443" -Description "Allow HTTPS" -Force
# Create a rule to allow DNS
New-OPNSenseFirewallRule -Interface "lan" -Protocol "udp" -DestinationPort "53" -Description "Allow DNS" -Force
# Apply the changes
Apply-OPNSenseFirewallChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Securing a Network
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Block outgoing SMTP to prevent spam
New-OPNSenseFirewallRule -Interface "lan" -Direction "out" -Protocol "tcp" -DestinationPort "25" -Action "block" -Description "Block outgoing SMTP" -Log -Force
# Allow only specific hosts to access the management interface
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -Source "192.168.1.10,192.168.1.11" -Destination "192.168.1.1" -DestinationPort "443" -Description "Allow management access" -Force
# Block all other access to the management interface
New-OPNSenseFirewallRule -Interface "lan" -Protocol "tcp" -Destination "192.168.1.1" -DestinationPort "443" -Action "block" -Description "Block management access" -Log -Force
# Apply the changes
Apply-OPNSenseFirewallChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Existing Rules
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all firewall rules
$rules = Get-OPNSenseFirewallRule
# Disable all rules with "Temporary" in the description
$rules | Where-Object { $_.Description -like "*Temporary*" } | ForEach-Object {
Disable-OPNSenseFirewallRule -Uuid $_.Uuid -Force
Write-Output "Disabled rule: $($_.Description)"
}
# Update all rules with "HTTP" in the description to use port 8080 instead of 80
$rules | Where-Object { $_.Description -like "*HTTP*" -and $_.DestinationPort -eq "80" } | ForEach-Object {
Set-OPNSenseFirewallRule -Uuid $_.Uuid -DestinationPort "8080" -Description "$($_.Description) (Updated Port)" -Force
Write-Output "Updated rule: $($_.Description)"
}
# Remove all rules with "Obsolete" in the description
$rules | Where-Object { $_.Description -like "*Obsolete*" } | ForEach-Object {
Remove-OPNSenseFirewallRule -Uuid $_.Uuid -Force
Write-Output "Removed rule: $($_.Description)"
}
# Apply the changes
Apply-OPNSenseFirewallChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Firewall rules are processed in order, with the first matching rule being applied.
- Changes to firewall rules are not applied until you call `Apply-OPNSenseFirewallChanges`.
- When creating or updating rules, consider the rule order and potential security implications.
- Use the `-Log` parameter for rules that you want to monitor for security purposes.
- Use aliases for frequently used IP addresses or networks to make rules more maintainable.
- Consider using the `-PassThru` parameter when updating rules to verify the changes.
- Always apply the principle of least privilege when creating firewall rules.
+295
View File
@@ -0,0 +1,295 @@
# Firmware Management
This component provides cmdlets for managing firmware on OPNSense firewalls.
## Overview
The Firmware Management component allows you to check for updates, install updates, and manage firmware settings on OPNSense firewalls. It provides cmdlets for checking firmware status, upgrading firmware, and managing firmware settings.
## Cmdlets
### Get-OPNSenseFirmwareStatus
Retrieves the current firmware status of an OPNSense firewall.
#### Examples
```powershell
# Get firmware status
Get-OPNSenseFirmwareStatus
```
### Get-OPNSenseFirmwareUpdate
Checks for available firmware updates for an OPNSense firewall.
#### Parameters
- **Force** - Forces a check for updates even if the update cache is current.
#### Examples
```powershell
# Check for updates
Get-OPNSenseFirmwareUpdate
# Force a check for updates
Get-OPNSenseFirmwareUpdate -Force
```
### Install-OPNSenseFirmwareUpdate
Installs available firmware updates on an OPNSense firewall.
#### Parameters
- **RebootAfterUpdate** - Whether to reboot the firewall after updating. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Install updates
Install-OPNSenseFirmwareUpdate
# Install updates and reboot
Install-OPNSenseFirmwareUpdate -RebootAfterUpdate
# Install updates without confirmation
Install-OPNSenseFirmwareUpdate -Force
```
### Invoke-OPNSenseFirmwareUpgrade
Performs a firmware upgrade on an OPNSense firewall.
#### Parameters
- **MajorVersion** - The major version to upgrade to.
- **RebootAfterUpgrade** - Whether to reboot the firewall after upgrading. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Upgrade to the latest version
Invoke-OPNSenseFirmwareUpgrade
# Upgrade to a specific major version
Invoke-OPNSenseFirmwareUpgrade -MajorVersion "23.1"
# Upgrade and reboot
Invoke-OPNSenseFirmwareUpgrade -RebootAfterUpgrade
# Upgrade without confirmation
Invoke-OPNSenseFirmwareUpgrade -Force
```
### Get-OPNSenseFirmwareSettings
Retrieves the firmware settings of an OPNSense firewall.
#### Examples
```powershell
# Get firmware settings
Get-OPNSenseFirmwareSettings
```
### Set-OPNSenseFirmwareSettings
Updates the firmware settings of an OPNSense firewall.
#### Parameters
- **Mirror** - The firmware mirror to use.
- **Flavour** - The firmware flavour to use (e.g., OpenSSL, LibreSSL).
- **Subscription** - The firmware subscription to use.
- **AutomaticUpdates** - Whether to enable automatic updates.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Set firmware mirror
Set-OPNSenseFirmwareSettings -Mirror "https://opnsense.c0urier.net"
# Enable automatic updates
Set-OPNSenseFirmwareSettings -AutomaticUpdates $true
# Set multiple firmware settings
Set-OPNSenseFirmwareSettings -Mirror "https://opnsense.c0urier.net" -Flavour "OpenSSL" -AutomaticUpdates $true
# Set firmware settings without confirmation
Set-OPNSenseFirmwareSettings -Mirror "https://opnsense.c0urier.net" -Force
```
### Get-OPNSenseFirmwareAudit
Retrieves the firmware audit log of an OPNSense firewall.
#### Parameters
- **Limit** - The maximum number of entries to retrieve. Default is 50.
#### Examples
```powershell
# Get firmware audit log
Get-OPNSenseFirmwareAudit
# Get the last 100 entries from the firmware audit log
Get-OPNSenseFirmwareAudit -Limit 100
```
### Invoke-OPNSenseReboot
Reboots an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
- **Wait** - Whether to wait for the firewall to come back online. Default is false.
- **Timeout** - The timeout in seconds to wait for the firewall to come back online. Default is 300.
#### Examples
```powershell
# Reboot the firewall
Invoke-OPNSenseReboot
# Reboot the firewall without confirmation
Invoke-OPNSenseReboot -Force
# Reboot the firewall and wait for it to come back online
Invoke-OPNSenseReboot -Wait
# Reboot the firewall and wait with a custom timeout
Invoke-OPNSenseReboot -Wait -Timeout 600
```
## Common Scenarios
### Checking and Installing Updates
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Check firmware status
$status = Get-OPNSenseFirmwareStatus
Write-Output "Current firmware version: $($status.Version)"
Write-Output "Current firmware status: $($status.Status)"
# Check for updates
$updates = Get-OPNSenseFirmwareUpdate -Force
if ($updates.Count -gt 0) {
Write-Output "Updates available:"
$updates | Format-Table -Property Name, Version, Size, Description
# Install updates
Install-OPNSenseFirmwareUpdate -Force
# Reboot if necessary
if ($updates | Where-Object { $_.RebootRequired -eq $true }) {
Write-Output "Rebooting to apply updates..."
Invoke-OPNSenseReboot -Force -Wait
}
} else {
Write-Output "No updates available."
}
# Disconnect from the firewall
Disconnect-OPNSense
```
### Upgrading to a New Major Version
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Check current version
$status = Get-OPNSenseFirmwareStatus
Write-Output "Current firmware version: $($status.Version)"
# Perform a backup before upgrading
New-OPNSenseBackup -IncludeRRD -IncludeInstalled -Force
$backups = Get-OPNSenseBackup
$latestBackup = $backups | Sort-Object -Property Date -Descending | Select-Object -First 1
$backupPath = "C:\Backups\opnsense-pre-upgrade-$(Get-Date -Format 'yyyyMMdd').xml"
Save-OPNSenseBackup -BackupId $latestBackup.Id -Path $backupPath -Force
Write-Output "Backup saved to: $backupPath"
# Upgrade to the latest version
Write-Output "Upgrading firmware..."
Invoke-OPNSenseFirmwareUpgrade -RebootAfterUpgrade -Force
# Wait for the firewall to come back online
Write-Output "Waiting for the firewall to come back online..."
Start-Sleep -Seconds 300
# Reconnect to the firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Check new version
$newStatus = Get-OPNSenseFirmwareStatus
Write-Output "New firmware version: $($newStatus.Version)"
# Disconnect from the firewall
Disconnect-OPNSense
```
### Configuring Firmware Settings
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get current firmware settings
$settings = Get-OPNSenseFirmwareSettings
Write-Output "Current firmware settings:"
$settings | Format-List
# Update firmware settings
Set-OPNSenseFirmwareSettings -Mirror "https://opnsense.c0urier.net" -Flavour "OpenSSL" -AutomaticUpdates $true -Force
# Get updated firmware settings
$updatedSettings = Get-OPNSenseFirmwareSettings
Write-Output "Updated firmware settings:"
$updatedSettings | Format-List
# Disconnect from the firewall
Disconnect-OPNSense
```
### Monitoring Firmware Audit Log
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get firmware audit log
$auditLog = Get-OPNSenseFirmwareAudit -Limit 20
Write-Output "Recent firmware changes:"
$auditLog | Format-Table -Property Date, User, Action, Package
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Firmware updates and upgrades can take some time to complete.
- Always create a backup before performing firmware updates or upgrades.
- Some updates may require a reboot to take effect.
- Major version upgrades should be performed with caution and only after thorough testing.
- Automatic updates can be configured to run at specific times.
- Firmware mirrors can affect the download speed and availability of updates.
- The firmware audit log provides a history of firmware changes.
- Consider using the `-Force` parameter when performing firmware operations in scripts to avoid confirmation prompts.
- The `-Wait` parameter for `Invoke-OPNSenseReboot` can be useful for scripts that need to wait for the firewall to come back online.
- Firmware settings are typically stored in the OPNSense configuration file.
- Some firmware operations may require administrative privileges.
- Firmware updates and upgrades can fail if there is insufficient disk space.
- Always check the OPNSense release notes before upgrading to a new major version.
+289
View File
@@ -0,0 +1,289 @@
# Gateway Management
This component provides cmdlets for managing gateways on OPNSense firewalls.
## Overview
The Gateway Management component allows you to configure and manage gateways on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting gateways, as well as monitoring gateway status.
## Cmdlets
### Get-OPNSenseGateway
Retrieves gateway configurations from an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific gateway to retrieve. If not specified, all gateways are returned.
- **Interface** - Filter gateways by interface.
- **Protocol** - Filter gateways by protocol (IPv4, IPv6).
#### Examples
```powershell
# Get all gateways
Get-OPNSenseGateway
# Get a specific gateway by name
Get-OPNSenseGateway -Name "WAN_GATEWAY"
# Get all gateways for a specific interface
Get-OPNSenseGateway -Interface "wan"
# Get all IPv4 gateways
Get-OPNSenseGateway -Protocol "IPv4"
```
### New-OPNSenseGateway
Creates a new gateway on an OPNSense firewall.
#### Parameters
- **Name** - The name of the gateway.
- **Interface** - The interface for the gateway.
- **IPAddress** - The IP address of the gateway.
- **Description** - A description for the gateway.
- **Enabled** - Whether the gateway is enabled. Default is true.
- **Monitor** - The IP address to monitor for gateway status.
- **MonitorDisable** - Whether to disable monitoring for this gateway. Default is false.
- **Weight** - The weight of the gateway for load balancing. Default is 1.
- **Protocol** - The protocol for the gateway (IPv4, IPv6). Default is IPv4.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic gateway
New-OPNSenseGateway -Name "WAN2_GATEWAY" -Interface "opt1" -IPAddress "203.0.113.1" -Description "Secondary WAN Gateway"
# Create a gateway with monitoring
New-OPNSenseGateway -Name "WAN3_GATEWAY" -Interface "opt2" -IPAddress "198.51.100.1" -Description "Tertiary WAN Gateway" -Monitor "198.51.100.254"
# Create a gateway with load balancing weight
New-OPNSenseGateway -Name "LB_GATEWAY" -Interface "opt3" -IPAddress "192.0.2.1" -Description "Load Balanced Gateway" -Weight 2
# Create an IPv6 gateway
New-OPNSenseGateway -Name "WAN_IPv6_GATEWAY" -Interface "wan" -IPAddress "2001:db8::1" -Description "IPv6 WAN Gateway" -Protocol "IPv6"
```
### Set-OPNSenseGateway
Updates an existing gateway on an OPNSense firewall.
#### Parameters
- **Name** - The name of the gateway to update.
- **Interface** - The interface for the gateway.
- **IPAddress** - The IP address of the gateway.
- **Description** - A description for the gateway.
- **Enabled** - Whether the gateway is enabled.
- **Monitor** - The IP address to monitor for gateway status.
- **MonitorDisable** - Whether to disable monitoring for this gateway.
- **Weight** - The weight of the gateway for load balancing.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated gateway.
#### Examples
```powershell
# Update a gateway's IP address
Set-OPNSenseGateway -Name "WAN_GATEWAY" -IPAddress "203.0.113.2"
# Update a gateway's description
Set-OPNSenseGateway -Name "WAN2_GATEWAY" -Description "Updated Secondary WAN Gateway"
# Update a gateway's monitoring settings
Set-OPNSenseGateway -Name "WAN3_GATEWAY" -Monitor "198.51.100.253"
# Disable a gateway
Set-OPNSenseGateway -Name "LB_GATEWAY" -Enabled:$false
# Update multiple properties of a gateway
Set-OPNSenseGateway -Name "WAN_GATEWAY" -IPAddress "203.0.113.3" -Description "Updated WAN Gateway" -Weight 3 -PassThru
```
### Remove-OPNSenseGateway
Removes a gateway from an OPNSense firewall.
#### Parameters
- **Name** - The name of the gateway to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a gateway
Remove-OPNSenseGateway -Name "WAN2_GATEWAY"
# Remove a gateway without confirmation
Remove-OPNSenseGateway -Name "WAN3_GATEWAY" -Force
```
### Get-OPNSenseGatewayStatus
Retrieves the status of gateways on an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific gateway to get the status for. If not specified, the status of all gateways is returned.
#### Examples
```powershell
# Get the status of all gateways
Get-OPNSenseGatewayStatus
# Get the status of a specific gateway
Get-OPNSenseGatewayStatus -Name "WAN_GATEWAY"
```
### Apply-OPNSenseGatewayChanges
Applies pending gateway changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply gateway changes
Apply-OPNSenseGatewayChanges
# Apply gateway changes without confirmation
Apply-OPNSenseGatewayChanges -Force
```
## Common Scenarios
### Basic Gateway Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a primary WAN gateway
New-OPNSenseGateway -Name "WAN_GATEWAY" -Interface "wan" -IPAddress "203.0.113.1" -Description "Primary WAN Gateway" -Monitor "8.8.8.8" -Force
# Apply the changes
Apply-OPNSenseGatewayChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Multi-WAN Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create gateways for multiple WAN connections
$wanGateways = @(
@{ Name = "WAN1_GATEWAY"; Interface = "wan"; IPAddress = "203.0.113.1"; Description = "Primary WAN Gateway"; Monitor = "8.8.8.8"; Weight = 1 },
@{ Name = "WAN2_GATEWAY"; Interface = "opt1"; IPAddress = "198.51.100.1"; Description = "Secondary WAN Gateway"; Monitor = "8.8.4.4"; Weight = 2 },
@{ Name = "WAN3_GATEWAY"; Interface = "opt2"; IPAddress = "192.0.2.1"; Description = "Tertiary WAN Gateway"; Monitor = "1.1.1.1"; Weight = 3 }
)
foreach ($gateway in $wanGateways) {
New-OPNSenseGateway -Name $gateway.Name -Interface $gateway.Interface -IPAddress $gateway.IPAddress -Description $gateway.Description -Monitor $gateway.Monitor -Weight $gateway.Weight -Force
}
# Apply the changes
Apply-OPNSenseGatewayChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Monitoring Gateway Status
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get the status of all gateways
$gatewayStatus = Get-OPNSenseGatewayStatus
# Display gateway status
$gatewayStatus | Format-Table -Property Name, Status, RTT, Loss
# Check for down gateways
$downGateways = $gatewayStatus | Where-Object { $_.Status -ne "online" }
if ($downGateways) {
Write-Output "The following gateways are not online:"
$downGateways | Format-Table -Property Name, Status, RTT, Loss
}
# Disconnect from the firewall
Disconnect-OPNSense
```
### Updating Gateway Monitoring
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all gateways
$gateways = Get-OPNSenseGateway
# Update monitoring settings for all gateways
foreach ($gateway in $gateways) {
# Use different monitoring IPs based on the gateway name
$monitorIP = switch ($gateway.Name) {
"WAN1_GATEWAY" { "8.8.8.8" }
"WAN2_GATEWAY" { "8.8.4.4" }
"WAN3_GATEWAY" { "1.1.1.1" }
default { "9.9.9.9" }
}
Set-OPNSenseGateway -Name $gateway.Name -Monitor $monitorIP -Force
Write-Output "Updated monitoring for gateway $($gateway.Name) to $monitorIP"
}
# Apply the changes
Apply-OPNSenseGatewayChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Failover Gateway Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create primary and backup gateways
New-OPNSenseGateway -Name "PRIMARY_GW" -Interface "wan" -IPAddress "203.0.113.1" -Description "Primary Gateway" -Monitor "8.8.8.8" -Weight 1 -Force
New-OPNSenseGateway -Name "BACKUP_GW" -Interface "opt1" -IPAddress "198.51.100.1" -Description "Backup Gateway" -Monitor "8.8.4.4" -Weight 2 -Force
# Apply the changes
Apply-OPNSenseGatewayChanges -Force
# Create a gateway group for failover
New-OPNSenseGatewayGroup -Name "FAILOVER_GROUP" -Description "Failover Gateway Group" -Gateways "PRIMARY_GW,BACKUP_GW" -Trigger "1" -Force
# Apply the changes
Apply-OPNSenseGatewayGroupChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Gateway changes are not applied until you call `Apply-OPNSenseGatewayChanges`.
- When creating a gateway, ensure that the IP address is reachable from the specified interface.
- The `Monitor` parameter specifies an IP address to ping to determine the gateway status.
- The `Weight` parameter is used for load balancing when multiple gateways are used in a gateway group.
- Gateway names should be descriptive and follow a consistent naming convention.
- Consider using the `-PassThru` parameter when updating gateways to verify the changes.
- Gateway monitoring can impact performance if too many gateways are monitored with a high frequency.
- The default gateway is typically named "WAN_GATEWAY" for IPv4 and "WAN_GATEWAY_V6" for IPv6.
- Gateway groups can be used for failover or load balancing between multiple gateways.
+166
View File
@@ -0,0 +1,166 @@
# IPNetwork2 Integration
This document provides information about the integration of the IPNetwork2 library in the PSOPNSenseAPI module.
## Overview
The PSOPNSenseAPI module uses the IPNetwork2 library for IP network calculations and manipulations. This library provides functionality for working with IP networks, subnets, CIDR notation, and other network-related operations.
## IPNetwork2 Library
The IPNetwork2 library is a .NET library that provides classes and methods for working with IP networks. It supports both IPv4 and IPv6 networks and provides functionality for:
- Parsing CIDR notation
- Subnetting
- Supernetting
- Network calculations
- IP address manipulation
- Network containment and overlap checks
## Integration in PSOPNSenseAPI
The IPNetwork2 library is integrated into the PSOPNSenseAPI module in the following ways:
1. **NetworkUtility Class**: The `NetworkUtility` class in the `PSOPNSenseAPI.Utilities` namespace provides wrapper methods for the IPNetwork2 functionality.
2. **Network Calculation Cmdlets**: The `Invoke-OPNSenseNetworkCalculation` cmdlet exposes the IPNetwork2 functionality to PowerShell users.
3. **VLAN and Subnet Management**: The `New-OPNSenseSubnetVLANs` cmdlet uses IPNetwork2 for subnet calculations when creating VLANs from subnet divisions.
## Using IPNetwork2 in the Code
When using IPNetwork2 in the code, it's important to use the correct namespace and class name:
```csharp
using System.Net;
// Parse a CIDR notation string
IPNetwork2 network = IPNetwork2.Parse("192.168.1.0/24");
// Get network properties
IPAddress networkAddress = network.Network;
IPAddress broadcastAddress = network.Broadcast;
int cidrPrefix = network.Cidr;
BigInteger totalHosts = network.Total;
// Subnet a network
IEnumerable<IPNetwork2> subnets = IPNetwork2.Subnet(network, 27);
// Check if an IP address is in a network
bool contains = network.Contains(IPAddress.Parse("192.168.1.100"));
// Check if networks overlap
bool overlaps = network1.Overlap(network2);
// Create a supernet
IPNetwork2[] supernet = IPNetwork2.Supernet(new[] { network1, network2 });
```
## Common Issues and Solutions
### Namespace and Class Name
The most common issue when working with IPNetwork2 is using the incorrect namespace or class name. The correct usage is:
```csharp
using System.Net;
// Use the class name directly
IPNetwork2 network = IPNetwork2.Parse("192.168.1.0/24");
// Or use the fully qualified name for clarity
System.Net.IPNetwork2 network = System.Net.IPNetwork2.Parse("192.168.1.0/24");
```
### Version Compatibility
Ensure that you're using a compatible version of IPNetwork2. The PSOPNSenseAPI module uses version 3.1.764, which is the latest version as of April 2025.
```xml
<PackageReference Include="IPNetwork2" Version="3.1.764" />
```
This version supports .NET 8.0, .NET 9.0, .NET Standard 2.0, and .NET Standard 2.1.
### Method Signatures
Be aware of the method signatures when using IPNetwork2. For example, the `Subnet` method has multiple overloads:
```csharp
// Subnet by prefix length
IEnumerable<IPNetwork2> Subnet(IPNetwork2 network, int prefixLength);
// Subnet by subnet count
IEnumerable<IPNetwork2> Subnet(IPNetwork2 network, BigInteger subnetCount);
// Subnet by target network
IEnumerable<IPNetwork2> Subnet(IPNetwork2 network, IPNetwork2 targetNetwork);
```
### Memory Usage
When working with large networks (e.g., /8 networks) and small subnets (e.g., /30), be aware that operations like subnetting can generate a large number of results and consume significant memory.
## Exposing IPNetwork2 Functionality to PowerShell
The PSOPNSenseAPI module exposes IPNetwork2 functionality to PowerShell users through the `Invoke-OPNSenseNetworkCalculation` cmdlet:
```powershell
# Show network information
Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info
# Subnet a network
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation Subnet -PrefixLength 27
# Check if networks overlap
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Overlaps -AdditionalNetworks "10.0.1.0/24"
```
## Advanced Usage
### Custom Network Utility Methods
The `NetworkUtility` class provides additional methods that extend the functionality of IPNetwork2:
```csharp
// Get the first usable host address in a network
IPAddress firstHost = NetworkUtility.GetFirstUsableHost(network);
// Get the last usable host address in a network
IPAddress lastHost = NetworkUtility.GetLastUsableHost(network);
// Get the number of usable host addresses in a network
BigInteger usableHosts = NetworkUtility.GetUsableHostCount(network);
// Convert between CIDR and subnet mask
int cidr = NetworkUtility.GetCIDRFromSubnetMask("255.255.255.0");
string subnetMask = NetworkUtility.GetSubnetMaskFromCIDR(24);
```
### Network Summarization
The `SupernetSummarize` method provides advanced network summarization:
```csharp
// Summarize multiple networks into the smallest possible set
List<IPNetwork2> networks = new List<IPNetwork2>
{
IPNetwork2.Parse("192.168.1.0/24"),
IPNetwork2.Parse("192.168.2.0/24"),
IPNetwork2.Parse("192.168.3.0/24"),
IPNetwork2.Parse("192.168.4.0/24")
};
List<IPNetwork2> summarized = NetworkUtility.SupernetSummarize(networks);
// Result: 192.168.0.0/22
```
## Notes
- The IPNetwork2 library is a third-party library and is subject to its own licensing terms.
- The PSOPNSenseAPI module includes the IPNetwork2 library as a NuGet package dependency.
- The IPNetwork2 library is used for local network calculations and does not require communication with the OPNSense firewall.
- Version 3.1.764 of IPNetwork2 has moved the `IPNetwork2` class to the `System.Net` namespace, which is different from earlier versions that used the `System.Net.IPNetwork` namespace.
- When upgrading the IPNetwork2 library, ensure that all code is updated to use the correct namespace and class names.
- Version 3.1.764 supports .NET 8.0, .NET 9.0, .NET Standard 2.0, and .NET Standard 2.1.
- For .NET Standard 2.0 and 2.1, IPNetwork2 has a dependency on System.Memory (>= 4.5.5).
+217
View File
@@ -0,0 +1,217 @@
# Installation and Setup
This document provides instructions for installing and setting up the PSOPNSenseAPI PowerShell module.
## Overview
The PSOPNSenseAPI module is a PowerShell module that provides cmdlets for managing OPNSense firewalls through the OPNSense API. This document covers the installation of the module, setting up API access on the OPNSense firewall, and establishing a connection to the firewall.
## Prerequisites
Before installing the PSOPNSenseAPI module, ensure that you have the following:
- PowerShell 5.1 or later (Windows PowerShell or PowerShell Core)
- .NET Framework 4.7.2 or later (for Windows PowerShell)
- .NET Core 3.1 or later (for PowerShell Core)
- OPNSense 21.1 or later with API access configured
## Installation Methods
### Installing from PowerShell Gallery
The recommended way to install the PSOPNSenseAPI module is from the PowerShell Gallery:
```powershell
# Install the module for the current user
Install-Module -Name PSOPNSenseAPI -Scope CurrentUser
# Install the module for all users (requires administrator privileges)
Install-Module -Name PSOPNSenseAPI -Scope AllUsers
```
### Installing from GitHub
You can also install the module directly from the GitHub repository:
```powershell
# Clone the repository
git clone https://github.com/freedbygrace/PSOPNSenseAPI.git
# Navigate to the repository directory
cd PSOPNSenseAPI
# Build the module
.\build\build.ps1
# Import the module
Import-Module .\output\PSOPNSenseAPI
```
### Manual Installation
To install the module manually:
1. Download the latest release from the [GitHub releases page](https://github.com/freedbygrace/PSOPNSenseAPI/releases)
2. Extract the archive to a module directory:
- For the current user: `$env:USERPROFILE\Documents\WindowsPowerShell\Modules\PSOPNSenseAPI`
- For all users: `$env:ProgramFiles\WindowsPowerShell\Modules\PSOPNSenseAPI`
3. Import the module:
```powershell
Import-Module PSOPNSenseAPI
```
## Setting Up API Access on OPNSense
Before you can use the PSOPNSenseAPI module, you need to set up API access on your OPNSense firewall:
1. Log in to the OPNSense web interface
2. Navigate to **System > Access > Users**
3. Select the user you want to use for API access or create a new user
4. Ensure the user has the necessary privileges for the operations you want to perform
5. Click on the **API keys** tab
6. Click **+** to add a new API key
7. Note the **Key** and **Secret** values, as you will need them to connect to the firewall
## Connecting to an OPNSense Firewall
Once you have installed the module and set up API access, you can connect to an OPNSense firewall:
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"
# Connect to the OPNSense firewall with certificate validation disabled (for self-signed certificates)
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
```
## Verifying the Installation
To verify that the module is installed and working correctly:
```powershell
# Check the module version
Get-Module -Name PSOPNSenseAPI
# List available cmdlets
Get-Command -Module PSOPNSenseAPI
# Get help for a specific cmdlet
Get-Help -Name Connect-OPNSense -Full
```
## Updating the Module
To update the module to the latest version:
```powershell
# Update the module from PowerShell Gallery
Update-Module -Name PSOPNSenseAPI
```
## Uninstalling the Module
To uninstall the module:
```powershell
# Uninstall the module
Uninstall-Module -Name PSOPNSenseAPI
```
## Troubleshooting
### Connection Issues
If you encounter connection issues:
1. Verify that the OPNSense firewall is reachable from your computer
2. Check that the API key and secret are correct
3. Ensure that the user associated with the API key has the necessary privileges
4. If using HTTPS with a self-signed certificate, use the `-SkipCertificateCheck` parameter
5. Check if there are any firewall rules blocking access to the OPNSense web interface
### Module Loading Issues
If you encounter issues loading the module:
1. Verify that you have the required PowerShell and .NET versions
2. Check that the module is installed in a valid module path:
```powershell
# List module paths
$env:PSModulePath -split ';'
# Check if the module is in a valid path
Get-Module -Name PSOPNSenseAPI -ListAvailable
```
3. Try importing the module with verbose output:
```powershell
Import-Module -Name PSOPNSenseAPI -Verbose
```
### API Access Issues
If you encounter issues with API access:
1. Verify that the API is enabled on the OPNSense firewall
2. Check that the user has the necessary privileges
3. Ensure that the API key and secret are valid
4. Check if there are any firewall rules blocking access to the API
## Common Configuration
### Creating a Profile for Quick Connection
You can create a profile to store your connection information for quick access:
```powershell
# Create a directory for profiles
$profilesDir = "$env:USERPROFILE\Documents\PSOPNSenseAPI\Profiles"
New-Item -Path $profilesDir -ItemType Directory -Force
# Create a profile
$profile = @{
Server = "https://firewall.example.com"
ApiKey = "your_api_key"
ApiSecret = "your_api_secret"
SkipCertificateCheck = $true
}
# Save the profile
$profilePath = "$profilesDir\firewall.json"
$profile | ConvertTo-Json | Set-Content -Path $profilePath
# Load the profile and connect
$profile = Get-Content -Path $profilePath | ConvertFrom-Json
Connect-OPNSense -Server $profile.Server -ApiKey $profile.ApiKey -ApiSecret $profile.ApiSecret -SkipCertificateCheck:$profile.SkipCertificateCheck
```
### Setting Up a Module Import Profile
You can create a PowerShell profile that automatically imports the module:
```powershell
# Add the following line to your PowerShell profile
if (-not (Get-Module -Name PSOPNSenseAPI -ErrorAction SilentlyContinue)) {
Import-Module -Name PSOPNSenseAPI
}
# To edit your PowerShell profile
notepad $PROFILE
```
## Notes
- Store API keys and secrets securely, as they provide access to your OPNSense firewall.
- Consider using a dedicated user with limited privileges for API access.
- Always disconnect from the firewall when you're done:
```powershell
Disconnect-OPNSense
```
- For security reasons, avoid storing API keys and secrets in scripts or profiles that are shared or stored in unsecured locations.
- When using the module in scripts, consider using secure string variables or environment variables for API keys and secrets.
- The module uses HTTPS for all communication with the OPNSense firewall, ensuring that all data is encrypted in transit.
+298
View File
@@ -0,0 +1,298 @@
# Interface Management
This component provides cmdlets for managing network interfaces on OPNSense firewalls.
## Overview
The Interface Management component allows you to configure and manage network interfaces on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting interfaces, as well as configuring interface settings.
## Cmdlets
### Get-OPNSenseInterface
Retrieves interface configurations from an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific interface to retrieve. If not specified, all interfaces are returned.
- **Type** - Filter interfaces by type (e.g., physical, vlan, bridge).
- **Enabled** - Filter interfaces by enabled status.
#### Examples
```powershell
# Get all interfaces
Get-OPNSenseInterface
# Get a specific interface by name
Get-OPNSenseInterface -Name "lan"
# Get all VLAN interfaces
Get-OPNSenseInterface -Type "vlan"
# Get all enabled interfaces
Get-OPNSenseInterface -Enabled $true
```
### New-OPNSenseInterface
Creates a new interface on an OPNSense firewall.
#### Parameters
- **Name** - The name of the interface.
- **Description** - A description for the interface.
- **Type** - The type of the interface (e.g., physical, vlan, bridge).
- **Device** - The physical device for the interface.
- **IPv4Address** - The IPv4 address for the interface.
- **IPv4Subnet** - The IPv4 subnet mask for the interface.
- **IPv6Address** - The IPv6 address for the interface.
- **IPv6Subnet** - The IPv6 subnet mask for the interface.
- **Enabled** - Whether the interface is enabled. Default is true.
- **BlockPrivate** - Whether to block private networks. Default is false.
- **BlockBogons** - Whether to block bogon networks. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic interface
New-OPNSenseInterface -Name "opt1" -Description "Optional Interface 1" -Type "physical" -Device "em1" -IPv4Address "192.168.2.1" -IPv4Subnet "24"
# Create a VLAN interface
New-OPNSenseInterface -Name "vlan10" -Description "VLAN 10" -Type "vlan" -Device "em0.10" -IPv4Address "10.0.10.1" -IPv4Subnet "24"
# Create an interface with IPv6
New-OPNSenseInterface -Name "opt2" -Description "Optional Interface 2" -Type "physical" -Device "em2" -IPv4Address "192.168.3.1" -IPv4Subnet "24" -IPv6Address "2001:db8:1::1" -IPv6Subnet "64"
# Create an interface with security options
New-OPNSenseInterface -Name "dmz" -Description "DMZ Interface" -Type "physical" -Device "em3" -IPv4Address "192.168.100.1" -IPv4Subnet "24" -BlockPrivate -BlockBogons
```
### Set-OPNSenseInterface
Updates an existing interface on an OPNSense firewall.
#### Parameters
- **Name** - The name of the interface to update.
- **Description** - A description for the interface.
- **IPv4Address** - The IPv4 address for the interface.
- **IPv4Subnet** - The IPv4 subnet mask for the interface.
- **IPv6Address** - The IPv6 address for the interface.
- **IPv6Subnet** - The IPv6 subnet mask for the interface.
- **Enabled** - Whether the interface is enabled.
- **BlockPrivate** - Whether to block private networks.
- **BlockBogons** - Whether to block bogon networks.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated interface.
#### Examples
```powershell
# Update an interface's description
Set-OPNSenseInterface -Name "lan" -Description "Updated LAN Interface"
# Update an interface's IPv4 address
Set-OPNSenseInterface -Name "opt1" -IPv4Address "192.168.2.254" -IPv4Subnet "24"
# Update an interface's IPv6 address
Set-OPNSenseInterface -Name "opt2" -IPv6Address "2001:db8:2::1" -IPv6Subnet "64"
# Enable security options for an interface
Set-OPNSenseInterface -Name "dmz" -BlockPrivate -BlockBogons
# Disable an interface
Set-OPNSenseInterface -Name "opt3" -Enabled:$false
# Update multiple properties of an interface
Set-OPNSenseInterface -Name "lan" -Description "Main LAN Interface" -IPv4Address "192.168.1.254" -IPv4Subnet "24" -BlockBogons -PassThru
```
### Remove-OPNSenseInterface
Removes an interface from an OPNSense firewall.
#### Parameters
- **Name** - The name of the interface to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove an interface
Remove-OPNSenseInterface -Name "opt3"
# Remove an interface without confirmation
Remove-OPNSenseInterface -Name "vlan20" -Force
```
### Get-OPNSenseInterfaceStatistics
Retrieves interface statistics from an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific interface to get statistics for. If not specified, statistics for all interfaces are returned.
#### Examples
```powershell
# Get statistics for all interfaces
Get-OPNSenseInterfaceStatistics
# Get statistics for a specific interface
Get-OPNSenseInterfaceStatistics -Name "lan"
```
### Apply-OPNSenseInterfaceChanges
Applies pending interface changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply interface changes
Apply-OPNSenseInterfaceChanges
# Apply interface changes without confirmation
Apply-OPNSenseInterfaceChanges -Force
```
## Common Scenarios
### Basic Interface Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Configure the LAN interface
Set-OPNSenseInterface -Name "lan" -Description "Main LAN Interface" -IPv4Address "192.168.1.1" -IPv4Subnet "24" -Force
# Configure the WAN interface
Set-OPNSenseInterface -Name "wan" -Description "WAN Interface" -BlockPrivate -BlockBogons -Force
# Apply the changes
Apply-OPNSenseInterfaceChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Creating VLAN Interfaces
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define VLAN interfaces
$vlans = @(
@{ Name = "vlan10"; Description = "Management VLAN"; Device = "em0.10"; IPv4Address = "10.0.10.1"; IPv4Subnet = "24" },
@{ Name = "vlan20"; Description = "User VLAN"; Device = "em0.20"; IPv4Address = "10.0.20.1"; IPv4Subnet = "24" },
@{ Name = "vlan30"; Description = "Guest VLAN"; Device = "em0.30"; IPv4Address = "10.0.30.1"; IPv4Subnet = "24" },
@{ Name = "vlan40"; Description = "IoT VLAN"; Device = "em0.40"; IPv4Address = "10.0.40.1"; IPv4Subnet = "24" }
)
# Create VLAN interfaces
foreach ($vlan in $vlans) {
New-OPNSenseInterface -Name $vlan.Name -Description $vlan.Description -Type "vlan" -Device $vlan.Device -IPv4Address $vlan.IPv4Address -IPv4Subnet $vlan.IPv4Subnet -Force
}
# Apply the changes
Apply-OPNSenseInterfaceChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Configuring Dual-Stack IPv4/IPv6 Interfaces
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define dual-stack interfaces
$interfaces = @(
@{ Name = "lan"; Description = "LAN Interface"; IPv4Address = "192.168.1.1"; IPv4Subnet = "24"; IPv6Address = "2001:db8:1::1"; IPv6Subnet = "64" },
@{ Name = "opt1"; Description = "Optional Interface 1"; IPv4Address = "192.168.2.1"; IPv4Subnet = "24"; IPv6Address = "2001:db8:2::1"; IPv6Subnet = "64" },
@{ Name = "dmz"; Description = "DMZ Interface"; IPv4Address = "192.168.100.1"; IPv4Subnet = "24"; IPv6Address = "2001:db8:100::1"; IPv6Subnet = "64" }
)
# Configure dual-stack interfaces
foreach ($interface in $interfaces) {
Set-OPNSenseInterface -Name $interface.Name -Description $interface.Description -IPv4Address $interface.IPv4Address -IPv4Subnet $interface.IPv4Subnet -IPv6Address $interface.IPv6Address -IPv6Subnet $interface.IPv6Subnet -Force
}
# Apply the changes
Apply-OPNSenseInterfaceChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Monitoring Interface Statistics
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get interface statistics
$statistics = Get-OPNSenseInterfaceStatistics
# Display interface statistics
$statistics | Format-Table -Property Name, Status, InBytes, OutBytes, InPackets, OutPackets, Errors
# Check for interfaces with errors
$interfacesWithErrors = $statistics | Where-Object { $_.Errors -gt 0 }
if ($interfacesWithErrors) {
Write-Output "The following interfaces have errors:"
$interfacesWithErrors | Format-Table -Property Name, Status, Errors
}
# Disconnect from the firewall
Disconnect-OPNSense
```
### Securing Interfaces
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all interfaces
$interfaces = Get-OPNSenseInterface
# Enable security options for external interfaces
foreach ($interface in $interfaces) {
if ($interface.Name -eq "wan" -or $interface.Name -like "opt*") {
Set-OPNSenseInterface -Name $interface.Name -BlockPrivate -BlockBogons -Force
Write-Output "Enabled security options for interface $($interface.Name)"
}
}
# Apply the changes
Apply-OPNSenseInterfaceChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Interface changes are not applied until you call `Apply-OPNSenseInterfaceChanges`.
- When creating or updating interfaces, ensure that the IP addresses do not conflict with other interfaces.
- The `BlockPrivate` option blocks traffic from private networks (RFC 1918) on the interface.
- The `BlockBogons` option blocks traffic from bogon networks (unallocated or reserved IP space) on the interface.
- Interface names should follow OPNSense conventions (e.g., "lan", "wan", "opt1", "vlan10").
- VLAN interfaces require the parent interface to be properly configured.
- Consider using the `-PassThru` parameter when updating interfaces to verify the changes.
- Interface statistics can be useful for monitoring network traffic and identifying issues.
- When removing an interface, ensure that no other configurations (e.g., firewall rules, NAT rules) reference the interface.
- IPv6 addresses should be specified in the standard format (e.g., "2001:db8::1").
- IPv4 subnet masks can be specified in CIDR notation (e.g., "24" for "255.255.255.0") or dotted decimal notation (e.g., "255.255.255.0").
+378
View File
@@ -0,0 +1,378 @@
# NAT Rules Management
This component provides cmdlets for managing Network Address Translation (NAT) rules on OPNSense firewalls.
## Overview
The NAT Rules Management component allows you to configure and manage NAT rules on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting different types of NAT rules, including port forwarding, outbound NAT, and 1:1 NAT.
## Cmdlets
### Get-OPNSenseNatRule
Retrieves NAT rules from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific NAT rule to retrieve. If not specified, all NAT rules are returned.
- **Type** - Filter rules by type (port_forward, outbound, 1to1).
- **Interface** - Filter rules by interface.
- **Description** - Filter rules by description.
#### Examples
```powershell
# Get all NAT rules
Get-OPNSenseNatRule
# Get a specific NAT rule by UUID
Get-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Get all port forwarding rules
Get-OPNSenseNatRule -Type "port_forward"
# Get all NAT rules for a specific interface
Get-OPNSenseNatRule -Interface "wan"
```
### New-OPNSensePortForwardRule
Creates a new port forwarding rule on an OPNSense firewall.
#### Parameters
- **Interface** - The interface for the rule.
- **Protocol** - The protocol for the rule (tcp, udp, tcp/udp).
- **Source** - The source address for the rule. Default is "any".
- **SourcePort** - The source port for the rule. Default is "any".
- **Destination** - The destination address for the rule. Default is "wanip".
- **DestinationPort** - The destination port for the rule.
- **TargetIP** - The target IP address for the rule.
- **TargetPort** - The target port for the rule.
- **Description** - A description for the rule.
- **NatReflection** - The NAT reflection mode (enable, disable, purenat). Default is "enable".
- **FilterRuleAssociation** - Whether to create an associated filter rule. Default is true.
- **Enabled** - Whether the rule is enabled. Default is true.
- **Log** - Whether to log matches for this rule. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic port forwarding rule
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server"
# Create a port forwarding rule with custom source and destination
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -Source "203.0.113.0/24" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Secure Web Server"
# Create a port forwarding rule with NAT reflection disabled
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -DestinationPort "3389" -TargetIP "192.168.1.200" -TargetPort "3389" -Description "RDP Server" -NatReflection "disable"
# Create a port forwarding rule without an associated filter rule
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -DestinationPort "22" -TargetIP "192.168.1.200" -TargetPort "22" -Description "SSH Server" -FilterRuleAssociation:$false
```
### New-OPNSenseOutboundNatRule
Creates a new outbound NAT rule on an OPNSense firewall.
#### Parameters
- **Interface** - The interface for the rule.
- **Source** - The source address for the rule.
- **Destination** - The destination address for the rule. Default is "any".
- **TranslationAddress** - The translation address for the rule.
- **Description** - A description for the rule.
- **Enabled** - Whether the rule is enabled. Default is true.
- **Log** - Whether to log matches for this rule. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic outbound NAT rule
New-OPNSenseOutboundNatRule -Interface "wan" -Source "192.168.1.0/24" -TranslationAddress "203.0.113.1" -Description "Outbound NAT for LAN"
# Create an outbound NAT rule with a specific destination
New-OPNSenseOutboundNatRule -Interface "wan" -Source "192.168.1.0/24" -Destination "198.51.100.0/24" -TranslationAddress "203.0.113.1" -Description "Outbound NAT for specific destination"
# Create an outbound NAT rule with logging enabled
New-OPNSenseOutboundNatRule -Interface "wan" -Source "192.168.1.0/24" -TranslationAddress "203.0.113.1" -Description "Logged Outbound NAT" -Log
```
### New-OPNSense1to1NatRule
Creates a new 1:1 NAT rule on an OPNSense firewall.
#### Parameters
- **Interface** - The interface for the rule.
- **ExternalNetwork** - The external network for the rule.
- **InternalIP** - The internal IP address for the rule.
- **Description** - A description for the rule.
- **NatReflection** - The NAT reflection mode (enable, disable, purenat). Default is "enable".
- **Enabled** - Whether the rule is enabled. Default is true.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic 1:1 NAT rule
New-OPNSense1to1NatRule -Interface "wan" -ExternalNetwork "203.0.113.10" -InternalIP "192.168.1.10" -Description "1:1 NAT for Server"
# Create a 1:1 NAT rule with NAT reflection disabled
New-OPNSense1to1NatRule -Interface "wan" -ExternalNetwork "203.0.113.11" -InternalIP "192.168.1.11" -Description "1:1 NAT without reflection" -NatReflection "disable"
# Create a 1:1 NAT rule for a network
New-OPNSense1to1NatRule -Interface "wan" -ExternalNetwork "203.0.113.0/29" -InternalIP "192.168.1.0/29" -Description "1:1 NAT for Network"
```
### Set-OPNSenseNatRule
Updates an existing NAT rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the NAT rule to update.
- **Interface** - The interface for the rule.
- **Protocol** - The protocol for the rule (tcp, udp, tcp/udp).
- **Source** - The source address for the rule.
- **SourcePort** - The source port for the rule.
- **Destination** - The destination address for the rule.
- **DestinationPort** - The destination port for the rule.
- **TargetIP** - The target IP address for the rule.
- **TargetPort** - The target port for the rule.
- **TranslationAddress** - The translation address for the rule.
- **ExternalNetwork** - The external network for the rule.
- **InternalIP** - The internal IP address for the rule.
- **Description** - A description for the rule.
- **NatReflection** - The NAT reflection mode (enable, disable, purenat).
- **FilterRuleAssociation** - Whether to create an associated filter rule.
- **Enabled** - Whether the rule is enabled.
- **Log** - Whether to log matches for this rule.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Update a port forwarding rule's target IP
Set-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -TargetIP "192.168.1.101"
# Update a port forwarding rule's description
Set-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated Web Server"
# Update an outbound NAT rule's translation address
Set-OPNSenseNatRule -Uuid "b2c3d4e5-f6g7-h8i9-j0k1-l2m3n4o5p6q7" -TranslationAddress "203.0.113.2"
# Update a 1:1 NAT rule's internal IP
Set-OPNSenseNatRule -Uuid "c3d4e5f6-g7h8-i9j0-k1l2-m3n4o5p6q7r8" -InternalIP "192.168.1.12"
# Disable a NAT rule
Set-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Enabled:$false
# Update multiple properties of a NAT rule
Set-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -TargetIP "192.168.1.101" -TargetPort "8080" -Description "Updated Web Server" -PassThru
```
### Remove-OPNSenseNatRule
Removes a NAT rule from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the NAT rule to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a NAT rule
Remove-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a NAT rule without confirmation
Remove-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Enable-OPNSenseNatRule
Enables a NAT rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the NAT rule to enable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Enable a NAT rule
Enable-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Enable a NAT rule and return the updated rule
Enable-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Disable-OPNSenseNatRule
Disables a NAT rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the NAT rule to disable.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Disable a NAT rule
Disable-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Disable a NAT rule and return the updated rule
Disable-OPNSenseNatRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -PassThru
```
### Apply-OPNSenseNatChanges
Applies pending NAT changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply NAT changes
Apply-OPNSenseNatChanges
# Apply NAT changes without confirmation
Apply-OPNSenseNatChanges -Force
```
## Common Scenarios
### Setting Up Port Forwarding for a Web Server
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create port forwarding rules for HTTP and HTTPS
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server HTTP" -Force
New-OPNSensePortForwardRule -Interface "wan" -Protocol "tcp" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Web Server HTTPS" -Force
# Apply the changes
Apply-OPNSenseNatChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Configuring Outbound NAT for Multiple Networks
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define networks and their translation addresses
$networks = @(
@{ Source = "192.168.1.0/24"; Translation = "203.0.113.1"; Description = "LAN Outbound NAT" },
@{ Source = "192.168.2.0/24"; Translation = "203.0.113.2"; Description = "Guest Outbound NAT" },
@{ Source = "192.168.3.0/24"; Translation = "203.0.113.3"; Description = "DMZ Outbound NAT" }
)
# Create outbound NAT rules
foreach ($network in $networks) {
New-OPNSenseOutboundNatRule -Interface "wan" -Source $network.Source -TranslationAddress $network.Translation -Description $network.Description -Force
}
# Apply the changes
Apply-OPNSenseNatChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Setting Up 1:1 NAT for a Server Farm
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define server mappings
$servers = @(
@{ External = "203.0.113.10"; Internal = "192.168.1.10"; Description = "Web Server 1" },
@{ External = "203.0.113.11"; Internal = "192.168.1.11"; Description = "Web Server 2" },
@{ External = "203.0.113.12"; Internal = "192.168.1.12"; Description = "Database Server" },
@{ External = "203.0.113.13"; Internal = "192.168.1.13"; Description = "Mail Server" }
)
# Create 1:1 NAT rules
foreach ($server in $servers) {
New-OPNSense1to1NatRule -Interface "wan" -ExternalNetwork $server.External -InternalIP $server.Internal -Description $server.Description -Force
}
# Apply the changes
Apply-OPNSenseNatChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Existing NAT Rules
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all NAT rules
$natRules = Get-OPNSenseNatRule
# Update port forwarding rules to use a new target IP
$portForwardRules = $natRules | Where-Object { $_.Type -eq "port_forward" -and $_.TargetIP -eq "192.168.1.100" }
foreach ($rule in $portForwardRules) {
Set-OPNSenseNatRule -Uuid $rule.Uuid -TargetIP "192.168.1.101" -Description "$($rule.Description) (Updated)" -Force
Write-Output "Updated rule: $($rule.Description)"
}
# Disable temporary NAT rules
$tempRules = $natRules | Where-Object { $_.Description -like "*Temporary*" }
foreach ($rule in $tempRules) {
Disable-OPNSenseNatRule -Uuid $rule.Uuid -Force
Write-Output "Disabled rule: $($rule.Description)"
}
# Remove obsolete NAT rules
$obsoleteRules = $natRules | Where-Object { $_.Description -like "*Obsolete*" }
foreach ($rule in $obsoleteRules) {
Remove-OPNSenseNatRule -Uuid $rule.Uuid -Force
Write-Output "Removed rule: $($rule.Description)"
}
# Apply the changes
Apply-OPNSenseNatChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- NAT rules are processed in order, with the first matching rule being applied.
- Changes to NAT rules are not applied until you call `Apply-OPNSenseNatChanges`.
- Port forwarding rules create a mapping from an external port to an internal IP address and port.
- Outbound NAT rules control how internal addresses are translated when accessing external networks.
- 1:1 NAT rules create a one-to-one mapping between an external IP address and an internal IP address.
- NAT reflection allows internal clients to access forwarded services using the external IP address.
- The `FilterRuleAssociation` parameter for port forwarding rules determines whether a corresponding firewall rule is created.
- When creating or updating NAT rules, consider the rule order and potential security implications.
- Use the `-Log` parameter for rules that you want to monitor for security purposes.
- Consider using the `-PassThru` parameter when updating NAT rules to verify the changes.
- NAT rules can reference aliases for source, destination, and port fields.
- The `NatReflection` parameter can be set to "enable", "disable", or "purenat".
- The `Source` parameter can be set to "any" to match any source address.
- The `Destination` parameter for port forwarding rules can be set to "wanip" to use the WAN IP address.
- The `TranslationAddress` parameter for outbound NAT rules can be set to "wanip" to use the WAN IP address.
+155
View File
@@ -0,0 +1,155 @@
# Network Utilities
This component provides cmdlets for performing network calculations and conversions.
## Overview
The Network Utilities component includes cmdlets for working with IP networks, subnets, CIDR notation, and other network-related calculations. These utilities help with planning and managing network configurations on OPNSense firewalls.
## Cmdlets
### Invoke-OPNSenseNetworkCalculation
Performs various network calculations on IP networks.
#### Parameters
- **Network** - The network in CIDR notation to perform calculations on.
- **Operation** - The operation to perform. Valid values are:
- **Info** - Shows detailed information about the network.
- **Subnet** - Divides the network into subnets of a specified prefix length.
- **SubnetByCount** - Divides the network into a specified number of subnets.
- **Contains** - Checks if an IP address or network is contained within the specified network.
- **Overlaps** - Checks if the network overlaps with other networks.
- **Supernet** - Combines the network with other networks into a supernet.
- **SupernetSummarize** - Summarizes multiple networks into the smallest possible set of networks.
- **PrefixLength** - The prefix length to use for subnetting.
- **SubnetCount** - The number of subnets to create when using SubnetByCount.
- **IpAddress** - The IP address to check when using Contains.
- **AdditionalNetworks** - Additional networks to use with Overlaps, Supernet, or SupernetSummarize.
#### Examples
```powershell
# Show network information
Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info
# Subnet a network into /27 networks
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation Subnet -PrefixLength 27
# Create 4 equal-sized subnets
Invoke-OPNSenseNetworkCalculation -Network "172.16.0.0/24" -Operation SubnetByCount -SubnetCount 4
# Check if an IP is within a network
Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Contains -IpAddress "192.168.1.100"
# Check if networks overlap
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Overlaps -AdditionalNetworks "10.0.1.0/24","10.0.2.0/24"
# Combine networks into a supernet
Invoke-OPNSenseNetworkCalculation -Network "192.168.0.0/24" -Operation Supernet -AdditionalNetworks "192.168.1.0/24"
# Summarize multiple networks
Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "10.0.1.0/24","10.0.2.0/24"
```
### ConvertTo-OPNSenseNetworkNotation
Converts between different network notation formats.
#### Parameters
- **CIDR** - The CIDR prefix length to convert to a subnet mask.
- **SubnetMask** - The subnet mask to convert to a CIDR prefix length.
#### Examples
```powershell
# Convert CIDR to subnet mask
ConvertTo-OPNSenseNetworkNotation -CIDR 24 # Returns "255.255.255.0"
# Convert subnet mask to CIDR
ConvertTo-OPNSenseNetworkNotation -SubnetMask "255.255.255.0" # Returns 24
```
## Common Scenarios
### Network Planning
```powershell
# Plan a network subdivision
$network = "10.0.0.0/16"
$subnets = Invoke-OPNSenseNetworkCalculation -Network $network -Operation Subnet -PrefixLength 24
$subnets | Format-Table -Property CIDR, Network, Broadcast, FirstUsableHost, LastUsableHost, UsableHostCount
# Create equal-sized subnets
$departmentCount = 8
$subnets = Invoke-OPNSenseNetworkCalculation -Network "172.16.0.0/20" -Operation SubnetByCount -SubnetCount $departmentCount
$subnets | Format-Table -Property CIDR, Network, Broadcast, UsableHostCount
```
### Network Verification
```powershell
# Verify if an IP address is within a network
$serverIP = "192.168.1.50"
$network = "192.168.1.0/24"
$isInNetwork = Invoke-OPNSenseNetworkCalculation -Network $network -Operation Contains -IpAddress $serverIP
# Check if networks overlap
$network1 = "10.0.0.0/16"
$network2 = "10.0.5.0/24"
$overlaps = Invoke-OPNSenseNetworkCalculation -Network $network1 -Operation Overlaps -AdditionalNetworks $network2
```
### Network Optimization
```powershell
# Optimize a list of networks by summarizing them
$networks = @(
"192.168.1.0/24",
"192.168.2.0/24",
"192.168.3.0/24",
"192.168.4.0/24"
)
$optimized = Invoke-OPNSenseNetworkCalculation -Network $networks[0] -Operation SupernetSummarize -AdditionalNetworks $networks[1..($networks.Length-1)]
$optimized | Format-Table -Property CIDR, Network, Broadcast
```
### VLAN Planning
```powershell
# Plan VLANs with appropriate subnet sizes
$corporateNetwork = "10.0.0.0/16"
$vlans = @{
"Management" = 10
"Servers" = 20
"Users" = 30
"Guest" = 40
"IoT" = 50
}
foreach ($vlan in $vlans.GetEnumerator()) {
$vlanName = $vlan.Key
$vlanId = $vlan.Value
$prefix = switch ($vlanName) {
"Management" { 24 } # 254 hosts
"Servers" { 23 } # 510 hosts
"Users" { 22 } # 1022 hosts
"Guest" { 24 } # 254 hosts
"IoT" { 23 } # 510 hosts
}
# Calculate network details
$subnet = Invoke-OPNSenseNetworkCalculation -Network $corporateNetwork -Operation Subnet -PrefixLength $prefix | Select-Object -First 1
Write-Output "VLAN $vlanId ($vlanName): $($subnet.CIDR) - $($subnet.UsableHostCount) usable hosts"
}
```
## Notes
- The Network Utilities component uses the IPNetwork2 library for network calculations.
- All operations are performed locally and do not require communication with the OPNSense firewall.
- These utilities can be used for planning network configurations before implementing them on the firewall.
- When working with large networks, be aware that some operations (like subnetting a /8 network into /30 networks) may generate a large number of results.
+296
View File
@@ -0,0 +1,296 @@
# Plugin Management
This component provides cmdlets for managing plugins on OPNSense firewalls.
## Overview
The Plugin Management component allows you to install, configure, and manage plugins on OPNSense firewalls. It provides cmdlets for listing available plugins, installing and uninstalling plugins, and managing plugin configurations.
## Cmdlets
### Get-OPNSensePlugin
Retrieves a list of available and installed plugins on an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific plugin to retrieve. If not specified, all plugins are returned.
- **Category** - Filter plugins by category.
- **Installed** - Filter plugins by installation status.
#### Examples
```powershell
# Get all plugins
Get-OPNSensePlugin
# Get a specific plugin by name
Get-OPNSensePlugin -Name "os-tailscale"
# Get all installed plugins
Get-OPNSensePlugin -Installed $true
# Get all plugins in a specific category
Get-OPNSensePlugin -Category "security"
```
### Install-OPNSensePlugin
Installs a plugin on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to install.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Install a plugin
Install-OPNSensePlugin -Name "os-tailscale"
# Install a plugin without confirmation
Install-OPNSensePlugin -Name "os-wireguard" -Force
```
### Uninstall-OPNSensePlugin
Uninstalls a plugin from an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to uninstall.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Uninstall a plugin
Uninstall-OPNSensePlugin -Name "os-tailscale"
# Uninstall a plugin without confirmation
Uninstall-OPNSensePlugin -Name "os-wireguard" -Force
```
### Enable-OPNSensePlugin
Enables a plugin on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to enable.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Enable a plugin
Enable-OPNSensePlugin -Name "os-tailscale"
# Enable a plugin without confirmation
Enable-OPNSensePlugin -Name "os-wireguard" -Force
```
### Disable-OPNSensePlugin
Disables a plugin on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to disable.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Disable a plugin
Disable-OPNSensePlugin -Name "os-tailscale"
# Disable a plugin without confirmation
Disable-OPNSensePlugin -Name "os-wireguard" -Force
```
### Get-OPNSensePluginConfiguration
Retrieves the configuration of a plugin on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to get the configuration for.
#### Examples
```powershell
# Get the configuration of a plugin
Get-OPNSensePluginConfiguration -Name "os-tailscale"
```
### Set-OPNSensePluginConfiguration
Updates the configuration of a plugin on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to update the configuration for.
- **Configuration** - The configuration to set.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Update the configuration of a plugin
$config = @{
enabled = "1"
settings = @{
hostname = "opnsense-tailscale"
acceptDns = "1"
}
}
Set-OPNSensePluginConfiguration -Name "os-tailscale" -Configuration $config
# Update the configuration of a plugin without confirmation
Set-OPNSensePluginConfiguration -Name "os-tailscale" -Configuration $config -Force
```
### Apply-OPNSensePluginChanges
Applies pending plugin changes on an OPNSense firewall.
#### Parameters
- **Name** - The name of the plugin to apply changes for.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply changes for a plugin
Apply-OPNSensePluginChanges -Name "os-tailscale"
# Apply changes for a plugin without confirmation
Apply-OPNSensePluginChanges -Name "os-tailscale" -Force
```
## Common Scenarios
### Installing and Configuring a Plugin
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Install the Tailscale plugin
Install-OPNSensePlugin -Name "os-tailscale" -Force
# Configure the plugin
$config = @{
enabled = "1"
settings = @{
hostname = "opnsense-tailscale"
acceptDns = "1"
acceptRoutes = "1"
advertiseRoutes = "192.168.1.0/24,10.0.0.0/8"
}
}
Set-OPNSensePluginConfiguration -Name "os-tailscale" -Configuration $config -Force
# Apply the changes
Apply-OPNSensePluginChanges -Name "os-tailscale" -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Multiple Plugins
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define plugins to install
$plugins = @(
"os-tailscale",
"os-wireguard",
"os-acme-client",
"os-theme-vicuna"
)
# Install plugins
foreach ($plugin in $plugins) {
Install-OPNSensePlugin -Name $plugin -Force
Write-Output "Installed plugin: $plugin"
}
# Get all installed plugins
$installedPlugins = Get-OPNSensePlugin -Installed $true
Write-Output "Installed plugins:"
$installedPlugins | Format-Table -Property Name, Version, Description
# Disconnect from the firewall
Disconnect-OPNSense
```
### Updating Plugin Configurations
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get the current configuration of a plugin
$currentConfig = Get-OPNSensePluginConfiguration -Name "os-wireguard"
# Update the configuration
$currentConfig.server.enabled = "1"
$currentConfig.server.port = "51820"
$currentConfig.server.dns = "192.168.1.1"
# Set the updated configuration
Set-OPNSensePluginConfiguration -Name "os-wireguard" -Configuration $currentConfig -Force
# Apply the changes
Apply-OPNSensePluginChanges -Name "os-wireguard" -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Cleaning Up Unused Plugins
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all installed plugins
$installedPlugins = Get-OPNSensePlugin -Installed $true
# Define plugins to keep
$pluginsToKeep = @(
"os-tailscale",
"os-wireguard",
"os-acme-client"
)
# Uninstall unused plugins
foreach ($plugin in $installedPlugins) {
if ($pluginsToKeep -notcontains $plugin.Name) {
Uninstall-OPNSensePlugin -Name $plugin.Name -Force
Write-Output "Uninstalled plugin: $($plugin.Name)"
}
}
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Plugin installation and uninstallation may require a firewall reboot to take effect.
- Some plugins may have dependencies that need to be installed first.
- Plugin configurations vary widely depending on the plugin.
- Always check the OPNSense documentation for specific plugin requirements and configuration options.
- Plugin management requires administrative privileges.
- Plugin installation and uninstallation can take some time, especially for larger plugins.
- Some plugins may not be available for all OPNSense versions.
- Plugin configurations are typically stored in XML format.
- Changes to plugin configurations may not take effect until the plugin service is restarted or the firewall is rebooted.
- Consider using the `-Force` parameter when installing or uninstalling plugins in scripts to avoid confirmation prompts.
+158
View File
@@ -0,0 +1,158 @@
# Port Forwarding Management
This component provides cmdlets for managing port forwarding rules on OPNSense firewalls.
## Overview
Port forwarding (also known as destination NAT or DNAT) allows external traffic to be redirected to internal servers. This component provides cmdlets to create, view, modify, and delete port forwarding rules on OPNSense firewalls.
## Cmdlets
### Get-OPNSensePortForwardingRule
Retrieves port forwarding rules from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific port forwarding rule to retrieve. If not specified, all rules are returned.
#### Examples
```powershell
# Get all port forwarding rules
Get-OPNSensePortForwardingRule
# Get a specific port forwarding rule by UUID
Get-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
```
### New-OPNSensePortForwardingRule
Creates a new port forwarding rule on an OPNSense firewall.
#### Parameters
- **Enabled** - Whether the rule is enabled. Default is true.
- **Description** - A description for the rule.
- **Interface** - The interface for the rule (e.g., "WAN").
- **Protocol** - The TCP/IP protocol (tcp, udp, tcp/udp). Default is "tcp".
- **Source** - The source address for the rule. Default is "any".
- **SourcePort** - The source port range for the rule. Default is "any".
- **Destination** - The destination address for the rule. Default is "wanip".
- **DestinationPort** - The destination port range for the rule.
- **TargetIP** - The target IP address for the rule.
- **TargetPort** - The target port for the rule.
- **NatReflection** - The NAT reflection mode (enable, disable, purenat). Default is "enable".
- **FilterRuleAssociation** - Whether to create an associated filter rule. Default is true.
- **Log** - Whether to enable logging for this rule. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a new port forwarding rule for HTTP
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server HTTP"
# Create a new port forwarding rule for HTTPS with logging enabled
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Web Server HTTPS" -Log -Force
```
### Set-OPNSensePortForwardingRule
Updates an existing port forwarding rule on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the port forwarding rule to update.
- **Enabled** - Whether the rule is enabled.
- **Description** - A description for the rule.
- **Interface** - The interface for the rule.
- **Protocol** - The TCP/IP protocol (tcp, udp, tcp/udp).
- **Source** - The source address for the rule.
- **SourcePort** - The source port range for the rule.
- **Destination** - The destination address for the rule.
- **DestinationPort** - The destination port range for the rule.
- **TargetIP** - The target IP address for the rule.
- **TargetPort** - The target port for the rule.
- **NatReflection** - The NAT reflection mode (enable, disable, purenat).
- **FilterRuleAssociation** - Whether to create an associated filter rule.
- **Log** - Whether to enable logging for this rule.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated rule.
#### Examples
```powershell
# Update a port forwarding rule's target IP
Set-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -TargetIP "192.168.1.200"
# Update a port forwarding rule's description and enable logging
Set-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated Web Server" -Log -PassThru
```
### Remove-OPNSensePortForwardingRule
Removes a port forwarding rule from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the port forwarding rule to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a port forwarding rule
Remove-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a port forwarding rule without confirmation
Remove-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
## Common Scenarios
### Web Server Port Forwarding
```powershell
# Forward HTTP and HTTPS to an internal web server
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server HTTP"
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Web Server HTTPS"
```
### Remote Desktop Access
```powershell
# Forward RDP to an internal server on a non-standard port
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "33389" -TargetIP "192.168.1.200" -TargetPort "3389" -Description "Remote Desktop"
```
### Game Server
```powershell
# Forward multiple ports for a game server
New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp/udp" -DestinationPort "27015-27020" -TargetIP "192.168.1.150" -TargetPort "27015-27020" -Description "Game Server"
```
### Managing Rules
```powershell
# Get all port forwarding rules
$rules = Get-OPNSensePortForwardingRule
# Update all rules targeting a specific IP
$rules | Where-Object { $_.TargetIP -eq "192.168.1.100" } | ForEach-Object {
Set-OPNSensePortForwardingRule -Uuid $_.Uuid -TargetIP "192.168.1.101" -Force
}
# Remove all rules with a specific description
$rules | Where-Object { $_.Description -like "*Temporary*" } | ForEach-Object {
Remove-OPNSensePortForwardingRule -Uuid $_.Uuid -Force
}
```
## Notes
- Port forwarding rules are applied immediately after creation, update, or deletion.
- When creating or updating rules, consider security implications and only forward necessary ports.
- Use the `FilterRuleAssociation` parameter to automatically create associated firewall rules.
- NAT reflection allows internal clients to access forwarded services using the external IP address.
+291
View File
@@ -0,0 +1,291 @@
# Route Management
This component provides cmdlets for managing static routes on OPNSense firewalls.
## Overview
The Route Management component allows you to configure and manage static routes on OPNSense firewalls. It provides cmdlets for creating, viewing, modifying, and deleting static routes.
## Cmdlets
### Get-OPNSenseRoute
Retrieves static routes from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific route to retrieve. If not specified, all routes are returned.
- **Network** - Filter routes by network.
- **Gateway** - Filter routes by gateway.
- **Description** - Filter routes by description.
#### Examples
```powershell
# Get all static routes
Get-OPNSenseRoute
# Get a specific route by UUID
Get-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Get routes for a specific network
Get-OPNSenseRoute -Network "192.168.100.0/24"
# Get routes using a specific gateway
Get-OPNSenseRoute -Gateway "WAN_GATEWAY"
```
### New-OPNSenseRoute
Creates a new static route on an OPNSense firewall.
#### Parameters
- **Network** - The network for the route in CIDR notation.
- **Gateway** - The gateway for the route.
- **Description** - A description for the route.
- **Disabled** - Whether the route is disabled. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic static route
New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN_GATEWAY" -Description "Remote Office Network"
# Create a disabled static route
New-OPNSenseRoute -Network "10.0.0.0/8" -Gateway "WAN2_GATEWAY" -Description "Corporate Network" -Disabled
# Create a static route without confirmation
New-OPNSenseRoute -Network "172.16.0.0/16" -Gateway "WAN3_GATEWAY" -Description "Partner Network" -Force
```
### Set-OPNSenseRoute
Updates an existing static route on an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the route to update.
- **Network** - The network for the route in CIDR notation.
- **Gateway** - The gateway for the route.
- **Description** - A description for the route.
- **Disabled** - Whether the route is disabled.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated route.
#### Examples
```powershell
# Update a route's network
Set-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Network "192.168.200.0/24"
# Update a route's gateway
Set-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Gateway "WAN2_GATEWAY"
# Update a route's description
Set-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Description "Updated Remote Office Network"
# Enable a disabled route
Set-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Disabled:$false
# Update multiple properties of a route
Set-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Network "192.168.200.0/24" -Gateway "WAN3_GATEWAY" -Description "Updated Remote Office Network" -PassThru
```
### Remove-OPNSenseRoute
Removes a static route from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the route to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a route
Remove-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a route without confirmation
Remove-OPNSenseRoute -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### Apply-OPNSenseRouteChanges
Applies pending route changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply route changes
Apply-OPNSenseRouteChanges
# Apply route changes without confirmation
Apply-OPNSenseRouteChanges -Force
```
## Common Scenarios
### Basic Route Configuration
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a static route to a remote network
New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN_GATEWAY" -Description "Remote Office Network" -Force
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Multiple Routes
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define routes for different networks
$routes = @(
@{ Network = "192.168.100.0/24"; Gateway = "WAN_GATEWAY"; Description = "Remote Office 1" },
@{ Network = "192.168.200.0/24"; Gateway = "WAN_GATEWAY"; Description = "Remote Office 2" },
@{ Network = "10.0.0.0/8"; Gateway = "WAN2_GATEWAY"; Description = "Corporate Network" },
@{ Network = "172.16.0.0/16"; Gateway = "WAN3_GATEWAY"; Description = "Partner Network" }
)
# Create routes
foreach ($route in $routes) {
New-OPNSenseRoute -Network $route.Network -Gateway $route.Gateway -Description $route.Description -Force
}
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Updating Routes for a Gateway Change
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all routes using a specific gateway
$routes = Get-OPNSenseRoute -Gateway "WAN_GATEWAY"
# Update routes to use a different gateway
foreach ($route in $routes) {
Set-OPNSenseRoute -Uuid $route.Uuid -Gateway "WAN2_GATEWAY" -Description "$($route.Description) (Updated)" -Force
Write-Output "Updated route for network $($route.Network) to use gateway WAN2_GATEWAY"
}
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Temporarily Disabling Routes
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all routes
$routes = Get-OPNSenseRoute
# Disable routes for a specific network range
foreach ($route in $routes) {
if ($route.Network -like "10.*") {
Set-OPNSenseRoute -Uuid $route.Uuid -Disabled:$true -Force
Write-Output "Disabled route for network $($route.Network)"
}
}
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Route Cleanup
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all routes
$routes = Get-OPNSenseRoute
# Remove routes with "Temporary" in the description
foreach ($route in $routes) {
if ($route.Description -like "*Temporary*") {
Remove-OPNSenseRoute -Uuid $route.Uuid -Force
Write-Output "Removed route for network $($route.Network) with description '$($route.Description)'"
}
}
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Creating Routes from Network Calculations
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Calculate subnets
$network = "10.0.0.0/16"
$prefixLength = 24
$subnets = Invoke-OPNSenseNetworkCalculation -Network $network -Operation Subnet -PrefixLength $prefixLength
# Create routes for each subnet
foreach ($subnet in $subnets) {
# Determine the gateway based on the subnet
$gateway = if ($subnet.CIDR -like "10.0.1*") {
"WAN_GATEWAY"
} elseif ($subnet.CIDR -like "10.0.2*") {
"WAN2_GATEWAY"
} else {
"WAN3_GATEWAY"
}
New-OPNSenseRoute -Network $subnet.CIDR -Gateway $gateway -Description "Subnet $($subnet.CIDR)" -Force
Write-Output "Created route for network $($subnet.CIDR) via gateway $gateway"
}
# Apply the changes
Apply-OPNSenseRouteChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Route changes are not applied until you call `Apply-OPNSenseRouteChanges`.
- When creating a route, ensure that the gateway is properly configured and reachable.
- Static routes take precedence over dynamic routes.
- The network should be specified in CIDR notation (e.g., "192.168.1.0/24").
- Routes can be temporarily disabled without removing them.
- Consider using the `-PassThru` parameter when updating routes to verify the changes.
- Route descriptions should be descriptive and follow a consistent naming convention.
- When managing multiple routes, consider using a CSV file or other structured data source to maintain the route information.
- Static routes are useful for directing traffic to specific networks through different gateways.
- For complex routing scenarios, consider using policy-based routing instead of static routes.
+296
View File
@@ -0,0 +1,296 @@
# System Backup and Restore
This component provides cmdlets for backing up and restoring OPNSense firewall configurations.
## Overview
The System Backup and Restore component allows you to create, download, upload, and restore backups of OPNSense firewall configurations. It provides cmdlets for managing full and partial backups, as well as scheduling automatic backups.
## Cmdlets
### Get-OPNSenseBackup
Retrieves a list of available backups on an OPNSense firewall.
#### Examples
```powershell
# Get all available backups
Get-OPNSenseBackup
```
### New-OPNSenseBackup
Creates a new backup of an OPNSense firewall configuration.
#### Parameters
- **IncludeRRD** - Whether to include RRD data in the backup. Default is false.
- **IncludeInstalled** - Whether to include installed packages in the backup. Default is false.
- **Encrypted** - Whether to encrypt the backup. Default is false.
- **Password** - The password to use for encryption.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic configuration backup
New-OPNSenseBackup
# Create a full backup including RRD data and installed packages
New-OPNSenseBackup -IncludeRRD -IncludeInstalled
# Create an encrypted backup
New-OPNSenseBackup -Encrypted -Password "SecurePassword123"
# Create a full encrypted backup without confirmation
New-OPNSenseBackup -IncludeRRD -IncludeInstalled -Encrypted -Password "SecurePassword123" -Force
```
### Save-OPNSenseBackup
Downloads a backup from an OPNSense firewall to a local file.
#### Parameters
- **BackupId** - The ID of the backup to download.
- **Path** - The local path to save the backup to.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Download the latest backup
$backups = Get-OPNSenseBackup
$latestBackup = $backups | Sort-Object -Property Date -Descending | Select-Object -First 1
Save-OPNSenseBackup -BackupId $latestBackup.Id -Path "C:\Backups\opnsense-backup.xml"
# Download a specific backup
Save-OPNSenseBackup -BackupId "config-1234567890.xml" -Path "C:\Backups\opnsense-specific-backup.xml"
# Download a backup and overwrite existing file without confirmation
Save-OPNSenseBackup -BackupId "config-1234567890.xml" -Path "C:\Backups\opnsense-backup.xml" -Force
```
### Restore-OPNSenseBackup
Restores an OPNSense firewall configuration from a backup.
#### Parameters
- **BackupId** - The ID of the backup to restore.
- **Password** - The password for encrypted backups.
- **RebootAfterRestore** - Whether to reboot the firewall after restoring. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Restore a backup
Restore-OPNSenseBackup -BackupId "config-1234567890.xml"
# Restore an encrypted backup
Restore-OPNSenseBackup -BackupId "config-1234567890.xml" -Password "SecurePassword123"
# Restore a backup and reboot the firewall
Restore-OPNSenseBackup -BackupId "config-1234567890.xml" -RebootAfterRestore
# Restore a backup without confirmation
Restore-OPNSenseBackup -BackupId "config-1234567890.xml" -Force
```
### Import-OPNSenseBackup
Uploads and restores a backup file to an OPNSense firewall.
#### Parameters
- **Path** - The local path of the backup file to upload.
- **Password** - The password for encrypted backups.
- **RebootAfterRestore** - Whether to reboot the firewall after restoring. Default is false.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Upload and restore a backup
Import-OPNSenseBackup -Path "C:\Backups\opnsense-backup.xml"
# Upload and restore an encrypted backup
Import-OPNSenseBackup -Path "C:\Backups\opnsense-encrypted-backup.xml" -Password "SecurePassword123"
# Upload and restore a backup and reboot the firewall
Import-OPNSenseBackup -Path "C:\Backups\opnsense-backup.xml" -RebootAfterRestore
# Upload and restore a backup without confirmation
Import-OPNSenseBackup -Path "C:\Backups\opnsense-backup.xml" -Force
```
### Remove-OPNSenseBackup
Removes a backup from an OPNSense firewall.
#### Parameters
- **BackupId** - The ID of the backup to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a backup
Remove-OPNSenseBackup -BackupId "config-1234567890.xml"
# Remove a backup without confirmation
Remove-OPNSenseBackup -BackupId "config-1234567890.xml" -Force
```
## Common Scenarios
### Creating and Downloading a Backup
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a full backup
New-OPNSenseBackup -IncludeRRD -IncludeInstalled -Force
# Get the latest backup
$backups = Get-OPNSenseBackup
$latestBackup = $backups | Sort-Object -Property Date -Descending | Select-Object -First 1
# Download the backup
$backupPath = "C:\Backups\opnsense-$(Get-Date -Format 'yyyyMMdd-HHmmss').xml"
Save-OPNSenseBackup -BackupId $latestBackup.Id -Path $backupPath -Force
Write-Output "Backup saved to: $backupPath"
# Disconnect from the firewall
Disconnect-OPNSense
```
### Scheduled Backup with Rotation
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a new backup
New-OPNSenseBackup -IncludeRRD -IncludeInstalled -Force
# Get all backups
$backups = Get-OPNSenseBackup
# Keep only the 5 most recent backups
if ($backups.Count -gt 5) {
$backupsToRemove = $backups | Sort-Object -Property Date -Descending | Select-Object -Skip 5
foreach ($backup in $backupsToRemove) {
Remove-OPNSenseBackup -BackupId $backup.Id -Force
Write-Output "Removed old backup: $($backup.Id)"
}
}
# Download the latest backup
$latestBackup = $backups | Sort-Object -Property Date -Descending | Select-Object -First 1
$backupPath = "C:\Backups\opnsense-$(Get-Date -Format 'yyyyMMdd').xml"
Save-OPNSenseBackup -BackupId $latestBackup.Id -Path $backupPath -Force
Write-Output "Backup saved to: $backupPath"
# Disconnect from the firewall
Disconnect-OPNSense
```
### Restoring from a Local Backup
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Upload and restore a backup
$backupPath = "C:\Backups\opnsense-backup.xml"
Import-OPNSenseBackup -Path $backupPath -RebootAfterRestore -Force
Write-Output "Backup restored from: $backupPath"
Write-Output "The firewall will reboot to apply the changes."
# Disconnect from the firewall
Disconnect-OPNSense
```
### Creating Encrypted Backups
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Generate a secure password
$password = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 16 | ForEach-Object { [char]$_ })
# Create an encrypted backup
New-OPNSenseBackup -IncludeRRD -IncludeInstalled -Encrypted -Password $password -Force
# Get the latest backup
$backups = Get-OPNSenseBackup
$latestBackup = $backups | Sort-Object -Property Date -Descending | Select-Object -First 1
# Download the backup
$backupPath = "C:\Backups\opnsense-encrypted-$(Get-Date -Format 'yyyyMMdd-HHmmss').xml"
Save-OPNSenseBackup -BackupId $latestBackup.Id -Path $backupPath -Force
# Save the password to a secure file
$passwordPath = "C:\Backups\opnsense-backup-password.txt"
$password | Out-File -FilePath $passwordPath -Force
Write-Output "Encrypted backup saved to: $backupPath"
Write-Output "Password saved to: $passwordPath"
Write-Output "Keep the password file secure, as it is required to restore the backup."
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing Backup History
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all backups
$backups = Get-OPNSenseBackup
# Display backup information
Write-Output "Available backups:"
$backups | Format-Table -Property Id, Date, Size, Description
# Calculate total backup size
$totalSize = ($backups | Measure-Object -Property Size -Sum).Sum
Write-Output "Total backup size: $($totalSize / 1MB) MB"
# Remove backups older than 30 days
$cutoffDate = (Get-Date).AddDays(-30)
$oldBackups = $backups | Where-Object { [DateTime]::Parse($_.Date) -lt $cutoffDate }
foreach ($backup in $oldBackups) {
Remove-OPNSenseBackup -BackupId $backup.Id -Force
Write-Output "Removed old backup: $($backup.Id) from $($backup.Date)"
}
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Backups can be large, especially when including RRD data and installed packages.
- Encrypted backups provide additional security but require the password for restoration.
- The `RebootAfterRestore` parameter will cause the firewall to reboot immediately after restoring a backup.
- When restoring a backup, all current configuration settings will be replaced with those from the backup.
- Consider implementing a backup rotation strategy to manage disk space.
- Store backup passwords securely, as they are required to restore encrypted backups.
- Regular backups are essential for disaster recovery.
- Backup files contain sensitive information, so they should be stored securely.
- The backup ID is typically in the format "config-timestamp.xml".
- When scheduling automatic backups, consider using the `New-OPNSenseCronJob` cmdlet to create a scheduled task.
- Backups can be used to migrate configurations between OPNSense firewalls.
- Before major configuration changes, create a backup to allow for easy rollback if needed.
+263
View File
@@ -0,0 +1,263 @@
# Tailscale Integration
This component provides cmdlets for managing Tailscale VPN on OPNSense firewalls.
## Overview
The Tailscale Integration component allows you to install, configure, and manage Tailscale VPN on OPNSense firewalls. It provides cmdlets for enabling Tailscale, configuring subnet routes, and managing the Tailscale connection.
## Cmdlets
### Get-OPNSenseTailscaleStatus
Retrieves the status of Tailscale on an OPNSense firewall.
#### Examples
```powershell
# Get Tailscale status
Get-OPNSenseTailscaleStatus
```
### Install-OPNSenseTailscale
Installs the Tailscale plugin on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Install Tailscale
Install-OPNSenseTailscale
# Install Tailscale without confirmation
Install-OPNSenseTailscale -Force
```
### Enable-OPNSenseTailscale
Enables Tailscale on an OPNSense firewall.
#### Parameters
- **AuthKey** - The Tailscale authentication key.
- **Hostname** - The hostname to use for the Tailscale node.
- **AcceptDNS** - Whether to accept DNS settings from Tailscale.
- **AcceptRoutes** - Whether to accept routes from Tailscale.
- **AdvertiseRoutes** - The routes to advertise to Tailscale.
- **ExitNode** - Whether to use this node as an exit node.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the Tailscale status.
#### Examples
```powershell
# Enable Tailscale with basic settings
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456"
# Enable Tailscale with a custom hostname
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -Hostname "opnsense-firewall"
# Enable Tailscale with DNS and route acceptance
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -AcceptDNS -AcceptRoutes
# Enable Tailscale with route advertisement
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -AdvertiseRoutes "192.168.1.0/24,10.0.0.0/8"
# Enable Tailscale as an exit node
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -ExitNode
```
### Disable-OPNSenseTailscale
Disables Tailscale on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Disable Tailscale
Disable-OPNSenseTailscale
# Disable Tailscale without confirmation
Disable-OPNSenseTailscale -Force
```
### Set-OPNSenseTailscaleRoutes
Updates the routes advertised by Tailscale on an OPNSense firewall.
#### Parameters
- **AdvertiseRoutes** - The routes to advertise to Tailscale.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the Tailscale status.
#### Examples
```powershell
# Set Tailscale routes
Set-OPNSenseTailscaleRoutes -AdvertiseRoutes "192.168.1.0/24,10.0.0.0/8"
# Set Tailscale routes without confirmation
Set-OPNSenseTailscaleRoutes -AdvertiseRoutes "192.168.1.0/24,10.0.0.0/8" -Force
```
### Get-OPNSenseTailscalePeers
Retrieves the Tailscale peers connected to an OPNSense firewall.
#### Examples
```powershell
# Get Tailscale peers
Get-OPNSenseTailscalePeers
```
### Apply-OPNSenseTailscaleChanges
Applies pending Tailscale changes on an OPNSense firewall.
#### Parameters
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Apply Tailscale changes
Apply-OPNSenseTailscaleChanges
# Apply Tailscale changes without confirmation
Apply-OPNSenseTailscaleChanges -Force
```
## Common Scenarios
### Installing and Configuring Tailscale
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Install Tailscale
Install-OPNSenseTailscale -Force
# Enable Tailscale with basic settings
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -Hostname "opnsense-firewall" -Force
# Apply the changes
Apply-OPNSenseTailscaleChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Configuring Tailscale as a Subnet Router
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get the current network interfaces
$interfaces = Get-OPNSenseInterface
# Build a list of subnets to advertise
$subnets = @()
foreach ($interface in $interfaces) {
if ($interface.Name -ne "wan" -and $interface.IPv4Address) {
$subnet = "$($interface.IPv4Network)/$($interface.IPv4Subnet)"
$subnets += $subnet
}
}
# Join the subnets with commas
$advertisedRoutes = $subnets -join ","
# Enable Tailscale with route advertisement
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -AdvertiseRoutes $advertisedRoutes -Force
# Apply the changes
Apply-OPNSenseTailscaleChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Configuring Tailscale as an Exit Node
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Enable Tailscale as an exit node
Enable-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -ExitNode -Force
# Apply the changes
Apply-OPNSenseTailscaleChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Updating Tailscale Routes
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get the current Tailscale status
$status = Get-OPNSenseTailscaleStatus
# Add a new subnet to the advertised routes
$currentRoutes = $status.AdvertisedRoutes -split ","
$newSubnet = "172.16.0.0/16"
if ($currentRoutes -notcontains $newSubnet) {
$currentRoutes += $newSubnet
}
# Update the advertised routes
$advertisedRoutes = $currentRoutes -join ","
Set-OPNSenseTailscaleRoutes -AdvertiseRoutes $advertisedRoutes -Force
# Apply the changes
Apply-OPNSenseTailscaleChanges -Force
# Disconnect from the firewall
Disconnect-OPNSense
```
### Monitoring Tailscale Peers
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get Tailscale peers
$peers = Get-OPNSenseTailscalePeers
# Display peer information
$peers | Format-Table -Property Name, IP, Status, LastSeen
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Tailscale requires the Tailscale plugin to be installed on the OPNSense firewall.
- The `Install-OPNSenseTailscale` cmdlet will install the plugin if it's not already installed.
- Tailscale authentication keys can be generated from the Tailscale admin console.
- Authentication keys are single-use and expire after a short period.
- When advertising routes, ensure that the routes are valid and do not overlap with Tailscale's internal routes.
- The `AcceptDNS` option allows Tailscale to configure DNS settings on the OPNSense firewall.
- The `AcceptRoutes` option allows Tailscale to add routes to the OPNSense firewall.
- The `ExitNode` option allows other Tailscale nodes to use the OPNSense firewall as an internet gateway.
- Changes to Tailscale settings are not applied until you call `Apply-OPNSenseTailscaleChanges`.
- Consider using the `-PassThru` parameter when updating Tailscale settings to verify the changes.
+334
View File
@@ -0,0 +1,334 @@
# Troubleshooting Guide
This document provides troubleshooting information for common issues with the PSOPNSenseAPI module.
## Connection Issues
### Unable to Connect to OPNSense Firewall
**Symptoms:**
- `Connect-OPNSense` fails with connection errors
- Error messages about unreachable hosts or connection timeouts
**Possible Causes and Solutions:**
1. **Incorrect URL:**
- Ensure the URL is correct and includes the protocol (https://)
- Verify there are no typos in the domain name or IP address
```powershell
# Correct format
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"
```
2. **Network Connectivity:**
- Verify that you can reach the OPNSense firewall from your computer
- Try pinging the firewall or accessing the web interface in a browser
```powershell
# Test connectivity
Test-NetConnection -ComputerName "firewall.example.com" -Port 443
```
3. **Certificate Issues:**
- If the firewall uses a self-signed certificate, use the `-SkipCertificateCheck` parameter
```powershell
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
```
4. **Firewall Rules:**
- Check if there are any firewall rules blocking access to the OPNSense web interface
- Ensure that port 443 (HTTPS) is open for your IP address
5. **Proxy Settings:**
- If you're behind a proxy, configure PowerShell to use the proxy
```powershell
# Configure proxy
[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy("http://proxy.example.com:8080")
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
```
### Authentication Failures
**Symptoms:**
- `Connect-OPNSense` fails with authentication errors
- Error messages about invalid credentials or unauthorized access
**Possible Causes and Solutions:**
1. **Incorrect API Key or Secret:**
- Verify that the API key and secret are correct
- Regenerate the API key and secret if necessary
2. **API Access Not Enabled:**
- Ensure that API access is enabled for the user
- Check the user's privileges in the OPNSense web interface
3. **User Permissions:**
- Verify that the user has the necessary privileges for the operations you're trying to perform
- Consider using a user with administrative privileges for testing
4. **API Key Expiration:**
- Some OPNSense configurations may have API key expiration
- Generate a new API key if the current one has expired
## Module Loading Issues
### Module Not Found
**Symptoms:**
- `Import-Module PSOPNSenseAPI` fails with module not found errors
- Commands from the module are not recognized
**Possible Causes and Solutions:**
1. **Module Not Installed:**
- Verify that the module is installed
```powershell
# Check if the module is installed
Get-Module -Name PSOPNSenseAPI -ListAvailable
```
2. **Module Not in PSModulePath:**
- Check if the module is installed in a valid module path
```powershell
# List module paths
$env:PSModulePath -split ';'
```
3. **Module Version Mismatch:**
- Check if you have multiple versions of the module installed
```powershell
# List all versions of the module
Get-Module -Name PSOPNSenseAPI -ListAvailable | Select-Object Name, Version
```
4. **PowerShell Version Compatibility:**
- Verify that you're using a compatible PowerShell version
- The module requires PowerShell 5.1 or later
```powershell
# Check PowerShell version
$PSVersionTable
```
### Module Loading Errors
**Symptoms:**
- `Import-Module PSOPNSenseAPI` fails with loading errors
- Error messages about missing dependencies or assembly loading failures
**Possible Causes and Solutions:**
1. **Missing Dependencies:**
- Ensure that all dependencies are installed
- The module requires .NET Framework 4.7.2 or later for Windows PowerShell
2. **Assembly Loading Issues:**
- Try loading the module with verbose output to identify the specific issue
```powershell
# Load module with verbose output
Import-Module -Name PSOPNSenseAPI -Verbose
```
3. **File Corruption:**
- Reinstall the module to ensure all files are intact
```powershell
# Uninstall and reinstall the module
Uninstall-Module -Name PSOPNSenseAPI -Force
Install-Module -Name PSOPNSenseAPI -Force
```
## Command Execution Issues
### Command Fails with Error
**Symptoms:**
- Commands fail with error messages
- Unexpected results or behavior
**Possible Causes and Solutions:**
1. **Not Connected to Firewall:**
- Ensure that you're connected to the firewall before running commands
```powershell
# Check if connected
if (-not $OPNSenseSessionState.Instance.ApiClient) {
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"
}
```
2. **Insufficient Permissions:**
- Verify that the user has the necessary privileges for the operation
- Check the error message for permission-related issues
3. **Invalid Parameters:**
- Check that you're using the correct parameters and values
- Use `Get-Help` to see the required and optional parameters
```powershell
# Get help for a command
Get-Help -Name New-OPNSenseFirewallRule -Full
```
4. **API Limitations:**
- Some operations may not be supported by the OPNSense API
- Check the OPNSense API documentation for supported operations
5. **Firewall Configuration:**
- The current state of the firewall may prevent certain operations
- Check the OPNSense logs for more information
### Changes Not Applied
**Symptoms:**
- Commands appear to succeed, but changes are not reflected on the firewall
- Configuration changes don't persist after a firewall reboot
**Possible Causes and Solutions:**
1. **Apply Changes Not Called:**
- Many commands require an explicit call to apply the changes
```powershell
# Apply changes after making configuration changes
Apply-OPNSenseFirewallChanges
```
2. **Caching Issues:**
- The OPNSense web interface may be showing cached data
- Refresh the web interface or wait a few moments
3. **Conflicting Configurations:**
- Other configurations may be overriding your changes
- Check for conflicting rules or settings
4. **Firewall Reboot Required:**
- Some changes may require a firewall reboot to take effect
```powershell
# Reboot the firewall
Invoke-OPNSenseReboot
```
## Performance Issues
### Slow Command Execution
**Symptoms:**
- Commands take a long time to execute
- Timeouts or performance degradation
**Possible Causes and Solutions:**
1. **Network Latency:**
- High latency between your computer and the firewall can slow down commands
- Consider running commands from a location with better connectivity
2. **Firewall Load:**
- The firewall may be under heavy load
- Try running commands during periods of lower activity
3. **Large Data Sets:**
- Commands that retrieve large amounts of data may be slow
- Use filtering parameters to limit the data returned
```powershell
# Filter results to reduce data
Get-OPNSenseFirewallRule -Interface "lan"
```
4. **Inefficient Scripts:**
- Scripts that make many individual API calls can be slow
- Batch operations where possible and minimize the number of API calls
## Logging and Debugging
### Enabling Verbose Logging
To troubleshoot issues, you can enable verbose logging:
```powershell
# Enable verbose output
$VerbosePreference = "Continue"
# Run commands with verbose output
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -Verbose
```
### Capturing HTTP Traffic
For advanced troubleshooting, you can capture the HTTP traffic between the module and the OPNSense firewall:
```powershell
# Enable Fiddler capture
[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy("http://localhost:8888")
[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $false
```
Note: This requires [Fiddler](https://www.telerik.com/fiddler) or a similar HTTP debugging proxy to be installed and running.
### Checking OPNSense Logs
Check the OPNSense logs for additional information:
1. Log in to the OPNSense web interface
2. Navigate to **System > Log Files > General**
3. Look for entries related to the API or the operations you're performing
## Common Error Messages
### "Not connected to an OPNSense firewall"
**Cause:** You're trying to run a command without first connecting to the firewall.
**Solution:** Connect to the firewall before running commands:
```powershell
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"
```
### "The remote server returned an error: (401) Unauthorized"
**Cause:** The API key or secret is incorrect, or the user doesn't have the necessary privileges.
**Solution:** Verify the API key and secret, and check the user's privileges.
### "The remote server returned an error: (404) Not Found"
**Cause:** The requested resource or API endpoint doesn't exist.
**Solution:** Check that you're using the correct command and parameters, and that the resource exists on the firewall.
### "The remote server returned an error: (500) Internal Server Error"
**Cause:** An error occurred on the OPNSense firewall while processing the request.
**Solution:** Check the OPNSense logs for more information, and verify that the firewall is functioning correctly.
### "Unable to find type [System.Net.IPNetwork.IPNetwork]"
**Cause:** The IPNetwork2 assembly is not loaded or is missing.
**Solution:** Reinstall the module to ensure all dependencies are properly installed.
## Getting Help
If you're still experiencing issues after trying the troubleshooting steps above:
1. Check the [GitHub repository](https://github.com/freedbygrace/PSOPNSenseAPI) for known issues and solutions
2. Open an issue on GitHub with detailed information about the problem
3. Include the following information in your issue:
- PSOPNSenseAPI module version
- PowerShell version
- OPNSense version
- Error messages (with sensitive information redacted)
- Steps to reproduce the issue
+388
View File
@@ -0,0 +1,388 @@
# User Management
This component provides cmdlets for managing users on OPNSense firewalls.
## Overview
The User Management component allows you to create, view, modify, and delete users on OPNSense firewalls. It provides cmdlets for managing user accounts, privileges, and API keys.
## Cmdlets
### Get-OPNSenseUser
Retrieves users from an OPNSense firewall.
#### Parameters
- **Username** - The username of a specific user to retrieve. If not specified, all users are returned.
- **Uid** - The UID of a specific user to retrieve.
#### Examples
```powershell
# Get all users
Get-OPNSenseUser
# Get a specific user by username
Get-OPNSenseUser -Username "admin"
# Get a specific user by UID
Get-OPNSenseUser -Uid 1000
```
### New-OPNSenseUser
Creates a new user on an OPNSense firewall.
#### Parameters
- **Username** - The username for the new user.
- **Password** - The password for the new user.
- **FullName** - The full name of the user.
- **Email** - The email address of the user.
- **Authorized** - Whether the user is authorized to log in. Default is true.
- **Privileges** - The privileges to assign to the user.
- **Group** - The group to assign the user to.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic user
New-OPNSenseUser -Username "john" -Password "SecurePassword123" -FullName "John Doe" -Email "john@example.com"
# Create a user with specific privileges
New-OPNSenseUser -Username "jane" -Password "SecurePassword456" -FullName "Jane Smith" -Email "jane@example.com" -Privileges "page-system-access", "page-diagnostics-logs"
# Create a user in a specific group
New-OPNSenseUser -Username "bob" -Password "SecurePassword789" -FullName "Bob Johnson" -Email "bob@example.com" -Group "admins"
# Create a user without confirmation
New-OPNSenseUser -Username "alice" -Password "SecurePassword101" -FullName "Alice Brown" -Email "alice@example.com" -Force
```
### Set-OPNSenseUser
Updates an existing user on an OPNSense firewall.
#### Parameters
- **Username** - The username of the user to update.
- **Password** - The new password for the user.
- **FullName** - The new full name of the user.
- **Email** - The new email address of the user.
- **Authorized** - Whether the user is authorized to log in.
- **Privileges** - The new privileges to assign to the user.
- **Group** - The new group to assign the user to.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated user.
#### Examples
```powershell
# Update a user's email address
Set-OPNSenseUser -Username "john" -Email "john.doe@example.com"
# Update a user's password
Set-OPNSenseUser -Username "jane" -Password "NewSecurePassword456"
# Update a user's privileges
Set-OPNSenseUser -Username "bob" -Privileges "page-system-access", "page-diagnostics-logs", "page-firewall-rules"
# Update a user's group
Set-OPNSenseUser -Username "alice" -Group "operators"
# Disable a user
Set-OPNSenseUser -Username "temp" -Authorized:$false
# Update multiple properties of a user
Set-OPNSenseUser -Username "john" -FullName "John A. Doe" -Email "john.a.doe@example.com" -Privileges "page-system-access", "page-diagnostics-logs" -PassThru
```
### Remove-OPNSenseUser
Removes a user from an OPNSense firewall.
#### Parameters
- **Username** - The username of the user to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a user
Remove-OPNSenseUser -Username "temp"
# Remove a user without confirmation
Remove-OPNSenseUser -Username "guest" -Force
```
### Get-OPNSenseUserGroup
Retrieves user groups from an OPNSense firewall.
#### Parameters
- **Name** - The name of a specific group to retrieve. If not specified, all groups are returned.
#### Examples
```powershell
# Get all user groups
Get-OPNSenseUserGroup
# Get a specific user group by name
Get-OPNSenseUserGroup -Name "admins"
```
### New-OPNSenseUserGroup
Creates a new user group on an OPNSense firewall.
#### Parameters
- **Name** - The name of the new group.
- **Description** - A description for the group.
- **Privileges** - The privileges to assign to the group.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a basic user group
New-OPNSenseUserGroup -Name "operators" -Description "System Operators"
# Create a user group with specific privileges
New-OPNSenseUserGroup -Name "firewall-admins" -Description "Firewall Administrators" -Privileges "page-firewall-rules", "page-firewall-nat"
# Create a user group without confirmation
New-OPNSenseUserGroup -Name "readonly" -Description "Read-Only Users" -Privileges "page-system-access" -Force
```
### Set-OPNSenseUserGroup
Updates an existing user group on an OPNSense firewall.
#### Parameters
- **Name** - The name of the group to update.
- **Description** - The new description for the group.
- **Privileges** - The new privileges to assign to the group.
- **Force** - Suppresses the confirmation prompt.
- **PassThru** - Returns the updated group.
#### Examples
```powershell
# Update a user group's description
Set-OPNSenseUserGroup -Name "operators" -Description "System Operators with Limited Access"
# Update a user group's privileges
Set-OPNSenseUserGroup -Name "firewall-admins" -Privileges "page-firewall-rules", "page-firewall-nat", "page-firewall-aliases"
# Update multiple properties of a user group
Set-OPNSenseUserGroup -Name "readonly" -Description "Read-Only Access Users" -Privileges "page-system-access", "page-diagnostics-logs" -PassThru
```
### Remove-OPNSenseUserGroup
Removes a user group from an OPNSense firewall.
#### Parameters
- **Name** - The name of the group to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a user group
Remove-OPNSenseUserGroup -Name "temp-group"
# Remove a user group without confirmation
Remove-OPNSenseUserGroup -Name "guest-group" -Force
```
### Get-OPNSenseApiKey
Retrieves API keys for a user on an OPNSense firewall.
#### Parameters
- **Username** - The username to get API keys for.
#### Examples
```powershell
# Get API keys for a user
Get-OPNSenseApiKey -Username "admin"
```
### New-OPNSenseApiKey
Creates a new API key for a user on an OPNSense firewall.
#### Parameters
- **Username** - The username to create an API key for.
- **Description** - A description for the API key.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create an API key for a user
New-OPNSenseApiKey -Username "admin" -Description "Automation API Key"
# Create an API key without confirmation
New-OPNSenseApiKey -Username "john" -Description "Monitoring API Key" -Force
```
### Remove-OPNSenseApiKey
Removes an API key from an OPNSense firewall.
#### Parameters
- **KeyId** - The ID of the API key to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove an API key
Remove-OPNSenseApiKey -KeyId "abcdef123456"
# Remove an API key without confirmation
Remove-OPNSenseApiKey -KeyId "abcdef123456" -Force
```
## Common Scenarios
### Creating a New Administrator User
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create a new administrator user
New-OPNSenseUser -Username "admin2" -Password "SecurePassword123" -FullName "Secondary Admin" -Email "admin2@example.com" -Group "admins" -Force
# Create an API key for the new user
New-OPNSenseApiKey -Username "admin2" -Description "Admin API Key" -Force
# Get the API key details
$apiKeys = Get-OPNSenseApiKey -Username "admin2"
Write-Output "API Key created for admin2:"
$apiKeys | Format-Table -Property KeyId, Secret, Description, Created
# Disconnect from the firewall
Disconnect-OPNSense
```
### Creating Users with Different Privilege Levels
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Create user groups with different privilege levels
New-OPNSenseUserGroup -Name "firewall-admins" -Description "Firewall Administrators" -Privileges "page-firewall-rules", "page-firewall-nat", "page-firewall-aliases" -Force
New-OPNSenseUserGroup -Name "network-admins" -Description "Network Administrators" -Privileges "page-interfaces", "page-routing", "page-diagnostics-interface" -Force
New-OPNSenseUserGroup -Name "monitoring" -Description "Monitoring Users" -Privileges "page-diagnostics-logs", "page-diagnostics-system", "page-status-dashboard" -Force
# Create users in different groups
$users = @(
@{ Username = "firewall"; FullName = "Firewall Admin"; Email = "firewall@example.com"; Group = "firewall-admins" },
@{ Username = "network"; FullName = "Network Admin"; Email = "network@example.com"; Group = "network-admins" },
@{ Username = "monitor"; FullName = "Monitoring User"; Email = "monitor@example.com"; Group = "monitoring" }
)
foreach ($user in $users) {
# Generate a secure password
$password = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 16 | ForEach-Object { [char]$_ })
# Create the user
New-OPNSenseUser -Username $user.Username -Password $password -FullName $user.FullName -Email $user.Email -Group $user.Group -Force
Write-Output "Created user: $($user.Username) with password: $password"
}
# Disconnect from the firewall
Disconnect-OPNSense
```
### Managing API Keys
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all users
$users = Get-OPNSenseUser
# Create API keys for users without them
foreach ($user in $users) {
$apiKeys = Get-OPNSenseApiKey -Username $user.Username
if (-not $apiKeys) {
New-OPNSenseApiKey -Username $user.Username -Description "Automated API Key" -Force
Write-Output "Created API key for user: $($user.Username)"
} else {
Write-Output "User $($user.Username) already has $($apiKeys.Count) API key(s)"
}
}
# Disconnect from the firewall
Disconnect-OPNSense
```
### Cleaning Up Inactive Users
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all users
$users = Get-OPNSenseUser
# Define a cutoff date (e.g., 90 days ago)
$cutoffDate = (Get-Date).AddDays(-90)
# Disable inactive users
foreach ($user in $users) {
# Skip the admin user
if ($user.Username -eq "admin") {
continue
}
# Check if the user has been inactive
if ($user.LastLogin -and [DateTime]::Parse($user.LastLogin) -lt $cutoffDate) {
Set-OPNSenseUser -Username $user.Username -Authorized:$false -Force
Write-Output "Disabled inactive user: $($user.Username) (Last login: $($user.LastLogin))"
}
}
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- User management requires administrative privileges.
- The `admin` user cannot be removed.
- API keys provide access to the OPNSense API and should be kept secure.
- User privileges determine what actions a user can perform in the OPNSense web interface and API.
- User groups provide a way to assign the same privileges to multiple users.
- Passwords should be strong and meet the OPNSense password policy requirements.
- When a user is removed, all associated API keys are also removed.
- API keys can be used to authenticate with the OPNSense API without a username and password.
- Consider using the `-Force` parameter when managing users in scripts to avoid confirmation prompts.
- User accounts can be disabled by setting the `Authorized` parameter to `$false`.
- The `PassThru` parameter can be used to return the updated user or group for further processing.
- User privileges are typically specified as page identifiers (e.g., "page-system-access").
- The available privileges can be found in the OPNSense web interface under System > Access > Privileges.
- User groups can be used to organize users and assign privileges more efficiently.
- API keys can have descriptions to help identify their purpose.
- When creating API keys, both the key ID and secret are returned, but the secret is only shown once.
+173
View File
@@ -0,0 +1,173 @@
# VLAN and Subnet Management
This component provides cmdlets for managing VLANs and subnets on OPNSense firewalls.
## Overview
The VLAN and Subnet Management component allows you to create, view, modify, and delete VLANs on OPNSense firewalls. It also includes advanced functionality for automatically creating VLANs from subnet divisions, making it easy to implement complex network segmentation.
## Cmdlets
### Get-OPNSenseVLAN
Retrieves VLAN configurations from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of a specific VLAN to retrieve. If not specified, all VLANs are returned.
#### Examples
```powershell
# Get all VLANs
Get-OPNSenseVLAN
# Get a specific VLAN by UUID
Get-OPNSenseVLAN -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
```
### New-OPNSenseVLAN
Creates a new VLAN on an OPNSense firewall.
#### Parameters
- **Interface** - The parent interface for the VLAN.
- **Tag** - The VLAN tag (1-4094).
- **Priority** - The VLAN priority (0-7).
- **Description** - A description for the VLAN.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create a new VLAN
New-OPNSenseVLAN -Interface "em0" -Tag 10 -Description "Management VLAN"
# Create a new VLAN with priority and without confirmation
New-OPNSenseVLAN -Interface "em1" -Tag 20 -Priority 5 -Description "Voice VLAN" -Force
```
### Remove-OPNSenseVLAN
Removes a VLAN from an OPNSense firewall.
#### Parameters
- **Uuid** - The UUID of the VLAN to remove.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Remove a VLAN
Remove-OPNSenseVLAN -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
# Remove a VLAN without confirmation
Remove-OPNSenseVLAN -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -Force
```
### New-OPNSenseSubnetVLANs
Creates VLANs for subnets by dividing a network into smaller subnets.
#### Parameters
- **ParentInterface** - The parent interface for the VLANs.
- **Network** - The network in CIDR notation to divide into subnets.
- **SubnetMaskBits** - The subnet mask bits for the subnets.
- **StartingVlanId** - The starting VLAN ID.
- **VlanIdIncrement** - The increment for VLAN IDs.
- **DescriptionPrefix** - The prefix for VLAN descriptions.
- **EnableDHCP** - Whether to enable DHCP on the created VLANs.
- **DHCPRangeStart** - The starting IP address for the DHCP range.
- **DHCPRangeEnd** - The ending IP address for the DHCP range.
- **DHCPDomain** - The domain name for DHCP clients.
- **DHCPDnsServers** - The DNS servers for DHCP clients.
- **Force** - Suppresses the confirmation prompt.
#### Examples
```powershell
# Create VLANs for subnets with sequential VLAN IDs
New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 1
# Create VLANs for subnets with VLAN IDs in multiples of 10
New-OPNSenseSubnetVLANs -ParentInterface "em1" -Network "10.0.0.0/16" -SubnetMaskBits 24 -StartingVlanId 100 -VlanIdIncrement 10
# Create VLANs for subnets with DHCP enabled
New-OPNSenseSubnetVLANs -ParentInterface "em2" -Network "172.16.0.0/20" -SubnetMaskBits 24 -StartingVlanId 200 -VlanIdIncrement 1 -EnableDHCP -DescriptionPrefix "VLAN-DHCP"
# Create VLANs with custom DHCP settings
New-OPNSenseSubnetVLANs -ParentInterface "em3" -Network "192.168.100.0/24" -SubnetMaskBits 26 -StartingVlanId 300 -EnableDHCP -DHCPDomain "example.com" -DHCPDnsServers "8.8.8.8","8.8.4.4"
```
## Common Scenarios
### Basic VLAN Management
```powershell
# Get all VLANs
$vlans = Get-OPNSenseVLAN
$vlans | Format-Table -Property Uuid, Tag, Interface, Description
# Create a new VLAN
New-OPNSenseVLAN -Interface "em0" -Tag 100 -Description "Server VLAN"
# Remove a VLAN
$vlanToRemove = $vlans | Where-Object { $_.Description -eq "Temporary VLAN" }
if ($vlanToRemove) {
Remove-OPNSenseVLAN -Uuid $vlanToRemove.Uuid -Force
}
```
### Network Segmentation with VLANs
```powershell
# Create VLANs for different departments
$departments = @{
"Management" = 10
"Finance" = 20
"HR" = 30
"Engineering" = 40
"Sales" = 50
"Guest" = 60
}
foreach ($dept in $departments.GetEnumerator()) {
New-OPNSenseVLAN -Interface "em0" -Tag $dept.Value -Description "$($dept.Key) VLAN" -Force
}
```
### Automated Subnet Division with VLANs
```powershell
# Divide a /24 network into /27 subnets (8 subnets) with VLANs
New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.1.0/24" -SubnetMaskBits 27 -StartingVlanId 100 -VlanIdIncrement 1 -DescriptionPrefix "Dept-"
# Divide a /16 network into /20 subnets (16 subnets) with VLANs in multiples of 10
New-OPNSenseSubnetVLANs -ParentInterface "em1" -Network "10.0.0.0/16" -SubnetMaskBits 20 -StartingVlanId 100 -VlanIdIncrement 10 -DescriptionPrefix "Branch-"
# Create VLANs with DHCP for a campus network
New-OPNSenseSubnetVLANs -ParentInterface "em2" -Network "172.16.0.0/16" -SubnetMaskBits 22 -StartingVlanId 200 -VlanIdIncrement 1 -EnableDHCP -DescriptionPrefix "Campus-" -DHCPDomain "campus.example.com"
```
### Creating a Multi-Tenant Network
```powershell
# Create a multi-tenant network with VLANs and DHCP
$tenantNetwork = "10.100.0.0/16"
$tenantCount = 16 # Number of tenants
$subnetMaskBits = 20 # /20 networks for each tenant (4,094 hosts per tenant)
New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network $tenantNetwork -SubnetMaskBits $subnetMaskBits -StartingVlanId 1000 -VlanIdIncrement 1 -EnableDHCP -DescriptionPrefix "Tenant-" -DHCPDomain "tenants.example.com" -DHCPDnsServers "10.0.0.1","10.0.0.2"
```
## Notes
- When creating VLANs, ensure that the parent interface supports VLAN tagging.
- The `New-OPNSenseSubnetVLANs` cmdlet automatically creates interfaces for each VLAN.
- If DHCP is enabled, the cmdlet configures DHCP servers for each VLAN with appropriate ranges.
- The VLAN ID must be between 1 and 4094, and must be unique for each parent interface.
- When dividing networks, ensure that the subnet mask bits are larger than the original network's mask bits (e.g., dividing a /24 into /27 subnets).
- The cmdlet automatically calculates appropriate gateway addresses for each subnet (first usable IP address).
+132
View File
@@ -0,0 +1,132 @@
# Visual Studio Solution
This document provides information about the Visual Studio solution for the PSOPNSenseAPI project.
## Overview
The PSOPNSenseAPI solution is a Visual Studio solution that contains the source code for the PSOPNSenseAPI PowerShell module. The solution is designed to be opened in Visual Studio for development, debugging, and troubleshooting.
## Solution Structure
The solution contains the following projects:
- **PSOPNSenseAPI**: The main project containing the PowerShell module code.
## Opening the Solution
To open the solution in Visual Studio:
1. Launch Visual Studio
2. Select "Open a project or solution"
3. Navigate to the root directory of the PSOPNSenseAPI repository
4. Select the `PSOPNSenseAPI.sln` file
5. Click "Open"
## Building the Solution
To build the solution in Visual Studio:
1. Open the solution in Visual Studio
2. Select the desired build configuration (Debug or Release) from the dropdown in the toolbar
3. Select "Build > Build Solution" from the menu or press F6
Alternatively, you can build the solution from the command line using the build scripts:
```powershell
# Build the module
.\build\build.ps1
# Build a release version with automatic versioning
.\build\build-release.ps1 -Clean -Test -Package
```
## Debugging
To debug the module in Visual Studio:
1. Open the solution in Visual Studio
2. Set breakpoints in the code
3. Select "Debug > Start Debugging" from the menu or press F5
For debugging PowerShell cmdlets, you can also use the PowerShell Integrated Scripting Environment (ISE) or Visual Studio Code with the PowerShell extension.
## Troubleshooting IPNetwork2 Issues
If you encounter issues with the IPNetwork2 library, here are some common troubleshooting steps:
1. **Check the reference**: Ensure that the IPNetwork2 package is properly referenced in the project file.
```xml
<PackageReference Include="IPNetwork2" Version="2.6.618" />
```
2. **Verify the namespace**: The correct namespace for IPNetwork2 is `System.Net.IPNetwork`.
```csharp
using System.Net.IPNetwork;
```
3. **Check the class name**: The main class in IPNetwork2 is `IPNetwork`, not `IPNetwork2`.
```csharp
// Correct usage
System.Net.IPNetwork.IPNetwork network = System.Net.IPNetwork.IPNetwork.Parse("192.168.1.0/24");
// Incorrect usage
IPNetwork2 network = IPNetwork2.Parse("192.168.1.0/24");
```
4. **Update package references**: If you're still having issues, try updating the package reference to the latest version.
```powershell
# In Package Manager Console
Update-Package IPNetwork2
```
5. **Restore NuGet packages**: Ensure all NuGet packages are properly restored.
```powershell
# In Package Manager Console
Restore-Package
```
6. **Clean and rebuild**: Sometimes a clean rebuild can resolve reference issues.
```powershell
# In Package Manager Console
Clean-Project
Build-Project
```
## Adding New Features
When adding new features to the solution:
1. Create appropriate model classes in the `Models` directory
2. Implement service classes in the `Services` directory
3. Create PowerShell cmdlets in the `Cmdlets` directory
4. Update the module manifest (`PSOPNSenseAPI.psd1`) to export the new cmdlets
5. Add tests for the new features
6. Update documentation
## Testing
The solution includes unit tests that can be run from Visual Studio using the Test Explorer or from the command line:
```powershell
# Run tests
.\build\test.ps1
```
## Continuous Integration
The project uses GitHub Actions for continuous integration. The CI workflow builds and tests the solution on every push to the main branch.
## Dependencies
The solution has the following dependencies:
- PowerShellStandard.Library (5.1.1)
- Newtonsoft.Json (13.0.3)
- System.Net.Http (4.3.4)
- IPNetwork2 (2.6.618)
## Notes
- The solution is configured to target both .NET Framework 4.7.2 and .NET Standard 2.0 to support both Windows PowerShell 5.1 and PowerShell 7+.
- The module uses a versioning scheme of `yyyy.MM.dd.HHmm` for releases, which is automatically generated during the build process.
- The solution includes XML documentation comments that are used to generate help content for the PowerShell cmdlets.
+135
View File
@@ -0,0 +1,135 @@
TOPIC
about_PSOPNSenseAPI
SHORT DESCRIPTION
PowerShell module for interacting with the OPNSense API to configure firewalls.
LONG DESCRIPTION
The PSOPNSenseAPI module provides cmdlets for managing OPNSense firewalls through their API.
It allows you to perform various firewall management tasks such as:
- Managing firewall rules (create, read, update, delete)
- Configuring NAT rules and port forwarding
- Managing aliases and address groups
- Managing network interfaces and VLANs
- Configuring DNS settings and overrides
- Backing up, restoring, exporting, and importing configurations
- Managing plugins (install, uninstall, enable, disable)
- Managing users and permissions
- Updating and upgrading firmware
- Rebooting firewall with wait for reconnection
- Creating VLANs from subnet divisions
- Configuring DHCP servers and static mappings
- Managing cron jobs
- Configuring and managing Tailscale VPN (with auto-installation)
- Applying and reverting configuration changes
The module is built as a binary module in C# and is compatible with both PowerShell 5.1 and PowerShell 7.
EXAMPLES
Connect to an OPNSense firewall:
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"
Get all firewall rules:
Get-OPNSenseFirewallRule
Create a new firewall rule:
New-OPNSenseFirewallRule -Description "Allow HTTP" -Protocol TCP -DestinationPort 80 -Action pass
Apply changes:
Apply-OPNSenseFirewallChanges
Manage interfaces:
Get-OPNSenseInterface
Set-OPNSenseInterface -Name "lan" -Description "Local Network" -IpAddress "192.168.1.1" -SubnetMask "24"
Create VLANs from subnet divisions:
New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 10
Configure DNS:
Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4" -Apply
New-OPNSenseDNSOverride -Hostname "server" -Domain "local" -IpAddress "192.168.1.10"
Manage plugins:
Get-OPNSensePlugin -Installed
Install-OPNSensePlugin -Name "os-acme-client" -Wait
Manage users:
New-OPNSenseUser -Username "john" -Password "P@ssw0rd" -FullName "John Doe" -Groups "admins"
Configure DHCP:
Get-OPNSenseDHCPServer
Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Apply
New-OPNSenseDHCPStaticMapping -Interface "lan" -MacAddress "00:11:22:33:44:55" -IpAddress "192.168.1.50"
Manage cron jobs:
Get-OPNSenseCronJob
New-OPNSenseCronJob -Description "Daily backup" -Command "/usr/local/bin/backup.sh" -Minutes "0" -Hours "2" -Apply
Configure and manage Tailscale:
Get-OPNSenseTailscaleStatus -IncludeInterfaces
Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Force
# Advertise subnet routes to Tailscale network
Enable-OPNSenseTailscale -AdvertiseRoutes -SubnetRoutes "192.168.1.0/24","10.0.0.0/8" -Force
Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing -Force
Firmware management:
Update-OPNSenseFirmware -Wait
Reboot firewall:
Restart-OPNSenseFirewall -Wait -Timeout 300
Backup and restore configuration:
Backup-OPNSenseConfig -Filename "pre-upgrade-backup"
Export-OPNSenseConfig -Path "C:\Backups\opnsense-config.xml"
KEYWORDS
OPNSense, Firewall, API, Network, Security
SEE ALSO
Connect-OPNSense
Disconnect-OPNSense
Get-OPNSenseFirewallRule
New-OPNSenseFirewallRule
Apply-OPNSenseFirewallChanges
Get-OPNSenseInterface
Set-OPNSenseInterface
New-OPNSenseSubnetVLANs
Get-OPNSenseVLAN
New-OPNSenseVLAN
Get-OPNSenseDNSServer
Set-OPNSenseDNSServer
Get-OPNSensePlugin
Install-OPNSensePlugin
Get-OPNSenseUser
New-OPNSenseUser
Get-OPNSenseDHCPServer
Set-OPNSenseDHCPServer
Get-OPNSenseDHCPStaticMapping
New-OPNSenseDHCPStaticMapping
Get-OPNSenseCronJob
New-OPNSenseCronJob
Get-OPNSenseTailscaleStatus
Enable-OPNSenseTailscale
Connect-OPNSenseTailscale
Disconnect-OPNSenseTailscale
Get-OPNSenseFirmware
Update-OPNSenseFirmware
Restart-OPNSenseFirewall
Backup-OPNSenseConfig
Export-OPNSenseConfig
+81
View File
@@ -0,0 +1,81 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all aliases
$aliases = Get-OPNSenseAlias
Write-Output "All Aliases:"
$aliases | Format-Table -Property Uuid, Name, Type, Content, Description, Enabled
# Get aliases by type
$hostAliases = Get-OPNSenseAlias -Type host
Write-Output "Host Aliases:"
$hostAliases | Format-Table -Property Uuid, Name, Content, Description
$networkAliases = Get-OPNSenseAlias -Type network
Write-Output "Network Aliases:"
$networkAliases | Format-Table -Property Uuid, Name, Content, Description
$portAliases = Get-OPNSenseAlias -Type port
Write-Output "Port Aliases:"
$portAliases | Format-Table -Property Uuid, Name, Content, Description
# Get a specific alias by name
$webServersAlias = Get-OPNSenseAlias -Name "WebServers"
Write-Output "WebServers Alias:"
$webServersAlias | Format-Table -Property Uuid, Name, Type, Content, Description
# Get a specific alias by UUID
$aliasUuid = $aliases[0].Uuid
$specificAlias = Get-OPNSenseAlias -Uuid $aliasUuid
Write-Output "Specific Alias by UUID:"
$specificAlias | Format-List
# Create a new host alias
$webServersUuid = New-OPNSenseAlias -Name "WebServers" -Type host -Content "192.168.1.10,192.168.1.11" -Description "Web Servers" -Apply
Write-Output "Created WebServers alias with UUID: $webServersUuid"
# Create a new network alias
$internalNetworksUuid = New-OPNSenseAlias -Name "InternalNetworks" -Type network -Content "192.168.1.0/24,192.168.2.0/24" -Description "Internal Networks" -Apply
Write-Output "Created InternalNetworks alias with UUID: $internalNetworksUuid"
# Create a new port alias
$webPortsUuid = New-OPNSenseAlias -Name "WebPorts" -Type port -Content "80,443" -Protocol TCP -Description "Web Ports" -Apply
Write-Output "Created WebPorts alias with UUID: $webPortsUuid"
# Create a new URL alias
$blockListUuid = New-OPNSenseAlias -Name "BlockList" -Type url -Content "https://example.com/blocklist.txt" -UpdateFrequency 1 -Description "Block List" -Apply
Write-Output "Created BlockList alias with UUID: $blockListUuid"
# Update an alias's content
Set-OPNSenseAlias -Uuid $webServersUuid -Content "192.168.1.10,192.168.1.11,192.168.1.12" -Apply
Write-Output "Updated WebServers alias content"
# Update an alias's description
Set-OPNSenseAlias -Uuid $internalNetworksUuid -Description "All Internal Networks" -Apply
Write-Output "Updated InternalNetworks alias description"
# Disable an alias
Set-OPNSenseAlias -Uuid $blockListUuid -Disabled -Apply
Write-Output "Disabled BlockList alias"
# Enable an alias
Set-OPNSenseAlias -Uuid $blockListUuid -Enabled -Apply
Write-Output "Enabled BlockList alias"
# Enable counters for an alias
Set-OPNSenseAlias -Uuid $webServersUuid -EnableCounters -Apply
Write-Output "Enabled counters for WebServers alias"
# Remove an alias
Remove-OPNSenseAlias -Uuid $blockListUuid -Force -Apply
Write-Output "Removed BlockList alias"
# Remove aliases by pipeline
Get-OPNSenseAlias -Name "WebServers" | Remove-OPNSenseAlias -Force -Apply
Write-Output "Removed WebServers alias"
# Disconnect from the firewall
Disconnect-OPNSense
+22
View File
@@ -0,0 +1,22 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get the current connection information
Get-OPNSenseConnection
# Get all firewall rules
$rules = Get-OPNSenseFirewallRule
$rules | Format-Table -Property Uuid, Description, Protocol, SourceNet, DestinationPort, Action
# Create a new firewall rule to allow HTTP traffic
$ruleId = New-OPNSenseFirewallRule -Description "Allow HTTP" -Protocol TCP -DestinationPort 80 -Action pass
Write-Output "Created rule with ID: $ruleId"
# Apply the changes
Apply-OPNSenseFirewallChanges -CancelRollback -Timeout 30
# Disconnect from the firewall
Disconnect-OPNSense
@@ -0,0 +1,29 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all configuration backups
$backups = Get-OPNSenseConfigBackup
$backups | Format-Table -Property Filename, Description, FileSize, Date, Version
# Create a new configuration backup
$backupFilename = Backup-OPNSenseConfig -Filename "pre-upgrade-backup"
Write-Output "Created backup: $backupFilename"
# Export the configuration to a file
$exportPath = "C:\Backups\opnsense-config.xml"
Export-OPNSenseConfig -Path $exportPath -Force
Write-Output "Exported configuration to: $exportPath"
# Import a configuration from a file
# Note: This will restart the firewall
# Import-OPNSenseConfig -Path $exportPath -Confirm
# Restore a configuration backup
# Note: This will restart the firewall
# Restore-OPNSenseConfig -Filename $backupFilename -Confirm
# Disconnect from the firewall
Disconnect-OPNSense
+36
View File
@@ -0,0 +1,36 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all cron jobs
$cronJobs = Get-OPNSenseCronJob
$cronJobs | Format-Table -Property Uuid, Description, Command, Minutes, Hours, Days, Months, Weekdays, Enabled
# Get a specific cron job
$job = Get-OPNSenseCronJob -Uuid $cronJobs[0].Uuid
$job
# Create a new cron job that runs daily at 2:00 AM
$dailyBackup = New-OPNSenseCronJob -Description "Daily backup" -Command "/usr/local/bin/backup.sh" -Minutes "0" -Hours "2" -Days "*" -Months "*" -Weekdays "*" -Apply
$dailyBackup
# Create a new cron job that runs weekly on Sunday at 3:00 AM
$weeklyCleanup = New-OPNSenseCronJob -Description "Weekly cleanup" -Command "/usr/local/bin/cleanup.sh" -Minutes "0" -Hours "3" -Days "*" -Months "*" -Weekdays "0" -Apply
$weeklyCleanup
# Update a cron job
Set-OPNSenseCronJob -Uuid $dailyBackup -Hours "3" -Description "Updated daily backup" -Apply
# Disable a cron job
Disable-OPNSenseCronJob -Uuid $dailyBackup -Apply
# Enable a cron job
Enable-OPNSenseCronJob -Uuid $dailyBackup -Apply
# Remove a cron job
Remove-OPNSenseCronJob -Uuid $weeklyCleanup -Force -Apply
# Disconnect from the firewall
Disconnect-OPNSense
+41
View File
@@ -0,0 +1,41 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all DHCP servers
$dhcpServers = Get-OPNSenseDHCPServer
$dhcpServers | Format-Table -Property Interface, Enabled, RangeFrom, RangeTo, Gateway
# Get a specific DHCP server
$lanDhcp = Get-OPNSenseDHCPServer -Interface "lan"
$lanDhcp
# Update a DHCP server
Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Domain "example.local" -DnsServers "8.8.8.8","8.8.4.4" -Apply
# Get all DHCP leases
$dhcpLeases = Get-OPNSenseDHCPLease
$dhcpLeases | Format-Table -Property MacAddress, IpAddress, Hostname, State
# Get active DHCP leases
$activeLeases = $dhcpLeases | Where-Object { $_.State -eq "active" }
$activeLeases | Format-Table -Property MacAddress, IpAddress, Hostname
# Get all static mappings for an interface
$staticMappings = Get-OPNSenseDHCPStaticMapping -Interface "lan"
$staticMappings | Format-Table -Property Uuid, MacAddress, IpAddress, Hostname, Description
# Create a new static mapping
$newMapping = New-OPNSenseDHCPStaticMapping -Interface "lan" -MacAddress "00:11:22:33:44:55" -IpAddress "192.168.1.50" -Hostname "printer" -Description "Office Printer" -Apply
$newMapping
# Update a static mapping
Set-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid $newMapping -IpAddress "192.168.1.51" -Description "Updated Printer" -Apply
# Remove a static mapping
Remove-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid $newMapping -Force -Apply
# Disconnect from the firewall
Disconnect-OPNSense
+27
View File
@@ -0,0 +1,27 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get DNS server configuration
$dnsConfig = Get-OPNSenseDNSServer
Write-Output "DNS Server Configuration:"
$dnsConfig
# Update DNS server configuration
Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4" -RegisterDhcp -RegisterDhcpDomain "local" -Apply
# Get all DNS overrides
$overrides = Get-OPNSenseDNSOverride
$overrides | Format-Table -Property Uuid, Hostname, Domain, IpAddress, Description
# Create a new DNS override
$overrideId = New-OPNSenseDNSOverride -Hostname "server" -Domain "local" -IpAddress "192.168.1.10" -Description "Internal server" -Apply
Write-Output "Created DNS override with ID: $overrideId"
# Remove a DNS override
Remove-OPNSenseDNSOverride -Uuid $overrideId -Apply -Confirm:$false
# Disconnect from the firewall
Disconnect-OPNSense
+52
View File
@@ -0,0 +1,52 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get DNS server configuration
$dnsServer = Get-OPNSenseDNSServer
Write-Output "DNS Server Configuration:"
$dnsServer | Format-List
# Update DNS server configuration
Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4" -Apply
Write-Output "DNS Server updated to use Google DNS"
# Get DNS forwarding configuration
$dnsForwarding = Get-OPNSenseDNSForwarding
Write-Output "DNS Forwarding Configuration:"
$dnsForwarding | Format-List
# Enable DNS forwarding
Set-OPNSenseDNSForwarding -Enabled -DnsServers "1.1.1.1","1.0.0.1" -Apply
Write-Output "DNS Forwarding enabled with Cloudflare DNS"
# Get DNS forwarding hosts
$forwardingHosts = Get-OPNSenseDNSForwardingHost
Write-Output "DNS Forwarding Hosts:"
$forwardingHosts | Format-Table
# Create a new DNS forwarding host
$newHost = New-OPNSenseDNSForwardingHost -Domain "example.com" -Server "192.168.1.10" -Description "Internal DNS Server" -Apply
Write-Output "Created new forwarding host with UUID: $newHost"
# Update a DNS forwarding host
Set-OPNSenseDNSForwardingHost -Uuid $newHost -Server "192.168.1.20" -Apply
Write-Output "Updated forwarding host server"
# Remove a DNS forwarding host
Remove-OPNSenseDNSForwardingHost -Uuid $newHost -Force -Apply
Write-Output "Removed forwarding host"
# Get system DNS configuration
$systemDNS = Get-OPNSenseSystemDNS
Write-Output "System DNS Configuration:"
$systemDNS | Format-List
# Update system DNS configuration
Set-OPNSenseSystemDNS -Hostname "firewall" -Domain "example.com" -DnsServers "8.8.8.8","8.8.4.4" -Apply
Write-Output "Updated system DNS configuration"
# Disconnect from the firewall
Disconnect-OPNSense
+37
View File
@@ -0,0 +1,37 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get firmware status
$firmwareStatus = Get-OPNSenseFirmware
Write-Output "Firmware Status:"
$firmwareStatus
# Check for updates
Get-OPNSenseFirmware -Check
# Get firmware changelog
$changelog = Get-OPNSenseFirmware -Changelog
Write-Output "Firmware Changelog:"
$changelog
# Get firmware audit
$audit = Get-OPNSenseFirmware -Audit
$audit | Format-Table -Property Name, Version, Installed
# Update firmware (install updates)
Update-OPNSenseFirmware -Wait
Write-Output "Firmware updated successfully"
# Upgrade firmware (major version upgrade)
# Note: This will restart the firewall
# Upgrade-OPNSenseFirmware -Wait -Timeout 1200
# Restart the firewall
Restart-OPNSenseFirewall -Wait -Timeout 300
Write-Output "Firewall restarted successfully"
# Disconnect from the firewall
Disconnect-OPNSense
@@ -0,0 +1,59 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all gateways
$gateways = Get-OPNSenseGateway
Write-Output "Gateways:"
$gateways | Format-Table
# Get gateways with status information
$gatewaysWithStatus = Get-OPNSenseGateway -IncludeStatus
Write-Output "Gateways with Status:"
$gatewaysWithStatus | Format-Table
# Create a new gateway
$newGateway = New-OPNSenseGateway -Name "WAN2_GW" -Interface "opt1" -IpAddress "203.0.113.1" -Description "Secondary WAN" -Apply
Write-Output "Created new gateway with UUID: $newGateway"
# Update a gateway
Set-OPNSenseGateway -Uuid $newGateway -MonitorIp "8.8.8.8" -Weight 2 -Apply
Write-Output "Updated gateway monitor IP and weight"
# Make a gateway the default gateway
Set-OPNSenseGateway -Uuid $newGateway -Default -Apply
Write-Output "Set gateway as default"
# Get all routes
$routes = Get-OPNSenseRoute
Write-Output "Routes:"
$routes | Format-Table
# Create a new route
$newRoute = New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN2_GW" -Description "Remote Office" -Apply
Write-Output "Created new route with UUID: $newRoute"
# Update a route
Set-OPNSenseRoute -Uuid $newRoute -Gateway "WAN_GW" -Apply
Write-Output "Updated route gateway"
# Disable a route
Set-OPNSenseRoute -Uuid $newRoute -Disabled -Apply
Write-Output "Disabled route"
# Enable a route
Set-OPNSenseRoute -Uuid $newRoute -Enabled -Apply
Write-Output "Enabled route"
# Remove a route
Remove-OPNSenseRoute -Uuid $newRoute -Force -Apply
Write-Output "Removed route"
# Remove a gateway
Remove-OPNSenseGateway -Uuid $newGateway -Force -Apply
Write-Output "Removed gateway"
# Disconnect from the firewall
Disconnect-OPNSense
+27
View File
@@ -0,0 +1,27 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all interfaces
$interfaces = Get-OPNSenseInterface
$interfaces | Format-Table -Property Name, Description, IpAddress, SubnetMask, Status
# Get interface statistics
$stats = Get-OPNSenseInterfaceStatistics
$stats | Format-Table -Property Name, InPackets, OutPackets, InBytes, OutBytes
# Update an interface
Set-OPNSenseInterface -Name "lan" -Description "Local Area Network" -IpAddress "192.168.1.1" -SubnetMask "24" -Apply
# Create a new VLAN
$vlanId = New-OPNSenseVLAN -Interface "em0" -Tag 10 -Description "Management VLAN"
Write-Output "Created VLAN with ID: $vlanId"
# Get all VLANs
$vlans = Get-OPNSenseVLAN
$vlans | Format-Table -Property Uuid, Tag, Interface, Description
# Disconnect from the firewall
Disconnect-OPNSense
+57
View File
@@ -0,0 +1,57 @@
# Import the module
Import-Module PSOPNSenseAPI
# Basic supernetting of two networks
$supernet = Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Supernet -AdditionalNetworks "192.168.2.0/24"
Write-Output "Supernet of 192.168.1.0/24 and 192.168.2.0/24:"
$supernet
# Supernetting of multiple networks
$supernet = Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation Supernet -AdditionalNetworks "10.0.1.0/24","10.0.2.0/24","10.0.3.0/24"
Write-Output "Supernet of multiple /24 networks:"
$supernet
# Advanced supernetting with summarization
$summarizedNetworks = Invoke-OPNSenseNetworkCalculation -Network "172.16.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "172.16.1.0/24","172.16.2.0/24","172.16.4.0/24","172.16.5.0/24"
Write-Output "Summarized networks:"
$summarizedNetworks | Format-Table
# Example of non-contiguous networks being summarized efficiently
$summarizedNetworks = Invoke-OPNSenseNetworkCalculation -Network "10.1.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "10.1.1.0/24","10.1.2.0/24","10.2.0.0/24","10.2.1.0/24"
Write-Output "Summarized non-contiguous networks:"
$summarizedNetworks | Format-Table
# Example with mixed IPv4 and IPv6 networks
$summarizedNetworks = Invoke-OPNSenseNetworkCalculation -Network "192.168.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "192.168.1.0/24","2001:db8::/64","2001:db8:1::/64"
Write-Output "Summarized mixed IPv4 and IPv6 networks:"
$summarizedNetworks | Format-Table
# Practical example: Summarizing a large number of networks
$networks = @(
"10.0.0.0/24"
"10.0.1.0/24"
"10.0.2.0/24"
"10.0.3.0/24"
"10.0.4.0/24"
"10.0.5.0/24"
"10.0.6.0/24"
"10.0.7.0/24"
"10.1.0.0/24"
"10.1.1.0/24"
"10.2.0.0/24"
"10.2.1.0/24"
"172.16.0.0/24"
"172.16.1.0/24"
"172.16.2.0/24"
"172.16.3.0/24"
)
$summarizedNetworks = Invoke-OPNSenseNetworkCalculation -Network $networks[0] -Operation SupernetSummarize -AdditionalNetworks $networks[1..($networks.Length-1)]
Write-Output "Summarized large set of networks:"
$summarizedNetworks | Format-Table
# Using the summarized networks for route configuration
Write-Output "Example of using summarized networks for route configuration:"
foreach ($network in $summarizedNetworks) {
Write-Output "New-OPNSenseRoute -Network '$network' -Gateway 'WAN_GW' -Description 'Summarized Route' -Apply"
}
+44
View File
@@ -0,0 +1,44 @@
# Import the module
Import-Module PSOPNSenseAPI
# Network information
$networkInfo = Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info
Write-Output "Network Information:"
$networkInfo | Format-List
# Subnet a network into smaller networks
$subnets = Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Subnet -PrefixLength 24
Write-Output "First 5 subnets of 10.0.0.0/16 divided into /24 networks:"
$subnets | Select-Object -First 5 | Format-Table
# Subnet a network into a specific number of subnets
$subnets = Invoke-OPNSenseNetworkCalculation -Network "172.16.0.0/16" -Operation SubnetByCount -SubnetCount 4
Write-Output "172.16.0.0/16 divided into 4 equal subnets:"
$subnets | Format-Table
# Check if an IP address is within a network
$contains = Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Contains -IPAddress "192.168.1.100"
Write-Output "Is 192.168.1.100 within 192.168.1.0/24? $contains"
# Check if networks overlap
$overlaps = Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation Overlaps -AdditionalNetworks "10.0.0.128/25"
Write-Output "Network overlap check:"
$overlaps | Format-Table
# Create a supernet from multiple networks
$supernet = Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Supernet -AdditionalNetworks "192.168.2.0/24","192.168.3.0/24"
Write-Output "Supernet of 192.168.1.0/24, 192.168.2.0/24, and 192.168.3.0/24:"
$supernet
# Convert between CIDR and subnet mask
$subnetMask = ConvertTo-OPNSenseNetworkNotation -CIDR 24
Write-Output "Subnet mask for /24: $subnetMask"
$cidr = ConvertTo-OPNSenseNetworkNotation -SubnetMask "255.255.255.0"
Write-Output "CIDR for 255.255.255.0: $cidr"
$ipWithSubnetMask = ConvertTo-OPNSenseNetworkNotation -IPWithCIDR "192.168.1.0/24"
Write-Output "IP with subnet mask for 192.168.1.0/24: $ipWithSubnetMask"
$ipWithCIDR = ConvertTo-OPNSenseNetworkNotation -IPWithSubnetMask "192.168.1.0 255.255.255.0"
Write-Output "IP with CIDR for 192.168.1.0 255.255.255.0: $ipWithCIDR"
+29
View File
@@ -0,0 +1,29 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all installed plugins
$installedPlugins = Get-OPNSensePlugin -Installed
$installedPlugins | Format-Table -Property Name, Version, Comment, Enabled
# Get all available plugins
$availablePlugins = Get-OPNSensePlugin -Available
$availablePlugins | Format-Table -Property Name, Version, Comment
# Install a plugin
Install-OPNSensePlugin -Name "os-acme-client" -Wait
Write-Output "Plugin installed successfully"
# Enable a plugin
Enable-OPNSensePlugin -Name "os-acme-client"
# Disable a plugin
Disable-OPNSensePlugin -Name "os-acme-client"
# Uninstall a plugin
Uninstall-OPNSensePlugin -Name "os-acme-client" -Wait -Confirm:$false
# Disconnect from the firewall
Disconnect-OPNSense
+212
View File
@@ -0,0 +1,212 @@
# Port Forwarding Examples
This document provides examples of using the PSOPNSenseAPI module to manage port forwarding rules on OPNSense firewalls.
## Basic Port Forwarding
The following example demonstrates how to create, view, update, and delete port forwarding rules:
```powershell
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all port forwarding rules
$rules = Get-OPNSensePortForwardingRule
Write-Output "Current port forwarding rules:"
$rules | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Create a new port forwarding rule for HTTP
$httpRule = New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server HTTP"
Write-Output "Created HTTP port forwarding rule:"
$httpRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Create a new port forwarding rule for HTTPS
$httpsRule = New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Web Server HTTPS"
Write-Output "Created HTTPS port forwarding rule:"
$httpsRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Update the HTTP rule to point to a different server
$updatedRule = Set-OPNSensePortForwardingRule -Uuid $httpRule.Uuid -TargetIP "192.168.1.200" -Description "Updated Web Server HTTP" -PassThru
Write-Output "Updated HTTP port forwarding rule:"
$updatedRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Get a specific rule by UUID
$rule = Get-OPNSensePortForwardingRule -Uuid $httpsRule.Uuid
Write-Output "Retrieved HTTPS port forwarding rule:"
$rule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Remove the HTTP rule
Remove-OPNSensePortForwardingRule -Uuid $httpRule.Uuid -Force
Write-Output "Removed HTTP port forwarding rule"
# Get all port forwarding rules again to verify changes
$rules = Get-OPNSensePortForwardingRule
Write-Output "Updated port forwarding rules:"
$rules | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
```
## Advanced Port Forwarding Scenarios
### Web Server with Multiple Services
This example shows how to set up port forwarding for a web server with multiple services:
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define the web server details
$webServerIP = "192.168.1.100"
$services = @(
@{ Name = "HTTP"; Protocol = "tcp"; ExternalPort = "80"; InternalPort = "80" },
@{ Name = "HTTPS"; Protocol = "tcp"; ExternalPort = "443"; InternalPort = "443" },
@{ Name = "Alternative HTTP"; Protocol = "tcp"; ExternalPort = "8080"; InternalPort = "8080" },
@{ Name = "WebSocket"; Protocol = "tcp"; ExternalPort = "9000"; InternalPort = "9000" }
)
# Create port forwarding rules for each service
foreach ($service in $services) {
New-OPNSensePortForwardingRule -Interface "WAN" `
-Protocol $service.Protocol `
-DestinationPort $service.ExternalPort `
-TargetIP $webServerIP `
-TargetPort $service.InternalPort `
-Description "Web Server - $($service.Name)" `
-Force
}
# Verify the rules were created
Get-OPNSensePortForwardingRule | Where-Object { $_.TargetIP -eq $webServerIP } |
Format-Table -Property Description, Protocol, DestinationPort, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
```
### Game Server Port Forwarding
This example demonstrates how to set up port forwarding for a game server with multiple ports:
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define the game server details
$gameServerIP = "192.168.1.150"
$gameServerPorts = @(
@{ Name = "Game Server - Main"; Protocol = "tcp/udp"; Ports = "27015" },
@{ Name = "Game Server - Query"; Protocol = "udp"; Ports = "27016" },
@{ Name = "Game Server - RCON"; Protocol = "tcp"; Ports = "27017" },
@{ Name = "Game Server - Voice"; Protocol = "udp"; Ports = "9987-9989" }
)
# Create port forwarding rules for the game server
foreach ($port in $gameServerPorts) {
New-OPNSensePortForwardingRule -Interface "WAN" `
-Protocol $port.Protocol `
-DestinationPort $port.Ports `
-TargetIP $gameServerIP `
-TargetPort $port.Ports `
-Description $port.Name `
-Force
}
# Verify the rules were created
Get-OPNSensePortForwardingRule | Where-Object { $_.TargetIP -eq $gameServerIP } |
Format-Table -Property Description, Protocol, DestinationPort, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
```
### Remote Access Services
This example shows how to set up port forwarding for remote access services:
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Define remote access services
$remoteServices = @(
@{ Name = "RDP - Admin Server"; TargetIP = "192.168.1.200"; ExternalPort = "33389"; InternalPort = "3389"; Protocol = "tcp" },
@{ Name = "SSH - Dev Server"; TargetIP = "192.168.1.201"; ExternalPort = "2222"; InternalPort = "22"; Protocol = "tcp" },
@{ Name = "VNC - Support"; TargetIP = "192.168.1.202"; ExternalPort = "5900"; InternalPort = "5900"; Protocol = "tcp" }
)
# Create port forwarding rules for remote access
foreach ($service in $remoteServices) {
New-OPNSensePortForwardingRule -Interface "WAN" `
-Protocol $service.Protocol `
-DestinationPort $service.ExternalPort `
-TargetIP $service.TargetIP `
-TargetPort $service.InternalPort `
-Description $service.Name `
-Log ` # Enable logging for security
-Force
}
# Verify the rules were created
Get-OPNSensePortForwardingRule | Where-Object { $_.Description -like "* - *" } |
Format-Table -Property Description, Protocol, DestinationPort, TargetIP, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
```
### Bulk Management of Port Forwarding Rules
This example demonstrates how to perform bulk operations on port forwarding rules:
```powershell
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all port forwarding rules
$rules = Get-OPNSensePortForwardingRule
# Disable all rules with "Temporary" in the description
$rules | Where-Object { $_.Description -like "*Temporary*" } | ForEach-Object {
Set-OPNSensePortForwardingRule -Uuid $_.Uuid -Enabled:$false -Force
Write-Output "Disabled rule: $($_.Description)"
}
# Update all rules pointing to a decommissioned server
$oldServerIP = "192.168.1.100"
$newServerIP = "192.168.1.150"
$rules | Where-Object { $_.TargetIP -eq $oldServerIP } | ForEach-Object {
Set-OPNSensePortForwardingRule -Uuid $_.Uuid -TargetIP $newServerIP -Description "$($_.Description) (Migrated)" -Force
Write-Output "Updated rule: $($_.Description) to point to $newServerIP"
}
# Delete all rules with "Obsolete" in the description
$rules | Where-Object { $_.Description -like "*Obsolete*" } | ForEach-Object {
Remove-OPNSensePortForwardingRule -Uuid $_.Uuid -Force
Write-Output "Removed rule: $($_.Description)"
}
# Verify changes
$updatedRules = Get-OPNSensePortForwardingRule
Write-Output "Rules after bulk operations:"
$updatedRules | Format-Table -Property Uuid, Description, Enabled, TargetIP, DestinationPort, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
```
## Notes
- Port forwarding rules are applied immediately after creation, update, or deletion.
- When creating or updating rules, consider security implications and only forward necessary ports.
- Use the `FilterRuleAssociation` parameter to automatically create associated firewall rules.
- NAT reflection allows internal clients to access forwarded services using the external IP address.
- For security-sensitive rules, enable logging with the `-Log` parameter.
- Always use strong authentication and encryption for remote access services.
- Consider using non-standard external ports for common services to reduce automated scanning attempts.
+42
View File
@@ -0,0 +1,42 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all port forwarding rules
$rules = Get-OPNSensePortForwardingRule
Write-Output "Current port forwarding rules:"
$rules | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Create a new port forwarding rule for HTTP
$httpRule = New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server HTTP"
Write-Output "Created HTTP port forwarding rule:"
$httpRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Create a new port forwarding rule for HTTPS
$httpsRule = New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "443" -TargetIP "192.168.1.100" -TargetPort "443" -Description "Web Server HTTPS"
Write-Output "Created HTTPS port forwarding rule:"
$httpsRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Update the HTTP rule to point to a different server
$updatedRule = Set-OPNSensePortForwardingRule -Uuid $httpRule.Uuid -TargetIP "192.168.1.200" -Description "Updated Web Server HTTP" -PassThru
Write-Output "Updated HTTP port forwarding rule:"
$updatedRule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Get a specific rule by UUID
$rule = Get-OPNSensePortForwardingRule -Uuid $httpsRule.Uuid
Write-Output "Retrieved HTTPS port forwarding rule:"
$rule | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Remove the HTTP rule
Remove-OPNSensePortForwardingRule -Uuid $httpRule.Uuid -Force
Write-Output "Removed HTTP port forwarding rule"
# Get all port forwarding rules again to verify changes
$rules = Get-OPNSensePortForwardingRule
Write-Output "Updated port forwarding rules:"
$rules | Format-Table -Property Uuid, Description, Interface, Protocol, DestinationPort, TargetIP, TargetPort
# Disconnect from the firewall
Disconnect-OPNSense
+31
View File
@@ -0,0 +1,31 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get available interfaces
$interfaces = Get-OPNSenseInterface
$interfaces | Format-Table -Property Name, Description, Status
# Create VLANs for subnets with sequential VLAN IDs
$result1 = New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 1
Write-Output "Created VLANs with sequential IDs:"
$result1.VLANs | Format-Table -Property VlanId, Subnet, Gateway, Status
# Create VLANs for subnets with VLAN IDs in multiples of 10
$result2 = New-OPNSenseSubnetVLANs -ParentInterface "em1" -Network "10.0.0.0/16" -SubnetMaskBits 24 -StartingVlanId 100 -VlanIdIncrement 10
Write-Output "Created VLANs with IDs in multiples of 10:"
$result2.VLANs | Format-Table -Property VlanId, Subnet, Gateway, Status
# Create VLANs for subnets with DHCP enabled
$result3 = New-OPNSenseSubnetVLANs -ParentInterface "em2" -Network "172.16.0.0/20" -SubnetMaskBits 24 -StartingVlanId 200 -VlanIdIncrement 1 -EnableDHCP -DescriptionPrefix "VLAN-DHCP"
Write-Output "Created VLANs with DHCP enabled:"
$result3.VLANs | Format-Table -Property VlanId, Subnet, Gateway, Status
# Get all VLANs
$vlans = Get-OPNSenseVLAN
$vlans | Format-Table -Property Uuid, Tag, Interface, Description
# Disconnect from the firewall
Disconnect-OPNSense
+45
View File
@@ -0,0 +1,45 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get Tailscale status
$status = Get-OPNSenseTailscaleStatus
Write-Output "Tailscale Status:"
$status
# Get detailed Tailscale status with interfaces and settings
$detailedStatus = Get-OPNSenseTailscaleStatus -IncludeInterfaces -IncludeSettings
Write-Output "Tailscale Interfaces:"
$detailedStatus.Interfaces
# Enable Tailscale with default settings (will install plugin if not present)
Enable-OPNSenseTailscale -Force
# Enable Tailscale with custom settings
Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Hostname "opnsense-firewall" -Force
# Enable Tailscale with subnet route advertising
Enable-OPNSenseTailscale -AdvertiseRoutes -SubnetRoutes "192.168.1.0/24","10.0.0.0/8" -Force
# Connect to Tailscale network with an auth key
# You can generate an auth key at https://login.tailscale.com/admin/settings/keys
Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing -EnableIfDisabled -StartIfStopped -Force
# Connect to Tailscale and advertise subnet routes
Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -SubnetRoutes "192.168.1.0/24","10.0.0.0/8" -AdvertiseRoutes -Force
# Get Tailscale status after connecting
$connectedStatus = Get-OPNSenseTailscaleStatus -IncludeInterfaces
Write-Output "Tailscale Connected Status:"
$connectedStatus
# Disconnect from Tailscale network
Disconnect-OPNSenseTailscale -Force
# Disable Tailscale and stop the service
Disable-OPNSenseTailscale -Stop -Force
# Disconnect from the firewall
Disconnect-OPNSense
+28
View File
@@ -0,0 +1,28 @@
# Import the module
Import-Module PSOPNSenseAPI
# Connect to the OPNSense firewall
Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
# Get all users
$users = Get-OPNSenseUser
$users | Format-Table -Property Uuid, Username, FullName, Email, Disabled
# Create a new user
$userId = New-OPNSenseUser -Username "john" -Password "P@ssw0rd" -FullName "John Doe" -Email "john@example.com" -Groups "admins"
Write-Output "Created user with ID: $userId"
# Update a user
Set-OPNSenseUser -Uuid $userId -Email "john.doe@example.com" -FullName "John A. Doe"
# Disable a user
Set-OPNSenseUser -Uuid $userId -Disabled
# Enable a user
Set-OPNSenseUser -Uuid $userId -Enabled
# Remove a user
Remove-OPNSenseUser -Uuid $userId -Confirm:$false
# Disconnect from the firewall
Disconnect-OPNSense
Binary file not shown.
Binary file not shown.
+85
View File
@@ -0,0 +1,85 @@
@{
RootModule = 'PSOPNSenseAPI.dll'
ModuleVersion = '2025.04.14.2246'
GUID = '1f0e4b77-cc7c-4a1e-b45a-d7c51a3c562e'
Author = 'PSOPNSenseAPI Contributors'
CompanyName = 'PSOPNSenseAPI'
Copyright = 'Copyright (c) 2025 PSOPNSenseAPI Contributors'
Description = 'PowerShell module for interacting with the OPNSense API to configure firewalls'
PowerShellVersion = '5.1'
CompatiblePSEditions = @('Desktop', 'Core')
DotNetFrameworkVersion = '4.7.2'
CLRVersion = '4.0.0'
FunctionsToExport = @()
CmdletsToExport = @(
'Connect-OPNSense',
'Disconnect-OPNSense',
'Get-OPNSenseInterface',
'Set-OPNSenseInterface',
'Restart-OPNSenseInterface',
'Get-OPNSenseInterfaceStatistics',
'Get-OPNSenseVLAN',
'New-OPNSenseVLAN',
'Set-OPNSenseVLAN',
'Remove-OPNSenseVLAN',
'Get-OPNSenseFirewallRule',
'New-OPNSenseFirewallRule',
'Set-OPNSenseFirewallRule',
'Remove-OPNSenseFirewallRule',
'Enable-OPNSenseFirewallRule',
'Disable-OPNSenseFirewallRule',
'Get-OPNSenseAlias',
'New-OPNSenseAlias',
'Set-OPNSenseAlias',
'Remove-OPNSenseAlias',
'Get-OPNSenseNATRule',
'New-OPNSenseNATRule',
'Set-OPNSenseNATRule',
'Remove-OPNSenseNATRule',
'Get-OPNSensePlugin',
'Enable-OPNSensePlugin',
'Disable-OPNSensePlugin',
'Install-OPNSensePlugin',
'Uninstall-OPNSensePlugin',
'Get-OPNSenseUser',
'New-OPNSenseUser',
'Set-OPNSenseUser',
'Remove-OPNSenseUser',
'Get-OPNSenseFirmware',
'Update-OPNSenseFirmware',
'Upgrade-OPNSenseFirmware',
'Restart-OPNSenseFirewall',
'New-OPNSenseSubnetVLANs',
'Get-OPNSenseDHCPServer',
'Set-OPNSenseDHCPServer',
'Get-OPNSenseDHCPStaticMapping',
'New-OPNSenseDHCPStaticMapping',
'Set-OPNSenseDHCPStaticMapping',
'Remove-OPNSenseDHCPStaticMapping',
'Get-OPNSenseCronJob',
'New-OPNSenseCronJob',
'Set-OPNSenseCronJob',
'Remove-OPNSenseCronJob',
'Enable-OPNSenseCronJob',
'Disable-OPNSenseCronJob',
'Get-OPNSenseTailscale',
'Enable-OPNSenseTailscale',
'Disable-OPNSenseTailscale',
'Connect-OPNSenseTailscale',
'Disconnect-OPNSenseTailscale',
'Get-OPNSensePortForwardingRule',
'New-OPNSensePortForwardingRule',
'Set-OPNSensePortForwardingRule',
'Remove-OPNSensePortForwardingRule'
)
VariablesToExport = @()
AliasesToExport = @()
PrivateData = @{
PSData = @{
Tags = @('PowerShell', 'OPNSense', 'Firewall', 'API')
LicenseUri = 'https://github.com/freedbygrace/PSOPNSenseAPI/blob/main/LICENSE'
ProjectUri = 'https://github.com/freedbygrace/PSOPNSenseAPI'
ReleaseNotes = 'https://github.com/freedbygrace/PSOPNSenseAPI/blob/main/CHANGELOG.md'
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+122
View File
@@ -0,0 +1,122 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests
{
[TestClass]
public class ApiClientTests
{
private Mock<ILogger> _loggerMock;
[TestInitialize]
public void Initialize()
{
_loggerMock = new Mock<ILogger>();
}
[TestMethod]
public void Constructor_ValidParameters_CreatesClient()
{
// Arrange
string baseUrl = "https://firewall.example.com";
string apiKey = "key";
string apiSecret = "secret";
bool skipCertificateCheck = true;
// Act
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
// Assert
Assert.IsNotNull(client);
Assert.AreEqual(baseUrl, client.BaseUrl);
Assert.IsTrue(client.IsConnected);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Constructor_NullBaseUrl_ThrowsArgumentNullException()
{
// Arrange
string baseUrl = null;
string apiKey = "key";
string apiSecret = "secret";
bool skipCertificateCheck = true;
// Act
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
// Assert - Exception expected
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Constructor_NullApiKey_ThrowsArgumentNullException()
{
// Arrange
string baseUrl = "https://firewall.example.com";
string apiKey = null;
string apiSecret = "secret";
bool skipCertificateCheck = true;
// Act
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
// Assert - Exception expected
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Constructor_NullApiSecret_ThrowsArgumentNullException()
{
// Arrange
string baseUrl = "https://firewall.example.com";
string apiKey = "key";
string apiSecret = null;
bool skipCertificateCheck = true;
// Act
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
// Assert - Exception expected
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Constructor_NullLogger_ThrowsArgumentNullException()
{
// Arrange
string baseUrl = "https://firewall.example.com";
string apiKey = "key";
string apiSecret = "secret";
bool skipCertificateCheck = true;
// Act
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, null);
// Assert - Exception expected
}
[TestMethod]
public void Dispose_SetsIsConnectedToFalse()
{
// Arrange
string baseUrl = "https://firewall.example.com";
string apiKey = "key";
string apiSecret = "secret";
bool skipCertificateCheck = true;
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
// Act
client.Dispose();
// Assert
Assert.IsFalse(client.IsConnected);
}
}
}
@@ -0,0 +1,354 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using PSOPNSenseAPI.Cmdlets;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests.Cmdlets
{
[TestClass]
public class GetOPNSenseAliasCmdletTests
{
private Mock<OPNSenseApiClient> _apiClientMock;
private Mock<ILogger> _loggerMock;
private GetOPNSenseAliasCmdlet _cmdlet;
[TestInitialize]
public void Initialize()
{
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
_loggerMock = new Mock<ILogger>();
_cmdlet = new GetOPNSenseAliasCmdlet();
// Use reflection to set private fields
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
}
[TestMethod]
public void ProcessRecord_GetAllAliases_WritesAliasesToPipeline()
{
// Arrange
var aliases = new List<Alias>
{
new Alias
{
Uuid = "uuid1",
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Enabled = "1"
},
new Alias
{
Uuid = "uuid2",
Name = "WebPorts",
Type = "port",
Content = "80,443",
Description = "Web Ports",
Enabled = "1"
}
};
var response = new AliasListResponse
{
Total = aliases.Count,
RowCount = aliases.Count,
Current = 1,
Rows = aliases
};
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
// Mock the AliasService creation
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
taskCompletionSource.SetResult(response);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(2, results.Count);
Assert.IsInstanceOfType(results[0], typeof(Alias));
Assert.IsInstanceOfType(results[1], typeof(Alias));
var alias1 = results[0] as Alias;
var alias2 = results[1] as Alias;
Assert.AreEqual("WebServers", alias1.Name);
Assert.AreEqual("WebPorts", alias2.Name);
}
[TestMethod]
public void ProcessRecord_GetAliasByUuid_WritesAliasDetailToPipeline()
{
// Arrange
string uuid = "uuid1";
_cmdlet.Uuid = uuid;
// Use reflection to set the parameter set name
typeof(PSCmdlet).GetProperty("ParameterSetName").SetValue(_cmdlet, "ByUuid");
var aliasDetail = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
};
var response = new AliasResponse
{
Alias = aliasDetail
};
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
aliasServiceMock.Setup(x => x.GetAliasAsync(uuid)).ReturnsAsync(response);
// Mock the AliasService creation
var taskCompletionSource = new TaskCompletionSource<AliasResponse>();
taskCompletionSource.SetResult(response);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.IsInstanceOfType(results[0], typeof(AliasDetail));
var alias = results[0] as AliasDetail;
Assert.AreEqual("WebServers", alias.Name);
Assert.AreEqual("host", alias.Type);
Assert.AreEqual("192.168.1.10,192.168.1.11", alias.Content);
}
[TestMethod]
public void ProcessRecord_GetAliasByName_WritesFilteredAliasesToPipeline()
{
// Arrange
string name = "WebServers";
_cmdlet.Name = name;
// Use reflection to set the parameter set name
typeof(PSCmdlet).GetProperty("ParameterSetName").SetValue(_cmdlet, "ByName");
var aliases = new List<Alias>
{
new Alias
{
Uuid = "uuid1",
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Enabled = "1"
},
new Alias
{
Uuid = "uuid2",
Name = "WebPorts",
Type = "port",
Content = "80,443",
Description = "Web Ports",
Enabled = "1"
}
};
var response = new AliasListResponse
{
Total = aliases.Count,
RowCount = aliases.Count,
Current = 1,
Rows = aliases
};
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
// Mock the AliasService creation
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
taskCompletionSource.SetResult(response);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.IsInstanceOfType(results[0], typeof(Alias));
var alias = results[0] as Alias;
Assert.AreEqual("WebServers", alias.Name);
Assert.AreEqual("host", alias.Type);
}
[TestMethod]
public void ProcessRecord_GetAliasByType_WritesFilteredAliasesToPipeline()
{
// Arrange
string type = "host";
_cmdlet.Type = type;
var aliases = new List<Alias>
{
new Alias
{
Uuid = "uuid1",
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Enabled = "1"
},
new Alias
{
Uuid = "uuid2",
Name = "WebPorts",
Type = "port",
Content = "80,443",
Description = "Web Ports",
Enabled = "1"
}
};
var response = new AliasListResponse
{
Total = aliases.Count,
RowCount = aliases.Count,
Current = 1,
Rows = aliases
};
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
// Mock the AliasService creation
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
taskCompletionSource.SetResult(response);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.IsInstanceOfType(results[0], typeof(Alias));
var alias = results[0] as Alias;
Assert.AreEqual("WebServers", alias.Name);
Assert.AreEqual("host", alias.Type);
}
}
// Helper class for testing cmdlets
public class MockCommandRuntime : ICommandRuntime
{
private readonly Action<object> _outputHandler;
private readonly Action<string> _warningHandler;
private readonly Action<string> _verboseHandler;
private readonly bool _shouldProcessResult;
public MockCommandRuntime(Action<object> outputHandler, Action<string> warningHandler = null, Action<string> verboseHandler = null, bool shouldProcessResult = true)
{
_outputHandler = outputHandler;
_warningHandler = warningHandler ?? (_ => { });
_verboseHandler = verboseHandler ?? (_ => { });
_shouldProcessResult = shouldProcessResult;
}
public PSHost Host => throw new NotImplementedException();
public PSTransactionContext CurrentPSTransaction => throw new NotImplementedException();
public virtual bool ShouldProcess(string target) => _shouldProcessResult;
public virtual bool ShouldProcess(string target, string action) => _shouldProcessResult;
public virtual bool ShouldProcess(string verboseDescription, string verboseWarning, string caption) => _shouldProcessResult;
public virtual bool ShouldProcess(string verboseDescription, string verboseWarning, string caption, out ShouldProcessReason shouldProcessReason)
{
shouldProcessReason = ShouldProcessReason.None;
return _shouldProcessResult;
}
public bool ShouldContinue(string query, string caption) => true;
public bool ShouldContinue(string query, string caption, ref bool yesToAll, ref bool noToAll) => true;
public void WriteCommandDetail(string text) { }
public void WriteDebug(string text) { }
public void WriteError(ErrorRecord errorRecord) { throw errorRecord.Exception; }
public void WriteObject(object sendToPipeline) => _outputHandler(sendToPipeline);
public void WriteObject(object sendToPipeline, bool enumerateCollection)
{
if (enumerateCollection && sendToPipeline is IEnumerable<object> enumerable)
{
foreach (var item in enumerable)
{
_outputHandler(item);
}
}
else
{
_outputHandler(sendToPipeline);
}
}
public void WriteProgress(ProgressRecord progressRecord) { }
public void WriteProgress(long sourceId, ProgressRecord progressRecord) { }
public void WriteVerbose(string text) => _verboseHandler(text);
public void WriteWarning(string text) => _warningHandler(text);
}
}
@@ -0,0 +1,285 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using PSOPNSenseAPI.Cmdlets;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests.Cmdlets
{
[TestClass]
public class NewOPNSenseAliasCmdletTests
{
private Mock<OPNSenseApiClient> _apiClientMock;
private Mock<ILogger> _loggerMock;
private NewOPNSenseAliasCmdlet _cmdlet;
[TestInitialize]
public void Initialize()
{
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
_loggerMock = new Mock<ILogger>();
_cmdlet = new NewOPNSenseAliasCmdlet();
// Use reflection to set private fields
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
}
[TestMethod]
public void ProcessRecord_CreateHostAlias_ReturnsUuid()
{
// Arrange
_cmdlet.Name = "WebServers";
_cmdlet.Type = "host";
_cmdlet.Content = "192.168.1.10,192.168.1.11";
_cmdlet.Description = "Web Servers";
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
// Mock the API client response
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
taskCompletionSource.SetResult(expectedResponse);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
}
[TestMethod]
public void ProcessRecord_CreatePortAlias_WithProtocol_ReturnsUuid()
{
// Arrange
_cmdlet.Name = "WebPorts";
_cmdlet.Type = "port";
_cmdlet.Content = "80,443";
_cmdlet.Description = "Web Ports";
_cmdlet.Protocol = "TCP";
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
// Mock the API client response
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
taskCompletionSource.SetResult(expectedResponse);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
// Verify the correct protocol was set
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Protocol").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "TCP")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_CreateUrlAlias_WithUpdateFrequency_ReturnsUuid()
{
// Arrange
_cmdlet.Name = "BlockList";
_cmdlet.Type = "url";
_cmdlet.Content = "https://example.com/blocklist.txt";
_cmdlet.Description = "Block List";
_cmdlet.UpdateFrequency = 1;
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
// Mock the API client response
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
taskCompletionSource.SetResult(expectedResponse);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
// Verify the correct update frequency was set
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("UpdateFrequency").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_CreateDisabledAlias_ReturnsUuid()
{
// Arrange
_cmdlet.Name = "WebServers";
_cmdlet.Type = "host";
_cmdlet.Content = "192.168.1.10,192.168.1.11";
_cmdlet.Description = "Web Servers";
_cmdlet.Disabled = true;
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
// Mock the API client response
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
taskCompletionSource.SetResult(expectedResponse);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
// Verify the alias was created as disabled
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "0")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_CreateAliasWithCounters_ReturnsUuid()
{
// Arrange
_cmdlet.Name = "WebServers";
_cmdlet.Type = "host";
_cmdlet.Content = "192.168.1.10,192.168.1.11";
_cmdlet.Description = "Web Servers";
_cmdlet.EnableCounters = true;
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
// Mock the API client response
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
taskCompletionSource.SetResult(expectedResponse);
var task = taskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(task);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
// Verify the alias was created with counters enabled
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Counters").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_CreateAliasAndApply_ReconfiguresAliases()
{
// Arrange
_cmdlet.Name = "WebServers";
_cmdlet.Type = "host";
_cmdlet.Content = "192.168.1.10,192.168.1.11";
_cmdlet.Description = "Web Servers";
_cmdlet.Apply = true;
var createResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
var reconfigureResponse = new AliasReconfigureResponse
{
Status = "ok"
};
// Mock the API client responses
var createTaskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
createTaskCompletionSource.SetResult(createResponse);
var createTask = createTaskCompletionSource.Task;
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
var reconfigureTask = reconfigureTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.Returns(createTask);
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
.Returns(reconfigureTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
Assert.AreEqual(1, results.Count);
Assert.AreEqual("new-uuid", results[0]);
// Verify the reconfigure method was called
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
}
}
}
@@ -0,0 +1,213 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using PSOPNSenseAPI.Cmdlets;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests.Cmdlets
{
[TestClass]
public class RemoveOPNSenseAliasCmdletTests
{
private Mock<OPNSenseApiClient> _apiClientMock;
private Mock<ILogger> _loggerMock;
private RemoveOPNSenseAliasCmdlet _cmdlet;
[TestInitialize]
public void Initialize()
{
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
_loggerMock = new Mock<ILogger>();
_cmdlet = new RemoveOPNSenseAliasCmdlet();
// Use reflection to set private fields
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
}
[TestMethod]
public void ProcessRecord_RemoveAliasWithForce_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Force = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var deleteResponse = new AliasDeleteResponse
{
Result = "deleted"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
deleteTaskCompletionSource.SetResult(deleteResponse);
var deleteTask = deleteTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
.Returns(deleteTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the delete method was called
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
}
[TestMethod]
public void ProcessRecord_RemoveAliasWithShouldProcess_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var deleteResponse = new AliasDeleteResponse
{
Result = "deleted"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
deleteTaskCompletionSource.SetResult(deleteResponse);
var deleteTask = deleteTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
.Returns(deleteTask);
// Create a PowerShell pipeline to capture output with ShouldProcess always returning true
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the delete method was called
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
}
[TestMethod]
public void ProcessRecord_RemoveAliasAndApply_ReconfiguresAliases()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Force = true;
_cmdlet.Apply = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var deleteResponse = new AliasDeleteResponse
{
Result = "deleted"
};
var reconfigureResponse = new AliasReconfigureResponse
{
Status = "ok"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
deleteTaskCompletionSource.SetResult(deleteResponse);
var deleteTask = deleteTaskCompletionSource.Task;
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
var reconfigureTask = reconfigureTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
.Returns(deleteTask);
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
.Returns(reconfigureTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the delete and reconfigure methods were called
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
}
}
}
@@ -0,0 +1,456 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using PSOPNSenseAPI.Cmdlets;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests.Cmdlets
{
[TestClass]
public class SetOPNSenseAliasCmdletTests
{
private Mock<OPNSenseApiClient> _apiClientMock;
private Mock<ILogger> _loggerMock;
private SetOPNSenseAliasCmdlet _cmdlet;
[TestInitialize]
public void Initialize()
{
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
_loggerMock = new Mock<ILogger>();
_cmdlet = new SetOPNSenseAliasCmdlet();
// Use reflection to set private fields
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
}
[TestMethod]
public void ProcessRecord_UpdateAliasContent_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Content = "192.168.1.10,192.168.1.11,192.168.1.12";
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with the correct content
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Content").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "192.168.1.10,192.168.1.11,192.168.1.12")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_UpdateAliasDescription_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Description = "Updated Web Servers";
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with the correct description
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Description").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "Updated Web Servers")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_DisableAlias_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Disabled = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with the alias disabled
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "0")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_EnableAlias_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Enabled = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "0"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with the alias enabled
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_EnableCounters_Success()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.EnableCounters = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with counters enabled
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Counters").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
Times.Once);
}
[TestMethod]
public void ProcessRecord_UpdateAndApply_ReconfiguresAliases()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Content = "192.168.1.10,192.168.1.11,192.168.1.12";
_cmdlet.Apply = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
var reconfigureResponse = new AliasReconfigureResponse
{
Status = "ok"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
var reconfigureTask = reconfigureTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
.Returns(reconfigureTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the reconfigure method was called
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
}
[TestMethod]
public void ProcessRecord_BothEnabledAndDisabled_UsesEnabled()
{
// Arrange
string uuid = "test-uuid";
_cmdlet.Uuid = uuid;
_cmdlet.Enabled = true;
_cmdlet.Disabled = true;
var getResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "0"
}
};
var updateResponse = new AliasUpdateResponse
{
Result = "saved"
};
// Mock the API client responses
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
getTaskCompletionSource.SetResult(getResponse);
var getTask = getTaskCompletionSource.Task;
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
updateTaskCompletionSource.SetResult(updateResponse);
var updateTask = updateTaskCompletionSource.Task;
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.Returns(getTask);
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.Returns(updateTask);
// Create a PowerShell pipeline to capture output
var results = new List<object>();
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output), warning => { });
// Act
_cmdlet.ProcessRecord();
// Assert
// Verify the update method was called with the alias enabled
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
It.Is<object>(o =>
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
Times.Once);
}
}
}
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="Moq" Version="4.18.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PSOPNSenseAPI\PSOPNSenseAPI.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,211 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Newtonsoft.Json;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Services;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PSOPNSenseAPI.Tests.Services
{
[TestClass]
public class AliasServiceTests
{
private Mock<OPNSenseApiClient> _apiClientMock;
private Mock<ILogger> _loggerMock;
private AliasService _aliasService;
[TestInitialize]
public void Initialize()
{
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
_loggerMock = new Mock<ILogger>();
_aliasService = new AliasService(_apiClientMock.Object, _loggerMock.Object);
}
[TestMethod]
public async Task GetAliasesAsync_ReturnsAliases()
{
// Arrange
var expectedResponse = new AliasListResponse
{
Total = 2,
RowCount = 2,
Current = 1,
Rows = new List<Alias>
{
new Alias
{
Uuid = "uuid1",
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Enabled = "1"
},
new Alias
{
Uuid = "uuid2",
Name = "WebPorts",
Type = "port",
Content = "80,443",
Description = "Web Ports",
Enabled = "1"
}
}
};
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.GetAliasesAsync();
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(2, result.Total);
Assert.AreEqual(2, result.Rows.Count);
Assert.AreEqual("WebServers", result.Rows[0].Name);
Assert.AreEqual("WebPorts", result.Rows[1].Name);
_loggerMock.Verify(x => x.Information("Getting aliases"), Times.Once);
}
[TestMethod]
public async Task GetAliasAsync_ReturnsAlias()
{
// Arrange
string uuid = "uuid1";
var expectedResponse = new AliasResponse
{
Alias = new AliasDetail
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Protocol = "",
UpdateFrequency = "",
Counters = "0",
Enabled = "1"
}
};
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.GetAliasAsync(uuid);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("WebServers", result.Alias.Name);
Assert.AreEqual("host", result.Alias.Type);
_loggerMock.Verify(x => x.Information($"Getting alias with UUID {uuid}"), Times.Once);
}
[TestMethod]
public async Task CreateAliasAsync_ReturnsUuid()
{
// Arrange
var alias = new AliasConfig
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11",
Description = "Web Servers",
Enabled = "1"
};
var expectedResponse = new AliasCreateResponse
{
Uuid = "new-uuid"
};
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.CreateAliasAsync(alias);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("new-uuid", result.Uuid);
_loggerMock.Verify(x => x.Information("Creating alias"), Times.Once);
}
[TestMethod]
public async Task UpdateAliasAsync_ReturnsSuccess()
{
// Arrange
string uuid = "uuid1";
var alias = new AliasConfig
{
Name = "WebServers",
Type = "host",
Content = "192.168.1.10,192.168.1.11,192.168.1.12",
Description = "Updated Web Servers",
Enabled = "1"
};
var expectedResponse = new AliasUpdateResponse
{
Result = "saved"
};
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.UpdateAliasAsync(uuid, alias);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("saved", result.Result);
_loggerMock.Verify(x => x.Information($"Updating alias with UUID {uuid}"), Times.Once);
}
[TestMethod]
public async Task DeleteAliasAsync_ReturnsSuccess()
{
// Arrange
string uuid = "uuid1";
var expectedResponse = new AliasDeleteResponse
{
Result = "deleted"
};
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.DeleteAliasAsync(uuid);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("deleted", result.Result);
_loggerMock.Verify(x => x.Information($"Deleting alias with UUID {uuid}"), Times.Once);
}
[TestMethod]
public async Task ReconfigureAliasesAsync_ReturnsSuccess()
{
// Arrange
var expectedResponse = new AliasReconfigureResponse
{
Status = "ok"
};
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
.ReturnsAsync(expectedResponse);
// Act
var result = await _aliasService.ReconfigureAliasesAsync();
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("ok", result.Status);
_loggerMock.Verify(x => x.Information("Reconfiguring aliases"), Times.Once);
}
}
}
@@ -0,0 +1,100 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Applies firewall changes on an OPNSense firewall.</para>
/// <para type="description">The Apply-OPNSenseFirewallChanges cmdlet applies pending firewall changes on an OPNSense firewall.</para>
/// <para type="description">This cmdlet creates a savepoint before applying changes, which allows for automatic rollback if the changes cause connectivity issues.</para>
/// <example>
/// <para>Example 1: Apply firewall changes</para>
/// <code>Apply-OPNSenseFirewallChanges</code>
/// <para>This example applies pending firewall changes with automatic rollback if connectivity is lost.</para>
/// </example>
/// <example>
/// <para>Example 2: Apply firewall changes without automatic rollback</para>
/// <code>Apply-OPNSenseFirewallChanges -NoRollback</code>
/// <para>This example applies pending firewall changes without creating a savepoint for automatic rollback.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsData.Update, "OPNSenseFirewallChanges")]
[OutputType(typeof(void))]
public class ApplyOPNSenseFirewallChangesCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">Applies changes without creating a savepoint for automatic rollback.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter NoRollback { get; set; }
/// <summary>
/// <para type="description">Cancels the automatic rollback after applying changes.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter CancelRollback { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait before cancelling the rollback.</para>
/// </summary>
[Parameter(Mandatory = false)]
[ValidateRange(1, 300)]
public int Timeout { get; set; } = 60;
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var firewallService = new FirewallService(ApiClient, Logger);
if (NoRollback.IsPresent)
{
WriteVerbose("Applying firewall changes without rollback protection");
var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync());
var applyResult = applyTask.GetAwaiter().GetResult();
WriteVerbose($"Firewall changes applied: {applyResult.Status}");
}
else
{
WriteVerbose("Creating savepoint for rollback protection");
var savepointTask = Task.Run(async () => await firewallService.CreateSavepointAsync());
var savepointResult = savepointTask.GetAwaiter().GetResult();
var revision = savepointResult.Revision;
WriteVerbose($"Created savepoint with revision {revision}");
WriteVerbose("Applying firewall changes with rollback protection");
var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync(revision));
var applyResult = applyTask.GetAwaiter().GetResult();
WriteVerbose($"Firewall changes applied: {applyResult.Status}");
if (CancelRollback.IsPresent)
{
WriteVerbose($"Waiting {Timeout} seconds before cancelling rollback");
System.Threading.Thread.Sleep(Timeout * 1000);
WriteVerbose("Cancelling automatic rollback");
var cancelTask = Task.Run(async () => await firewallService.CancelRollbackAsync(revision));
var cancelResult = cancelTask.GetAwaiter().GetResult();
WriteVerbose($"Rollback cancelled: {cancelResult.Status}");
}
else
{
WriteVerbose($"Automatic rollback will occur in 60 seconds if connectivity is lost");
}
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,53 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a backup of the OPNSense firewall configuration.</para>
/// <para type="description">The Backup-OPNSenseConfig cmdlet creates a backup of the OPNSense firewall configuration.</para>
/// <example>
/// <para>Example 1: Create a backup</para>
/// <code>Backup-OPNSenseConfig</code>
/// <para>This example creates a backup of the OPNSense firewall configuration with an automatically generated filename.</para>
/// </example>
/// <example>
/// <para>Example 2: Create a backup with a specific filename</para>
/// <code>Backup-OPNSenseConfig -Filename "pre-upgrade-backup"</code>
/// <para>This example creates a backup of the OPNSense firewall configuration with a specific filename.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsData.Backup, "OPNSenseConfig")]
[OutputType(typeof(string))]
public class BackupOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The filename for the backup.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0)]
public string Filename { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var configService = new ConfigService(ApiClient, Logger);
var task = Task.Run(async () => await configService.CreateConfigBackupAsync(Filename));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Created configuration backup: {result.Filename}");
WriteObject(result.Filename);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,99 @@
using System;
using System.Management.Automation;
using PSOPNSenseAPI.Logging;
using PSOPNSenseAPI.Models;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Connects to an OPNSense firewall.</para>
/// <para type="description">The Connect-OPNSense cmdlet establishes a connection to an OPNSense firewall using the API.</para>
/// <para type="description">This cmdlet must be called before using any other cmdlets in the module.</para>
/// <example>
/// <para>Example 1: Connect to an OPNSense firewall</para>
/// <code>Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"</code>
/// <para>This example connects to an OPNSense firewall at the specified URL using the provided API credentials.</para>
/// </example>
/// <example>
/// <para>Example 2: Connect to an OPNSense firewall with certificate validation disabled</para>
/// <code>Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck</code>
/// <para>This example connects to an OPNSense firewall at the specified URL using the provided API credentials, skipping certificate validation.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Connect, "OPNSense")]
[OutputType(typeof(void))]
public class ConnectOPNSenseCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The URL of the OPNSense firewall.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateNotNullOrEmpty]
public string Server { get; set; }
/// <summary>
/// <para type="description">The API key for authentication.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 1)]
[ValidateNotNullOrEmpty]
public string ApiKey { get; set; }
/// <summary>
/// <para type="description">The API secret for authentication.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 2)]
[ValidateNotNullOrEmpty]
public string ApiSecret { get; set; }
/// <summary>
/// <para type="description">Skips certificate validation when connecting to the OPNSense firewall.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter SkipCertificateCheck { get; set; }
/// <summary>
/// <para type="description">Forces a new connection even if one already exists.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
// Check if already connected
if (OPNSenseSession.IsConnected && !Force.IsPresent)
{
WriteWarning($"Already connected to {OPNSenseSession.BaseUrl}. Use -Force to reconnect.");
return;
}
// Dispose existing connection if there is one
OPNSenseSession.Current?.Dispose();
// Create a new logger
var logger = new PowerShellLogger(this);
// Create a new API client
var client = new OPNSenseApiClient(Server, ApiKey, ApiSecret, SkipCertificateCheck.IsPresent, logger);
// Set the current session
OPNSenseSession.Current = client;
WriteVerbose($"Connected to OPNSense firewall at {Server}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
ex,
"ConnectionFailed",
ErrorCategory.ConnectionError,
Server));
}
}
}
}
@@ -0,0 +1,253 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Connects an OPNSense firewall to a Tailscale network.</para>
/// <para type="description">The Connect-OPNSenseTailscale cmdlet connects an OPNSense firewall to a Tailscale network using an authentication key.</para>
/// <example>
/// <para>Example 1: Connect to Tailscale network</para>
/// <code>Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456"</code>
/// <para>This example connects the OPNSense firewall to a Tailscale network using the specified authentication key.</para>
/// </example>
/// <example>
/// <para>Example 2: Connect to Tailscale network with auto-installation</para>
/// <code>Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing</code>
/// <para>This example installs the Tailscale plugin if it's not already installed, then connects to the Tailscale network.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Connect, "OPNSenseTailscale", SupportsShouldProcess = true)]
[OutputType(typeof(PSObject))]
public class ConnectOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The Tailscale authentication key to use for connecting.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateNotNullOrEmpty]
public string AuthKey { get; set; }
/// <summary>
/// <para type="description">Whether to install the Tailscale plugin if it's not already installed.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter InstallIfMissing { get; set; }
/// <summary>
/// <para type="description">Whether to enable Tailscale if it's not already enabled.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter EnableIfDisabled { get; set; }
/// <summary>
/// <para type="description">Whether to start the Tailscale service if it's not already running.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter StartIfStopped { get; set; }
/// <summary>
/// <para type="description">Whether to advertise routes to the Tailscale network.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AdvertiseRoutes { get; set; }
/// <summary>
/// <para type="description">The subnet routes to advertise to the Tailscale network (e.g., "192.168.1.0/24", "10.0.0.0/8").</para>
/// <para type="description">Multiple routes can be specified.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] SubnetRoutes { get; set; }
/// <summary>
/// <para type="description">Whether to advertise this node as an exit node.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AdvertiseExitNode { get; set; }
/// <summary>
/// <para type="description">Suppresses the confirmation prompt.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var tailscaleService = new TailscaleService(ApiClient, Logger);
// Check if the plugin is installed
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
if (!isInstalled)
{
if (!InstallIfMissing.IsPresent)
{
WriteError(new ErrorRecord(
new Exception("Tailscale plugin is not installed. Use -InstallIfMissing to install it."),
"TailscalePluginNotInstalled",
ErrorCategory.InvalidOperation,
null));
return;
}
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Install Tailscale plugin"))
{
return;
}
WriteVerbose("Tailscale plugin is not installed. Installing...");
var installTask = Task.Run(async () => await tailscaleService.InstallPluginAsync());
var installResult = installTask.GetAwaiter().GetResult();
if (!installResult)
{
WriteError(new ErrorRecord(
new Exception("Failed to install Tailscale plugin."),
"TailscalePluginInstallFailed",
ErrorCategory.InvalidOperation,
null));
return;
}
WriteVerbose("Tailscale plugin installed successfully.");
}
// Get current status
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
var status = statusTask.GetAwaiter().GetResult();
// Enable Tailscale if needed
if (!status.Enabled && EnableIfDisabled.IsPresent)
{
WriteVerbose("Tailscale is disabled. Enabling...");
// Get current settings
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
// Process subnet routes if provided
string routesToAdvertise = currentSettings.RoutesToAdvertise;
bool advertiseRoutes = AdvertiseRoutes.IsPresent || currentSettings.AdvertiseRoutes == "1";
bool advertiseExitNode = AdvertiseExitNode.IsPresent || currentSettings.AdvertiseExitNode == "1";
if (SubnetRoutes != null && SubnetRoutes.Length > 0)
{
routesToAdvertise = string.Join(",", SubnetRoutes);
WriteVerbose($"Advertising subnet routes: {routesToAdvertise}");
// If routes are specified but AdvertiseRoutes is not set, enable it automatically
if (!advertiseRoutes)
{
WriteVerbose("Automatically enabling route advertisement because subnet routes were specified.");
advertiseRoutes = true;
}
}
// Create new settings with enabled flag
var settings = new TailscaleSettings
{
Enabled = "1",
AcceptDns = currentSettings.AcceptDns,
AcceptRoutes = currentSettings.AcceptRoutes,
AdvertiseExitNode = advertiseExitNode ? "1" : "0",
AdvertiseRoutes = advertiseRoutes ? "1" : "0",
RoutesToAdvertise = routesToAdvertise,
Hostname = currentSettings.Hostname,
LoginServer = currentSettings.LoginServer,
Ssh = currentSettings.Ssh,
Ephemeral = currentSettings.Ephemeral,
ResetOnStart = currentSettings.ResetOnStart
};
// Update settings
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
var updateResult = updateTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
// Get updated status
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
status = statusTask.GetAwaiter().GetResult();
}
// Start the service if needed
if (!status.Running && StartIfStopped.IsPresent)
{
WriteVerbose("Tailscale service is not running. Starting...");
var startTask = Task.Run(async () => await tailscaleService.StartServiceAsync());
var startResult = startTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale service started: {startResult.Status}");
// Get updated status
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
status = statusTask.GetAwaiter().GetResult();
}
// Check if Tailscale is enabled and running
if (!status.Enabled)
{
WriteError(new ErrorRecord(
new Exception("Tailscale is not enabled. Use -EnableIfDisabled to enable it."),
"TailscaleNotEnabled",
ErrorCategory.InvalidOperation,
null));
return;
}
if (!status.Running)
{
WriteError(new ErrorRecord(
new Exception("Tailscale service is not running. Use -StartIfStopped to start it."),
"TailscaleNotRunning",
ErrorCategory.InvalidOperation,
null));
return;
}
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Connect to Tailscale network"))
{
return;
}
// Connect to Tailscale
WriteVerbose("Connecting to Tailscale network...");
var connectTask = Task.Run(async () => await tailscaleService.ConnectAsync(AuthKey));
var connectResult = connectTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale connection status: {connectResult.Status}");
WriteVerbose($"Tailscale connection message: {connectResult.Message}");
// Get updated status
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
status = statusTask.GetAwaiter().GetResult();
// Get interfaces
var interfacesTask = Task.Run(async () => await tailscaleService.GetInterfacesAsync());
var interfaces = interfacesTask.GetAwaiter().GetResult();
// Create result object
var result = new PSObject();
result.Properties.Add(new PSNoteProperty("Status", status.Status));
result.Properties.Add(new PSNoteProperty("Running", status.Running));
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
result.Properties.Add(new PSNoteProperty("ConnectionStatus", connectResult.Status));
result.Properties.Add(new PSNoteProperty("ConnectionMessage", connectResult.Message));
result.Properties.Add(new PSNoteProperty("Interfaces", interfaces.Interfaces));
WriteObject(result);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,147 @@
using System;
using System.Management.Automation;
using PSOPNSenseAPI.Utilities;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Converts between different network notation formats.</para>
/// <para type="description">The ConvertTo-OPNSenseNetworkNotation cmdlet converts between CIDR notation and subnet mask notation.</para>
/// <example>
/// <para>Example 1: Convert CIDR to subnet mask</para>
/// <code>ConvertTo-OPNSenseNetworkNotation -CIDR 24</code>
/// <para>This example converts the CIDR prefix length 24 to the subnet mask 255.255.255.0.</para>
/// </example>
/// <example>
/// <para>Example 2: Convert subnet mask to CIDR</para>
/// <code>ConvertTo-OPNSenseNetworkNotation -SubnetMask "255.255.255.0"</code>
/// <para>This example converts the subnet mask 255.255.255.0 to the CIDR prefix length 24.</para>
/// </example>
/// <example>
/// <para>Example 3: Convert IP with CIDR to IP with subnet mask</para>
/// <code>ConvertTo-OPNSenseNetworkNotation -IPWithCIDR "192.168.1.0/24"</code>
/// <para>This example converts the IP with CIDR 192.168.1.0/24 to the IP with subnet mask 192.168.1.0 255.255.255.0.</para>
/// </example>
/// <example>
/// <para>Example 4: Convert IP with subnet mask to IP with CIDR</para>
/// <code>ConvertTo-OPNSenseNetworkNotation -IPWithSubnetMask "192.168.1.0 255.255.255.0"</code>
/// <para>This example converts the IP with subnet mask 192.168.1.0 255.255.255.0 to the IP with CIDR 192.168.1.0/24.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsData.ConvertTo, "OPNSenseNetworkNotation")]
[OutputType(typeof(string), typeof(int))]
public class ConvertToOPNSenseNetworkNotationCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The CIDR prefix length to convert to a subnet mask.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "FromCIDR")]
[ValidateRange(0, 32)]
public int? CIDR { get; set; }
/// <summary>
/// <para type="description">The subnet mask to convert to a CIDR prefix length.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "FromSubnetMask")]
public string SubnetMask { get; set; }
/// <summary>
/// <para type="description">The IP address with CIDR notation to convert to IP address with subnet mask.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "FromIPWithCIDR")]
public string IPWithCIDR { get; set; }
/// <summary>
/// <para type="description">The IP address with subnet mask to convert to IP address with CIDR notation.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "FromIPWithSubnetMask")]
public string IPWithSubnetMask { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
switch (ParameterSetName)
{
case "FromCIDR":
if (CIDR.HasValue)
{
string subnetMask = NetworkUtility.GetSubnetMaskFromCIDR(CIDR.Value);
WriteObject(subnetMask);
}
break;
case "FromSubnetMask":
if (!string.IsNullOrEmpty(SubnetMask))
{
int cidr = NetworkUtility.GetCIDRFromSubnetMask(SubnetMask);
WriteObject(cidr);
}
break;
case "FromIPWithCIDR":
if (!string.IsNullOrEmpty(IPWithCIDR))
{
string[] parts = IPWithCIDR.Split('/');
if (parts.Length != 2)
{
WriteError(new ErrorRecord(
new ArgumentException($"Invalid IP with CIDR: {IPWithCIDR}. Expected format: 192.168.1.0/24"),
"InvalidIPWithCIDR",
ErrorCategory.InvalidArgument,
null));
return;
}
string ip = parts[0];
if (!int.TryParse(parts[1], out int cidr))
{
WriteError(new ErrorRecord(
new ArgumentException($"Invalid CIDR: {parts[1]}"),
"InvalidCIDR",
ErrorCategory.InvalidArgument,
null));
return;
}
string subnetMask = NetworkUtility.GetSubnetMaskFromCIDR(cidr);
WriteObject($"{ip} {subnetMask}");
}
break;
case "FromIPWithSubnetMask":
if (!string.IsNullOrEmpty(IPWithSubnetMask))
{
string[] parts = IPWithSubnetMask.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
{
WriteError(new ErrorRecord(
new ArgumentException($"Invalid IP with subnet mask: {IPWithSubnetMask}. Expected format: 192.168.1.0 255.255.255.0"),
"InvalidIPWithSubnetMask",
ErrorCategory.InvalidArgument,
null));
return;
}
string ip = parts[0];
string subnetMask = parts[1];
int cidr = NetworkUtility.GetCIDRFromSubnetMask(subnetMask);
WriteObject($"{ip}/{cidr}");
}
break;
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
ex,
"ConversionError",
ErrorCategory.InvalidOperation,
null));
}
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disables a cron job on an OPNSense firewall.</para>
/// <para type="description">The Disable-OPNSenseCronJob cmdlet disables a cron job on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Disable a cron job</para>
/// <code>Disable-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example disables a cron job by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseCronJob")]
[OutputType(typeof(void))]
public class DisableOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the cron job to disable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// <para type="description">Whether to apply the changes immediately.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Apply { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var cronService = new CronService(ApiClient, Logger);
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, false));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Cron job {Uuid} disabled: {result.Result}");
// Apply the changes if requested
if (Apply.IsPresent)
{
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
var applyResult = applyTask.GetAwaiter().GetResult();
WriteVerbose($"Cron changes applied: {applyResult.Status}");
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,48 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disables a firewall rule on an OPNSense firewall.</para>
/// <para type="description">The Disable-OPNSenseFirewallRule cmdlet disables a firewall rule on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Disable a firewall rule</para>
/// <code>Disable-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example disables a firewall rule by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseFirewallRule")]
[OutputType(typeof(void))]
public class DisableOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the firewall rule to disable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var firewallService = new FirewallService(ApiClient, Logger);
var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, false));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Firewall rule {Uuid} disabled: {result.Result}");
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disables a plugin on an OPNSense firewall.</para>
/// <para type="description">The Disable-OPNSensePlugin cmdlet disables a plugin on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Disable a plugin</para>
/// <code>Disable-OPNSensePlugin -Name "os-acme-client"</code>
/// <para>This example disables the ACME client plugin on the OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "OPNSensePlugin")]
[OutputType(typeof(void))]
public class DisableOPNSensePluginCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The name of the plugin to disable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var pluginService = new PluginService(ApiClient, Logger);
var task = Task.Run(async () => await pluginService.DisablePluginAsync(Name));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Plugin {Name} disabled: {result.Status}");
WriteObject($"Plugin {Name} disabled: {result.Status}");
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,116 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disables Tailscale on an OPNSense firewall.</para>
/// <para type="description">The Disable-OPNSenseTailscale cmdlet disables Tailscale on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Disable Tailscale</para>
/// <code>Disable-OPNSenseTailscale</code>
/// <para>This example disables Tailscale on the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Disable Tailscale and stop the service</para>
/// <code>Disable-OPNSenseTailscale -Stop</code>
/// <para>This example disables Tailscale and stops the Tailscale service.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseTailscale", SupportsShouldProcess = true)]
[OutputType(typeof(PSObject))]
public class DisableOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">Whether to stop the Tailscale service after disabling it.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Stop { get; set; }
/// <summary>
/// <para type="description">Suppresses the confirmation prompt.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var tailscaleService = new TailscaleService(ApiClient, Logger);
// Check if the plugin is installed
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
if (!isInstalled)
{
WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
return;
}
// Get current settings
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
// Create new settings with disabled flag
var settings = new TailscaleSettings
{
Enabled = "0",
AcceptDns = currentSettings.AcceptDns,
AcceptRoutes = currentSettings.AcceptRoutes,
AdvertiseExitNode = currentSettings.AdvertiseExitNode,
AdvertiseRoutes = currentSettings.AdvertiseRoutes,
RoutesToAdvertise = currentSettings.RoutesToAdvertise,
Hostname = currentSettings.Hostname,
LoginServer = currentSettings.LoginServer,
Ssh = currentSettings.Ssh,
Ephemeral = currentSettings.Ephemeral,
ResetOnStart = currentSettings.ResetOnStart
};
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disable Tailscale"))
{
return;
}
// Update settings
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
var updateResult = updateTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
// Stop the service if requested
if (Stop.IsPresent)
{
WriteVerbose("Stopping Tailscale service...");
var stopTask = Task.Run(async () => await tailscaleService.StopServiceAsync());
var stopResult = stopTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale service stopped: {stopResult.Status}");
}
// Get updated status
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
var status = statusTask.GetAwaiter().GetResult();
// Create result object
var result = new PSObject();
result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
result.Properties.Add(new PSNoteProperty("Running", status.Running));
result.Properties.Add(new PSNoteProperty("Status", status.Status));
WriteObject(result);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.Management.Automation;
using PSOPNSenseAPI.Models;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disconnects from an OPNSense firewall.</para>
/// <para type="description">The Disconnect-OPNSense cmdlet closes the connection to an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Disconnect from an OPNSense firewall</para>
/// <code>Disconnect-OPNSense</code>
/// <para>This example disconnects from the currently connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Disconnect, "OPNSense")]
[OutputType(typeof(void))]
public class DisconnectOPNSenseCmdlet : PSCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
if (!OPNSenseSession.IsConnected)
{
WriteWarning("Not connected to any OPNSense firewall.");
return;
}
var baseUrl = OPNSenseSession.BaseUrl;
OPNSenseSession.Current?.Dispose();
OPNSenseSession.Current = null;
WriteVerbose($"Disconnected from OPNSense firewall at {baseUrl}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
ex,
"DisconnectionFailed",
ErrorCategory.ConnectionError,
null));
}
}
}
}
@@ -0,0 +1,87 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disconnects an OPNSense firewall from a Tailscale network.</para>
/// <para type="description">The Disconnect-OPNSenseTailscale cmdlet disconnects an OPNSense firewall from a Tailscale network.</para>
/// <example>
/// <para>Example 1: Disconnect from Tailscale network</para>
/// <code>Disconnect-OPNSenseTailscale</code>
/// <para>This example disconnects the OPNSense firewall from the Tailscale network.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Disconnect, "OPNSenseTailscale", SupportsShouldProcess = true)]
[OutputType(typeof(PSObject))]
public class DisconnectOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">Suppresses the confirmation prompt.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var tailscaleService = new TailscaleService(ApiClient, Logger);
// Check if the plugin is installed
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
if (!isInstalled)
{
WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
return;
}
// Get current status
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
var status = statusTask.GetAwaiter().GetResult();
if (!status.Running)
{
WriteWarning("Tailscale service is not running.");
return;
}
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disconnect from Tailscale network"))
{
return;
}
// Disconnect from Tailscale
WriteVerbose("Disconnecting from Tailscale network...");
var disconnectTask = Task.Run(async () => await tailscaleService.DisconnectAsync());
var disconnectResult = disconnectTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale disconnection status: {disconnectResult.Status}");
// Get updated status
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
status = statusTask.GetAwaiter().GetResult();
// Create result object
var result = new PSObject();
result.Properties.Add(new PSNoteProperty("Status", status.Status));
result.Properties.Add(new PSNoteProperty("Running", status.Running));
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
result.Properties.Add(new PSNoteProperty("DisconnectionStatus", disconnectResult.Status));
WriteObject(result);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Enables a cron job on an OPNSense firewall.</para>
/// <para type="description">The Enable-OPNSenseCronJob cmdlet enables a cron job on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Enable a cron job</para>
/// <code>Enable-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example enables a cron job by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseCronJob")]
[OutputType(typeof(void))]
public class EnableOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the cron job to enable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// <para type="description">Whether to apply the changes immediately.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Apply { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var cronService = new CronService(ApiClient, Logger);
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, true));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
// Apply the changes if requested
if (Apply.IsPresent)
{
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
var applyResult = applyTask.GetAwaiter().GetResult();
WriteVerbose($"Cron changes applied: {applyResult.Status}");
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,48 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Enables a firewall rule on an OPNSense firewall.</para>
/// <para type="description">The Enable-OPNSenseFirewallRule cmdlet enables a firewall rule on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Enable a firewall rule</para>
/// <code>Enable-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example enables a firewall rule by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseFirewallRule")]
[OutputType(typeof(void))]
public class EnableOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the firewall rule to enable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var firewallService = new FirewallService(ApiClient, Logger);
var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, true));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Firewall rule {Uuid} enabled: {result.Result}");
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Enables a plugin on an OPNSense firewall.</para>
/// <para type="description">The Enable-OPNSensePlugin cmdlet enables a plugin on an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Enable a plugin</para>
/// <code>Enable-OPNSensePlugin -Name "os-acme-client"</code>
/// <para>This example enables the ACME client plugin on the OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "OPNSensePlugin")]
[OutputType(typeof(void))]
public class EnableOPNSensePluginCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The name of the plugin to enable.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var pluginService = new PluginService(ApiClient, Logger);
var task = Task.Run(async () => await pluginService.EnablePluginAsync(Name));
var result = task.GetAwaiter().GetResult();
WriteVerbose($"Plugin {Name} enabled: {result.Status}");
WriteObject($"Plugin {Name} enabled: {result.Status}");
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,235 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Enables and configures Tailscale on an OPNSense firewall.</para>
/// <para type="description">The Enable-OPNSenseTailscale cmdlet enables and configures Tailscale on an OPNSense firewall. If the Tailscale plugin is not installed, it will be installed automatically.</para>
/// <example>
/// <para>Example 1: Enable Tailscale with default settings</para>
/// <code>Enable-OPNSenseTailscale</code>
/// <para>This example enables Tailscale with default settings.</para>
/// </example>
/// <example>
/// <para>Example 2: Enable Tailscale with custom settings</para>
/// <code>Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Hostname "opnsense-firewall"</code>
/// <para>This example enables Tailscale and configures it to accept DNS and routes from Tailscale, and sets the hostname.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseTailscale", SupportsShouldProcess = true)]
[OutputType(typeof(PSObject))]
public class EnableOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">Whether to accept DNS configuration from Tailscale.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AcceptDns { get; set; }
/// <summary>
/// <para type="description">Whether to accept routes from Tailscale.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AcceptRoutes { get; set; }
/// <summary>
/// <para type="description">Whether to advertise this node as an exit node.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AdvertiseExitNode { get; set; }
/// <summary>
/// <para type="description">Whether to advertise routes to the Tailscale network.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter AdvertiseRoutes { get; set; }
/// <summary>
/// <para type="description">The routes to advertise to the Tailscale network (e.g., "192.168.1.0/24,10.0.0.0/8").</para>
/// <para type="description">Multiple routes should be comma-separated.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] SubnetRoutes { get; set; }
/// <summary>
/// <para type="description">The hostname to use for this node in the Tailscale network.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Hostname { get; set; }
/// <summary>
/// <para type="description">The login server to use (leave empty for default).</para>
/// </summary>
[Parameter(Mandatory = false)]
public string LoginServer { get; set; }
/// <summary>
/// <para type="description">Whether to enable SSH access through Tailscale.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter EnableSsh { get; set; }
/// <summary>
/// <para type="description">Whether to use an ephemeral node key (node will disappear from network when restarted).</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Ephemeral { get; set; }
/// <summary>
/// <para type="description">Whether to reset the Tailscale state on service start.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter ResetOnStart { get; set; }
/// <summary>
/// <para type="description">Whether to start the Tailscale service after enabling it.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Start { get; set; } = true;
/// <summary>
/// <para type="description">Whether to restart the Tailscale service if it's already running.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Restart { get; set; }
/// <summary>
/// <para type="description">Whether to force installation of the Tailscale plugin if it's not already installed.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var tailscaleService = new TailscaleService(ApiClient, Logger);
// Check if the plugin is installed
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
if (!isInstalled)
{
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Install Tailscale plugin"))
{
WriteWarning("Tailscale plugin is not installed and -Force was not specified. Operation cancelled.");
return;
}
WriteVerbose("Tailscale plugin is not installed. Installing...");
var installTask = Task.Run(async () => await tailscaleService.InstallPluginAsync());
var installResult = installTask.GetAwaiter().GetResult();
if (!installResult)
{
WriteError(new ErrorRecord(
new Exception("Failed to install Tailscale plugin."),
"TailscalePluginInstallFailed",
ErrorCategory.InvalidOperation,
null));
return;
}
WriteVerbose("Tailscale plugin installed successfully.");
}
// Get current settings
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
// Process subnet routes if provided
string routesToAdvertise = currentSettings.RoutesToAdvertise;
if (SubnetRoutes != null && SubnetRoutes.Length > 0)
{
routesToAdvertise = string.Join(",", SubnetRoutes);
WriteVerbose($"Advertising subnet routes: {routesToAdvertise}");
// If routes are specified but AdvertiseRoutes is not set, enable it automatically
if (!AdvertiseRoutes.IsPresent)
{
WriteVerbose("Automatically enabling route advertisement because subnet routes were specified.");
AdvertiseRoutes = true;
}
}
// Create new settings
var settings = new TailscaleSettings
{
Enabled = "1",
AcceptDns = AcceptDns.IsPresent ? "1" : "0",
AcceptRoutes = AcceptRoutes.IsPresent ? "1" : "0",
AdvertiseExitNode = AdvertiseExitNode.IsPresent ? "1" : "0",
AdvertiseRoutes = AdvertiseRoutes.IsPresent ? "1" : "0",
RoutesToAdvertise = routesToAdvertise,
Hostname = Hostname ?? currentSettings.Hostname,
LoginServer = LoginServer ?? currentSettings.LoginServer,
Ssh = EnableSsh.IsPresent ? "1" : "0",
Ephemeral = Ephemeral.IsPresent ? "1" : "0",
ResetOnStart = ResetOnStart.IsPresent ? "1" : "0"
};
if (!ShouldProcess("OPNSense firewall", "Enable and configure Tailscale"))
{
return;
}
// Update settings
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
var updateResult = updateTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
// Get current status
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
var status = statusTask.GetAwaiter().GetResult();
// Start or restart the service if requested
if (Restart.IsPresent || (Start.IsPresent && !status.Running))
{
if (status.Running)
{
if (Restart.IsPresent)
{
WriteVerbose("Restarting Tailscale service...");
var restartTask = Task.Run(async () => await tailscaleService.RestartServiceAsync());
var restartResult = restartTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale service restarted: {restartResult.Status}");
}
}
else if (Start.IsPresent)
{
WriteVerbose("Starting Tailscale service...");
var startTask = Task.Run(async () => await tailscaleService.StartServiceAsync());
var startResult = startTask.GetAwaiter().GetResult();
WriteVerbose($"Tailscale service started: {startResult.Status}");
}
}
// Get updated status
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
status = statusTask.GetAwaiter().GetResult();
// Create result object
var result = new PSObject();
result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
result.Properties.Add(new PSNoteProperty("Running", status.Running));
result.Properties.Add(new PSNoteProperty("Status", status.Status));
result.Properties.Add(new PSNoteProperty("Settings", settings));
WriteObject(result);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,76 @@
using System;
using System.IO;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Exports the OPNSense firewall configuration.</para>
/// <para type="description">The Export-OPNSenseConfig cmdlet exports the OPNSense firewall configuration to a file.</para>
/// <example>
/// <para>Example 1: Export the configuration to a file</para>
/// <code>Export-OPNSenseConfig -Path "C:\Backups\opnsense-config.xml"</code>
/// <para>This example exports the OPNSense firewall configuration to a file.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsData.Export, "OPNSenseConfig")]
[OutputType(typeof(void))]
public class ExportOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The path to save the configuration file.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateNotNullOrEmpty]
public string Path { get; set; }
/// <summary>
/// <para type="description">Overwrites the file if it exists.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
// Check if the file exists
if (File.Exists(Path) && !Force.IsPresent)
{
WriteError(new ErrorRecord(
new IOException($"The file '{Path}' already exists. Use -Force to overwrite."),
"FileExists",
ErrorCategory.ResourceExists,
Path));
return;
}
var configService = new ConfigService(ApiClient, Logger);
var task = Task.Run(async () => await configService.ExportConfigAsync());
var configContent = task.GetAwaiter().GetResult();
// Create the directory if it doesn't exist
var directory = System.IO.Path.GetDirectoryName(Path);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// Write the configuration to the file
File.WriteAllBytes(Path, configContent);
WriteVerbose($"Exported configuration to {Path}");
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,106 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets aliases from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseAlias cmdlet retrieves aliases from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all aliases</para>
/// <code>Get-OPNSenseAlias</code>
/// <para>This example retrieves all aliases from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific alias by UUID</para>
/// <code>Get-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific alias by its UUID.</para>
/// </example>
/// <example>
/// <para>Example 3: Get aliases by type</para>
/// <code>Get-OPNSenseAlias | Where-Object { $_.Type -eq "host" }</code>
/// <para>This example retrieves all host aliases.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseAlias")]
[OutputType(typeof(Alias), typeof(AliasDetail))]
public class GetOPNSenseAliasCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the alias to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// <para type="description">The name of the alias to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByName")]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
/// <summary>
/// <para type="description">The type of aliases to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
[ValidateSet("host", "network", "port", "url", "urltable", "geoip", "networkgroup", "mac", "interface", "dynipv6host", "internal", "external")]
public string Type { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var aliasService = new AliasService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Alias);
}
else
{
var task = Task.Run(async () => await aliasService.GetAliasesAsync());
var result = task.GetAwaiter().GetResult();
// Filter by name if specified
if (ParameterSetName == "ByName")
{
var filteredByName = result.Rows.FindAll(a => a.Name.Equals(Name, StringComparison.OrdinalIgnoreCase));
// Further filter by type if specified
if (!string.IsNullOrEmpty(Type))
{
var filteredByType = filteredByName.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
WriteObject(filteredByType, true);
}
else
{
WriteObject(filteredByName, true);
}
}
// Filter by type if specified
else if (!string.IsNullOrEmpty(Type))
{
var filteredByType = result.Rows.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
WriteObject(filteredByType, true);
}
else
{
WriteObject(result.Rows, true);
}
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,41 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets configuration backups from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseConfigBackup cmdlet retrieves configuration backups from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all configuration backups</para>
/// <code>Get-OPNSenseConfigBackup</code>
/// <para>This example retrieves all configuration backups from the connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseConfigBackup")]
[OutputType(typeof(ConfigBackup))]
public class GetOPNSenseConfigBackupCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var configService = new ConfigService(ApiClient, Logger);
var task = Task.Run(async () => await configService.GetConfigBackupsAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Backups, true);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.Management.Automation;
using PSOPNSenseAPI.Models;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets information about the current OPNSense connection.</para>
/// <para type="description">The Get-OPNSenseConnection cmdlet retrieves information about the current connection to an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get the current connection information</para>
/// <code>Get-OPNSenseConnection</code>
/// <para>This example retrieves information about the current connection to an OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseConnection")]
[OutputType(typeof(PSObject))]
public class GetOPNSenseConnectionCmdlet : PSCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
if (!OPNSenseSession.IsConnected)
{
WriteWarning("Not connected to any OPNSense firewall.");
return;
}
var connectionInfo = new PSObject();
connectionInfo.Properties.Add(new PSNoteProperty("Server", OPNSenseSession.BaseUrl));
connectionInfo.Properties.Add(new PSNoteProperty("Connected", OPNSenseSession.IsConnected));
WriteObject(connectionInfo);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
ex,
"GetConnectionFailed",
ErrorCategory.ConnectionError,
null));
}
}
}
}
@@ -0,0 +1,61 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets cron jobs from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseCronJob cmdlet retrieves cron jobs from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all cron jobs</para>
/// <code>Get-OPNSenseCronJob</code>
/// <para>This example retrieves all cron jobs from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific cron job by UUID</para>
/// <code>Get-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific cron job by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseCronJob")]
[OutputType(typeof(CronJob), typeof(CronJobDetail))]
public class GetOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the cron job to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var cronService = new CronService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await cronService.GetJobAsync(Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Job);
}
else
{
var task = Task.Run(async () => await cronService.GetJobsAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,46 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DHCP leases from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDHCPLease cmdlet retrieves DHCP leases from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all DHCP leases</para>
/// <code>Get-OPNSenseDHCPLease</code>
/// <para>This example retrieves all DHCP leases from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get active DHCP leases</para>
/// <code>Get-OPNSenseDHCPLease | Where-Object { $_.State -eq "active" }</code>
/// <para>This example retrieves all active DHCP leases from the connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPLease")]
[OutputType(typeof(DHCPLease))]
public class GetOPNSenseDHCPLeaseCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dhcpService = new DHCPService(ApiClient, Logger);
var task = Task.Run(async () => await dhcpService.GetLeasesAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DHCP options from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDHCPOption cmdlet retrieves DHCP options from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all DHCP options for an interface</para>
/// <code>Get-OPNSenseDHCPOption -Interface "lan"</code>
/// <para>This example retrieves all DHCP options for the LAN interface.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific DHCP option by UUID</para>
/// <code>Get-OPNSenseDHCPOption -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific DHCP option by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPOption")]
[OutputType(typeof(DHCPOption), typeof(DHCPOptionDetail))]
public class GetOPNSenseDHCPOptionCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The interface name.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateNotNullOrEmpty]
public string Interface { get; set; }
/// <summary>
/// <para type="description">The UUID of the DHCP option to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 1, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dhcpService = new DHCPService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Option);
}
else
{
var task = Task.Run(async () => await dhcpService.GetOptionsAsync(Interface));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,76 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DHCP servers from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDHCPServer cmdlet retrieves DHCP servers from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all DHCP servers</para>
/// <code>Get-OPNSenseDHCPServer</code>
/// <para>This example retrieves all DHCP servers from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific DHCP server by interface</para>
/// <code>Get-OPNSenseDHCPServer -Interface "lan"</code>
/// <para>This example retrieves the DHCP server for the LAN interface.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPServer")]
[OutputType(typeof(PSObject), typeof(DHCPServerDetail))]
public class GetOPNSenseDHCPServerCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The interface to get the DHCP server for.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByInterface")]
[ValidateNotNullOrEmpty]
public string Interface { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dhcpService = new DHCPService(ApiClient, Logger);
if (ParameterSetName == "ByInterface")
{
var task = Task.Run(async () => await dhcpService.GetServerAsync(Interface));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Server);
}
else
{
var task = Task.Run(async () => await dhcpService.GetServersAsync());
var result = task.GetAwaiter().GetResult();
foreach (var kvp in result.Servers.Interfaces)
{
var server = new PSObject();
server.Properties.Add(new PSNoteProperty("Interface", kvp.Key));
server.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
server.Properties.Add(new PSNoteProperty("RangeFrom", kvp.Value.RangeFrom));
server.Properties.Add(new PSNoteProperty("RangeTo", kvp.Value.RangeTo));
server.Properties.Add(new PSNoteProperty("DefaultLeaseTime", kvp.Value.DefaultLeaseTime));
server.Properties.Add(new PSNoteProperty("MaxLeaseTime", kvp.Value.MaxLeaseTime));
server.Properties.Add(new PSNoteProperty("Domain", kvp.Value.Domain));
server.Properties.Add(new PSNoteProperty("DnsServers", kvp.Value.DnsServers));
server.Properties.Add(new PSNoteProperty("Gateway", kvp.Value.Gateway));
WriteObject(server);
}
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DHCP static mappings from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDHCPStaticMapping cmdlet retrieves DHCP static mappings from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all static mappings for an interface</para>
/// <code>Get-OPNSenseDHCPStaticMapping -Interface "lan"</code>
/// <para>This example retrieves all static mappings for the LAN interface.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific static mapping by UUID</para>
/// <code>Get-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific static mapping by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPStaticMapping")]
[OutputType(typeof(DHCPStaticMapping), typeof(DHCPStaticMappingDetail))]
public class GetOPNSenseDHCPStaticMappingCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The interface to get static mappings for.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateNotNullOrEmpty]
public string Interface { get; set; }
/// <summary>
/// <para type="description">The UUID of the static mapping to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 1, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dhcpService = new DHCPService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Mapping);
}
else
{
var task = Task.Run(async () => await dhcpService.GetStaticMappingsAsync(Interface));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,41 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets the DNS forwarding configuration from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDNSForwarding cmdlet retrieves the DNS forwarding configuration from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get DNS forwarding configuration</para>
/// <code>Get-OPNSenseDNSForwarding</code>
/// <para>This example retrieves the DNS forwarding configuration from the connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSForwarding")]
[OutputType(typeof(DNSForwardingConfig))]
public class GetOPNSenseDNSForwardingCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dnsService = new DNSService(ApiClient, Logger);
var task = Task.Run(async () => await dnsService.GetDNSForwardingAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Forward);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,61 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DNS forwarding hosts from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDNSForwardingHost cmdlet retrieves DNS forwarding hosts from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all DNS forwarding hosts</para>
/// <code>Get-OPNSenseDNSForwardingHost</code>
/// <para>This example retrieves all DNS forwarding hosts from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific DNS forwarding host by UUID</para>
/// <code>Get-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific DNS forwarding host by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSForwardingHost")]
[OutputType(typeof(DNSForwardingHost), typeof(DNSForwardingHostDetail))]
public class GetOPNSenseDNSForwardingHostCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the DNS forwarding host to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dnsService = new DNSService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Host);
}
else
{
var task = Task.Run(async () => await dnsService.GetDNSForwardingHostsAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,61 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DNS overrides from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDNSOverride cmdlet retrieves DNS overrides from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all DNS overrides</para>
/// <code>Get-OPNSenseDNSOverride</code>
/// <para>This example retrieves all DNS overrides from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific DNS override by UUID</para>
/// <code>Get-OPNSenseDNSOverride -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific DNS override by its UUID.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSOverride")]
[OutputType(typeof(DNSOverride), typeof(DNSOverrideDetail))]
public class GetOPNSenseDNSOverrideCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the DNS override to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dnsService = new DNSService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await dnsService.GetDNSOverrideAsync(Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Host);
}
else
{
var task = Task.Run(async () => await dnsService.GetDNSOverridesAsync());
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,52 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets DNS server configuration from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseDNSServer cmdlet retrieves DNS server configuration from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get DNS server configuration</para>
/// <code>Get-OPNSenseDNSServer</code>
/// <para>This example retrieves the DNS server configuration from the connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSServer")]
[OutputType(typeof(PSObject))]
public class GetOPNSenseDNSServerCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var dnsService = new DNSService(ApiClient, Logger);
var task = Task.Run(async () => await dnsService.GetDNSConfigAsync());
var result = task.GetAwaiter().GetResult();
var dnsConfig = new PSObject();
dnsConfig.Properties.Add(new PSNoteProperty("Enabled", result.Unbound.Enabled == "1"));
dnsConfig.Properties.Add(new PSNoteProperty("Port", result.Unbound.Port));
dnsConfig.Properties.Add(new PSNoteProperty("Interfaces", result.Unbound.Interfaces));
dnsConfig.Properties.Add(new PSNoteProperty("Forwarding", result.Unbound.Forwarding == "1"));
dnsConfig.Properties.Add(new PSNoteProperty("Forwarders", result.Unbound.Forwarders));
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcp", result.Unbound.RegisterDhcp == "1"));
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpDomain", result.Unbound.RegisterDhcpDomain));
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpStatic", result.Unbound.RegisterDhcpStatic == "1"));
dnsConfig.Properties.Add(new PSNoteProperty("ActiveInterfaces", result.Unbound.ActiveInterfaces));
WriteObject(dnsConfig);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,86 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets firewall rules from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseFirewallRule cmdlet retrieves firewall rules from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get all firewall rules</para>
/// <code>Get-OPNSenseFirewallRule</code>
/// <para>This example retrieves all firewall rules from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get a specific firewall rule by UUID</para>
/// <code>Get-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
/// <para>This example retrieves a specific firewall rule by its UUID.</para>
/// </example>
/// <example>
/// <para>Example 3: Search for firewall rules by description</para>
/// <code>Get-OPNSenseFirewallRule -SearchPhrase "Allow HTTP"</code>
/// <para>This example searches for firewall rules with a description containing "Allow HTTP".</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseFirewallRule")]
[OutputType(typeof(FirewallRule), typeof(FirewallRuleDetails))]
public class GetOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">The UUID of the firewall rule to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
[ValidateNotNullOrEmpty]
public string Uuid { get; set; }
/// <summary>
/// <para type="description">The search phrase to filter rules by.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
public string SearchPhrase { get; set; } = "";
/// <summary>
/// <para type="description">The page number to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
[ValidateRange(1, int.MaxValue)]
public int Page { get; set; } = 1;
/// <summary>
/// <para type="description">The number of rules to retrieve per page.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
[ValidateRange(1, 1000)]
public int RowCount { get; set; } = 100;
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var firewallService = new FirewallService(ApiClient, Logger);
if (ParameterSetName == "ByUuid")
{
var task = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rule);
}
else
{
var task = Task.Run(async () => await firewallService.GetRulesAsync(SearchPhrase, Page, RowCount));
var result = task.GetAwaiter().GetResult();
WriteObject(result.Rows, true);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
@@ -0,0 +1,112 @@
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PSOPNSenseAPI.Services;
namespace PSOPNSenseAPI.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets firmware information from an OPNSense firewall.</para>
/// <para type="description">The Get-OPNSenseFirmware cmdlet retrieves firmware information from an OPNSense firewall.</para>
/// <example>
/// <para>Example 1: Get firmware status</para>
/// <code>Get-OPNSenseFirmware</code>
/// <para>This example retrieves the firmware status from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 2: Get firmware changelog</para>
/// <code>Get-OPNSenseFirmware -Changelog</code>
/// <para>This example retrieves the firmware changelog from the connected OPNSense firewall.</para>
/// </example>
/// <example>
/// <para>Example 3: Get firmware audit</para>
/// <code>Get-OPNSenseFirmware -Audit</code>
/// <para>This example retrieves the firmware audit from the connected OPNSense firewall.</para>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "OPNSenseFirmware")]
[OutputType(typeof(PSObject))]
public class GetOPNSenseFirmwareCmdlet : OPNSenseBaseCmdlet
{
/// <summary>
/// <para type="description">Gets the firmware changelog.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Changelog")]
public SwitchParameter Changelog { get; set; }
/// <summary>
/// <para type="description">Gets the firmware audit.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Audit")]
public SwitchParameter Audit { get; set; }
/// <summary>
/// <para type="description">Gets the firmware health.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Health")]
public SwitchParameter Health { get; set; }
/// <summary>
/// <para type="description">Checks for firmware updates.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Check")]
public SwitchParameter Check { get; set; }
/// <summary>
/// Processes the cmdlet
/// </summary>
protected override void ProcessRecord()
{
try
{
var firmwareService = new FirmwareService(ApiClient, Logger);
switch (ParameterSetName)
{
case "Changelog":
var changelogTask = Task.Run(async () => await firmwareService.GetChangelogAsync());
var changelogResult = changelogTask.GetAwaiter().GetResult();
WriteObject(changelogResult.Changelog);
break;
case "Audit":
var auditTask = Task.Run(async () => await firmwareService.GetAuditAsync());
var auditResult = auditTask.GetAwaiter().GetResult();
WriteObject(auditResult.Audit, true);
break;
case "Health":
var healthTask = Task.Run(async () => await firmwareService.GetHealthAsync());
var healthResult = healthTask.GetAwaiter().GetResult();
WriteObject(healthResult.Health);
break;
case "Check":
var checkTask = Task.Run(async () => await firmwareService.CheckForUpdatesAsync());
var checkResult = checkTask.GetAwaiter().GetResult();
WriteObject($"Check for updates: {checkResult.Status}");
break;
default:
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
var statusResult = statusTask.GetAwaiter().GetResult();
var firmware = new PSObject();
firmware.Properties.Add(new PSNoteProperty("Status", statusResult.Status));
firmware.Properties.Add(new PSNoteProperty("Connection", statusResult.Connection));
firmware.Properties.Add(new PSNoteProperty("DownloadSize", statusResult.DownloadSize));
firmware.Properties.Add(new PSNoteProperty("LastCheck", statusResult.LastCheck));
firmware.Properties.Add(new PSNoteProperty("UpgradeMessage", statusResult.UpgradeMessage));
firmware.Properties.Add(new PSNoteProperty("Updates", statusResult.Updates));
WriteObject(firmware);
break;
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More