Elvith Ma'for

Former Reddfugee, found a new home on feddit.de. Server errors made me switch to discuss.tchncs.de. Now finally @ home on feddit.org.

Likes music, tech, programming, board games and video games. Oh… and coffee, lots of coffee!

I � Unicode!

  • 1 Post
  • 83 Comments
Joined 2 years ago
cake
Cake day: June 21st, 2024

help-circle

  • No, that’s just another hypothetical app that you’re using a reverse proxy for. I just included it to show how you can also set settings for a single subdomain/reverse proxy entry that isn’t used globally on all domains that get served. I used a hypothetical REST API that needs a CORS Header that other apps don’t need (or maybe serve themselves).

    admin off disables Caddy’s admin interface (which shouldn’t be public and if you’re using config files this usually isn’t needed. So just a bit of gardening)

    servers sets some general server options.

    and then I just inserted several blocks that each define a reverse proxy to a different app / backend to show that you can just dump them all in a single Caddyfile. And the last example to show that you can set specific settings only for a specific subdomain instead of globally. As I set headers mostly used by REST APIs, I just called that api.example.com instead of app3.example.com.


  • If you like, I can send you an example of the Caddyfiles, that I’m using (I used the import directive to split every service into its own Caddyfiles, you could just copy and paste everything in the same file). It will take a few hours until I get home, though.

    But basically you can just put every subdomain and it’s target in a separate block and the add some things globally (e.g. passing the original IP, switching off the admin API of Caddy,…)

    Something like this should work:

    
    admin off 
    
    servers {
    		client_ip_headers X-Forwarded-For X-Real-IP
    }
    
    app.example.com {
        reverse_proxy 127.0.0.1:8080
    }
    
    app2.example.com {
        reverse_proxy 127.0.0.1:8081
    }
    
    api.example.com {
        reverse_proxy 127.0.0.1:8082
        header {
            Access-Control-Allow-Methods "GET, OPTIONS"
            Access-Control-Allow-Origin "*"
        }
    }
    

  • Yeah, that’s exactly why I didn’t use my own CA. There’s a plethora of devices that you now need to import the CA to and then you need to hope, that every application uses the system cert store and doesn’t roll its own (IIRC e.g. Firefox uses its own cert store and doesn’t use the system cert store. Same for every java based application,…)

    It’s fiddly with Caddy, as you need a specific plugin to get it to work with anything else than the default challenge. That means using a custom build via caddy - and with docker, you’re SOL. BUT you can just use certbot and point caddy to the cert file in your file system.


  • I have this setup. I bought a domain (say homeserver.tld) from a registrar that allows zone edits with an API. Then I use certbot with a plugin that supports my registrar to get real Let’s Encrypt certificates. Usually Let’s encrypt connects to your server to ensure that it responds to the domain you’re requesting a certificate for, but this challenge can also be done by editing the DNS record of your domain to prove ownership. That is called DNS-01 challenge and is useful of your domain is not publicly reachable. Google for certbot DNS-01 your registrar to find some documentation.

    Some of the VMs/LXC now get certificates for a specific subdomain (“some-app.homeserver.tld”), other just get a wildcard certificate (“*.homeserver.tld”) - e.g. my docker host.










  • Townsfolk: “No one dares to go even near these woods. Even $WellKnownHighlevelLegendaryHero found his end there!”

    Tavern: “Keep away from the woods to the east!”

    City guards (obviously more experienced and way higher level than the group): “We’ve lost so many troops around there, no one goes there in that wishes to live on.”

    “Everyday there are funerals on the towns cemetery - concerning part is, that that only happens on the northern cemetery, where people from the eastern fields near the woods are buried.”

    “The east gate of the town is closed. Only the grave diggers may use it to deliver new corpses of adventurous groups and heroes like you”

    “You look weaker than the other bunch who dare to come here. Are you suicidal or …?”

    “You have the feeling that something’s a bit unusual here. Everyone is armed, even the children.”

    “You begin to notice the fine gear and the muscular shape of the bloody, dismembered dead bodies constantly arriving at the east gate.”

    “On your way east toward the forest you pass many warning signs, each one getting drastically more graphic that the ones before…”

    “You arrive at the edge of the wood, eager to enter. Your game master breaks the fourth wall and directly asks you bluntly ‘Are you sure you want to do that?’ and hands you some dice…”






  • ##############################
    # ALL YE WHO ENTER HERE BE WARNED  
    # THIS ISN'T MY FAULT, BUT $TOOL ONLY 
    # ALLOWS THIS DIRTY WORKAROUND
    #
    # DO NOT CHANGE OR REFACTOR
    # ANYTHING.
    # 
    # IF YOU NEED TO TOUCH THIS CODE
    # INCREMENT THIS COUNTER AS A
    # WARNING FOR THE NEXT POOR FUCK
    # 
    # TOTAL HOURS WASTED DEBUGGING
    # 15
    # TOTAL HOURS WASTED REFACTORING
    # 8
    # SUCCESSFUL CHANGES
    # 0
    ##############################
    

  • For me it was usually that the config that I need to serve a site with TLS is quite short, there are sensible defaults and many things (e.g. websockets) just work without further declaration. That’s especially important if you want to host a container that has some lacking documentation about usage of reverse proxies, as most things “just work fine” for me.

    And using a simple include directive, you can even replicate ‘sites-available’ and ‘sites-enabled’ behaviour. My standard Caddyfile just sets up the log file format and location and basic Let Encrypt values. Then it includes /foo/bar/sites-available/*. Every deployment/container now has its own Caddyfile that just gets linked there.