From cd2f4720340debe60b2cf5b778d6678fa9e62424 Mon Sep 17 00:00:00 2001 From: OscarSotoSanchez Date: Thu, 30 Apr 2020 14:27:40 +0200 Subject: [PATCH] proxy ip restrictions added --- .../docker/openvidu-docker-compose/.env | 26 ++--- .../docker-compose.yml | 2 +- .../docker/openvidu-proxy/Dockerfile | 11 +- .../ce/default-app-without-demos.conf | 19 ++- .../default_nginx_conf/ce/default-app.conf | 19 ++- .../pro/default-app-without-demos.conf | 42 +++++-- .../default_nginx_conf/pro/default.conf | 42 +++++-- .../openvidu-proxy/discover_my_public_ip.sh | 47 ++++++++ .../docker/openvidu-proxy/entrypoint.sh | 110 ++++++++++++++++++ 9 files changed, 271 insertions(+), 47 deletions(-) create mode 100755 openvidu-server/docker/openvidu-proxy/discover_my_public_ip.sh diff --git a/openvidu-server/docker/openvidu-docker-compose/.env b/openvidu-server/docker/openvidu-docker-compose/.env index dfdd8318..b7d20bbb 100644 --- a/openvidu-server/docker/openvidu-docker-compose/.env +++ b/openvidu-server/docker/openvidu-docker-compose/.env @@ -40,23 +40,23 @@ LETSENCRYPT_EMAIL=user@example.com # HTTPS_PORT=443 # Access restrictions -# In this section you will be able to restrict the ips from which you can access to +# In this section you will be able to restrict the IPs from which you can access to # Openvidu API and the Administration Panel -# WARNING! If you touch this configuration you can lose access to the platform from some IPs, -# use it carefully. +# WARNING! If you touch this configuration you can lose access to the platform from some IPs. +# Use it carefully. -# This section limits access to the /dashboard and /inspector page. -# The form for a single IP or RANGE is: -# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1 and ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1/24 -# To limit multiple IPs or RANGESs, separate by commas: -# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1, 198.51.100.1/24 +# This section limits access to the /dashboard (OpenVidu CE) and /inspector (OpenVidu Pro) pages. +# The form for a single IP or an IP range is: +# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1 and ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.0/24 +# To limit multiple IPs or IP ranges, separate by commas like this: +# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1, 198.51.100.0/24 # ALLOWED_ACCESS_TO_DASHBOARD= -# This section limits access to the Openvidu API. -# The form for a single IP or RANGE is: -# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1 and ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1/24 -# To limit multiple IPs or RANGEs, separate by commas: -# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1, 198.51.100.1/24 +# This section limits access to the Openvidu REST API. +# The form for a single IP or an IP range is: +# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1 and ALLOWED_ACCESS_TO_RESTAPI=198.51.100.0/24 +# To limit multiple IPs or or IP ranges, separate by commas like this: +# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1, 198.51.100.0/24 # ALLOWED_ACCESS_TO_RESTAPI= # Whether to enable recording module or not diff --git a/openvidu-server/docker/openvidu-docker-compose/docker-compose.yml b/openvidu-server/docker/openvidu-docker-compose/docker-compose.yml index 0fa31f30..2d46c6b7 100644 --- a/openvidu-server/docker/openvidu-docker-compose/docker-compose.yml +++ b/openvidu-server/docker/openvidu-docker-compose/docker-compose.yml @@ -67,7 +67,7 @@ services: - MAX_PORT=65535 nginx: - image: openvidu/openvidu-proxy:2.0.0-beta1 + image: openvidu/openvidu-proxy:2.0.0-beta2 restart: on-failure network_mode: host volumes: diff --git a/openvidu-server/docker/openvidu-proxy/Dockerfile b/openvidu-server/docker/openvidu-proxy/Dockerfile index de6f9271..4c7de9e4 100644 --- a/openvidu-server/docker/openvidu-proxy/Dockerfile +++ b/openvidu-server/docker/openvidu-proxy/Dockerfile @@ -1,19 +1,24 @@ FROM nginx:1.18.0-alpine -# Install certbot +# Install required software RUN apk update && \ + apk add bash && \ apk add certbot && \ apk add openssl && \ apk add apache2-utils && \ + apk add ipcalc && \ rm -rf /var/cache/apk/* # Default nginx conf COPY ./default.conf /etc/nginx/conf.d/default.conf COPY ./default_nginx_conf /default_nginx_conf -# Entrypoint +# Entrypoint and discover public ip scripts +COPY ./discover_my_public_ip.sh /usr/local/bin COPY ./entrypoint.sh /usr/local/bin + RUN mkdir -p /var/www/certbot && \ - chmod +x /usr/local/bin/entrypoint.sh + chmod +x /usr/local/bin/entrypoint.sh && \ + chmod +x /usr/local/bin/discover_my_public_ip.sh CMD /usr/local/bin/entrypoint.sh diff --git a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app-without-demos.conf b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app-without-demos.conf index 35c1bd9a..22c5a6d4 100644 --- a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app-without-demos.conf +++ b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app-without-demos.conf @@ -46,6 +46,13 @@ server { # proxy_pass http://yourapp; # Openvidu call by default #} + # Openvidu Admin Panel + location /dashboard { + {rules_access_dashboard} + deny all; + proxy_pass http://openviduserver; + } + # Openvidu Server location /layouts/custom { rewrite ^/layouts/custom/(.*)$ /custom-layout/$1 break; @@ -57,6 +64,8 @@ server { } location /api { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -65,10 +74,14 @@ server { } location /info { + {rules_access_dashboard} + deny all; proxy_pass http://openviduserver; } location /config { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -77,10 +90,8 @@ server { } location /cdr { - proxy_pass http://openviduserver; - } - - location /dashboard { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } } diff --git a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app.conf b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app.conf index 3a3aeab9..a3c1787e 100644 --- a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app.conf +++ b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/ce/default-app.conf @@ -46,6 +46,13 @@ server { proxy_pass http://yourapp; # Openvidu call by default } + # Openvidu Admin Panel + location /dashboard { + {rules_access_dashboard} + deny all; + proxy_pass http://openviduserver; + } + # Openvidu Server location /layouts/custom { rewrite ^/layouts/custom/(.*)$ /custom-layout/$1 break; @@ -57,6 +64,8 @@ server { } location /api { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -65,10 +74,14 @@ server { } location /info { + {rules_access_dashboard} + deny all; proxy_pass http://openviduserver; } location /config { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -77,10 +90,8 @@ server { } location /cdr { - proxy_pass http://openviduserver; - } - - location /dashboard { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } } diff --git a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default-app-without-demos.conf b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default-app-without-demos.conf index 778d00e5..58a72c7e 100644 --- a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default-app-without-demos.conf +++ b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default-app-without-demos.conf @@ -72,8 +72,23 @@ server { # Welcome root /var/www/html; - # Kibana panel + # Openvidu Admin Panel + location /dashboard { + {rules_access_dashboard} + deny all; + rewrite ^/dashboard/(.*)$ /$1 break; + proxy_pass http://openviduserver/; + } + + location /inspector { + {rules_access_dashboard} + deny all; + proxy_pass http://openviduserver; + } + location /kibana { + {rules_access_dashboard} + deny all; auth_basic "Openvidu Monitoring"; auth_basic_user_file /etc/nginx/kibana.htpasswd; @@ -92,6 +107,8 @@ server { } location /api { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -100,10 +117,14 @@ server { } location /info { + {rules_access_dashboard} + deny all; proxy_pass http://openviduserver; } location /config { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -111,29 +132,28 @@ server { proxy_pass http://openviduserver; } - location /dashboard { - rewrite ^/dashboard/(.*)$ /$1 break; - proxy_pass http://openviduserver/; - } - - # Openvidu Server Pro location /cdr { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } + # Openvidu Server Pro location /pro { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } location /api-login { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } location /elasticsearch { - proxy_pass http://openviduserver; - } - - location /inspector { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } } diff --git a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default.conf b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default.conf index 364c14c5..ff98de0f 100644 --- a/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default.conf +++ b/openvidu-server/docker/openvidu-proxy/default_nginx_conf/pro/default.conf @@ -82,8 +82,23 @@ server { proxy_pass http://yourapp; # Openvidu call by default } - # Kibana panel + # Openvidu Admin Panel + location /dashboard { + {rules_access_dashboard} + deny all; + rewrite ^/dashboard/(.*)$ /$1 break; + proxy_pass http://openviduserver/; + } + + location /inspector { + {rules_access_dashboard} + deny all; + proxy_pass http://openviduserver; + } + location /kibana { + {rules_access_dashboard} + deny all; auth_basic "Openvidu Monitoring"; auth_basic_user_file /etc/nginx/kibana.htpasswd; @@ -102,6 +117,8 @@ server { } location /api { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -110,10 +127,14 @@ server { } location /info { + {rules_access_dashboard} + deny all; proxy_pass http://openviduserver; } location /config { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } @@ -121,29 +142,28 @@ server { proxy_pass http://openviduserver; } - location /dashboard { - rewrite ^/dashboard/(.*)$ /$1 break; - proxy_pass http://openviduserver/; - } - - # Openvidu Server Pro location /cdr { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } + # Openvidu Server Pro location /pro { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } location /api-login { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } location /elasticsearch { - proxy_pass http://openviduserver; - } - - location /inspector { + {rules_acess_api} + deny all; proxy_pass http://openviduserver; } } diff --git a/openvidu-server/docker/openvidu-proxy/discover_my_public_ip.sh b/openvidu-server/docker/openvidu-proxy/discover_my_public_ip.sh new file mode 100755 index 00000000..b42b3a97 --- /dev/null +++ b/openvidu-server/docker/openvidu-proxy/discover_my_public_ip.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Check if a txt is a valid ip +function valid_ip() +{ + local ip=$1 + local stat=1 + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + OIFS=$IFS + IFS='.' + ip=($ip) + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] + stat=$? + fi + return $stat +} + +# Services to get public ip +SERVICES=( + "curl --silent -sw :%{http_code} ipv4.icanhazip.com" + "curl --silent -sw :%{http_code} ifconfig.me" + "curl --silent -sw :%{http_code} -4 ifconfig.co" + "curl --silent -sw :%{http_code} ipecho.net/plain" + "curl --silent -sw :%{http_code} ipinfo.io/ip" + "curl --silent -sw :%{http_code} checkip.amazonaws.com" + "curl --silent -sw :%{http_code} v4.ident.me" +) + +# Get public ip +for service in "${SERVICES[@]}"; do + RUN_COMMAND=$($service | tr -d '[:space:]') + IP=$(echo "$RUN_COMMAND" | cut -d':' -f1) + HTTP_CODE=$(echo "$RUN_COMMAND" | cut -d':' -f2) + + if [ "$HTTP_CODE" == "200" ]; then + if valid_ip "$IP"; then + printf "%s" "$IP" + exit 0 + fi + fi +done + +printf "error" +exit 0 \ No newline at end of file diff --git a/openvidu-server/docker/openvidu-proxy/entrypoint.sh b/openvidu-server/docker/openvidu-proxy/entrypoint.sh index 99d2575a..3169d507 100644 --- a/openvidu-server/docker/openvidu-proxy/entrypoint.sh +++ b/openvidu-server/docker/openvidu-proxy/entrypoint.sh @@ -2,6 +2,8 @@ [ -z "${PROXY_HTTP_PORT}" ] && export PROXY_HTTP_PORT=80 [ -z "${PROXY_HTTPS_PORT}" ] && export PROXY_HTTPS_PORT=443 +[ -z "${ALLOWED_ACCESS_TO_DASHBOARD}" ] && export ALLOWED_ACCESS_TO_DASHBOARD=all +[ -z "${ALLOWED_ACCESS_TO_RESTAPI}" ] && export ALLOWED_ACCESS_TO_RESTAPI=all # Start with default certbot conf nginx -g "daemon on;" @@ -9,6 +11,8 @@ nginx -g "daemon on;" # Show input enviroment variables echo "Http Port: ${PROXY_HTTP_PORT}" echo "Https Port: ${PROXY_HTTPS_PORT}" +echo "Allowed Dashboard: ${ALLOWED_ACCESS_TO_DASHBOARD}" +echo "Allowed API: ${ALLOWED_ACCESS_TO_RESTAPI}" echo "Domain name: ${DOMAIN_OR_PUBLIC_IP}" echo "Certificated: ${CERTIFICATE_TYPE}" echo "Letsencrypt Email: ${LETSENCRYPT_EMAIL}" @@ -108,6 +112,112 @@ sed -i "s/{domain_name}/${DOMAIN_OR_PUBLIC_IP}/g" /etc/nginx/conf.d/* sed -i "s/{http_port}/${PROXY_HTTP_PORT}/g" /etc/nginx/conf.d/* sed -i "s/{https_port}/${PROXY_HTTPS_PORT}/g" /etc/nginx/conf.d/* +# NGINX access +LOCAL_NETWORKS=$(ip route list | grep -Eo '([0-9]*\.){3}[0-9]*/[0-9]*') +PUBLIC_IP=$(/usr/local/bin/discover_my_public_ip.sh) + +valid_ip_v4() +{ + if ipcalc "$1" \ + | awk 'BEGIN{FS=":"; is_invalid=0} /^INVALID/ {is_invalid=1} END {exit is_invalid}' + then + return "$?" + else + return "$?" + fi +} + +if [ "${ALLOWED_ACCESS_TO_DASHBOARD}" != "all" ]; then + IFS=',' + for IP in $(echo "${ALLOWED_ACCESS_TO_DASHBOARD}" | tr -d '[:space:]') + do + if valid_ip_v4 "$IP"; then + if [ -z "${RULES_DASHBOARD}" ]; then + RULES_DASHBOARD="allow $IP;" + else + if ! echo "${RULES_DASHBOARD}" | grep -q "$IP"; then + RULES_DASHBOARD="${RULES_DASHBOARD}{new_line}allow $IP;" + fi + fi + + if [ -z "${RULES_RESTAPI}" ]; then + RULES_RESTAPI="allow $IP;" + else + if ! echo "${RULES_RESTAPI}" | grep -q "$IP"; then + RULES_RESTAPI="${RULES_RESTAPI}{new_line}allow $IP;" + fi + fi + else + echo "Ip or range $IP is not valid" + fi + done +else + RULES_DASHBOARD="allow all;" +fi + +if [ "${ALLOWED_ACCESS_TO_RESTAPI}" != "all" ]; then + IFS=',' + for IP in $(echo "${ALLOWED_ACCESS_TO_RESTAPI}" | tr -d '[:space:]') + do + if valid_ip_v4 "$IP"; then + if [ -z "${RULES_RESTAPI}" ]; then + RULES_RESTAPI="allow $IP;" + else + if ! echo "${RULES_RESTAPI}" | grep -q "$IP"; then + RULES_RESTAPI="${RULES_RESTAPI}{new_line}allow $IP;" + fi + fi + else + echo "Ip or range $IP is not valid" + fi + done +else + RULES_RESTAPI="allow all;" +fi + +if [ "${RULES_DASHBOARD}" != "allow all;" ]; then + if ! echo "${RULES_DASHBOARD}" | grep -q "$PUBLIC_IP" && valid_ip_v4 "$PUBLIC_IP"; then + RULES_DASHBOARD="${RULES_DASHBOARD}{new_line}allow $PUBLIC_IP;" + fi + + if ! echo "${RULES_DASHBOARD}" | grep -q "127.0.0.1"; then + RULES_DASHBOARD="${RULES_DASHBOARD}{new_line}allow 127.0.0.1;" + fi + + IFS=$'\n' + for IP in ${LOCAL_NETWORKS} + do + if ! echo "${RULES_DASHBOARD}" | grep -q "$IP" && valid_ip_v4 "$IP"; then + RULES_DASHBOARD="${RULES_DASHBOARD}{new_line}allow $IP;" + fi + done +fi + +if [ "${RULES_RESTAPI}" != "allow all;" ]; then + if ! echo "${RULES_RESTAPI}" | grep -q "$PUBLIC_IP" && valid_ip_v4 "$PUBLIC_IP"; then + RULES_RESTAPI="${RULES_RESTAPI}{new_line}allow $PUBLIC_IP;" + fi + + if ! echo "${RULES_DASHBOARD}" | grep -q "127.0.0.1"; then + RULES_DASHBOARD="${RULES_DASHBOARD}{new_line}allow 127.0.0.1;" + fi + + IFS=$'\n' + for IP in ${LOCAL_NETWORKS} + do + if ! echo "${RULES_RESTAPI}" | grep -q "$IP" && valid_ip_v4 "$IP"; then + RULES_RESTAPI="${RULES_RESTAPI}{new_line}allow $IP;" + fi + done +fi + +sed -i "s/{rules_access_dashboard}/$(echo "${RULES_DASHBOARD}" | sed 's#/#\\/#g')/g" /etc/nginx/conf.d/* +sed -i "s/{rules_acess_api}/$(echo "${RULES_RESTAPI}" | sed 's#/#\\/#g')/g" /etc/nginx/conf.d/* +sed -i "s/{new_line}/\n\t/g" /etc/nginx/conf.d/* # New line + +printf "Rules DASHBOARD: \n \t%s\n" "$(echo "${RULES_DASHBOARD}" | sed 's/{new_line}/\n\t/g')" +printf "Rules RESTAPI: \n \t%s\n" "$(echo "${RULES_RESTAPI}" | sed 's/{new_line}/\n\t/g')" + # Restart nginx service nginx -s reload