417 lines
12 KiB
YAML
417 lines
12 KiB
YAML
---
|
|
# PrivateBin - Zero-knowledge pastebin
|
|
# Domain: privatebin.dooplex.hu
|
|
# Authentication: Authentik proxy for POST (create), public GET (read)
|
|
# Version: 2.0.3
|
|
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: privatebin-data
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
recurring-job-group.longhorn.io/default: enabled
|
|
recurring-job.longhorn.io/source: enabled
|
|
annotations:
|
|
argocd.argoproj.io/sync-options: Prune=false
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
storageClassName: longhorn
|
|
resources:
|
|
requests:
|
|
storage: 2Gi
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: privatebin-configs
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
data:
|
|
conf.php: |
|
|
;<?php http_response_code(403); /*
|
|
; PrivateBin configuration
|
|
; https://github.com/PrivateBin/PrivateBin/wiki/Configuration
|
|
|
|
[main]
|
|
; Project name displayed on the website
|
|
name = "Dooplex Paste"
|
|
|
|
; Base path for OpenGraph/social media previews
|
|
basepath = "https://privatebin.dooplex.hu/"
|
|
|
|
; Enable discussion/comments feature
|
|
discussion = true
|
|
|
|
; Don't preselect discussion by default
|
|
opendiscussion = false
|
|
|
|
; Enable password protection option
|
|
password = true
|
|
|
|
; Allow file uploads (attached files)
|
|
fileupload = true
|
|
|
|
; Don't preselect burn after reading
|
|
burnafterreadingselected = false
|
|
|
|
; Default text formatter
|
|
defaultformatter = "syntaxhighlighting"
|
|
|
|
; Syntax highlighting theme (empty = default)
|
|
syntaxhighlightingtheme = "sons-of-obsidian"
|
|
|
|
; Maximum paste size (10 MB)
|
|
sizelimit = 10485760
|
|
|
|
; Use Bootstrap 5 template (dark mode)
|
|
template = "bootstrap-dark"
|
|
|
|
; Enable QR code generation for paste URLs
|
|
qrcode = true
|
|
|
|
; Enable email sharing button
|
|
email = true
|
|
|
|
; Icon style (identicon/jdenticon/vizhash/none)
|
|
icon = "jdenticon"
|
|
|
|
; Custom notice (optional)
|
|
; notice = "Note: Pastes may be deleted after expiration."
|
|
|
|
; Compression algorithm (zlib/none)
|
|
compression = "zlib"
|
|
|
|
[expire]
|
|
; Default expiration time
|
|
default = "1week"
|
|
|
|
[expire_options]
|
|
; Available expiration options
|
|
5min = 300
|
|
10min = 600
|
|
1hour = 3600
|
|
1day = 86400
|
|
1week = 604800
|
|
1month = 2592000
|
|
1year = 31536000
|
|
never = 0
|
|
|
|
[formatter_options]
|
|
; Available formatters
|
|
plaintext = "Plain Text"
|
|
syntaxhighlighting = "Source Code"
|
|
markdown = "Markdown"
|
|
|
|
[traffic]
|
|
; Rate limiting - 10 seconds between paste creations per IP
|
|
limit = 10
|
|
|
|
; Exempted IPs from rate limiting (internal networks)
|
|
exempted = "10.42.0.0/16,10.43.0.0/16"
|
|
|
|
; Traffic limit in bytes (0 = no limit)
|
|
; creators = 0
|
|
|
|
[purge]
|
|
; Purge expired pastes probability (1 in X requests)
|
|
limit = 300
|
|
|
|
; Maximum items to delete per purge
|
|
batchsize = 10
|
|
|
|
[model]
|
|
; Use filesystem storage
|
|
class = Filesystem
|
|
|
|
[model_options]
|
|
; Data directory (mounted via PVC)
|
|
dir = PATH "data"
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: privatebin
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
app.kubernetes.io/version: "2.0.3"
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
app.kubernetes.io/version: "2.0.3"
|
|
spec:
|
|
automountServiceAccountToken: false
|
|
securityContext:
|
|
runAsUser: 65534
|
|
runAsGroup: 82
|
|
fsGroup: 82
|
|
containers:
|
|
- name: privatebin
|
|
image: privatebin/nginx-fpm-alpine:2.0.3
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- name: http
|
|
containerPort: 8080
|
|
protocol: TCP
|
|
securityContext:
|
|
readOnlyRootFilesystem: true
|
|
privileged: false
|
|
allowPrivilegeEscalation: false
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: http
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 64Mi
|
|
limits:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
volumeMounts:
|
|
- name: configs
|
|
mountPath: /srv/cfg
|
|
- name: data
|
|
mountPath: /srv/data
|
|
- name: run
|
|
mountPath: /run
|
|
- name: tmp
|
|
mountPath: /tmp
|
|
- name: nginx-cache
|
|
mountPath: /var/lib/nginx/tmp
|
|
volumes:
|
|
- name: configs
|
|
configMap:
|
|
name: privatebin-configs
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: privatebin-data
|
|
- name: run
|
|
emptyDir:
|
|
medium: Memory
|
|
- name: tmp
|
|
emptyDir:
|
|
medium: Memory
|
|
- name: nginx-cache
|
|
emptyDir: {}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: privatebin
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
spec:
|
|
type: ClusterIP
|
|
ports:
|
|
- name: http
|
|
port: 80
|
|
targetPort: http
|
|
protocol: TCP
|
|
selector:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
---
|
|
# =============================================================================
|
|
# INGRESS CONFIGURATION
|
|
# =============================================================================
|
|
#
|
|
# OPTION 1 (Current): Public access on both domains
|
|
# - privatebin.dooplex.hu - public HTTPS access
|
|
# - privatebin.home - internal access
|
|
#
|
|
# OPTION 2: Authenticated writes, public reads
|
|
# This requires Authentik configuration (see instructions below).
|
|
# Comment out the public ingress and uncomment the authenticated one.
|
|
#
|
|
# =============================================================================
|
|
|
|
# PUBLIC INGRESS - No authentication required
|
|
# Anyone can create and view pastes
|
|
#apiVersion: networking.k8s.io/v1
|
|
#kind: Ingress
|
|
#metadata:
|
|
# name: privatebin
|
|
# namespace: privatebin-system
|
|
# labels:
|
|
# app.kubernetes.io/name: privatebin
|
|
# app.kubernetes.io/instance: privatebin
|
|
# annotations:
|
|
# cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
# external-dns.alpha.kubernetes.io/hostname: privatebin.home,privatebin.dooplex.hu
|
|
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
# nginx.ingress.kubernetes.io/proxy-body-size: "12m"
|
|
#spec:
|
|
# ingressClassName: nginx-internal
|
|
# tls:
|
|
# - hosts:
|
|
# - privatebin.dooplex.hu
|
|
# secretName: privatebin-tls
|
|
# rules:
|
|
# - host: privatebin.dooplex.hu
|
|
# http:
|
|
# paths:
|
|
# - path: /
|
|
# pathType: Prefix
|
|
# backend:
|
|
# service:
|
|
# name: privatebin
|
|
# port:
|
|
# number: 80
|
|
# - host: privatebin.home
|
|
# http:
|
|
# paths:
|
|
# - path: /
|
|
# pathType: Prefix
|
|
# backend:
|
|
# service:
|
|
# name: privatebin
|
|
# port:
|
|
# number: 80
|
|
#
|
|
# =============================================================================
|
|
# AUTHENTICATED INGRESS (Optional)
|
|
# =============================================================================
|
|
# To enable authentication for creating pastes while keeping viewing public,
|
|
# follow these steps:
|
|
#
|
|
# 1. AUTHENTIK SETUP:
|
|
# a) Create Application:
|
|
# - Name: PrivateBin
|
|
# - Slug: privatebin
|
|
# - Provider: (create new proxy provider below)
|
|
#
|
|
# b) Create Proxy Provider:
|
|
# - Name: privatebin-provider
|
|
# - Authorization flow: default-provider-authorization-implicit-consent
|
|
# - Mode: Forward auth (single application)
|
|
# - External host: https://privatebin.dooplex.hu
|
|
#
|
|
# c) Create Expression Policy for conditional auth:
|
|
# - Name: privatebin-method-check
|
|
# - Expression:
|
|
# # GET/HEAD requests pass through without requiring login
|
|
# # POST requests require authentication
|
|
# if request.http_request.method in ["GET", "HEAD", "OPTIONS"]:
|
|
# # Pass the policy - but note: user may still not be authenticated
|
|
# # The key is setting "Unauthenticated URLs" below
|
|
# return True
|
|
# # For POST/PUT/DELETE, require the user to be authenticated
|
|
# if request.user.is_authenticated:
|
|
# return True
|
|
# return False
|
|
#
|
|
# d) Configure Provider settings:
|
|
# - Unauthenticated URLs: ^https://privatebin\.dooplex\.hu/\?[a-f0-9]+.*$
|
|
# (This regex matches paste view URLs)
|
|
# - Or simpler: Check "Intercept header authentication" in advanced settings
|
|
# and handle auth at ingress level
|
|
#
|
|
# e) Create/Update Outpost:
|
|
# - Name: privatebin-outpost
|
|
# - Type: Proxy
|
|
# - Add the PrivateBin application
|
|
#
|
|
# 2. UPDATE INGRESS:
|
|
# Comment out the public ingress above and uncomment this one:
|
|
#
|
|
---
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: privatebin
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
annotations:
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
external-dns.alpha.kubernetes.io/hostname: privatebin.home,privatebin.dooplex.hu
|
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "12m"
|
|
nginx.ingress.kubernetes.io/auth-url: http://ak-outpost-privatebin-outpost.auth-system.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx
|
|
nginx.ingress.kubernetes.io/auth-signin: https://privatebin.dooplex.hu/outpost.goauthentik.io/start?rd=$escaped_request_uri
|
|
nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email
|
|
nginx.ingress.kubernetes.io/auth-snippet: |
|
|
proxy_set_header X-Forwarded-Host $http_host;
|
|
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
|
|
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
|
|
nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "32k"
|
|
spec:
|
|
ingressClassName: nginx-internal
|
|
tls:
|
|
- hosts:
|
|
- privatebin.dooplex.hu
|
|
secretName: privatebin-tls
|
|
rules:
|
|
- host: privatebin.dooplex.hu
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: privatebin
|
|
port:
|
|
number: 80
|
|
- host: privatebin.home
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: privatebin
|
|
port:
|
|
number: 80
|
|
#
|
|
# 3. ALTERNATIVE: Use existing outpost
|
|
# If you want to use an existing outpost (like arr-outpost),
|
|
# just add privatebin.dooplex.hu to that outpost's applications
|
|
# and update the auth-url to point to that outpost.
|
|
---
|
|
# ServiceAccount (minimal, not needed but good practice)
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: privatebin
|
|
namespace: privatebin-system
|
|
labels:
|
|
app.kubernetes.io/name: privatebin
|
|
app.kubernetes.io/instance: privatebin
|
|
automountServiceAccountToken: false
|