This project represents a simple demo of a reverse proxy. A reverse proxy is a server that accepts a request from a client, forwards the request to another one of many other servers, and returns the results from the server that actually processed the request to the client as if the proxy server had processed the request itself.
Some of the features this project have are:
- Inspecting and masking sensitive json data
- Logging all input and output traffic
- Block requests based on set of predefined rules
Proxy also adds header to your forwarded responses. X-Proxy-Error
which can be true
or false
. It signals internal proxy errors proxy-ing or inspecting the request.
This project features a json endpoint that allows easy testing of reverse proxy.
To run both proxy and the json endpoint all you need to do is docker compose up
- It will create a container of proxy listening on port
8000
- It will create a container of jsonendpoint listening on port
8001
- Proxy will load config.json file containing request blocking rules as well as config to which host and scheme to forward requests
- To test the proxy masking you can send a
GET
request to proxy
curl localhost:8000
- To test blocking you can send a
DELETE
request to proxy
curl -X POST localhost:8000
- To test forwarding request without masking send a
PUT
request
curl -X PUT localhost:8000
Whole project is comprehensively using interfaces in order to allow easy unit testing.
Due to that whole project is also unit tested. For some tests snapshoting library cupaloy was used. It generates snapshots in ./snapshots
dir.
To run tests
go test ./...
Proxy will forward requests to a host specified in config.json in field forward_host
It will use a scheme specified as forward_scheme
Default masking rules for PII (Personally identifiable information) are quite simple and if it were a real world project i would aim to use a more comprehensive set of detections instead of a couple of simple detections. They are located here and are easily extendible
As explained in top comment: If this was a real world user facing software i would use open policy agent rego, however my understanding of the task was that it was required to build some kind of rules mechanism myself.
Blocking rules are loaded from config.json block
field
Blocking rules are designed in a way that you can compose different rules in order to build different combinations of blocking rules.
For example if you want to block all delete or posts requests you use this blocking rules:
{
"forward_host": "jsonendpoint:8000",
"forward_scheme": "http",
"block": [
[
{
"method": "POST"
}
],
[
{
"method": "DELETE"
}
]
]
}
If on the other hand you would like to block all POST
requests that start with path /api
or any DELETE
request
{
"forward_host": "jsonendpoint:8000",
"forward_scheme": "http",
"block": [
[
{
"method": "POST"
},
{
"path": "/api"
}
],
[
{
"method": "DELETE"
}
]
]
}
First level of block property acts as OR
(||
) and second level acts as AND
(&&
) when matching
All guards used for blocks are located here
- Method block
{
"method": "DELETE"
}
- Path block
{
"path": "/api"
}
- Query Parameter block
{
"query_param": "userID"
"value": "userID"
}
- Header block
{
"header": "Content-Type"
"value": "text/html; charset=utf-8"
}