• Tim Rice's avatar
    Add pool tokens so a backend can tell the fleet from anybody else · a8a0017c
    Tim Rice authored
    An app server sits on a port and anything that can reach that port looks exactly
    like nginx does to it.  A pool token closes that.  nginx puts a shared secret on
    every request it proxies to the pool, the backend checks it, and a scanner that
    finds port 8080 gets a 403 instead of your application.
    
    The header is set rather than added, so a client sending that header itself has
    it replaced on the way through and cannot forge its way in.  It is hidden on the
    way back in case the backend echoes it.
    
    The health checker sends the token too.  Without that, the moment a backend
    started enforcing it every check would come back 403, and the manager would mark
    a perfectly healthy pool down and pull it out of service.
    
    Rotation is deliberately two steps.  nginx can only send one value and you
    cannot change both ends at once, so a single swap would 403 every request in the
    gap.  Rotate stages a new token while nginx keeps sending the old one, you teach
    the backends to accept either, then Activate flips it.  The old value is kept
    afterwards so you know what to go and delete.
    
    Supplied tokens are held to a plain charset rather than a blocklist.  A
    semicolon in a value that gets written into an nginx directive ends the
    directive early and turns the rest into config.  The renderer already refused
    those, but by then one bad field breaks the whole fleet's apply, so it is caught
    at the API instead.
    
    Secrets are encrypted at rest and only sent to the browser when somebody presses
    Show, so they are not sitting in the HTML of every pool page.  A token that
    cannot be decrypted renders no header at all, which fails closed.
    
    Also adds diagrams to the README showing how two or more servers work together,
    because "does this need to go on every box" was not answered anywhere.  It does,
    on every nginx server, and not on the backends.
    a8a0017c
This project is licensed under the MIT License. Learn more