From f0b25fc0ab2c855e3915d383974e328070a99117 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 10 Jun 2021 10:30:08 +0200 Subject: [PATCH 1/8] replace nginx with openresty to support lua scripts Signed-off-by: mteodor --- docker/docker-compose.yml | 10 +- docker/nginx/Dockerfile | 14 ++ docker/nginx/README.md | 15 ++ docker/nginx/entrypoint.sh | 16 ++- docker/nginx/mfx-key.conf | 116 ++++++++++++++++ docker/nginx/mfx-nginx-x509.conf | 96 +++++++++++++ docker/nginx/mqtt-key.conf | 17 +++ docker/nginx/mqtt-x509.conf | 23 ++++ docker/nginx/nginx-key.conf | 184 ++++++------------------- docker/nginx/nginx-x509.conf | 175 +++++------------------ docker/nginx/snippets/authorization.js | 0 11 files changed, 377 insertions(+), 289 deletions(-) create mode 100644 docker/nginx/Dockerfile create mode 100644 docker/nginx/README.md create mode 100644 docker/nginx/mfx-key.conf create mode 100644 docker/nginx/mfx-nginx-x509.conf create mode 100644 docker/nginx/mqtt-key.conf create mode 100644 docker/nginx/mqtt-x509.conf create mode 100755 docker/nginx/snippets/authorization.js diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e95a43fc..335322b6 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -39,14 +39,16 @@ services: command: /entrypoint.sh nginx: - image: nginx:1.20.0-alpine + image: mainflux-nginx:latest container_name: mainflux-nginx restart: on-failure volumes: - - ./nginx/nginx-${AUTH-key}.conf:/etc/nginx/nginx.conf.template + - ./nginx/mfx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf.template + - ./nginx/mqtt-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/mqtt.conf.template + - ./nginx/nginx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf - ./nginx/entrypoint.sh:/entrypoint.sh - - ./nginx/snippets:/etc/nginx/snippets - - ./ssl/authorization.js:/etc/nginx/authorization.js + - ./nginx/snippets:/usr/local/openresty/nginx/conf/snippets + - ./ssl/authorization.js:/usr/local/openresty/nginx/conf/snippets/authorization.js - ./ssl/certs/mainflux-server.crt:/etc/ssl/certs/mainflux-server.crt - ./ssl/certs/ca.crt:/etc/ssl/certs/ca.crt - ./ssl/certs/mainflux-server.key:/etc/ssl/private/mainflux-server.key diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 00000000..63e8009e --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,14 @@ +FROM openresty/openresty:alpine-fat + +RUN mkdir -p /var/log/nginx && \ + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + +RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http +RUN /usr/local/openresty/luajit/bin/luarocks install lua-cjson +RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-session +RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-openidc + +RUN mkdir -p /data/nginx/cache/ui + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/docker/nginx/README.md b/docker/nginx/README.md new file mode 100644 index 00000000..acd37d0b --- /dev/null +++ b/docker/nginx/README.md @@ -0,0 +1,15 @@ +# Openresty configuration + +Prior to the starting the composition `mainflux-nginx` image must be built using [Dockerfile](Dockerfile) + +``` +pwd +../ui/docker +docker build --tag=mainflux-nginx -f Dockerfile . +``` + +When starting `openresty` image we must mount our own `nginx.conf` as a volume, we cannot rely on `entrypoint.sh` to parse template configuration and create `nginx.conf`. +So we mount `nginx.conf` which will include configuration files that should be parsed and adjusted according to environment variables. + +- `nginx-key.conf` will be mounted as volume in case of plain HTTP, it will include `mfx.conf` which will be result of parsing `mfx-key.conf`. Similar it will include `mqtt.conf` which is result of parsing `mqtt-key.conf` in `entrypoint.sh`. +- `nginx-x509.conf` will be mounted as volume in case of HTTPS it will include `mfx.conf` which will be result of parsing `mfx-x509.conf`. Additionaly it includes `mqtt.conf` which is result of parsing `mqtt-x509.conf` in `entrypoint.sh` diff --git a/docker/nginx/entrypoint.sh b/docker/nginx/entrypoint.sh index 2e7b36f8..d548284c 100755 --- a/docker/nginx/entrypoint.sh +++ b/docker/nginx/entrypoint.sh @@ -2,11 +2,11 @@ if [ -z "$MF_MQTT_CLUSTER" ] then - envsubst '${MF_MQTT_ADAPTER_MQTT_PORT}' < /etc/nginx/snippets/mqtt-upstream-single.conf > /etc/nginx/snippets/mqtt-upstream.conf - envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-single.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf + envsubst '${MF_MQTT_ADAPTER_MQTT_PORT}' < /usr/local/openresty/nginx/conf/snippets/mqtt-upstream-single.conf > /usr/local/openresty/nginx/conf/snippets/mqtt-upstream.conf + envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /usr/local/openresty/nginx/conf/snippets/mqtt-ws-upstream-single.conf > /usr/local/openresty/nginx/conf/snippets/mqtt-ws-upstream.conf else - envsubst '${MF_MQTT_ADAPTER_MQTT_PORT}' < /etc/nginx/snippets/mqtt-upstream-cluster.conf > /etc/nginx/snippets/mqtt-upstream.conf - envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /etc/nginx/snippets/mqtt-ws-upstream-cluster.conf > /etc/nginx/snippets/mqtt-ws-upstream.conf + envsubst '${MF_MQTT_ADAPTER_MQTT_PORT}' < /usr/local/openresty/nginx/conf/snippets/mqtt-upstream-cluster.conf > /usr/local/openresty/nginx/conf/snippets/mqtt-upstream.conf + envsubst '${MF_MQTT_ADAPTER_WS_PORT}' < /usr/local/openresty/nginx/conf/snippets/mqtt-ws-upstream-cluster.conf > /usr/local/openresty/nginx/conf/snippets/mqtt-ws-upstream.conf fi envsubst ' @@ -22,6 +22,10 @@ envsubst ' ${MF_INFLUX_READER_PORT} ${MF_BOOTSTRAP_PORT} ${MF_TWINS_HTTP_PORT} - ${MF_OPCUA_ADAPTER_HTTP_PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf + ${MF_OPCUA_ADAPTER_HTTP_PORT}' < /usr/local/openresty/nginx/conf/nginx.conf.template > /usr/local/openresty/nginx/conf/mfx.conf -exec nginx -g "daemon off;" +envsubst ' + ${MF_NGINX_MQTT_PORT} + ${MF_NGINX_MQTTS_PORT}' < /usr/local/openresty/nginx/conf/mqtt.conf.template > /usr/local/openresty/nginx/conf/mqtt.conf + +exec /usr/local/openresty/bin/openresty -g "daemon off;" diff --git a/docker/nginx/mfx-key.conf b/docker/nginx/mfx-key.conf new file mode 100644 index 00000000..73c22296 --- /dev/null +++ b/docker/nginx/mfx-key.conf @@ -0,0 +1,116 @@ +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 + +# This is the default Mainflux NGINX configuration. + + + server { + listen 80 default_server; + listen [::]:80 default_server; + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + + include snippets/ssl.conf; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin '*'; + add_header Access-Control-Allow-Methods '*'; + add_header Access-Control-Allow-Headers '*'; + + server_name localhost; + + + # Proxy pass to users service + location ~ ^/(users|tokens|password) { + include snippets/proxy-headers.conf; + proxy_pass http://users:${MF_USERS_HTTP_PORT}; + } + + # Proxy pass to things service + location ~ ^/(things|channels|connect) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + location ~ ^/(identify){ + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; + } + + # Proxy pass for groups to things service + location ^~ /groups/things/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; + } + + # Proxy pass for groups to users service + location ^~ /groups/users/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; + } + + location ~ ^/(groups|members|keys) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; + } + + location /version { + include snippets/proxy-headers.conf; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + # Proxy pass to mainflux-http-adapter + location /http/ { + include snippets/proxy-headers.conf; + + # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass + # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, + # the part of a normalized request URI matching the location is replaced by a URI specified in the directive + proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; + } + + # Proxy pass to mainflux-mqtt-adapter over WS + location /mqtt { + include snippets/proxy-headers.conf; + include snippets/ws-upgrade.conf; + proxy_pass http://mqtt_ws_cluster; + } + + # Proxy pass to mainflux-influxdb-reader + location /reader/ { + include snippets/proxy-headers.conf; + proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; + } + + # Proxy pass to mainflux-bootstrap + location /bootstrap/ { + include snippets/proxy-headers.conf; + proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; + } + + # Proxy pass to mainflux-opcua-adapter + location /browse { + include snippets/proxy-headers.conf; + proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; + } + + # Proxy pass to mainflux-twins + location ~ ^/(twins|states) { + include snippets/proxy-headers.conf; + proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; + } + + location / { + include snippets/proxy-headers.conf; + proxy_pass http://ui:${MF_UI_PORT}; + } + + } + diff --git a/docker/nginx/mfx-nginx-x509.conf b/docker/nginx/mfx-nginx-x509.conf new file mode 100644 index 00000000..66f1455c --- /dev/null +++ b/docker/nginx/mfx-nginx-x509.conf @@ -0,0 +1,96 @@ +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 + +# This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes. + + + + + server { + listen 80 default_server; + listen [::]:80 default_server; + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + ssl_verify_client optional; + include snippets/ssl.conf; + include snippets/ssl-client.conf; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin '*'; + add_header Access-Control-Allow-Methods '*'; + add_header Access-Control-Allow-Headers '*'; + + server_name localhost; + + + # Proxy pass to users service + location ~ ^/(users|tokens|password) { + include snippets/proxy-headers.conf; + proxy_pass http://users:${MF_USERS_HTTP_PORT}; + } + + + + # Proxy pass to things service + location ~ ^/(things|channels|connect) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + location ~ ^/(identify){ + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; + } + + # Proxy pass for groups to things service + location ^~ /groups/things/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; + } + + # Proxy pass for groups to users service + location ^~ /groups/users/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; + } + + location ~ ^/(groups|members|keys) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; + } + + + location /version { + include snippets/proxy-headers.conf; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + # Proxy pass to mainflux-http-adapter + location /http/ { + include snippets/verify-ssl-client.conf; + include snippets/proxy-headers.conf; + proxy_set_header Authorization $auth_key; + + # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass + # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, + # the part of a normalized request URI matching the location is replaced by a URI specified in the directive + proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; + } + + # Proxy pass to mainflux-mqtt-adapter over WS + location /mqtt { + include snippets/verify-ssl-client.conf; + include snippets/proxy-headers.conf; + include snippets/ws-upgrade.conf; + proxy_pass http://mqtt_ws_cluster; + } + } +} + diff --git a/docker/nginx/mqtt-key.conf b/docker/nginx/mqtt-key.conf new file mode 100644 index 00000000..3399aa13 --- /dev/null +++ b/docker/nginx/mqtt-key.conf @@ -0,0 +1,17 @@ +stream { + include snippets/stream_access_log.conf; + + # Include single-node or multiple-node (cluster) upstream + include snippets/mqtt-upstream.conf; + + server { + listen ${MF_NGINX_MQTT_PORT}; + listen [::]:${MF_NGINX_MQTT_PORT}; + listen ${MF_NGINX_MQTTS_PORT} ssl; + listen [::]:${MF_NGINX_MQTTS_PORT} ssl; + + include snippets/ssl.conf; + + proxy_pass mqtt_cluster; + } +} \ No newline at end of file diff --git a/docker/nginx/mqtt-x509.conf b/docker/nginx/mqtt-x509.conf new file mode 100644 index 00000000..c230deb3 --- /dev/null +++ b/docker/nginx/mqtt-x509.conf @@ -0,0 +1,23 @@ +stream { + include snippets/stream_access_log.conf; + + # Include JS script for mTLS + js_include authorization.js; + + # Include single-node or multiple-node (cluster) upstream + include snippets/mqtt-upstream.conf; + ssl_verify_client on; + include snippets/ssl-client.conf; + + server { + listen ${MF_NGINX_MQTT_PORT}; + listen [::]:${MF_NGINX_MQTT_PORT}; + listen ${MF_NGINX_MQTTS_PORT} ssl; + listen [::]:${MF_NGINX_MQTTS_PORT} ssl; + + include snippets/ssl.conf; + js_preread authenticate; + + proxy_pass mqtt_cluster; + } +} \ No newline at end of file diff --git a/docker/nginx/nginx-key.conf b/docker/nginx/nginx-key.conf index 11601e9a..40851d3f 100644 --- a/docker/nginx/nginx-key.conf +++ b/docker/nginx/nginx-key.conf @@ -1,31 +1,19 @@ -# Copyright (c) Mainflux -# SPDX-License-Identifier: Apache-2.0 +worker_processes auto; -# This is the default Mainflux NGINX configuration. - -user nginx; -worker_processes auto; -worker_cpu_affinity auto; -pid /run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; +error_log /var/log/nginx/error.log debug; +pid /var/run/nginx.pid; events { - # Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections - # We'll keep 10k connections per core (assuming one worker per core) - worker_connections 10000; + worker_connections 1024; } http { - include snippets/http_access_log.conf; - sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; - include /etc/nginx/mime.types; - default_type application/octet-stream; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; @@ -33,132 +21,46 @@ http { # Include single-node or multiple-node (cluster) upstream include snippets/mqtt-ws-upstream.conf; - server { - listen 80 default_server; - listen [::]:80 default_server; - listen 443 ssl http2 default_server; - listen [::]:443 ssl http2 default_server; - - include snippets/ssl.conf; - - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Access-Control-Allow-Origin '*'; - add_header Access-Control-Allow-Methods '*'; - add_header Access-Control-Allow-Headers '*'; - - server_name localhost; - - # Proxy pass to users service - location ~ ^/(users|tokens|password) { - include snippets/proxy-headers.conf; - proxy_pass http://users:${MF_USERS_HTTP_PORT}; - } - - # Proxy pass to things service - location ~ ^/(things|channels|connect) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - location ~ ^/(identify){ - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; - } - - # Proxy pass for groups to things service - location ^~ /groups/things/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; - } - - # Proxy pass for groups to users service - location ^~ /groups/users/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; - } - - location ~ ^/(groups|members|keys) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; - } - - location /version { - include snippets/proxy-headers.conf; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - # Proxy pass to mainflux-http-adapter - location /http/ { - include snippets/proxy-headers.conf; - - # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass - # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, - # the part of a normalized request URI matching the location is replaced by a URI specified in the directive - proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; - } - - # Proxy pass to mainflux-mqtt-adapter over WS - location /mqtt { - include snippets/proxy-headers.conf; - include snippets/ws-upgrade.conf; - proxy_pass http://mqtt_ws_cluster; - } - - # Proxy pass to mainflux-influxdb-reader - location /reader/ { - include snippets/proxy-headers.conf; - proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; - } - - # Proxy pass to mainflux-bootstrap - location /bootstrap/ { - include snippets/proxy-headers.conf; - proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; - } - - # Proxy pass to mainflux-opcua-adapter - location /browse { - include snippets/proxy-headers.conf; - proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; - } - - # Proxy pass to mainflux-twins - location ~ ^/(twins|states) { - include snippets/proxy-headers.conf; - proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; - } - - location / { - include snippets/proxy-headers.conf; - proxy_pass http://ui:${MF_UI_PORT}; - } - } + include /usr/local/openresty/nginx/conf/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" ' + 'request ID "$upstream_http_x_men_requestid" ' + '$request_time'; + + log_format access_log_json '{ "timestamp": "$msec", ' + '"nginx": { ' + '"remote_addr": "$remote_addr", ' + '"remote_user": "$remote_user", ' + '"body_bytes_sent": "$body_bytes_sent", ' + '"status": "$status", ' + '"request_method": "$request_method", ' + '"request_uri": "$request_uri", ' + '"uri": "$uri", ' + '"request_time": "$request_time", ' + '"request_id": "$upstream_http_x_men_requestid", ' + '"http_referrer": "$http_referer", ' + '"http_x_forwarded_for": "$http_x_forwarded_for", ' + '"user": "$http_x_webauth_user", ' + '"http_user_agent": "$http_user_agent" } }'; + + access_log /var/log/nginx/access.log access_log_json; + + + proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m + inactive=1h use_temp_path=off; + + # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; + # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; + # limit_req_status 429; + + #gzip on; + include /usr/local/openresty/nginx/conf/mfx.conf; + } # MQTT -stream { - include snippets/stream_access_log.conf; - - # Include single-node or multiple-node (cluster) upstream - include snippets/mqtt-upstream.conf; - - server { - listen 1883; - listen [::]:1883; - listen 8883 ssl; - listen [::]:8883 ssl; - - include snippets/ssl.conf; - - proxy_pass mqtt_cluster; - } -} +include /usr/local/openresty/nginx/conf/mqtt.conf; -error_log info.log info; diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index 11a63a72..4dc055b8 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -1,8 +1,3 @@ -# Copyright (c) Mainflux -# SPDX-License-Identifier: Apache-2.0 - -# This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes. - user nginx; worker_processes auto; worker_cpu_affinity auto; @@ -18,8 +13,6 @@ events { } http { - include snippets/http_access_log.conf; - js_include authorization.js; js_set $auth_key setKey; @@ -29,8 +22,6 @@ http { keepalive_timeout 65; types_hash_max_size 2048; - include /etc/nginx/mime.types; - default_type application/octet-stream; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; @@ -38,141 +29,49 @@ http { # Include single-node or multiple-node (cluster) upstream include snippets/mqtt-ws-upstream.conf; - server { - listen 80 default_server; - listen [::]:80 default_server; - listen 443 ssl http2 default_server; - listen [::]:443 ssl http2 default_server; - ssl_verify_client optional; - include snippets/ssl.conf; - include snippets/ssl-client.conf; - - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Access-Control-Allow-Origin '*'; - add_header Access-Control-Allow-Methods '*'; - add_header Access-Control-Allow-Headers '*'; - - server_name localhost; - - # Proxy pass to users service - location ~ ^/(users|tokens|password) { - include snippets/proxy-headers.conf; - proxy_pass http://users:${MF_USERS_HTTP_PORT}; - } - - # Proxy pass to things service - location ~ ^/(things|channels|connect) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - location ~ ^/(identify){ - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; - } - - # Proxy pass for groups to things service - location ^~ /groups/things/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; - } - - # Proxy pass for groups to users service - location ^~ /groups/users/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; - } - - location ~ ^/(groups|members|keys) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; - } - - location /version { - include snippets/proxy-headers.conf; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - # Proxy pass to mainflux-http-adapter - location /http/ { - include snippets/verify-ssl-client.conf; - include snippets/proxy-headers.conf; - proxy_set_header Authorization $auth_key; - - # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass - # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, - # the part of a normalized request URI matching the location is replaced by a URI specified in the directive - proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; - } - - # Proxy pass to mainflux-mqtt-adapter over WS - location /mqtt { - include snippets/verify-ssl-client.conf; - include snippets/proxy-headers.conf; - include snippets/ws-upgrade.conf; - proxy_pass http://mqtt_ws_cluster; - } - - # Proxy pass to mainflux-influxdb-reader - location /reader/ { - include snippets/proxy-headers.conf; - proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; - } - - # Proxy pass to mainflux-bootstrap - location /bootstrap/ { - include snippets/proxy-headers.conf; - proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; - } - - # Proxy pass to mainflux-opcua-adapter - location /browse { - include snippets/proxy-headers.conf; - proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; - } - - location ~ ^/(twins|states) { - include snippets/proxy-headers.conf; - proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; - } - - location / { - include snippets/proxy-headers.conf; - proxy_pass http://ui:${MF_UI_PORT}; - } - } -} + include /usr/local/openresty/nginx/conf/mime.types; + default_type application/octet-stream; -# MQTT -stream { - include snippets/stream_access_log.conf; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" ' + 'request ID "$upstream_http_x_men_requestid" ' + '$request_time'; - # Include JS script for mTLS - js_include authorization.js; + log_format access_log_json '{ "timestamp": "$msec", ' + '"nginx": { ' + '"remote_addr": "$remote_addr", ' + '"remote_user": "$remote_user", ' + '"body_bytes_sent": "$body_bytes_sent", ' + '"status": "$status", ' + '"request_method": "$request_method", ' + '"request_uri": "$request_uri", ' + '"uri": "$uri", ' + '"request_time": "$request_time", ' + '"request_id": "$upstream_http_x_men_requestid", ' + '"http_referrer": "$http_referer", ' + '"http_x_forwarded_for": "$http_x_forwarded_for", ' + '"user": "$http_x_webauth_user", ' + '"http_user_agent": "$http_user_agent" } }'; - # Include single-node or multiple-node (cluster) upstream - include snippets/mqtt-upstream.conf; - ssl_verify_client on; - include snippets/ssl-client.conf; + access_log /var/log/nginx/access.log access_log_json; - server { - listen 1883; - listen [::]:1883; - listen 8883 ssl; - listen [::]:8883 ssl; - include snippets/ssl.conf; - js_preread authenticate; + proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m + inactive=1h use_temp_path=off; + + # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; + # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; + # limit_req_status 429; + + #gzip on; + + include /usr/local/openresty/nginx/conf/mfx.conf; +} + +# MQTT +include /usr/local/openresty/nginx/conf/mqtt.conf; - proxy_pass mqtt_cluster; - } } error_log info.log info; diff --git a/docker/nginx/snippets/authorization.js b/docker/nginx/snippets/authorization.js new file mode 100755 index 00000000..e69de29b From 0d77c692654e2bb2ced9b989272036f8cdb670d4 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 10 Jun 2021 10:31:53 +0200 Subject: [PATCH 2/8] replace nginx with openresty to support lua scripts Signed-off-by: mteodor --- docker/nginx/mqtt-key.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/nginx/mqtt-key.conf b/docker/nginx/mqtt-key.conf index 3399aa13..e9efccef 100644 --- a/docker/nginx/mqtt-key.conf +++ b/docker/nginx/mqtt-key.conf @@ -14,4 +14,4 @@ stream { proxy_pass mqtt_cluster; } -} \ No newline at end of file +} From 70abd870ac94c278e19be35ce3da66e7b026370f Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 10 Jun 2021 10:33:06 +0200 Subject: [PATCH 3/8] replace nginx with openresty to support lua scripts Signed-off-by: mteodor --- docker/nginx/mqtt-x509.conf | 5 ++++- docker/nginx/nginx-x509.conf | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docker/nginx/mqtt-x509.conf b/docker/nginx/mqtt-x509.conf index c230deb3..56d2d21e 100644 --- a/docker/nginx/mqtt-x509.conf +++ b/docker/nginx/mqtt-x509.conf @@ -1,3 +1,6 @@ +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 + stream { include snippets/stream_access_log.conf; @@ -20,4 +23,4 @@ stream { proxy_pass mqtt_cluster; } -} \ No newline at end of file +} diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index 4dc055b8..df2e7efc 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -1,3 +1,5 @@ +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 user nginx; worker_processes auto; worker_cpu_affinity auto; From 7a0f4a201dd4a1724c2cd4d56ca43cdea61c119e Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 10 Jun 2021 10:34:08 +0200 Subject: [PATCH 4/8] remove Signed-off-by: mteodor --- docker/nginx/snippets/authorization.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 docker/nginx/snippets/authorization.js diff --git a/docker/nginx/snippets/authorization.js b/docker/nginx/snippets/authorization.js deleted file mode 100755 index e69de29b..00000000 From e81831ac26c902c02cef0e082f5dbd224c345ab3 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 30 Sep 2021 17:47:01 +0200 Subject: [PATCH 5/8] rename nginx files Signed-off-by: mteodor --- docker/docker-compose.yml | 4 +- docker/nginx/entrypoint.sh | 2 +- docker/nginx/mfx-key.conf | 180 +++++++++++-------------------- docker/nginx/mfx-nginx-x509.conf | 96 ----------------- docker/nginx/mfx-x509.conf | 79 ++++++++++++++ docker/nginx/nginx-key.conf | 180 ++++++++++++++++++++----------- docker/nginx/nginx-x509.conf | 165 +++++++++++++++------------- 7 files changed, 353 insertions(+), 353 deletions(-) delete mode 100644 docker/nginx/mfx-nginx-x509.conf create mode 100644 docker/nginx/mfx-x509.conf diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 335322b6..a0b8c760 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -43,9 +43,9 @@ services: container_name: mainflux-nginx restart: on-failure volumes: - - ./nginx/mfx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf.template + - ./nginx/nginx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf.template - ./nginx/mqtt-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/mqtt.conf.template - - ./nginx/nginx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf + - ./nginx/mfx-${AUTH-key}.conf:/usr/local/openresty/nginx/conf/nginx.conf - ./nginx/entrypoint.sh:/entrypoint.sh - ./nginx/snippets:/usr/local/openresty/nginx/conf/snippets - ./ssl/authorization.js:/usr/local/openresty/nginx/conf/snippets/authorization.js diff --git a/docker/nginx/entrypoint.sh b/docker/nginx/entrypoint.sh index d548284c..29551354 100755 --- a/docker/nginx/entrypoint.sh +++ b/docker/nginx/entrypoint.sh @@ -22,7 +22,7 @@ envsubst ' ${MF_INFLUX_READER_PORT} ${MF_BOOTSTRAP_PORT} ${MF_TWINS_HTTP_PORT} - ${MF_OPCUA_ADAPTER_HTTP_PORT}' < /usr/local/openresty/nginx/conf/nginx.conf.template > /usr/local/openresty/nginx/conf/mfx.conf + ${MF_OPCUA_ADAPTER_HTTP_PORT}' < /usr/local/openresty/nginx/conf/nginx.conf.template > /usr/local/openresty/nginx/conf/mfx-nginx.conf envsubst ' ${MF_NGINX_MQTT_PORT} diff --git a/docker/nginx/mfx-key.conf b/docker/nginx/mfx-key.conf index 73c22296..90ee3a3c 100644 --- a/docker/nginx/mfx-key.conf +++ b/docker/nginx/mfx-key.conf @@ -1,116 +1,66 @@ -# Copyright (c) Mainflux -# SPDX-License-Identifier: Apache-2.0 - -# This is the default Mainflux NGINX configuration. - - - server { - listen 80 default_server; - listen [::]:80 default_server; - listen 443 ssl http2 default_server; - listen [::]:443 ssl http2 default_server; - - include snippets/ssl.conf; - - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Access-Control-Allow-Origin '*'; - add_header Access-Control-Allow-Methods '*'; - add_header Access-Control-Allow-Headers '*'; - - server_name localhost; - - - # Proxy pass to users service - location ~ ^/(users|tokens|password) { - include snippets/proxy-headers.conf; - proxy_pass http://users:${MF_USERS_HTTP_PORT}; - } - - # Proxy pass to things service - location ~ ^/(things|channels|connect) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - location ~ ^/(identify){ - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; - } - - # Proxy pass for groups to things service - location ^~ /groups/things/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; - } - - # Proxy pass for groups to users service - location ^~ /groups/users/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; - } - - location ~ ^/(groups|members|keys) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; - } - - location /version { - include snippets/proxy-headers.conf; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - # Proxy pass to mainflux-http-adapter - location /http/ { - include snippets/proxy-headers.conf; - - # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass - # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, - # the part of a normalized request URI matching the location is replaced by a URI specified in the directive - proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; - } - - # Proxy pass to mainflux-mqtt-adapter over WS - location /mqtt { - include snippets/proxy-headers.conf; - include snippets/ws-upgrade.conf; - proxy_pass http://mqtt_ws_cluster; - } - - # Proxy pass to mainflux-influxdb-reader - location /reader/ { - include snippets/proxy-headers.conf; - proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; - } - - # Proxy pass to mainflux-bootstrap - location /bootstrap/ { - include snippets/proxy-headers.conf; - proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; - } - - # Proxy pass to mainflux-opcua-adapter - location /browse { - include snippets/proxy-headers.conf; - proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; - } - - # Proxy pass to mainflux-twins - location ~ ^/(twins|states) { - include snippets/proxy-headers.conf; - proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; - } - - location / { - include snippets/proxy-headers.conf; - proxy_pass http://ui:${MF_UI_PORT}; - } - - } +worker_processes auto; + +error_log /var/log/nginx/error.log debug; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + # Include single-node or multiple-node (cluster) upstream + include snippets/mqtt-ws-upstream.conf; + + include /usr/local/openresty/nginx/conf/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" ' + 'request ID "$upstream_http_x_men_requestid" ' + '$request_time'; + + log_format access_log_json '{ "timestamp": "$msec", ' + '"nginx": { ' + '"remote_addr": "$remote_addr", ' + '"remote_user": "$remote_user", ' + '"body_bytes_sent": "$body_bytes_sent", ' + '"status": "$status", ' + '"request_method": "$request_method", ' + '"request_uri": "$request_uri", ' + '"uri": "$uri", ' + '"request_time": "$request_time", ' + '"request_id": "$upstream_http_x_men_requestid", ' + '"http_referrer": "$http_referer", ' + '"http_x_forwarded_for": "$http_x_forwarded_for", ' + '"user": "$http_x_webauth_user", ' + '"http_user_agent": "$http_user_agent" } }'; + + access_log /var/log/nginx/access.log access_log_json; + + + proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m + inactive=1h use_temp_path=off; + + # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; + # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; + # limit_req_status 429; + + #gzip on; + include /usr/local/openresty/nginx/conf/mfx-nginx.conf; + +} + +# MQTT +include /usr/local/openresty/nginx/conf/mqtt.conf; diff --git a/docker/nginx/mfx-nginx-x509.conf b/docker/nginx/mfx-nginx-x509.conf deleted file mode 100644 index 66f1455c..00000000 --- a/docker/nginx/mfx-nginx-x509.conf +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) Mainflux -# SPDX-License-Identifier: Apache-2.0 - -# This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes. - - - - - server { - listen 80 default_server; - listen [::]:80 default_server; - listen 443 ssl http2 default_server; - listen [::]:443 ssl http2 default_server; - ssl_verify_client optional; - include snippets/ssl.conf; - include snippets/ssl-client.conf; - - add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Access-Control-Allow-Origin '*'; - add_header Access-Control-Allow-Methods '*'; - add_header Access-Control-Allow-Headers '*'; - - server_name localhost; - - - # Proxy pass to users service - location ~ ^/(users|tokens|password) { - include snippets/proxy-headers.conf; - proxy_pass http://users:${MF_USERS_HTTP_PORT}; - } - - - - # Proxy pass to things service - location ~ ^/(things|channels|connect) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - location ~ ^/(identify){ - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; - } - - # Proxy pass for groups to things service - location ^~ /groups/things/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; - } - - # Proxy pass for groups to users service - location ^~ /groups/users/ { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; - } - - location ~ ^/(groups|members|keys) { - include snippets/proxy-headers.conf; - add_header Access-Control-Expose-Headers Location; - proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; - } - - - location /version { - include snippets/proxy-headers.conf; - proxy_pass http://things:${MF_THINGS_HTTP_PORT}; - } - - # Proxy pass to mainflux-http-adapter - location /http/ { - include snippets/verify-ssl-client.conf; - include snippets/proxy-headers.conf; - proxy_set_header Authorization $auth_key; - - # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass - # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, - # the part of a normalized request URI matching the location is replaced by a URI specified in the directive - proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; - } - - # Proxy pass to mainflux-mqtt-adapter over WS - location /mqtt { - include snippets/verify-ssl-client.conf; - include snippets/proxy-headers.conf; - include snippets/ws-upgrade.conf; - proxy_pass http://mqtt_ws_cluster; - } - } -} - diff --git a/docker/nginx/mfx-x509.conf b/docker/nginx/mfx-x509.conf new file mode 100644 index 00000000..05413cd2 --- /dev/null +++ b/docker/nginx/mfx-x509.conf @@ -0,0 +1,79 @@ +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 +user nginx; +worker_processes auto; +worker_cpu_affinity auto; +pid /run/nginx.pid; +load_module /etc/nginx/modules/ngx_stream_js_module.so; +load_module /etc/nginx/modules/ngx_http_js_module.so; +include /etc/nginx/modules-enabled/*.conf; + +events { + # Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections + # We'll keep 10k connections per core (assuming one worker per core) + worker_connections 10000; +} + +http { + js_include authorization.js; + js_set $auth_key setKey; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + # Include single-node or multiple-node (cluster) upstream + include snippets/mqtt-ws-upstream.conf; + + include /usr/local/openresty/nginx/conf/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" ' + 'request ID "$upstream_http_x_men_requestid" ' + '$request_time'; + + log_format access_log_json '{ "timestamp": "$msec", ' + '"nginx": { ' + '"remote_addr": "$remote_addr", ' + '"remote_user": "$remote_user", ' + '"body_bytes_sent": "$body_bytes_sent", ' + '"status": "$status", ' + '"request_method": "$request_method", ' + '"request_uri": "$request_uri", ' + '"uri": "$uri", ' + '"request_time": "$request_time", ' + '"request_id": "$upstream_http_x_men_requestid", ' + '"http_referrer": "$http_referer", ' + '"http_x_forwarded_for": "$http_x_forwarded_for", ' + '"user": "$http_x_webauth_user", ' + '"http_user_agent": "$http_user_agent" } }'; + + access_log /var/log/nginx/access.log access_log_json; + + + proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m + inactive=1h use_temp_path=off; + + # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; + # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; + # limit_req_status 429; + + #gzip on; + + include /usr/local/openresty/nginx/conf/mfx-nginx.conf; +} + +# MQTT +include /usr/local/openresty/nginx/conf/mqtt.conf; + +} + +error_log info.log info; diff --git a/docker/nginx/nginx-key.conf b/docker/nginx/nginx-key.conf index 40851d3f..73c22296 100644 --- a/docker/nginx/nginx-key.conf +++ b/docker/nginx/nginx-key.conf @@ -1,66 +1,116 @@ -worker_processes auto; - -error_log /var/log/nginx/error.log debug; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; -} - -http { - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - - - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - - # Include single-node or multiple-node (cluster) upstream - include snippets/mqtt-ws-upstream.conf; - - include /usr/local/openresty/nginx/conf/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for" ' - 'request ID "$upstream_http_x_men_requestid" ' - '$request_time'; - - log_format access_log_json '{ "timestamp": "$msec", ' - '"nginx": { ' - '"remote_addr": "$remote_addr", ' - '"remote_user": "$remote_user", ' - '"body_bytes_sent": "$body_bytes_sent", ' - '"status": "$status", ' - '"request_method": "$request_method", ' - '"request_uri": "$request_uri", ' - '"uri": "$uri", ' - '"request_time": "$request_time", ' - '"request_id": "$upstream_http_x_men_requestid", ' - '"http_referrer": "$http_referer", ' - '"http_x_forwarded_for": "$http_x_forwarded_for", ' - '"user": "$http_x_webauth_user", ' - '"http_user_agent": "$http_user_agent" } }'; - - access_log /var/log/nginx/access.log access_log_json; - - - proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m - inactive=1h use_temp_path=off; - - # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; - # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; - # limit_req_status 429; - - #gzip on; - include /usr/local/openresty/nginx/conf/mfx.conf; - -} - -# MQTT -include /usr/local/openresty/nginx/conf/mqtt.conf; +# Copyright (c) Mainflux +# SPDX-License-Identifier: Apache-2.0 + +# This is the default Mainflux NGINX configuration. + + + server { + listen 80 default_server; + listen [::]:80 default_server; + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + + include snippets/ssl.conf; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin '*'; + add_header Access-Control-Allow-Methods '*'; + add_header Access-Control-Allow-Headers '*'; + + server_name localhost; + + + # Proxy pass to users service + location ~ ^/(users|tokens|password) { + include snippets/proxy-headers.conf; + proxy_pass http://users:${MF_USERS_HTTP_PORT}; + } + + # Proxy pass to things service + location ~ ^/(things|channels|connect) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + location ~ ^/(identify){ + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; + } + + # Proxy pass for groups to things service + location ^~ /groups/things/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; + } + + # Proxy pass for groups to users service + location ^~ /groups/users/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; + } + + location ~ ^/(groups|members|keys) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; + } + + location /version { + include snippets/proxy-headers.conf; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + # Proxy pass to mainflux-http-adapter + location /http/ { + include snippets/proxy-headers.conf; + + # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass + # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, + # the part of a normalized request URI matching the location is replaced by a URI specified in the directive + proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; + } + + # Proxy pass to mainflux-mqtt-adapter over WS + location /mqtt { + include snippets/proxy-headers.conf; + include snippets/ws-upgrade.conf; + proxy_pass http://mqtt_ws_cluster; + } + + # Proxy pass to mainflux-influxdb-reader + location /reader/ { + include snippets/proxy-headers.conf; + proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; + } + + # Proxy pass to mainflux-bootstrap + location /bootstrap/ { + include snippets/proxy-headers.conf; + proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; + } + + # Proxy pass to mainflux-opcua-adapter + location /browse { + include snippets/proxy-headers.conf; + proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; + } + + # Proxy pass to mainflux-twins + location ~ ^/(twins|states) { + include snippets/proxy-headers.conf; + proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; + } + + location / { + include snippets/proxy-headers.conf; + proxy_pass http://ui:${MF_UI_PORT}; + } + + } diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index df2e7efc..66f1455c 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -1,79 +1,96 @@ # Copyright (c) Mainflux # SPDX-License-Identifier: Apache-2.0 -user nginx; -worker_processes auto; -worker_cpu_affinity auto; -pid /run/nginx.pid; -load_module /etc/nginx/modules/ngx_stream_js_module.so; -load_module /etc/nginx/modules/ngx_http_js_module.so; -include /etc/nginx/modules-enabled/*.conf; - -events { - # Explanation: https://serverfault.com/questions/787919/optimal-value-for-nginx-worker-connections - # We'll keep 10k connections per core (assuming one worker per core) - worker_connections 10000; -} - -http { - js_include authorization.js; - js_set $auth_key setKey; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - - - ssl_protocols TLSv1.2 TLSv1.3; - ssl_prefer_server_ciphers on; - - # Include single-node or multiple-node (cluster) upstream - include snippets/mqtt-ws-upstream.conf; - - include /usr/local/openresty/nginx/conf/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for" ' - 'request ID "$upstream_http_x_men_requestid" ' - '$request_time'; - - log_format access_log_json '{ "timestamp": "$msec", ' - '"nginx": { ' - '"remote_addr": "$remote_addr", ' - '"remote_user": "$remote_user", ' - '"body_bytes_sent": "$body_bytes_sent", ' - '"status": "$status", ' - '"request_method": "$request_method", ' - '"request_uri": "$request_uri", ' - '"uri": "$uri", ' - '"request_time": "$request_time", ' - '"request_id": "$upstream_http_x_men_requestid", ' - '"http_referrer": "$http_referer", ' - '"http_x_forwarded_for": "$http_x_forwarded_for", ' - '"user": "$http_x_webauth_user", ' - '"http_user_agent": "$http_user_agent" } }'; - - access_log /var/log/nginx/access.log access_log_json; - - - proxy_cache_path /data/nginx/cache/ui levels=1:2 keys_zone=ui_cache:10m max_size=100m - inactive=1h use_temp_path=off; - - # limit_req_zone $binary_remote_addr zone=mylimit:10m rate=@RATE_LIMIT_GLOBAL_RATE@; - # limit_req zone=mylimit @RATE_LIMIT_GLOBAL_BURST@ nodelay; - # limit_req_status 429; - - #gzip on; - - include /usr/local/openresty/nginx/conf/mfx.conf; -} - -# MQTT -include /usr/local/openresty/nginx/conf/mqtt.conf; +# This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes. + + + + + server { + listen 80 default_server; + listen [::]:80 default_server; + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + ssl_verify_client optional; + include snippets/ssl.conf; + include snippets/ssl-client.conf; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin '*'; + add_header Access-Control-Allow-Methods '*'; + add_header Access-Control-Allow-Headers '*'; + + server_name localhost; + + + # Proxy pass to users service + location ~ ^/(users|tokens|password) { + include snippets/proxy-headers.conf; + proxy_pass http://users:${MF_USERS_HTTP_PORT}; + } + + + + # Proxy pass to things service + location ~ ^/(things|channels|connect) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + location ~ ^/(identify){ + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; + } + + # Proxy pass for groups to things service + location ^~ /groups/things/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}/groups/; + } + + # Proxy pass for groups to users service + location ^~ /groups/users/ { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://users:${MF_USERS_HTTP_PORT}/groups/; + } + + location ~ ^/(groups|members|keys) { + include snippets/proxy-headers.conf; + add_header Access-Control-Expose-Headers Location; + proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; + } + + + location /version { + include snippets/proxy-headers.conf; + proxy_pass http://things:${MF_THINGS_HTTP_PORT}; + } + + # Proxy pass to mainflux-http-adapter + location /http/ { + include snippets/verify-ssl-client.conf; + include snippets/proxy-headers.conf; + proxy_set_header Authorization $auth_key; + + # Trailing `/` is mandatory. Refer to the http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass + # If the proxy_pass directive is specified with a URI, then when a request is passed to the server, + # the part of a normalized request URI matching the location is replaced by a URI specified in the directive + proxy_pass http://http-adapter:${MF_HTTP_ADAPTER_PORT}/; + } + + # Proxy pass to mainflux-mqtt-adapter over WS + location /mqtt { + include snippets/verify-ssl-client.conf; + include snippets/proxy-headers.conf; + include snippets/ws-upgrade.conf; + proxy_pass http://mqtt_ws_cluster; + } + } } -error_log info.log info; From 041776e16d6c5f02ff26d0bac8472c602e1613a0 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 30 Sep 2021 17:51:25 +0200 Subject: [PATCH 6/8] fix space, identation Signed-off-by: mteodor --- docker/nginx/nginx-key.conf | 4 +--- docker/nginx/nginx-x509.conf | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/docker/nginx/nginx-key.conf b/docker/nginx/nginx-key.conf index 73c22296..04a23e8a 100644 --- a/docker/nginx/nginx-key.conf +++ b/docker/nginx/nginx-key.conf @@ -20,9 +20,8 @@ add_header Access-Control-Allow-Headers '*'; server_name localhost; - - # Proxy pass to users service + # Proxy pass to users service location ~ ^/(users|tokens|password) { include snippets/proxy-headers.conf; proxy_pass http://users:${MF_USERS_HTTP_PORT}; @@ -111,6 +110,5 @@ include snippets/proxy-headers.conf; proxy_pass http://ui:${MF_UI_PORT}; } - } diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index 66f1455c..e08f837e 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -2,10 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # This is the Mainflux NGINX configuration for mututal authentication based on X.509 certifiactes. - - - - server { listen 80 default_server; listen [::]:80 default_server; @@ -24,15 +20,12 @@ server_name localhost; - # Proxy pass to users service location ~ ^/(users|tokens|password) { include snippets/proxy-headers.conf; proxy_pass http://users:${MF_USERS_HTTP_PORT}; } - - # Proxy pass to things service location ~ ^/(things|channels|connect) { include snippets/proxy-headers.conf; @@ -91,6 +84,33 @@ include snippets/ws-upgrade.conf; proxy_pass http://mqtt_ws_cluster; } + + # Proxy pass to mainflux-influxdb-reader + location /reader/ { + include snippets/proxy-headers.conf; + proxy_pass http://influxdb-reader:${MF_INFLUX_READER_PORT}/; + } + + # Proxy pass to mainflux-bootstrap + location /bootstrap/ { + include snippets/proxy-headers.conf; + proxy_pass http://bootstrap:${MF_BOOTSTRAP_PORT}/; + } + + # Proxy pass to mainflux-opcua-adapter + location /browse { + include snippets/proxy-headers.conf; + proxy_pass http://opcua-adapter:${MF_OPCUA_ADAPTER_HTTP_PORT}; + } + + location ~ ^/(twins|states) { + include snippets/proxy-headers.conf; + proxy_pass http://twins:${MF_TWINS_HTTP_PORT}; + } + + location / { + include snippets/proxy-headers.conf; + proxy_pass http://ui:${MF_UI_PORT}; + } } -} From 2a7a31f82e6002ed5ce8faaeabd23bb6145b2ad8 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 30 Sep 2021 18:04:49 +0200 Subject: [PATCH 7/8] remove extra lines Signed-off-by: mteodor --- docker/nginx/nginx-x509.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index e08f837e..9fce1e3e 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -59,7 +59,6 @@ proxy_pass http://auth:${MF_AUTH_HTTP_PORT}; } - location /version { include snippets/proxy-headers.conf; proxy_pass http://things:${MF_THINGS_HTTP_PORT}; From 54a629646cb295cd4ef235f6f2993e071d3685d0 Mon Sep 17 00:00:00 2001 From: mteodor Date: Thu, 30 Sep 2021 18:05:52 +0200 Subject: [PATCH 8/8] remove extra lines Signed-off-by: mteodor --- docker/nginx/nginx-x509.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/nginx/nginx-x509.conf b/docker/nginx/nginx-x509.conf index 9fce1e3e..f9a464cb 100644 --- a/docker/nginx/nginx-x509.conf +++ b/docker/nginx/nginx-x509.conf @@ -38,7 +38,7 @@ add_header Access-Control-Expose-Headers Location; proxy_pass http://things:${MF_THINGS_AUTH_HTTP_PORT}; } - + # Proxy pass for groups to things service location ^~ /groups/things/ { include snippets/proxy-headers.conf;