# ============================================================================== # EXAMPLE: Multiple Plugins Combined for Kubernetes # ============================================================================== # # WHAT THIS DEMONSTRATES: # - Using multiple security plugins together # - Different plugin combinations for different services # - Layered security approach in Kubernetes # - Three services with different security profiles: # 1. Public website: Cloudflare + path blocking # 2. Protected API: JWT validation + path blocking # 3. Admin panel: Strict IP whitelist # # REQUIREMENTS (run these first): # ```bash # # 1. Ensure EasyHAProxy is installed in your cluster # kubectl create namespace easyhaproxy # kubectl apply -f https://raw.githubusercontent.com/byjg/docker-easy-haproxy/4.6.0/deploy/kubernetes/easyhaproxy-daemonset.yml # # # 2. Generate JWT keys (idempotent - skips if exists) # [ -f jwt_private.pem ] || openssl genrsa -out jwt_private.pem 2048 # [ -f jwt_pubkey.pem ] || openssl rsa -in jwt_private.pem -pubout -out jwt_pubkey.pem # kubectl create configmap jwt-keys --from-file=api_pubkey.pem=jwt_pubkey.pem # # # 3. Download Cloudflare IPs # curl -s https://www.cloudflare.com/ips-v4 > cloudflare_ips.lst # curl -s https://www.cloudflare.com/ips-v6 >> cloudflare_ips.lst # kubectl create configmap cloudflare-ips \ # --from-file=cloudflare_ips.lst=cloudflare_ips.lst \ # -n easyhaproxy # # # 4. Mount ConfigMaps in EasyHAProxy deployment # # (See individual plugin examples for mount configuration) # ``` # # HOW TO START: # ```bash # kubectl apply -f plugins-combined.yml # ``` # # HOW TO VERIFY IT'S WORKING: # ```bash # # Check all resources are created # kubectl get deployment,service,ingress # # # Test public website (Cloudflare + path blocking) # kubectl port-forward -n easyhaproxy deployment/easyhaproxy 8080:80 # curl -H "Host: website.example.local" http://localhost:8080 # # Expected: 200 OK with "Public Website" # curl -H "Host: website.example.local" http://localhost:8080/admin # # Expected: HTTP 404 - Path blocked # # # Test protected API (JWT required) # curl -H "Host: api.example.local" http://localhost:8080 # # Expected: HTTP 403 - Missing Authorization header # # # Test admin panel (IP whitelist) # curl -H "Host: admin.example.local" http://localhost:8080 # # Expected: 200 OK from allowed IP, or HTTP 403 from blocked IP # ``` # # CLEAN UP: # ```bash # kubectl delete -f plugins-combined.yml # ``` # # ============================================================================== --- # Public website service apiVersion: v1 kind: Service metadata: name: website-service namespace: default spec: ports: - port: 8080 selector: app: website type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: website namespace: default spec: replicas: 3 selector: matchLabels: app: website template: metadata: labels: app: website spec: containers: - name: website image: byjg/static-httpserver env: - name: TITLE value: "Public Website" resources: requests: cpu: '0.05' memory: '32Mi' --- # Public website ingress with Cloudflare + path blocking apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: easyhaproxy-ingress # Cloudflare IP restoration + deny pages easyhaproxy.plugins: "cloudflare,deny_pages" easyhaproxy.plugin.deny_pages.paths: "/admin,/wp-admin,/wp-login.php,/.env,/config" easyhaproxy.plugin.deny_pages.status_code: "404" name: website-ingress namespace: default spec: rules: - host: website.example.local http: paths: - backend: service: name: website-service port: number: 8080 pathType: ImplementationSpecific --- # API service apiVersion: v1 kind: Service metadata: name: api-service namespace: default spec: ports: - port: 8080 selector: app: api type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: api namespace: default spec: replicas: 5 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: byjg/static-httpserver env: - name: TITLE value: "Protected API" resources: requests: cpu: '0.05' memory: '32Mi' --- # API ingress with JWT + path blocking apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: easyhaproxy-ingress # JWT validation + block internal endpoints easyhaproxy.plugins: "jwt_validator,deny_pages" # JWT config easyhaproxy.plugin.jwt_validator.algorithm: "RS256" easyhaproxy.plugin.jwt_validator.issuer: "https://auth.example.com/" easyhaproxy.plugin.jwt_validator.audience: "https://api.example.com" easyhaproxy.plugin.jwt_validator.pubkey_path: "/etc/haproxy/jwt_keys/api_pubkey.pem" # Block internal paths easyhaproxy.plugin.deny_pages.paths: "/internal,/debug,/metrics" easyhaproxy.plugin.deny_pages.status_code: "403" name: api-ingress namespace: default spec: rules: - host: api.example.local http: paths: - backend: service: name: api-service port: number: 8080 pathType: ImplementationSpecific --- # Admin service apiVersion: v1 kind: Service metadata: name: admin-service namespace: default spec: ports: - port: 8080 selector: app: admin type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: admin namespace: default spec: replicas: 2 selector: matchLabels: app: admin template: metadata: labels: app: admin spec: containers: - name: admin image: byjg/static-httpserver env: - name: TITLE value: "Admin Panel" resources: requests: cpu: '0.05' memory: '32Mi' --- # Admin ingress with strict IP whitelist apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: easyhaproxy-ingress # IP whitelist only (strictest security) easyhaproxy.plugins: "ip_whitelist" # UPDATE with your office/VPN IPs! easyhaproxy.plugin.ip_whitelist.allowed_ips: "203.0.113.0/24,10.0.0.0/8" easyhaproxy.plugin.ip_whitelist.status_code: "403" name: admin-ingress namespace: default spec: rules: - host: admin.example.local http: paths: - backend: service: name: admin-service port: number: 8080 pathType: ImplementationSpecific