diff --git a/Dockerfile b/Dockerfile index dd46ea0..c36ed60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ FROM proxy-scheduler:latest COPY scripts /scripts +COPY firewall-letsencrypt.json /firewall-files ENTRYPOINT ["/scripts/scheduler.sh"] diff --git a/alma.sh b/alma.sh new file mode 100755 index 0000000..f626041 --- /dev/null +++ b/alma.sh @@ -0,0 +1,371 @@ +#!/bin/sh + +GENERATE_CERTIFICATE=$GENERATE_CERTIFICATE + +cd /proxy_config + +FILENAME=$1 + +DOMAIN_SOURCE=/domains/$FILENAME +#DOMAIN_SOURCE=./domains/$FILENAME #TEMP +DOMAIN_NAME=$(jq -r .DOMAIN $DOMAIN_SOURCE) +HTTP_PORT=$(jq -r .HTTP_PORT $DOMAIN_SOURCE) +HTTPS_PORT=$(jq -r .HTTPS_PORT $DOMAIN_SOURCE); +ALIASES_HTTP=$(jq -r '.ALIASES_HTTP | select(.!="null") | join(" ")' $DOMAIN_SOURCE) +ALIASES_HTTPS=$(jq -r '.ALIASES_HTTPS | select(.!="null") | join(" ")' $DOMAIN_SOURCE) +REDIRECT_HTTP=$(jq -r .REDIRECT_HTTP $DOMAIN_SOURCE) +REDIRECT_HTTPS=$(jq -r .REDIRECT_HTTPS $DOMAIN_SOURCE) +ERROR_PAGE=$(jq -r .ERROR_PAGE $DOMAIN_SOURCE) +MAX_BODY_SIZE=$(jq -r .MAX_BODY_SIZE $DOMAIN_SOURCE) +DEBUG=$(jq -r .DEBUG $DOMAIN_SOURCE) +ALLOWED_NETWORK=$(jq -r '.ALLOWED_NETWORK | select(.!="null") | join(" ")' $DOMAIN_SOURCE) +OPERATION=$(jq -r '.OPERATION' $DOMAIN_SOURCE) +ALTERNATE_LOCATION_PATH=$(jq -r .ALTERNATE_LOCATION_PATH $DOMAIN_SOURCE) +LOCAL_NAME=$(jq -r .LOCAL_NAME $DOMAIN_SOURCE 2>/dev/null); +if [[ "$LOCAL_NAME" == "" || "$LOCAL_NAME" == "null" ]]; then + LOCAL_NAME=$(jq -r .LOCAL_IP $DOMAIN_SOURCE 2>/dev/null); +fi + +if [ -n "$2" ]; then + echo "$DOMAIN_NAME DELETED"; + rm $DOMAIN_NAME.conf; + exit; +fi + +add_alternate_location() { + { + cat $DOMAIN_NAME.conf | head -n -1 + add_location; + echo "}" + + } >> "$file" +} + +add_location() { + + if [[ "$ALTERNATE_LOCATION_PATH" != "" ]]; then + + ALP_IDX=$(jq -r '.ALTERNATE_LOCATION_PATH | length' $DOMAIN_SOURCE) + ALP_IDX=$(( $ALP_IDX - 1 )) + + for i in $(seq 0 $ALP_IDX) ; + do + ALP=$(jq -r .ALTERNATE_LOCATION_PATH[$i] $DOMAIN_SOURCE) + + ALP_LOCAL_PATH=$(echo $ALP | jq -rc .LOCAL_PATH); + ALP_LOCAL_NAME=$(echo $ALP | jq -rc .LOCAL_NAME); + ALP_LOCAL_PORT=$(echo $ALP | jq -rc .LOCAL_PORT); + ALP_LOCAL_ALLOWED_NETWORK=$(echo $ALP | jq -rc '.LOCAL_ALLOWED_NETWORK | select(.!="null") | join(" ")'); + + # do not duplicate locations + EXISTS=$(grep -rn "location /$ALP_LOCAL_PATH {" -m 1 $DOMAIN_NAME.conf); + if [ -n "$EXISTS" ]; then + # skip if exists + continue; + fi; + + if [[ "$ALP_LOCAL_NAME" = "" ]]; then + ALP_LOCAL_NAME=$LOCAL_NAME + fi; + + if [[ "$ALP_LOCAL_PORT" = "" ]]; then + ALP_LOCAL_PORT=$HTTP_PORT + fi; + + echo "location $ALP_LOCAL_PATH {" + + if [[ "$ALP_LOCAL_ALLOWED_NETWORK" != "" ]]; then + + for i in $(echo $ALP_LOCAL_ALLOWED_NETWORK) ; do + echo " allow "$i";" + done + echo " deny all;" + fi + + if [[ "$ALP_LOCAL_PORT" != "" ]]; then + echo " proxy_pass http://$ALP_LOCAL_NAME:$ALP_LOCAL_PORT;" + else + echo " proxy_pass http://$ALP_LOCAL_NAME:80;" + fi + + echo " proxy_set_header Host "'$http_host'"; + proxy_set_header X-Real-IP "'$remote_addr'"; + proxy_set_header X-Forwarded-For "'$proxy_add_x_forwarded_for'"; + proxy_set_header X-Forwarded-Proto "'$scheme'"; + proxy_set_header Upgrade "'$http_upgrade;'" + proxy_cookie_path $ALP_LOCAL_PATH $ALP_LOCAL_PATH; + proxy_set_header Connection "'$http_connection'"; + proxy_connect_timeout 300; + proxy_send_timeout 300; + proxy_read_timeout 300; + proxy_next_upstream off;" + + if [[ "$DEBUG" != "true" ]]; then + echo " access_log off;" + fi + echo " proxy_redirect off;" + echo " proxy_buffering off;" + echo "}" + echo "# location end" + done; + fi; + +} + +remove_alternate_location() { + + if [[ "$ALTERNATE_LOCATION_PATH" != "" ]]; then + + ALP_IDX=$(jq -r '.ALTERNATE_LOCATION_PATH | length' $DOMAIN_SOURCE) + ALP_IDX=$(( $ALP_IDX - 1 )) + + for i in $(seq 0 $ALP_IDX) ; + do + ALP=$(jq -r .ALTERNATE_LOCATION_PATH[$i] $DOMAIN_SOURCE) + ALP_LOCAL_PATH=$(echo $ALP | jq -rc .LOCAL_PATH); + remove_location $ALP_LOCAL_PATH + done; + fi; +} + +remove_location() { + local LOCATION=$1 + + LOCATION_ROW="location /$LOCATION {"; + ROW_NUMBER=$(grep -rn "$LOCATION_ROW" $DOMAIN_NAME.conf | cut -d ':' -f1); + OFFSET=$(tail -n+$ROW_NUMBER $DOMAIN_NAME.conf | grep -n '# location end' -m 1 | cut -d ':' -f1); + START=$(($ROW_NUMBER - 1)); + END=$(($ROW_NUMBER + $OFFSET)); + + { + head -n$START $DOMAIN_NAME.conf + tail -n+$END $DOMAIN_NAME.conf + } >> $file + + mv $file $DOMAIN_NAME.conf; +} + + +file="/tmp/$DOMAIN.conf" + +# check whether certificates exist or not + + +echo "created domain name: "$DOMAIN_NAME; + +#cp -a /scripts/nginx_template.conf /tmp/$DOMAIN.conf + +# if domain already exists as a config file append alternate location there +if [ -f $DOMAIN_NAME.conf ]; then + + if [ "$OPERATION" = "DELETE" ]; then + remove_alternate_location; + elif [ "$OPERATION" = "MODIFY" ]; then + remove_alternate_location; + add_alternate_location; + else + # default CREATE, append location + add_alternate_location; + fi; +else + +# create new nginx config +{ + +if [[ "$HTTP_PORT" != "80" ]]; then + echo "server { +listen 80 proxy_protocol;" + if [[ "$ALIASES_HTTP" != "" ]]; then + echo "server_name $DOMAIN_NAME $ALIASES_HTTP;" + else + echo "server_name $DOMAIN_NAME;" + fi +echo "set_real_ip_from 0.0.0.0/0; +real_ip_header proxy_protocol; +rewrite_log on; +return 301 https://$DOMAIN_NAME; +}" + +fi + +if [[ "$HTTP_PORT" != "" && "$HTTP_PORT" != "80" ]]; then + echo "server { + listen $HTTP_PORT proxy_protocol; + set_real_ip_from 0.0.0.0/0; + real_ip_header proxy_protocol;" + + if [[ "$ALIASES_HTTP" != "" ]]; then + echo "server_name $DOMAIN_NAME $ALIASES_HTTP;" + else + echo "server_name $DOMAIN_NAME;" + fi + + if [[ "$MAX_BODY_SIZE" != "" ]]; then + echo "client_max_body_size "$MAX_BODY_SIZE";" + + else + + echo "client_max_body_size 0;" + fi + + echo "rewrite_log on;" + + + if [[ "$REDIRECT_HTTP" != "" ]] ; then + echo "return 301 $REDIRECT_HTTP;" + elif [[ "$HTTP_PORT" == "" ]]; then + echo "return 301 https://"$DOMAIN_NAME; + + else + echo "location / {" + + if [[ "$ALLOWED_NETWORK" != "" ]]; then + ALLOWED_NETWORK_IDX=$(jq -r '.ALLOWED_NETWORK | length' $DOMAIN_SOURCE) + ALLOWED_NETWORK_IDX=$(( $ALLOWED_NETWORK_IDX - 1 )) + + for i in $(seq 0 $ALLOWED_NETWORK_IDX) ; do + AN=$(jq -r .ALLOWED_NETWORK[$i] $DOMAIN_SOURCE) + echo " allow "$AN";" + done + echo " deny all;" + fi + + if [[ "$HTTP_PORT" != "" ]]; then + echo " proxy_pass http://$LOCAL_NAME:$HTTP_PORT;" + fi + + echo " proxy_set_header Host "'$http_host'"; + proxy_set_header X-Real-IP "'$remote_addr'"; + proxy_set_header X-Forwarded-For "'$proxy_add_x_forwarded_for'"; + proxy_set_header X-Forwarded-Proto "'$scheme'"; + proxy_set_header Upgrade "'$http_upgrade;'" + proxy_cookie_path / /; + proxy_set_header Connection "'$http_connection'" ;" + + if [[ "$DEBUG" != "true" ]]; then + echo " access_log off;" + fi + echo " proxy_redirect off;" + echo " proxy_buffering off;" + echo "}" + + if [[ "$ERROR_PAGE" != "" && "$HTTP_PORT" != "" ]]; then + echo "error_page 404 /$ERROR_PAGE; + location = /$ERROR_PAGE { + root html; + allow all; + index 404.html; + rewrite ^ "'$scheme'" http://$ERROR_PAGE"'$request_uri'" permanent; + }" + fi + fi + echo "}" +fi + +if [[ "$HTTPS_PORT" != "" ]]; then + echo "server { +listen 443 ssl proxy_protocol; +set_real_ip_from 0.0.0.0/0; +real_ip_header proxy_protocol;" + +if [[ "$ALIASES_HTTPS" != "" ]]; then + echo "server_name $DOMAIN_NAME $ALIASES_HTTPS;" +else + echo "server_name $DOMAIN_NAME;" +fi + +if [[ "$MAX_BODY_SIZE" != "" ]]; then + echo "client_max_body_size "$MAX_BODY_SIZE";" +else + echo "client_max_body_size 0;" +fi + +echo "rewrite_log on; +proxy_ssl_server_name on; + ssl_dhparam /etc/ssl/keys/$DOMAIN_NAME/dhparam.pem;" + +if [ "$GENERATE_CERTIFICATE" == "true" ]; then + +echo "ssl_certificate /etc/ssl/keys/$DOMAIN_NAME/fullchain.pem; + ssl_certificate_key /etc/ssl/keys/$DOMAIN_NAME/key.pem;" + +else + echo "ssl_certificate /etc/ssl/keys/fullchain.pem; + ssl_certificate_key /etc/ssl/keys/key.pem;" + +fi + +echo "ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "'"EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !kDHE"'"; +ssl_session_cache shared:SSL:50m; +ssl_session_timeout 5m; +ssl_stapling on;" + + + if [[ "$ERROR_PAGE" != "" && "$HTTPS_PORT" != "" ]]; then + echo "error_page 404 /$ERROR_PAGE; +location = /$ERROR_PAGE { + root html; + allow all; + index 404.html; + rewrite ^ "'$scheme' "http://$ERROR_PAGE"'$request_uri'" permanent; + }" + fi + + if [[ "$REDIRECT_HTTPS" != "" ]]; then + echo "return 301 $REDIRECT_HTTPS;" + else + echo "location / {" + + if [[ "$ALLOWED_NETWORK" != "" ]]; then + ALLOWED_NETWORK_IDX=$(jq -r '.ALLOWED_NETWORK | length' $DOMAIN_SOURCE) + ALLOWED_NETWORK_IDX=$(( $ALLOWED_NETWORK_IDX - 1 )) + + for i in $(seq 0 $ALLOWED_NETWORK_IDX) ; do + AN=$(jq -r .ALLOWED_NETWORK[$i] $DOMAIN_SOURCE) + echo " allow "$AN";" + done + echo " deny all;" + fi +echo " proxy_pass http://$LOCAL_NAME:$HTTPS_PORT;" + + echo " proxy_set_header Host "'$http_host'"; + proxy_set_header X-Real-IP "'$remote_addr'"; + proxy_set_header X-Forwarded-For "'$proxy_add_x_forwarded_for'"; + proxy_set_header X-Forwarded-Proto "'$scheme'"; + proxy_set_header Upgrade "'$http_upgrade;'" + proxy_cookie_path / /; + proxy_set_header Connection "'$http_connection'"; + proxy_connect_timeout 300; + proxy_send_timeout 300; + proxy_read_timeout 300; + proxy_next_upstream off;" + + if [[ "$DEBUG" != "true" ]]; then + echo " access_log off;" + fi + echo " proxy_redirect off;" + echo " proxy_buffering off;" + echo "}" + + add_location; + + fi + +echo "}" + +fi + +} >> "$file" + +fi; # end of create new nginx config + +if [ "$OPERATION" != "DELETE" ]; then + mv $file $DOMAIN_NAME.conf; +fi; +echo "$DOMAIN" >> new_config + +if [ "$HTTPS_PORT" != "" ]; then + /scripts/check_certificates.sh "$DOMAIN_NAME"; +fi diff --git a/firewall-letsencrypt.json b/firewall-letsencrypt.json new file mode 100644 index 0000000..c5d074b --- /dev/null +++ b/firewall-letsencrypt.json @@ -0,0 +1,62 @@ +{ + "main": { + "SERVICE_NAME": "firewalls", + "DOMAIN": "null" + }, + "containers": [ + { + "IMAGE": "registry.format.hu/firewall", + "NAME": "firewall", + "MEMORY": "64M", + "NETWORK": "host", + "SCALE": "0", + "VOLUMES": [ + { + "SOURCE": "/run/", + "DEST": "/run/", + "TYPE": "rw" + }, + { + "SOURCE": "/etc/user/config/services", + "DEST": "/services", + "TYPE": "ro" + }, + { + "SOURCE": "/etc/system/data/dns/hosts.local", + "DEST": "/etc/dns/hosts.local", + "TYPE": "ro" + }, + { + "SOURCE": "/var/run/docker.sock", + "DEST": "/var/run/docker.sock", + "TYPE": "rw" + }, + { + "SOURCE": "/usr/bin/docker", + "DEST": "/usr/bin/docker", + "TYPE": "ro" + } + ], + "PORTS": [ ], + "READYNESS": [ + {"tcp": ""}, + {"HTTP": ""}, + {"EXEC": "/ready.sh"} + ], + "ENVS": [ + { "CHAIN": "DOCKER-USER" }, + { "SOURCE": "smarthostloadbalancer" }, + { "TARGET": "letsencrypt" }, + { "TYPE": "tcp" }, + { "TARGET_PORT": "80" }, + { "COMMENT": "letsencrypt" } + ], + "EXTRA": "--privileged --rm", + "DEPEND": "null", + "START_ON_BOOT": "false", + "CMD": "null", + "PRE_START": "null", + "POST_START": "null" + } + ] +} diff --git a/myfile b/myfile new file mode 100644 index 0000000..ece1839 --- /dev/null +++ b/myfile @@ -0,0 +1,24 @@ +registry.format.hu/firewall +latest +registry.format.hu/setup +latest +registry.format.hu/alpine/nginx +1.21.6 +registry.format.hu/openvpn +latest +registry.format.hu/alpine/apache-php8 +latest +registry.format.hu/haproxy +2.2.5 +registry.format.hu/dnsmasq +latest +registry.format.hu/wireguard-server +latest +registry.format.hu/alpine/nginx +latest +registry.format.hu/alpine/mariadb +latest +registry.format.hu/zabbix-nginx +latest +registry.format.hu/zabbix-server +latest diff --git a/new_config b/new_config new file mode 100644 index 0000000..fbc322b --- /dev/null +++ b/new_config @@ -0,0 +1 @@ +test.format.hu diff --git a/scripts/check_certificates.sh b/scripts/check_certificates.sh index bf235a3..297d1de 100755 --- a/scripts/check_certificates.sh +++ b/scripts/check_certificates.sh @@ -72,7 +72,8 @@ letsencrypt_certificates() { LETS_ENCRYPT_VALUE="$(docker ps | grep letsencrypt | grep Up | wc -l)"; if [[ $LETS_ENCRYPT_VALUE -eq 0 ]] ; then echo "Starting letsencrypt process"; - LETSENCRYPT_TEMP_SERVICE_FILE=$(mktemp -p /tmp/); + cp -av /firewall-files/firewall-letsencrypt.json /tmp/; + LETSENCRYPT_TEMP_SERVICE_FILE=$(mktemp -p /tmp/)".json"; ENVS='[ {"DOMAIN": "'$DOMAIN'"}, {"TIMEOUT": "'$TIMEOUT'"}, @@ -86,7 +87,8 @@ letsencrypt_certificates() { } '; jq '.containers[0].ENVS |='"$ENVS"' | .containers[0].VOLUMES[.containers[0].VOLUMES|length]|='"$VOLUMES" $SERVICE_FILES/$LETSENCRYPT_SERVICE_NAME > $LETSENCRYPT_TEMP_SERVICE_FILE; - $service_exec $(basename $LETSENCRYPT_TEMP_SERVICE_FILE) start info; + $service_exec $(basename ${LETSENCRYPT_TEMP_SERVICE_FILE%.*}) start info; + rm -v /tmp/firewall-letsencrypt.json ; break; else echo "Waiting "$TIMEOUT" second for previous letsencrypt process ending"; diff --git a/test.format.hu.conf b/test.format.hu.conf new file mode 100644 index 0000000..e69de29