Proof of concept for a HTTP proxy that pushes rotating authentication tokens to an end point that is known to be under the control of legitimate requestors.
1. Overview
2. Proof-of-Concept Walkthrough
2.1 Requirements
2.2 Setup
2.3 Verifying Setup
2.4 Running the Walkthrough
2.5 Sequence Diagram for Second and Third Calls
3. Directions for Further Research
4. Motivation
5. References
This proof-of-concept creates two subnets connected by an Nginx proxy server. The Nginx proxy offloads authentication decisions to an auth server that pushes fresh tokens to an application on its published URL. The example client application on the untrusted subnet attempts to connect to a secure service on the secure network, and the demo walkthrough shows how the example client is primed with a stale token, and can then connect when it receives a fresh token sent by the auth server.
Docker (tested on v1.12.5 on OSX 10.12.2)
Vagrant (tested on 1.9.1 on OSX 10.12.2)
- Clone this repository to your local machine
- Open a terminal inside the root
tokenrotatorproxy
folder - Run
./start-all.sh
- Run
./start-alpine-curl-untrustednet.sh
(keep this Alpine terminal somewhere handy) - Open a new terminal and run
docker logs -f authserver
to watch activity on theauthserver
as requests are made. - Open a new terminal and run
docker logs -f exampleclient
to watch activity on theexampleclient
as requests are made.
- Clone the repository to your local machine
- Open a terminal inside the
tokenrotatorproxy
folder - Use Vagrant to launch the Docker host VM:
cd demobox
vagrant up
- Open a terminal on the Vagrant machine:
vagrant ssh
tmux
cd tokenrotatorproxy
- Proceed from Step 3 above.
- Open a web browser on http://localhost:8012 to verify the
exampleclient
is running:
- Open a web browser on http://localhost:8010 to verify the
authserver
is running:
- Open a web browser on http://localhost:8081 to verify the
testngx
proxy is running:
- Open a web browser on http://localhost:8011 to verify the
secureservice
is running:
NOTE: Even though secureservice
is accessible to the Docker host (your machine), it is not accessible to machines on the untrustednet
subnet. You can verify this by attempting to curl to the secureservice
from the Alpine terminal.
- We first make a call from
exampleclient
tosecureservice
viatestngx
proxy, without any tokens being present. We can do this by calling http://localhost:8012/secure - We note that the call quickly fails:
- We now 'prime the pump,' by sending a stale token from our Alpine terminal to the
exampleclient
container:
curl -X POST -F "Otpcode=abc123" "http://exampleclient/tokencatcher"
- We should see a result like the following in our terminal:
- If we are monitoring the logs for
exampleclient
, we will also see a message there:
- We now make another call from
exampleclient
tosecureservice
(http://localhost:8012/secure) - the call fails again, but we a get a different message:
- Behind the scenes, our
authserver
has posted a new token to the URL it holds for theexampleclient
application. Note that it does this via DNS. We can again see this in the logs for theexampleclient
container:
- We make a final call from
exampleclient
(http://localhost:8012/secure) - this time the call succeeds:
- And we can see that the token has been accepted in the logs for
authserver
also:
The sequence diagram below illustrates stages 2.4.2 and 2.4.3 in the walkthrough visually:
- The proxy in the PoC uses an external auth server for making authentication decisions. It may be much more performant to run the auth function on the same machine, perhaps using something like the Lua scripting capabilities of HA Proxy.
- How do we decide to expire a token? Strategies could include by time, and by usage. We could use a fixed count, or even a random count.
- The client in the PoC uses TinyDB as a trivial external data store, to allow for multiple instances to feed off the same pile of tokens. For a high volume system, we would need to think about things such as keeping the token pile at a certain depth, and perhaps giving grace periods on expiring tokens, so an application has enough time to receive new ones.
- The auth server in the PoC helpfully sends a new token when it thinks an application might need one. This could equally be a client request, so long as delivery is to a URL defined by the administrator, not provided by the client.
- The auth server would need a management component to assist in definition and maintenance of valid tokens and destination URLs.
- Can we build this PoC using an existing security framework such as OAuth 2.0? GSS?
- The PoC requires any external client to implement a REST endpoint (
/tokencatcher
) to receive new tokens on. Is there a way of hiding this from applications by using some kind of container plugin strategy?
A common requirement for container-based platforms is to be able to secure access to external resources by an inherence factor such as IP address as well as a knowledge factor such as a password (which might be shared with or stolen by an unauthorized entity).
Although it is possible to map applications in the container world back to IP addresses in the infrastructure world (e.g. Calico), it is not straightforward, and also it limits the velocity of the container platform to the speed of change in the world of firewalls and networks.
This proof-of-concept is based on the idea that although we can't rely on anything in the network packets we receive from an application to identify it, we know that the application is identified by the URL on which it receives information.
By configuring our authentication service to push transient tokens to an application's URL, we can therefore make the sharing of these tokens arbitrarily difficult, depending on the rate at which requests are made, and our strategy for token expiry.
Docker Nginx Image
https://hub.docker.com/_/nginx/
Nginx Proxy Pass Directive
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
Nginx http auth request module
https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
The Three R’s of Enterprise Security: Rotate, Repave, and Repair
https://medium.com/built-to-adapt/the-three-r-s-of-enterprise-security-rotate-repave-and-repair-f64f6d6ba29d#.bxjtdmav4