mirror of
https://github.com/auricom/home-cluster.git
synced 2025-09-17 18:24:14 +02:00
✨ opnsense
This commit is contained in:
@@ -31,6 +31,7 @@ resources:
|
||||
- ./music-transcode/ks.yaml
|
||||
- ./navidrome/ks.yaml
|
||||
- ./nitter/ks.yaml
|
||||
- ./opnsense/ks.yaml
|
||||
- ./outline/ks.yaml
|
||||
- ./paperless/ks.yaml
|
||||
- ./pgadmin/ks.yaml
|
||||
|
202
kubernetes/apps/default/opnsense/app/dashboard.json
Normal file
202
kubernetes/apps/default/opnsense/app/dashboard.json
Normal file
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": 66,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"circleMaxSize": 30,
|
||||
"circleMinSize": 2,
|
||||
"colors": [
|
||||
"rgba(245, 54, 54, 0.9)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(50, 172, 45, 0.97)"
|
||||
],
|
||||
"datasource": {
|
||||
"type": "loki",
|
||||
"uid": "P8E80F9AEF21F6940"
|
||||
},
|
||||
"decimals": 0,
|
||||
"esMetric": "Count",
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"hideEmpty": false,
|
||||
"hideZero": false,
|
||||
"id": 2,
|
||||
"initialZoom": 1,
|
||||
"locationData": "countries",
|
||||
"mapCenter": "(0°, 0°)",
|
||||
"mapCenterLatitude": 0,
|
||||
"mapCenterLongitude": 0,
|
||||
"maxDataPoints": 1,
|
||||
"mouseWheelZoom": false,
|
||||
"showLegend": true,
|
||||
"stickyLabels": false,
|
||||
"tableQueryOptions": {
|
||||
"geohashField": "geohash",
|
||||
"latitudeField": "latitude",
|
||||
"longitudeField": "longitude",
|
||||
"metricField": "metric",
|
||||
"queryType": "geohash"
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "loki",
|
||||
"uid": "P8E80F9AEF21F6940"
|
||||
},
|
||||
"expr": "sum(count_over_time({hostname=\"opnsense\"} | json | appname = \"filterlog\" | filter_action = \"pass\"[$__interval])) by (geoip_country_code)",
|
||||
"legendFormat": "{{geoip_country_code}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": "0,10",
|
||||
"title": "Allowed incoming connections by GeoIP",
|
||||
"type": "grafana-worldmap-panel",
|
||||
"unitPlural": "",
|
||||
"unitSingle": "",
|
||||
"valueName": "total"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "loki",
|
||||
"uid": "P8E80F9AEF21F6940"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "continuous-GrYlRd"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"displayMode": "lcd",
|
||||
"orientation": "horizontal",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showUnfilled": true
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "loki",
|
||||
"uid": "P8E80F9AEF21F6940"
|
||||
},
|
||||
"expr": "topk(10, \n sum by (filter_destination_port) (\n count_over_time(\n {hostname=\"opnsense\"} \n | json \n | appname = \"filterlog\"\n | filter_destination_port != \"\"\n | filter_action = \"pass\"\n | filter_interface = \"igb0\"\n [$__range]\n )\n )\n)",
|
||||
"instant": true,
|
||||
"legendFormat": "{{filter_destination_port}}",
|
||||
"range": false,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Top 10 allowed incoming ports",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "sortBy",
|
||||
"options": {
|
||||
"fields": {},
|
||||
"sort": [
|
||||
{
|
||||
"desc": true,
|
||||
"field": "Value #A"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "rowsToFields",
|
||||
"options": {
|
||||
"mappings": [
|
||||
{
|
||||
"fieldName": "Time",
|
||||
"handlerKey": "field.value"
|
||||
},
|
||||
{
|
||||
"fieldName": "filter_source_port",
|
||||
"handlerKey": "field.name"
|
||||
},
|
||||
{
|
||||
"fieldName": "Value #A",
|
||||
"handlerKey": "field.value"
|
||||
},
|
||||
{
|
||||
"fieldName": "filter_destination_port",
|
||||
"handlerKey": "field.name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "bargauge"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 34,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "OPNsense",
|
||||
"uid": "itdu1LAnk",
|
||||
"version": 9,
|
||||
"weekStart": ""
|
||||
}
|
53
kubernetes/apps/default/opnsense/app/helmrelease.yaml
Normal file
53
kubernetes/apps/default/opnsense/app/helmrelease.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/helmrelease_v2beta1.json
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: opnsense-backup
|
||||
namespace: default
|
||||
spec:
|
||||
interval: 15m
|
||||
chart:
|
||||
spec:
|
||||
chart: app-template
|
||||
version: 1.2.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bjw-s
|
||||
namespace: flux-system
|
||||
install:
|
||||
createNamespace: true
|
||||
remediation:
|
||||
retries: 3
|
||||
upgrade:
|
||||
remediation:
|
||||
retries: 3
|
||||
values:
|
||||
controller:
|
||||
type: cronjob
|
||||
cronjob:
|
||||
concurrencyPolicy: Forbid
|
||||
schedule: "@daily"
|
||||
restartPolicy: OnFailure
|
||||
image:
|
||||
repository: ghcr.io/auricom/kubectl
|
||||
tag: 1.26.0@sha256:f512e3008d0492cbae7aac6eaccc21b13d723374715aaedd59d352d840f0229c
|
||||
command: ["/bin/bash", "/app/opnsense-backup.sh"]
|
||||
env:
|
||||
OPNSENSE_URL: "https://opnsense.${SECRET_DOMAIN}"
|
||||
S3_URL: "https://truenas.${SECRET_DOMAIN}:51515"
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: opnsense-backup-secret
|
||||
service:
|
||||
main:
|
||||
enabled: false
|
||||
persistence:
|
||||
config:
|
||||
enabled: true
|
||||
type: configMap
|
||||
name: opnsense-backup-configmap
|
||||
subPath: opnsense-backup.sh
|
||||
mountPath: /app/opnsense-backup.sh
|
||||
defaultMode: 0775
|
||||
readOnly: true
|
25
kubernetes/apps/default/opnsense/app/ks.yaml
Normal file
25
kubernetes/apps/default/opnsense/app/ks.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/kustomization_v1beta2.json
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: cluster-apps-opnsense
|
||||
namespace: flux-system
|
||||
labels:
|
||||
substitution.flux.home.arpa/enabled: "true"
|
||||
spec:
|
||||
dependsOn:
|
||||
- name: cluster-apps-onepassword-connect
|
||||
path: ./kubernetes/apps/default/opnsense/app
|
||||
prune: true
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: home-ops-kubernetes
|
||||
healthChecks:
|
||||
- apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
name: opnsense-backup
|
||||
namespace: default
|
||||
interval: 30m
|
||||
retryInterval: 1m
|
||||
timeout: 3m
|
21
kubernetes/apps/default/opnsense/app/kustomization.yaml
Normal file
21
kubernetes/apps/default/opnsense/app/kustomization.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: default
|
||||
resources:
|
||||
- ./secret.sops.yaml
|
||||
- ./helmrelease.yaml
|
||||
configMapGenerator:
|
||||
- name: opnsense-backup-configmap
|
||||
files:
|
||||
- ./opnsense-backup.sh
|
||||
- name: opnsense-dashboard
|
||||
files:
|
||||
- opnsense-dashboard.json=./dashboard.json
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/substitute: disabled
|
||||
labels:
|
||||
grafana_dashboard: "true"
|
33
kubernetes/apps/default/opnsense/app/opnsense-backup.sh
Executable file
33
kubernetes/apps/default/opnsense/app/opnsense-backup.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
|
||||
config_filename="$(date "+%Y%m%d-%H%M%S").xml"
|
||||
|
||||
http_host=${S3_URL#*//}
|
||||
http_host=${http_host%:*}
|
||||
http_request_date=$(date -R)
|
||||
http_filepath="opnsense/${config_filename}"
|
||||
http_signature=$(
|
||||
printf "PUT\n\ntext/xml\n%s\n/%s" "${http_request_date}" "${http_filepath}" \
|
||||
| openssl sha1 -hmac "${AWS_SECRET_ACCESS_KEY}" -binary \
|
||||
| base64
|
||||
)
|
||||
|
||||
echo "Download Opnsense config file ..."
|
||||
curl -fsSL \
|
||||
--user "${OPNSENSE_KEY}:${OPNSENSE_SECRET}" \
|
||||
--output "/tmp/${config_filename}" \
|
||||
"${OPNSENSE_URL}/api/backup/backup/download"
|
||||
|
||||
echo "Upload backup to s3 bucket ..."
|
||||
curl -fsSL \
|
||||
-X PUT -T "/tmp/${config_filename}" \
|
||||
-H "Host: ${http_host}" \
|
||||
-H "Date: ${http_request_date}" \
|
||||
-H "Content-Type: text/xml" \
|
||||
-H "Authorization: AWS ${AWS_ACCESS_KEY_ID}:${http_signature}" \
|
||||
"${S3_URL}/${http_filepath}"
|
||||
|
||||
test $? -eq 0 && curl -m 10 --retry 5 https://uptime-kuma.${SECRET_CLUSTER_DOMAIN}/api/push/14g69yYBhu?status=up&msg=OK&ping=
|
31
kubernetes/apps/default/opnsense/app/secret.sops.yaml
Normal file
31
kubernetes/apps/default/opnsense/app/secret.sops.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: opnsense-backup-secret
|
||||
namespace: default
|
||||
type: Opaque
|
||||
stringData:
|
||||
OPNSENSE_KEY: ENC[AES256_GCM,data:o2RT80AbQJg1EOFbX3iMIyC8eRIVx0YcL7/+H51SpDdcs0ynisIaKgycxOTg6t65VTApnVhyZaWgVbQxfSsH2zKuGT9dFYfUHbcFjve3isc=,iv:l/qvdOFBZhA2LFV7Q6vIBuVkNSJmEWEqiAUU9vXsSuo=,tag:Itiz/H7S4F+TktGyT7WX2A==,type:str]
|
||||
OPNSENSE_SECRET: ENC[AES256_GCM,data:ITYxDGhq7rxU2w3BSa3t+ka/TbPipP1tJzoUuWkvNyXxBlNV277oNRWxMUta210+xq9C8m7BD7ay6lVrbvev4Rf8YNdgTGXl6tFmfVnSqmo=,iv:MbrRhgGoRz2cu9H0y+pYBZrX2CikDfplOGH0h8e6GDo=,tag:pVqki2c534KKZ8GLSF3BlQ==,type:str]
|
||||
AWS_ACCESS_KEY_ID: ENC[AES256_GCM,data:bi/0BL4yJo64Ya4tFmyjjfxcSgM=,iv:WfaYaVCMvq4MlUY3AHyyd5UyVngLX8qjC4WDJyStGhg=,tag:6Rk/Qsf5cfSbZm0be4V1wA==,type:str]
|
||||
AWS_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:jfCGidFYWH45ilkGvViGLQ8ZXDTMCKaH93DtbtEwITGlEUuMYNZIxA==,iv:2kNo+aj7m9rCaovgXoIbiTQFgUux9L4LsQLH+GHGLaA=,tag:m+qNg1DHuNfaakYdMB4QpQ==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmMEhOUTJMcUYvNFozRDNr
|
||||
WnhJTEYzVWN4V1VXemhtWWU1SmMvUmljNFFNCk91aHhXRVBDSzhhcjIzalQ5SEpN
|
||||
cTJIOGVVYWNYRGdtMm5nZUZ5Q0EzTE0KLS0tIFRMYnNGakdrSktjT2ZoNk1sN21C
|
||||
YlhlTVhRdDFJUVZiMTdtVXlveWNDWE0KG7MKLp5tUCm7KpuhpmsvAWDrreBuHSEp
|
||||
zyH6hY1i7jgjh020qZI32zNDHeTIJhi+mHur/jvBJhEGLMz6JYUPrg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2022-12-29T07:38:56Z"
|
||||
mac: ENC[AES256_GCM,data:1tbBSKSUY1PFKcoQshI/6mv1KUV3b/K/BGALgNNDunjc4PRVBOMbZI6Aa4MWk0ElN7NB9Y6nO+Gv+i6sTet4peRMEBnfoWTSRjImYMiyt+aQ2XjMfI/ZEtOBgv8VFmSQr68Mkgp1zDLiD8lCwewE1nqoUg82jQNzy/bFUYcvIfY=,iv:IKd7yXgBfZBJX7yKH6HzlETA7WBvJrmsWNpO+ZZsElA=,tag:5R05VsD8CPHu8PX+MLXuJw==,type:str]
|
||||
pgp: []
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
version: 3.7.3
|
23
kubernetes/apps/default/opnsense/ks.yaml
Normal file
23
kubernetes/apps/default/opnsense/ks.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/kustomization_v1beta2.json
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: cluster-apps-opnsense
|
||||
namespace: flux-system
|
||||
labels:
|
||||
substitution.flux.home.arpa/enabled: "true"
|
||||
spec:
|
||||
path: ./kubernetes/apps/default/opnsense/app
|
||||
prune: true
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: home-ops-kubernetes
|
||||
healthChecks:
|
||||
- apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
name: opnsense-backup
|
||||
namespace: default
|
||||
interval: 30m
|
||||
retryInterval: 1m
|
||||
timeout: 3m
|
65
kubernetes/apps/default/opnsense/readme.md
Normal file
65
kubernetes/apps/default/opnsense/readme.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Opnsense
|
||||
|
||||
## S3 Configuration
|
||||
|
||||
1. Create `~/.mc/config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "10",
|
||||
"aliases": {
|
||||
"minio": {
|
||||
"url": "https://s3.<domain>",
|
||||
"accessKey": "<access-key>",
|
||||
"secretKey": "<secret-key>",
|
||||
"api": "S3v4",
|
||||
"path": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Create the opnsense user and password
|
||||
|
||||
```sh
|
||||
mc admin user add minio opnsense <super-secret-password>
|
||||
```
|
||||
|
||||
3. Create the opnsense bucket
|
||||
|
||||
```sh
|
||||
mc mb minio/opnsense
|
||||
```
|
||||
|
||||
4. Create `opnsense-user-policy.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"s3:ListBucket",
|
||||
"s3:PutObject",
|
||||
"s3:GetObject",
|
||||
"s3:DeleteObject"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Resource": ["arn:aws:s3:::opnsense/*", "arn:aws:s3:::opnsense"],
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
5. Apply the bucket policies
|
||||
|
||||
```sh
|
||||
mc admin policy add minio opnsense-private opnsense-user-policy.json
|
||||
```
|
||||
|
||||
6. Associate private policy with the user
|
||||
|
||||
```sh
|
||||
mc admin policy set minio opnsense-private user=opnsense
|
||||
```
|
Reference in New Issue
Block a user