用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/aibot88/sec_skill_store --skill ops-opnsense命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | ops-opnsense |
| description | OPNsense configuration via Terraform. Trigger for interfaces, firewall, NAT, DHCP/DNS, aliases. |
| allowed-tools | ["Read","Write","Edit","Bash","Glob","Grep"] |
| context | fork |
| argument-hint | [component] |
Complete guide to configure OPNsense declaratively with Terraform and the browningluke/opnsense provider.
Activate this skill to:
Do not use for:
/ops:ops-proxmox)| Attribute | Value |
|---|---|
| Provider | browningluke/opnsense |
| Version | >= 0.11 |
| Documentation | https://registry.terraform.io/providers/browningluke/opnsense/latest/docs |
| GitHub | https://github.com/browningluke/terraform-provider-opnsense |
terraform {
required_providers {
opnsense = {
source = "browningluke/opnsense"
version = "~> 0.11"
}
}
}
provider "opnsense" {
uri = var.opnsense_uri # https://192.168.10.1
api_key = var.opnsense_api_key # Sensitive
api_secret = var.opnsense_api_secret # Sensitive
allow_insecure = true # false in production
}
# WAN interface (DHCP from ISP box)
resource "opnsense_interface" "wan" {
device = "vtnet0"
description = "WAN - Orange Box"
ipv4_type = "dhcp"
block_private = true
block_bogons = true
}
# LAN interface (static IP)
resource "opnsense_interface" "lan" {
device = "vtnet1"
description = "LAN - Local network"
ipv4_type = "static"
ipv4_addr = "192.168.10.1"
ipv4_mask = 24
}
# MANDATORY: Anti-lockout rule (ALWAYS first)
resource "opnsense_firewall_filter" "anti_lockout" {
interface = "lan"
direction = "in"
action = "pass"
protocol = "tcp"
source_net = "lannet"
destination_net = "(self)"
destination_port = "443"
description = "ANTI-LOCKOUT: Admin access"
sequence = 1
}
# Allow outbound HTTP/HTTPS
resource "opnsense_firewall_filter" "lan_to_web" {
interface = "lan"
direction = "in"
action = "pass"
protocol = "tcp"
source_net = "lannet"
destination_net = "any"
destination_port = "80,443"
description = "Allow outbound HTTP/HTTPS"
sequence = 10
}
# Block everything else (deny by default)
resource "opnsense_firewall_filter" "lan_block_all" {
interface = "lan"
direction = "in"
action = "block"
protocol = "any"
source_net = "any"
destination_net = "any"
log = true
description = "Block and log everything else"
sequence = 65535
}
# Port forward HTTPS to internal web server
resource "opnsense_nat_port_forward" "https_to_web" {
interface = "wan"
protocol = "tcp"
source_net = "any"
source_port = "443"
destination_net = "wanip"
destination_port = "443"
target = "192.168.10.20"
local_port = "443"
description = "HTTPS to web server"
nat_reflection = "enable"
filter_rule_association = "add-associated"
}
# SSH on non-standard port
resource "opnsense_nat_port_forward" "ssh_to_server" {
interface = "wan"
protocol = "tcp"
source_net = "any"
source_port = "2222"
destination_net = "wanip"
destination_port = "2222"
target = "192.168.10.10"
local_port = "22"
description = "SSH to server (port 2222)"
}
# DHCP server on LAN
resource "opnsense_dhcp_v4_server" "lan" {
interface = "lan"
enabled = true
range_from = "192.168.10.100"
range_to = "192.168.10.200"
gateway = "192.168.10.1"
dns_servers = ["192.168.10.1"]
domain = "home.local"
lease_time = 86400
}
# DHCP reservation
resource "opnsense_dhcp_v4_static_map" "server_web" {
interface = "lan"
mac = "00:11:22:33:44:55"
ipaddr = "192.168.10.20"
hostname = "server-web"
description = "Main web server"
}
# DNS forwarder
resource "opnsense_unbound_forward" "cloudflare" {
enabled = true
host = "1.1.1.1"
port = 53
priority = 10
}
# Local DNS entry
resource "opnsense_unbound_host_override" "server_web" {
enabled = true
hostname = "server"
domain = "home.local"
server = "192.168.10.20"
}
# Server alias
resource "opnsense_firewall_alias" "servers_web" {
name = "SERVERS_WEB"
type = "host"
content = ["192.168.10.20", "192.168.10.21"]
description = "Internal web servers"
}
# Port alias
resource "opnsense_firewall_alias" "ports_web" {
name = "PORTS_WEB"
type = "port"
content = ["80", "443", "8080"]
description = "Web service ports"
}
# Use in a rule
resource "opnsense_firewall_filter" "to_web_servers" {
interface = "lan"
action = "pass"
protocol = "tcp"
source_net = "lannet"
destination_net = opnsense_firewall_alias.servers_web.name
destination_port = opnsense_firewall_alias.ports_web.name
description = "Access to web servers"
}
Anti-lockout (sequence = 1)
Deny by default (sequence = 65535)
Secure credentials
| Practice | Why |
|---|---|
| Use aliases | Readability and maintainability |
| Document each rule | Easier audit |
| Log block rules | Intrusion detection |
| Test in lab | Avoid lockouts |
| Backup before apply | Rollback possible |
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Internet │ │ Orange Box │ │ OPNsense │
│ │────▶│ (192.168.1.1) │────▶│ WAN: DHCP │
│ │ │ DMZ Mode │ │ LAN: .10.1 │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
┌─────────────┴─────────────┐
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ Server │ │ Client │
│ .10.20 │ │ DHCP │
└─────────────┘ └─────────────┘
http://192.168.1.1WireGuard VPN server configuration:
# WireGuard interface
resource "opnsense_wireguard_server" "vpn" {
name = "wg0"
enabled = true
listen_port = 51820
tunnel_addr = "10.10.10.1/24"
dns = "192.168.10.1"
private_key = var.wireguard_private_key # Sensitive
}
# Peer (VPN client)
resource "opnsense_wireguard_peer" "laptop" {
server_id = opnsense_wireguard_server.vpn.id
name = "laptop-chris"
public_key = "CLIENT_PUBLIC_KEY"
allowed_ips = "10.10.10.2/32"
}
# Firewall rule for WireGuard
resource "opnsense_firewall_filter" "wireguard_in" {
interface = "wan"
direction = "in"
action = "pass"
protocol = "udp"
destination_port = "51820"
description = "WireGuard VPN"
}
node_exporter package via OPNsense# prometheus.yml
scrape_configs:
- job_name: 'opnsense'
static_configs:
- targets: ['192.168.10.1:9100']
metrics_path: /metrics
| Metric | Description |
|---|---|
node_network_receive_bytes_total | Inbound traffic |
node_network_transmit_bytes_total | Outbound traffic |
node_cpu_seconds_total | CPU usage |
node_memory_MemAvailable_bytes | Available memory |
node_filesystem_avail_bytes | Disk space |
# Test the connection
curl -k -u "api-key:api-secret" \
"https://192.168.10.1/api/core/firmware/status"
# Check:
# 1. API enabled (System > Settings > Administration)
# 2. API user with permissions
# 3. Firewall is not blocking
# 4. HTTPS certificate
# Via Proxmox/local console
pfctl -d # Disable firewall
# Fix via web interface
pfctl -e # Re-enable firewall
# Import existing resource
terraform import opnsense_firewall_filter.rule "uuid"
# Refresh
terraform refresh
# Force recreation
terraform taint opnsense_firewall_filter.rule
terraform apply
Templates are in .claude/templates/opnsense/:
| Template | Description |
|---|---|
provider-template.tf | Provider configuration |
interfaces-module.tf | WAN/LAN interfaces |
firewall-module.tf | Firewall rules |
nat-module.tf | NAT/port forward |
services-module.tf | DHCP/DNS |
aliases-module.tf | Address groups |
examples/orange-box-dmz/ | Complete example |