bigchaindb/k8s/nginx-https/container/nginx.conf.threescale.template
Shahbaz Nazir 0ddfc62e3b
Problem: No authorization mode without threescale (#2088)
Problem
The current production deployment template uses 3scale to ensure that POST requests to the network (from anyone) only get through if they come from a client with an account (app_id and app_key).

A private network wants to launch so that all HTTP requests (POST and GET) sent to the nodes in the network get be dropped unless they come from a small set of known (and unchanging) clients/sources. They don't need 3scale. They will want a modified version of the production deployment template.

Solution
Generate a special HTTP header and share it with all the known clients/sources.
Have a single NGINX in each node which checks for that HTTP header value. If it's present, let the request pass through to the network. (HTTP headers are encrypted if HTTPS is used.)
Are there other simpler or better options?
2018-02-23 16:00:36 +01:00

199 lines
6.5 KiB
Plaintext

# Frontend API server that:
# 1. Acts as the HTTPS termination point.
# 2. Forwards BDB HTTP requests to OpenResty backend.
# 3. Forwards BDB WS requests to BDB backend.
# 4. Does health check with LB.
worker_processes 2;
daemon off;
user nobody nogroup;
pid /tmp/nginx.pid;
error_log /dev/stderr;
events {
# Each worker handles up to 512 connections. Increase this for heavy
# workloads.
worker_connections 512;
accept_mutex on;
use epoll;
}
http {
access_log /dev/stdout combined buffer=16k flush=5s;
# Allow 10 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=10r/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 20 r/s,
# `nodelay` or drop connection immediately in case it exceeds this
# threshold.
limit_req zone=one burst=20 nodelay;
# `slowloris` attack mitigation settings.
client_body_timeout 10s;
client_header_timeout 10s;
# Do not expose nginx data/version number in error response and header
server_tokens off;
# To prevent cross-site scripting
add_header X-XSS-Protection "1; mode=block";
# 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 CLUSTER_FRONTEND_PORT ssl;
server_name "CLUSTER_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;
# Forward websockets directly to backend BDB.
location /api/v1/streams/valid_transactions {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://$bdb_backend:BIGCHAINDB_WS_PORT;
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 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;
# 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. Enable CORS too.
if ($request_method = POST ) {
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';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
proxy_pass http://$openresty_backend:OPENRESTY_BACKEND_PORT;
}
# OPTIONS requests handling for CORS.
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;
}
# Only return this reponse if request_method is neither POST|GET|OPTIONS
if ($request_method !~ ^(GET|OPTIONS|POST)$) {
return 444;
}
}
}
# Frontend server for the load balancer to respond to health checks.
server {
listen HEALTH_CHECK_PORT;
location = /health {
return 200;
}
}
# Frontend server for the external clients; returns a pretty error message
# when an HTTP request is sent instead of HTTPS.
server {
listen 80;
server_name "CLUSTER_FQDN";
location / {
add_header Upgrade "TLS/1.2, HTTP/1.1" always;
default_type text/plain;
return 426 'Consider using the HTTPS protocol next time!';
}
}
}
# NGINX stream block for TCP and UDP proxies.
stream {
log_format bdb_log '[$time_iso8601] $realip_remote_addr $remote_addr '
'$proxy_protocol_addr $proxy_protocol_port '
'$protocol $status $session_time $bytes_sent '
'$bytes_received "$upstream_addr" "$upstream_bytes_sent" '
'"$upstream_bytes_received" "$upstream_connect_time" ';
access_log /dev/stdout bdb_log buffer=16k flush=5s;
# Define a zone 'two' of size 10 megabytes to store the counters
# that hold number of TCP connections from a specific IP address.
limit_conn_zone $binary_remote_addr zone=two:10m;
# Enable logging when connections are being throttled.
limit_conn_log_level notice;
# Allow 256 connections from the same IP address.
limit_conn two 256;
# DNS resolver to use for all the backend names specified in this configuration.
resolver DNS_SERVER valid=30s ipv6=off;
# The following map block enables lazy-binding to the backend at runtime,
# rather than binding as soon as NGINX starts.
map $remote_addr $tm_backend {
default TM_BACKEND_HOST;
}
# Server to forward connection to nginx instance hosting
# tendermint node public key.
server {
listen TM_PUB_KEY_ACCESS_PORT;
proxy_pass $tm_backend:TM_PUB_KEY_ACCESS_PORT;
}
# Server to forward p2p connections to Tendermint instance.
server {
listen TM_P2P_PORT so_keepalive=3m:1m:5;
preread_timeout 60s;
tcp_nodelay on;
proxy_pass $tm_backend:TM_P2P_PORT;
}
}