diff --git a/pangolin/compose.yml b/pangolin/compose.yml new file mode 100644 index 0000000..8651567 --- /dev/null +++ b/pangolin/compose.yml @@ -0,0 +1,89 @@ +name: pangolin +networks: + default: + driver: bridge + name: pangolin +services: + crowdsec: + command: -t + container_name: crowdsec + environment: + ACQUIRE_FILES: /var/log/traefik/*.log + COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules + ENROLL_INSTANCE_NAME: pangolin-crowdsec + ENROLL_TAGS: docker + GID: "1000" + PARSERS: crowdsecurity/whitelists + expose: + - 6060 + healthcheck: + test: + - CMD + - cscli + - capi + - status + image: crowdsecurity/crowdsec:latest + labels: + - traefik.enable=false + ports: + - 6060:6060 + restart: unless-stopped + volumes: + - ./config/crowdsec:/etc/crowdsec + - ./config/crowdsec/db:/var/lib/crowdsec/data + - ./config/crowdsec_logs/auth.log:/var/log/auth.log:ro + - ./config/crowdsec_logs/syslog:/var/log/syslog:ro + - ./config/crowdsec_logs:/var/log + - ./config/traefik/logs:/var/log/traefik + gerbil: + cap_add: + - NET_ADMIN + - SYS_MODULE + command: + - --reachableAt=http://gerbil:3003 + - --generateAndSaveKeyTo=/var/config/key + - --remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config + - --reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth + container_name: gerbil + depends_on: + pangolin: + condition: service_healthy + image: fosrl/gerbil:1.0.0 + ports: + - 51820:51820/udp + - 443:443 + - 80:80 + restart: unless-stopped + volumes: + - ./config/:/var/config + pangolin: + container_name: pangolin + healthcheck: + interval: 3s + retries: 5 + test: + - CMD + - curl + - -f + - http://localhost:3001/api/v1/ + timeout: 3s + image: fosrl/pangolin:1.0.1 + restart: unless-stopped + volumes: + - ./config:/app/config + traefik: + command: + - --configFile=/etc/traefik/traefik_config.yml + container_name: traefik + depends_on: + pangolin: + condition: service_healthy + image: traefik:v3.3.3 + network_mode: service:gerbil + restart: unless-stopped + volumes: + - ./config/traefik:/etc/traefik:ro + - ./config/letsencrypt:/letsencrypt + - ./config/traefik/logs:/var/log/traefik + environment: + CLOUDFLARE_DNS_API_TOKEN: "lgd9u7SjT9QOfyMt4ungbiQXHAwhM7zd_4peNdsY" diff --git a/pangolin/config/config.yml b/pangolin/config/config.yml new file mode 100644 index 0000000..08b492e --- /dev/null +++ b/pangolin/config/config.yml @@ -0,0 +1,66 @@ +# To see all available options, please visit the docs: +# https://docs.fossorial.io/Pangolin/Configuration/config + +app: + dashboard_url: "https://pangolin.akanealw2.com" + log_level: "info" + save_logs: false + +domains: + domain1: + base_domain: "akanealw2.com" + cert_resolver: "letsencrypt" + domain2: + base_domain: "akanealw3.com" + cert_resolver: "letsencrypt" + +server: + external_port: 3000 + internal_port: 3001 + next_port: 3002 + internal_hostname: "pangolin" + session_cookie_name: "p_session_token" + resource_access_token_param: "p_token" + resource_session_request_param: "p_session_request" + cors: + origins: ["https://pangolin.akanealw2.com"] + methods: ["GET", "POST", "PUT", "DELETE", "PATCH"] + headers: ["X-CSRF-Token", "Content-Type"] + credentials: false + +traefik: + cert_resolver: "letsencrypt" + http_entrypoint: "web" + https_entrypoint: "websecure" + +gerbil: + start_port: 51820 + base_endpoint: "pangolin.akanealw2.com" + use_subdomain: false + block_size: 24 + site_block_size: 30 + subnet_group: 100.89.137.0/20 + +rate_limits: + global: + window_minutes: 1 + max_requests: 100 + +email: + smtp_host: "smtp.gmail.com" + smtp_port: 587 + smtp_user: "akanealw@gmail.com" + smtp_pass: "jlkjlkj;lj;lkj;lkj;kl" + no_reply: "akanealw@gmail.com" + +users: + server_admin: + email: "akanealw@gmail.com" + password: "Nealiscool#1" + +flags: + require_email_verification: true + disable_signup_without_invite: true + disable_user_create_org: false + allow_raw_resources: true + allow_base_domain_resources: true diff --git a/pangolin/config/traefik/dynamic_config.yml b/pangolin/config/traefik/dynamic_config.yml new file mode 100644 index 0000000..b517935 --- /dev/null +++ b/pangolin/config/traefik/dynamic_config.yml @@ -0,0 +1,100 @@ +http: + middlewares: + crowdsec: + plugin: + crowdsec: + clientTrustedIPs: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + - 100.89.137.0/20 + crowdsecAppsecEnabled: true + crowdsecAppsecFailureBlock: true + crowdsecAppsecHost: crowdsec:7422 + crowdsecAppsecUnreachableBlock: true + crowdsecLapiHost: crowdsec:8080 + crowdsecLapiKey: h+aTfhMBZ6DY5KLhOVncD2H+7K6izYCBi6I6WTYk/D8 + crowdsecLapiScheme: http + crowdsecMode: live + defaultDecisionSeconds: 15 + enabled: true + forwardedHeadersTrustedIPs: + - 0.0.0.0/0 + httpTimeoutSeconds: 10 + logLevel: INFO + updateIntervalSeconds: 15 + updateMaxFailure: 0 + default-whitelist: + ipWhiteList: + sourceRange: + - 10.0.0.0/8 + - 192.168.0.0/16 + - 172.16.0.0/12 + redirect-to-https: + redirectScheme: + scheme: https + security-headers: + headers: + contentTypeNosniff: true + customFrameOptionsValue: SAMEORIGIN + customResponseHeaders: + Server: "" + X-Forwarded-Proto: https + X-Powered-By: "" + forceSTSHeader: true + hostsProxyHeaders: + - X-Forwarded-Host + referrerPolicy: strict-origin-when-cross-origin + sslProxyHeaders: + X-Forwarded-Proto: https + stsIncludeSubdomains: true + stsPreload: true + stsSeconds: 63072000 + routers: + api-router: + entryPoints: + - websecure + middlewares: + - security-headers + rule: Host(`pangolin.akanealw2.com`) && PathPrefix(`/api/v1`) + service: api-service + tls: + certResolver: letsencrypt + main-app-router-redirect: + entryPoints: + - web + middlewares: + - redirect-to-https + rule: Host(`pangolin.akanealw2.com`) + service: next-service + next-router: + entryPoints: + - websecure + middlewares: + - security-headers + rule: Host(`pangolin.akanealw2.com`) && !PathPrefix(`/api/v1`) + service: next-service + tls: + certResolver: letsencrypt + domains: + - main: "akanealw2.com" + sans: + - "*.akanealw2.com" + ws-router: + entryPoints: + - websecure + middlewares: + - security-headers + rule: Host(`pangolin.akanealw2.com`) + service: api-service + tls: + certResolver: letsencrypt + services: + api-service: + loadBalancer: + servers: + - url: http://pangolin:3000 + next-service: + loadBalancer: + servers: + - url: http://pangolin:3002 diff --git a/pangolin/config/traefik/traefik_config.yml b/pangolin/config/traefik/traefik_config.yml new file mode 100644 index 0000000..68515d2 --- /dev/null +++ b/pangolin/config/traefik/traefik_config.yml @@ -0,0 +1,80 @@ +accessLog: + bufferingSize: 100 + fields: + defaultMode: drop + headers: + defaultMode: drop + names: + Authorization: redact + Content-Type: keep + Cookie: redact + User-Agent: keep + X-Forwarded-For: keep + X-Forwarded-Proto: keep + X-Real-Ip: keep + names: + ClientAddr: keep + ClientHost: keep + DownstreamContentSize: keep + DownstreamStatus: keep + Duration: keep + RequestMethod: keep + RequestPath: keep + RequestProtocol: keep + RetryAttempts: keep + ServiceName: keep + StartUTC: keep + TLSCipher: keep + TLSVersion: keep + filePath: /var/log/traefik/access.log + filters: + minDuration: 100ms + retryAttempts: true + statusCodes: + - 200-299 + - 400-499 + - 500-599 + format: json +api: + dashboard: true + insecure: true +certificatesResolvers: + letsencrypt: + acme: + dnsChallenge: + provider: "cloudflare" + caServer: https://acme-v02.api.letsencrypt.org/directory + email: akanealw@gmail.com + storage: /letsencrypt/acme.json +entryPoints: + web: + address: :80 + websecure: + address: :443 + http: + middlewares: + - crowdsec@file + tls: + certResolver: letsencrypt + transport: + respondingTimeouts: + readTimeout: 30m +experimental: + plugins: + badger: + moduleName: github.com/fosrl/badger + version: v1.0.0 + crowdsec: + moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin + version: v1.3.5 +log: + format: json + level: INFO +providers: + file: + filename: /etc/traefik/dynamic_config.yml + http: + endpoint: http://pangolin:3001/api/v1/traefik-config + pollInterval: 5s +serversTransport: + insecureSkipVerify: true