mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
BigchainDB Web Proxy to add headers to requests
Currently, the requests from public websites (like `bigchaindb.com/getstarted` and tutorials.bigchaindb.com/crab) cannot have the app_id and app_key required to access IPDB in the web page. We pass such requests through a web proxy that adds the required headers to any POST requests from `*.bigchaindb.com`.
This commit is contained in:
8
k8s/nginx-https-web-proxy/container/Dockerfile
Normal file
8
k8s/nginx-https-web-proxy/container/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM openresty/openresty:alpine
|
||||
RUN apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add bash
|
||||
COPY nginx.conf.template /etc/nginx/nginx.conf
|
||||
COPY nginx_entrypoint.bash /
|
||||
EXPOSE 443
|
||||
ENTRYPOINT ["/nginx_entrypoint.bash"]
|
||||
5
k8s/nginx-https-web-proxy/container/docker_build_and_push.bash
Executable file
5
k8s/nginx-https-web-proxy/container/docker_build_and_push.bash
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker build -t bigchaindb/nginx-https-web-proxy:0.10 .
|
||||
|
||||
docker push bigchaindb/nginx-https-web-proxy:0.10
|
||||
138
k8s/nginx-https-web-proxy/container/nginx.conf.template
Normal file
138
k8s/nginx-https-web-proxy/container/nginx.conf.template
Normal file
@@ -0,0 +1,138 @@
|
||||
# Frontend Proxy server that:
|
||||
# 1. Acts as the HTTPS proxy termination point.
|
||||
# 2. Forwards BDB POST requests to OpenResty backend after appending the app_id
|
||||
# and app_key headers.
|
||||
# 3. Forwards BDB GET requests to BDB backend.
|
||||
# 4. Does health check with LB.
|
||||
|
||||
worker_processes 4;
|
||||
daemon off;
|
||||
user nobody nogroup;
|
||||
pid /tmp/nginx.pid;
|
||||
error_log /dev/stderr;
|
||||
|
||||
events {
|
||||
# Each worker handles up to 1024 connections. Increase this for heavy
|
||||
# workloads.
|
||||
worker_connections 1024;
|
||||
accept_mutex on;
|
||||
use epoll;
|
||||
}
|
||||
|
||||
http {
|
||||
access_log /dev/stdout combined buffer=16k flush=5s;
|
||||
|
||||
# Allow 2048 req/sec from the same IP address, and store the counters in a
|
||||
# `zone` or shared memory location tagged as 'one'.
|
||||
limit_req_zone $binary_remote_addr zone=one:10m rate=2048r/s;
|
||||
|
||||
# Enable logging when requests are being throttled.
|
||||
limit_req_log_level notice;
|
||||
|
||||
# HTTP status code that is returned to the client; 429 is for TooManyRequests,
|
||||
# ref. RFC 6585
|
||||
limit_req_status 429;
|
||||
|
||||
# Limit requests from the same client, allow `burst` to 3072 r/s,
|
||||
# `nodelay` or drop connection immediately in case it exceeds this
|
||||
# threshold.
|
||||
limit_req zone=one burst=3072 nodelay;
|
||||
|
||||
# `slowloris` attack mitigation settings.
|
||||
client_body_timeout 30s;
|
||||
client_header_timeout 10s;
|
||||
|
||||
# DNS resolver to use for all the backend names specified in this configuration.
|
||||
resolver DNS_SERVER valid=30s ipv6=off;
|
||||
|
||||
keepalive_timeout 60s;
|
||||
|
||||
# The following map blocks enable lazy-binding to the backend at runtime,
|
||||
# rather than binding as soon as NGINX starts.
|
||||
map $remote_addr $bdb_backend {
|
||||
default BIGCHAINDB_BACKEND_HOST;
|
||||
}
|
||||
map $remote_addr $openresty_backend {
|
||||
default OPENRESTY_BACKEND_HOST;
|
||||
}
|
||||
|
||||
# Frontend server for the external clients; acts as HTTPS termination point.
|
||||
server {
|
||||
listen PROXY_FRONTEND_PORT ssl;
|
||||
server_name "PROXY_FQDN";
|
||||
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/cert.key;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
underscores_in_headers on;
|
||||
|
||||
# No websocket support for web proxy
|
||||
location /api/v1/streams/valid_transactions {
|
||||
return 403 'Websockets are not supported in the web proxy';
|
||||
}
|
||||
|
||||
# Forward other URL paths as per business logic/use case to BDB or
|
||||
# OpenResty instance.
|
||||
location / {
|
||||
proxy_ignore_client_abort on;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# max client request body size: avg transaction size.
|
||||
client_max_body_size 15k;
|
||||
|
||||
# Debug block for listing all the headers sent with the request
|
||||
header_filter_by_lua_block {
|
||||
local h = ngx.req.get_headers()
|
||||
for k, v in pairs(h) do
|
||||
ngx.log(ngx.ERR, "Header "..k..": "..v..";")
|
||||
end
|
||||
}
|
||||
|
||||
# check if the request originated from the required web page
|
||||
# use referer header.
|
||||
if ($http_referer !~ "PROXY_EXPECTED_REFERER_HEADER" ) {
|
||||
return 403 'Unknown referer';
|
||||
}
|
||||
|
||||
# check if the request has the expected origin header
|
||||
if ($http_origin !~ "PROXY_EXPECTED_ORIGIN_HEADER" ) {
|
||||
return 403 'Unknown origin';
|
||||
}
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,app_key,app_id';
|
||||
add_header 'Access-Control-Max-Age' 43200;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
# No auth for GETs, forward directly to BDB.
|
||||
if ($request_method = GET) {
|
||||
proxy_pass http://$bdb_backend:BIGCHAINDB_API_PORT;
|
||||
}
|
||||
|
||||
# POST requests get forwarded to OpenResty instance; set the correct
|
||||
# headers accordingly
|
||||
proxy_set_header app_id "PROXY_APP_ID";
|
||||
proxy_set_header app_key "PROXY_APP_KEY";
|
||||
if ($request_method = POST ) {
|
||||
proxy_pass http://$openresty_backend:OPENRESTY_BACKEND_PORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Frontend server for the load balancer to respond to health checks.
|
||||
server {
|
||||
listen HEALTH_CHECK_PORT;
|
||||
|
||||
location = /health {
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
74
k8s/nginx-https-web-proxy/container/nginx_entrypoint.bash
Executable file
74
k8s/nginx-https-web-proxy/container/nginx_entrypoint.bash
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Proxy vars
|
||||
proxy_fqdn=`printenv PROXY_FQDN`
|
||||
proxy_frontend_port=`printenv PROXY_FRONTEND_PORT`
|
||||
|
||||
proxy_app_id_file=/etc/nginx/proxy/credentials/app_id
|
||||
proxy_app_key_file=/etc/nginx/proxy/credentials/app_key
|
||||
proxy_app_id=`cat ${proxy_app_id_file}`
|
||||
proxy_app_key=`cat ${proxy_app_key_file}`
|
||||
|
||||
proxy_expected_referer_header=`printenv PROXY_EXPECTED_REFERER_HEADER`
|
||||
proxy_expected_origin_header=`printenv PROXY_EXPECTED_ORIGIN_HEADER`
|
||||
|
||||
# OpenResty vars
|
||||
openresty_backend_host=`printenv OPENRESTY_BACKEND_HOST`
|
||||
openresty_backend_port=`printenv OPENRESTY_BACKEND_PORT`
|
||||
|
||||
# NGINX vars
|
||||
dns_server=`printenv DNS_SERVER`
|
||||
health_check_port=`printenv HEALTH_CHECK_PORT`
|
||||
|
||||
# BigchainDB vars
|
||||
bdb_backend_host=`printenv BIGCHAINDB_BACKEND_HOST`
|
||||
bdb_api_port=`printenv BIGCHAINDB_API_PORT`
|
||||
|
||||
|
||||
# sanity check
|
||||
if [[ -z "${proxy_frontend_port:?PROXY_FRONTEND_PORT not specified. Exiting!}" || \
|
||||
-z "${openresty_backend_port:?OPENRESTY_BACKEND_PORT not specified. Exiting!}" || \
|
||||
-z "${openresty_backend_host:?OPENRESTY_BACKEND_HOST not specified. Exiting!}" || \
|
||||
-z "${bdb_backend_host:?BIGCHAINDB_BACKEND_HOST not specified. Exiting!}" || \
|
||||
-z "${bdb_api_port:?BIGCHAINDB_API_PORT not specified. Exiting!}" || \
|
||||
-z "${dns_server:?DNS_SERVER not specified. Exiting!}" || \
|
||||
-z "${health_check_port:?HEALTH_CHECK_PORT not specified. Exiting!}" || \
|
||||
-z "${proxy_app_id:?PROXY_APP_ID not specified. Exiting!}" || \
|
||||
-z "${proxy_app_key:?PROXY_APP_KEY not specified. Exiting!}" || \
|
||||
-z "${proxy_expected_referer_header:?PROXY_EXPECTED_REFERER_HEADER not specified. Exiting!}" || \
|
||||
-z "${proxy_expected_origin_header:?PROXY_EXPECTED_ORIGIN_HEADER not specified. Exiting!}" || \
|
||||
-z "${proxy_fqdn:?PROXY_FQDN not specified. Exiting!}" ]]; then
|
||||
exit 1
|
||||
else
|
||||
echo PROXY_FQDN="$proxy_fqdn"
|
||||
echo PROXY_FRONTEND_PORT="$proxy_frontend_port"
|
||||
echo PROXY_EXPECTED_REFERER_HEADER="$proxy_expected_referer_header"
|
||||
echo PROXY_EXPECTED_ORIGIN_HEADER="$proxy_expected_origin_header"
|
||||
echo DNS_SERVER="$dns_server"
|
||||
echo HEALTH_CHECK_PORT="$health_check_port"
|
||||
echo OPENRESTY_BACKEND_HOST="$openresty_backend_host"
|
||||
echo OPENRESTY_BACKEND_PORT="$openresty_backend_port"
|
||||
echo BIGCHAINDB_BACKEND_HOST="$bdb_backend_host"
|
||||
echo BIGCHAINDB_API_PORT="$bdb_api_port"
|
||||
fi
|
||||
|
||||
NGINX_CONF_FILE=/etc/nginx/nginx.conf
|
||||
|
||||
# configure the nginx.conf file with env variables
|
||||
sed -i "s|PROXY_FQDN|${proxy_fqdn}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|PROXY_FRONTEND_PORT|${proxy_frontend_port}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|OPENRESTY_BACKEND_PORT|${openresty_backend_port}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|OPENRESTY_BACKEND_HOST|${openresty_backend_host}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|BIGCHAINDB_BACKEND_HOST|${bdb_backend_host}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|BIGCHAINDB_API_PORT|${bdb_api_port}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|DNS_SERVER|${dns_server}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|HEALTH_CHECK_PORT|${health_check_port}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|PROXY_APP_ID|${proxy_app_id}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|PROXY_APP_KEY|${proxy_app_key}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|PROXY_EXPECTED_REFERER_HEADER|${proxy_expected_referer_header}|g" ${NGINX_CONF_FILE}
|
||||
sed -i "s|PROXY_EXPECTED_ORIGIN_HEADER|${proxy_expected_origin_header}|g" ${NGINX_CONF_FILE}
|
||||
|
||||
# start nginx
|
||||
echo "INFO: starting nginx..."
|
||||
exec nginx -c /etc/nginx/nginx.conf
|
||||
Reference in New Issue
Block a user