PunkProxy

This is the 5th iteration of PunkProxy and the first open source version.

PunkProxy was originally created because I had many web services running across multiple VMs. I was running out of public IP addresses and starting to hit Let's Encrypt rate limits. I needed a way to:

  • Use fewer public IP addresses
  • Consolidate TLS certificates to avoid rate limiting
  • 1 source of truth for edge of my http services
  • Pulling to get configs not pushing to nodes
  • No downtime reloads

PunkProxy v1 (2016–2018)

  • Built as an nginx Docker container
  • Used Python to generate all vhosts from a JSON file
  • Automatically issued TLS certificates using Certbot with the PowerDNS plugin

PunkProxy v2 (Prototype)

  • Based on OpenResty
  • Used a database to load vhosts
  • Loaded certificates from the file system
  • Controlled by an ASP.NET Core app:
    • Managed vhosts
    • Issued certificates

PunkProxy v3 (Prototype)

  • Similar to v2, but OpenResty was replaced with YARP (Yet Another Reverse Proxy)
  • This prototype was dropped due to technical limitations:
    • Wanted to add JA3 fingerprinting
    • Required access to the client hello packet, which meant modifying the .NET standard library
    • Didn’t want to maintain a fork of .NET

Side note I had created a tool to patch .NET DLLs at compile time instead of forking .NET, which became the POC for COSMOS Gen 3:


PunkProxy v4.8 (2018–2024)

  • Deployed across 2 VMs:
    • One running HAProxy
    • One running Certbot
  • Switched to HAProxy for simpler certificate management:
    • Used a text file listing certificate paths
    • HAProxy handled certificate loading automatically

PunkProxy v5 (Current)

View on GitLab

  • Rewritten in Go, including both the proxy and the control plane
  • Benefits:
    • Full freedom to edit, hook or make middleware for any of go
    • Able to make HTTP middleware to read the client hello packet and calculate the JA3 fingerprint
    • Easy integration with LEGO and its DNS providers (even if ill only be using PowerDNS)
  • Also served as a project to improve my Go skills