diff --git a/.gitignore b/.gitignore index d64f84c..465789d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,10 @@ .AppleDouble .LSOverride Desktop.ini - +.env # Icon must end with two \r Icon - +.yml # Compiled Python files *.pyc diff --git a/Dockerfile b/Dockerfile old mode 100644 new mode 100755 index f8d162f..63c9e5d --- a/Dockerfile +++ b/Dockerfile @@ -1,34 +1,148 @@ -FROM alpine:3.8 -MAINTAINER Thomas Spicer (thomas@openbridge.com) +# Stage 1: Build NGINX with modules +FROM alpine:3.21 AS builder -ARG NGINX_VERSION +# Build arguments for better versioning +ARG NGINX_VERSION=1.27.4 +ARG NGX_BROTLI_COMMIT=master +ARG NGX_NDK_VERSION=0.3.3 +ARG NGX_SET_MISC_VERSION=0.33 +ARG NGX_REDIS_VERSION=0.4.1-cmm +ARG NGX_REDIS2_VERSION=0.15 +ARG NGX_SRCACHE_VERSION=0.33 +ARG NGX_CACHE_PURGE_VERSION=2.3 +# Enhanced metadata +LABEL maintainer="Thomas Spicer (thomas@openbridge.com)" +LABEL org.opencontainers.image.version="${NGINX_VERSION}" +LABEL org.opencontainers.image.description="NGINX with enhanced modules" +LABEL org.opencontainers.image.licenses="MIT" + +# Define environment variables ENV VAR_PREFIX=/var/run \ LOG_PREFIX=/var/log/nginx \ TEMP_PREFIX=/tmp \ CACHE_PREFIX=/var/cache \ CONF_PREFIX=/etc/nginx \ - CERTS_PREFIX=/etc/pki/tls + CERTS_PREFIX=/etc/pki/tls \ + NGINX_DOCROOT=/usr/share/nginx/html \ + GEOIP_PREFIX=/usr/share/geoip + +# Set working directory to NGINX_DOCROOT +WORKDIR ${NGINX_DOCROOT} + +# Create www-data user and group +RUN if ! getent group www-data >/dev/null; then \ + addgroup -g 82 -S www-data; \ + fi \ + && if ! getent passwd www-data >/dev/null; then \ + adduser -u 82 -D -S -h /var/cache/nginx -s /sbin/nologin -G www-data www-data; \ + fi + +# Install build dependencies +RUN apk add --no-cache --virtual .build-deps \ + alpine-sdk \ + autoconf \ + automake \ + binutils \ + build-base \ + ca-certificates \ + cmake \ + findutils \ + g++ \ + gcc \ + gd-dev \ + geoip-dev \ + gettext \ + git \ + gnupg \ + go \ + gzip \ + libc-dev \ + libgcc \ + libstdc++ \ + libedit-dev \ + libmaxminddb-dev \ + libtool \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + mercurial \ + musl-dev \ + ninja \ + openssl-dev \ + pcre-dev \ + perl-dev \ + readline-dev \ + unzip \ + zlib-dev \ + zstd-dev + +# Install runtime dependencies +RUN apk add --no-cache \ + bash \ + curl \ + libmaxminddb-libs \ + openssl \ + pcre \ + tar \ + tini \ + wget + +# Handle envsubst installation +RUN apk add --no-cache gettext \ + && mv /usr/bin/envsubst /tmp/envsubst \ + && runDeps="$( \ + scanelf --needed --nobanner /tmp/envsubst \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u \ + )" \ + && apk add --no-cache --virtual .envsubst-deps $runDeps \ + && mv /tmp/envsubst /usr/local/bin/ + +# Download and prepare all modules +RUN set -x \ + && mkdir -p /usr/src \ + && cd /tmp \ + && git clone --depth=1 --branch ${NGX_BROTLI_COMMIT} https://github.com/google/ngx_brotli \ + && cd ngx_brotli && git submodule update --init && cd .. \ + && git clone https://github.com/openresty/echo-nginx-module.git \ + && git clone https://github.com/tokers/zstd-nginx-module.git \ + && git clone https://github.com/nginx/njs.git \ + && git clone https://github.com/leev/ngx_http_geoip2_module.git \ + && git clone https://github.com/openresty/headers-more-nginx-module.git \ + && wget -O dev.zip https://github.com/vision5/ngx_devel_kit/archive/v${NGX_NDK_VERSION}.zip \ + && wget -O setmisc.zip https://github.com/openresty/set-misc-nginx-module/archive/v${NGX_SET_MISC_VERSION}.zip \ + && wget -O ngx.zip https://github.com/centminmod/ngx_http_redis/archive/${NGX_REDIS_VERSION}.zip \ + && wget -O redis.zip https://github.com/openresty/redis2-nginx-module/archive/v${NGX_REDIS2_VERSION}.zip \ + && wget -O cache.zip https://github.com/openresty/srcache-nginx-module/archive/v${NGX_SRCACHE_VERSION}.zip \ + && wget -O purge.zip https://github.com/FRiCKLE/ngx_cache_purge/archive/${NGX_CACHE_PURGE_VERSION}.zip \ + && unzip '*.zip' \ + && wget -O nginx.tar.gz http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz \ + && tar -zxvf nginx.tar.gz -C /usr/src \ + && rm nginx.tar.gz -RUN set -x \ - && CONFIG="\ +# NGINX configuration +ENV CONFIG="\ --prefix=/usr/share/nginx/ \ --sbin-path=/usr/sbin/nginx \ - --add-module=/tmp/naxsi/naxsi_src \ --modules-path=/usr/lib/nginx/modules \ --conf-path=${CONF_PREFIX}/nginx.conf \ --error-log-path=${LOG_PREFIX}/error.log \ --http-log-path=${LOG_PREFIX}/access.log \ --pid-path=${VAR_PREFIX}/nginx.pid \ --lock-path=${VAR_PREFIX}/nginx.lock \ - --http-client-body-temp-path=${TEMP_PREFIX}/client_temp \ - --http-proxy-temp-path=${TEMP_PREFIX}/proxy_temp \ - --http-fastcgi-temp-path=${TEMP_PREFIX}/fastcgi_temp \ - --http-uwsgi-temp-path=${TEMP_PREFIX}/uwsgi_temp \ - --http-scgi-temp-path=${TEMP_PREFIX}/scgi_temp \ + --http-client-body-temp-path=${CACHE_PREFIX}/client_temp \ + --http-proxy-temp-path=${CACHE_PREFIX}/proxy_temp \ + --http-fastcgi-temp-path=${CACHE_PREFIX}/fastcgi_temp \ + --http-uwsgi-temp-path=${CACHE_PREFIX}/uwsgi_temp \ + --http-scgi-temp-path=${CACHE_PREFIX}/scgi_temp \ --user=www-data \ --group=www-data \ --with-http_ssl_module \ + --with-openssl-opt=enable-ktls \ --with-pcre-jit \ --with-http_realip_module \ --with-http_addition_module \ @@ -36,6 +150,7 @@ RUN set -x \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ + --with-http_geoip_module=dynamic \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_random_index_module \ @@ -44,7 +159,6 @@ RUN set -x \ --with-http_auth_request_module \ --with-http_xslt_module=dynamic \ --with-http_image_filter_module=dynamic \ - --with-http_geoip_module=dynamic \ --with-threads \ --with-stream \ --with-stream_ssl_module \ @@ -57,148 +171,119 @@ RUN set -x \ --with-compat \ --with-file-aio \ --with-http_v2_module \ - --add-module=/tmp/ngx_cache_purge-2.3 \ - --add-module=/tmp/ngx_http_redis-0.3.8 \ - --add-module=/tmp/redis2-nginx-module-0.15 \ - --add-module=/tmp/srcache-nginx-module-0.31 \ + --with-http_v3_module \ + --add-module=/tmp/ngx_cache_purge-${NGX_CACHE_PURGE_VERSION} \ + --add-module=/tmp/ngx_http_redis-${NGX_REDIS_VERSION} \ + --add-dynamic-module=/tmp/ngx_http_geoip2_module \ + --add-module=/tmp/redis2-nginx-module-${NGX_REDIS2_VERSION} \ + --add-module=/tmp/srcache-nginx-module-${NGX_SRCACHE_VERSION} \ --add-module=/tmp/echo-nginx-module \ - --add-module=/tmp/ngx_devel_kit-0.3.0 \ - --add-module=/tmp/set-misc-nginx-module-0.32 \ + --add-module=/tmp/ngx_devel_kit-${NGX_NDK_VERSION} \ + --add-module=/tmp/set-misc-nginx-module-${NGX_SET_MISC_VERSION} \ --add-module=/tmp/ngx_brotli \ + --add-module=/tmp/zstd-nginx-module \ + --add-module=/tmp/headers-more-nginx-module \ + --with-ld-opt='-L/usr/lib' \ --with-cc-opt=-Wno-error \ - " \ - && addgroup -g 82 -S www-data \ - && adduser -u 82 -D -S -h /var/cache/nginx -s /sbin/nologin -G www-data www-data \ - && apk add --no-cache --virtual .build-deps \ - build-base \ - ca-certificates \ - automake \ - autoconf \ - git \ - jemalloc-dev \ - libtool \ - binutils \ - gnupg \ - cmake \ - go \ - gcc \ - build-base \ - libc-dev \ - make \ - wget \ - gzip \ - libressl-dev \ - musl-dev \ - pcre-dev \ - zlib-dev \ - geoip-dev \ - git \ - linux-headers \ - gnupg \ - libxslt-dev \ - gd-dev \ - unzip \ - && apk add --no-cache --update \ - curl \ - monit \ - bash \ - bind-tools \ - rsync \ - geoip \ - libressl \ - tini \ - tar \ - && cd /tmp \ - && git clone https://github.com/google/ngx_brotli --depth=1 \ - && cd ngx_brotli && git submodule update --init \ - && export NGX_BROTLI_STATIC_MODULE_ONLY=1 \ - && cd /tmp \ - && git clone https://github.com/nbs-system/naxsi.git \ - && echo 'adding /usr/local/share/GeoIP/GeoIP.dat database' \ - && wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz \ - && wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz \ - && gunzip GeoIP.dat.gz \ - && gunzip GeoLiteCity.dat.gz \ - && mkdir /usr/local/share/GeoIP/ \ - && mv GeoIP.dat /usr/local/share/GeoIP/ \ - && mv GeoLiteCity.dat /usr/local/share/GeoIP/ \ - && chown -R www-data:www-data /usr/local/share/GeoIP/ \ - && curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \ - && mkdir -p /usr/src \ - && tar -zxC /usr/src -f nginx.tar.gz \ - && rm nginx.tar.gz \ - && cd /tmp \ - && git clone https://github.com/openresty/echo-nginx-module.git \ - && wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.zip -O dev.zip \ - && wget https://github.com/openresty/set-misc-nginx-module/archive/v0.32.zip -O setmisc.zip \ - && wget https://people.freebsd.org/~osa/ngx_http_redis-0.3.8.tar.gz \ - && wget https://github.com/openresty/redis2-nginx-module/archive/v0.15.zip -O redis.zip \ - && wget https://github.com/openresty/srcache-nginx-module/archive/v0.31.zip -O cache.zip \ - && wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.zip -O purge.zip \ - && tar -zx -f ngx_http_redis-0.3.8.tar.gz \ - && unzip dev.zip \ - && unzip setmisc.zip \ - && unzip redis.zip \ - && unzip cache.zip \ - && unzip purge.zip \ - && cd /usr/src/nginx-$NGINX_VERSION \ - && ./configure $CONFIG --with-debug \ - && make -j$(getconf _NPROCESSORS_ONLN) \ - && mv objs/nginx objs/nginx-debug \ - && mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \ - && mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \ - && mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \ - && ./configure $CONFIG \ - && make -j$(getconf _NPROCESSORS_ONLN) \ - && make install \ - && rm -rf /etc/nginx/html/ \ - && mkdir /etc/nginx/conf.d/ \ - && mkdir -p /usr/share/nginx/html/ \ - && install -m644 html/index.html /usr/share/nginx/html/ \ - && install -m644 html/50x.html /usr/share/nginx/html/ \ - && install -m755 objs/nginx-debug /usr/sbin/nginx-debug \ - && install -m755 objs/ngx_http_xslt_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_xslt_filter_module-debug.so \ - && install -m755 objs/ngx_http_image_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_image_filter_module-debug.so \ - && install -m755 objs/ngx_stream_geoip_module-debug.so /usr/lib/nginx/modules/ngx_stream_geoip_module-debug.so \ - && ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \ - && strip /usr/sbin/nginx* \ - && strip /usr/lib/nginx/modules/*.so \ - && mkdir -p /usr/local/bin/ \ - && mkdir -p ${CACHE_PREFIX} \ - && mkdir -p ${CERTS_PREFIX} \ - && cd ${CERTS_PREFIX} \ - && openssl dhparam 2048 -out ${CERTS_PREFIX}/dhparam.pem.default \ - && apk add --no-cache --virtual .gettext gettext \ - && mv /usr/bin/envsubst /tmp/ \ - \ - && runDeps="$( \ - scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --no-cache --virtual .nginx-rundeps $runDeps \ - && apk del .build-deps \ - && apk del .gettext \ - && cd /tmp/naxsi \ - && mv naxsi_config/naxsi_core.rules /etc/nginx/naxsi_core.rules \ - && mv /tmp/envsubst /usr/local/bin/ \ - && rm -rf /tmp/* \ - && rm -rf /usr/src/* \ - && ln -sf /dev/stdout ${LOG_PREFIX}/access.log \ - && ln -sf /dev/stderr ${LOG_PREFIX}/error.log \ - && ln -sf /dev/stdout ${LOG_PREFIX}/blocked.log + " + +# Build and install NGINX +RUN cd /usr/src/nginx-$NGINX_VERSION \ + && ./configure $CONFIG \ + && make -j$(nproc) \ + && make install \ + && strip /usr/sbin/nginx* \ + && strip /usr/lib/nginx/modules/*.so + +# Generate DH parameters +RUN mkdir -p ${CERTS_PREFIX} \ + && openssl dhparam -out ${CERTS_PREFIX}/dhparam.pem.default 4096 + +# Create GeoIP directory +RUN mkdir -p ${GEOIP_PREFIX} + +# Cleanup +RUN apk del .build-deps \ + && rm -rf /tmp/* \ + && rm -rf /usr/src/nginx-$NGINX_VERSION + +# Stage 2: Final image +FROM alpine:3.21 +# Add metadata +LABEL maintainer="Thomas Spicer (thomas@openbridge.com)" +LABEL org.opencontainers.image.description="NGINX with enhanced modules" +LABEL org.opencontainers.image.licenses="MIT" + +# Environment variables +ENV VAR_PREFIX=/var/run \ + LOG_PREFIX=/var/log/nginx \ + TEMP_PREFIX=/tmp \ + CACHE_PREFIX=/var/cache \ + CONF_PREFIX=/etc/nginx \ + CERTS_PREFIX=/etc/pki/tls \ + NGINX_DOCROOT=/usr/share/nginx/html \ + GEOIP_PREFIX=/usr/share/geoip + +# Create www-data user +RUN if ! getent group www-data >/dev/null; then \ + addgroup -g 82 -S www-data; \ + fi \ + && if ! getent passwd www-data >/dev/null; then \ + adduser -u 82 -D -S -h /var/cache/nginx -s /sbin/nologin -G www-data www-data; \ + fi + +# Install runtime dependencies +RUN apk add --no-cache \ + bash \ + curl \ + wget \ + gd \ + libgcc \ + libintl \ + libstdc++ \ + libxslt \ + libmaxminddb \ + openssl \ + pcre \ + tini \ + zlib \ + libintl + +# Copy files from builder +COPY --from=builder /usr/local/bin/envsubst /usr/local/bin/envsubst +COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx +COPY --from=builder /usr/lib/nginx /usr/lib/nginx +COPY --from=builder /usr/share/nginx /usr/share/nginx +COPY --from=builder /etc/nginx /etc/nginx +COPY --from=builder ${CERTS_PREFIX} ${CERTS_PREFIX} +COPY --from=builder ${GEOIP_PREFIX} ${GEOIP_PREFIX} + +# Create necessary directories and symlinks +RUN mkdir -p ${LOG_PREFIX} \ + && mkdir -p ${CACHE_PREFIX}/proxy ${CACHE_PREFIX}/fastcgi \ + && mkdir -p /etc/nginx/conf.d \ + && mkdir -p ${NGINX_DOCROOT}/error/ \ + && ln -s /usr/lib/nginx/modules /etc/nginx/modules \ + && ln -sf /dev/stdout ${LOG_PREFIX}/access.log \ + && ln -sf /dev/stderr ${LOG_PREFIX}/error.log \ + && ln -sf /dev/stdout ${LOG_PREFIX}/blocked.log + +# Copy configuration files COPY conf/ /conf -COPY test/ /tmp/test -COPY error/ /tmp/error/ -COPY check_wwwdata.sh /usr/bin/check_wwwdata -COPY check_folder.sh /usr/bin/check_folder -COPY check_host.sh /usr/bin/check_host +COPY error/ ${NGINX_DOCROOT}/error COPY docker-entrypoint.sh /docker-entrypoint.sh -RUN chmod +x /docker-entrypoint.sh /usr/bin/check_wwwdata /usr/bin/check_folder /usr/bin/check_host +# Copy GeoIP databases +COPY geoip/*.mmdb ${GEOIP_PREFIX}/ + +# Set permissions +RUN chmod +x /docker-entrypoint.sh \ + && chown -R www-data:www-data ${GEOIP_PREFIX} + +# Set stop signal STOPSIGNAL SIGQUIT -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["nginx", "-g", "daemon off;"] + +# Set entrypoint and CMD +ENTRYPOINT ["/sbin/tini", "--", "/usr/bin/env", "bash", "/docker-entrypoint.sh"] +CMD ["/usr/sbin/nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/Dockerfile-pagespeed b/Dockerfile-pagespeed deleted file mode 100644 index 778279c..0000000 --- a/Dockerfile-pagespeed +++ /dev/null @@ -1,283 +0,0 @@ -FROM alpine:3.8 -MAINTAINER Thomas Spicer (thomas@openbridge.com) - -ENV NGINX_VERSION=1.15.2 \ - VAR_PREFIX=/var/run \ - LOG_PREFIX=/var/log/nginx \ - MOD_PAGESPEED_VER=1.13.35.2 \ - NGX_PAGESPEED_VER=1.13.35.2 \ - TEMP_PREFIX=/tmp \ - CACHE_PREFIX=/var/cache \ - CONF_PREFIX=/etc/nginx \ - CERTS_PREFIX=/etc/pki/tls/ - -COPY psol/ /tmp -RUN set -x \ - && addgroup -g 82 -S www-data \ - && adduser -u 82 -D -S -h /var/cache/nginx -s /sbin/nologin -G www-data www-data \ - && echo -e '@community http://nl.alpinelinux.org/alpine/3.8/community' >> /etc/apk/repositories \ - && apk add --no-cache --virtual .build-deps \ - build-base \ - findutils \ - apr-dev \ - apr-util-dev \ - apache2-dev \ - gnupg \ - gperf \ - icu-dev \ - gettext-dev \ - libjpeg-turbo-dev \ - libpng-dev \ - libtool \ - ca-certificates \ - automake \ - autoconf \ - git \ - jemalloc-dev \ - libtool \ - binutils \ - gnupg \ - cmake \ - go \ - gcc \ - build-base \ - libc-dev \ - make \ - wget \ - gzip \ - libressl-dev \ - musl-dev \ - pcre-dev \ - zlib-dev \ - geoip-dev \ - git \ - linux-headers \ - libxslt-dev \ - nghttp2 \ - gd-dev \ - unzip \ - && apk add --no-cache --update \ - curl \ - monit \ - bash \ - bind-tools \ - rsync \ - geoip \ - libressl \ - tini \ - tar \ - && cd /tmp \ - && git clone https://github.com/google/ngx_brotli --depth=1 \ - && cd ngx_brotli && git submodule update --init \ - && export NGX_BROTLI_STATIC_MODULE_ONLY=1 \ - && cd /tmp \ - && git clone https://github.com/nbs-system/naxsi.git \ - && echo 'adding /usr/local/share/GeoIP/GeoIP.dat database' \ - && wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz \ - && wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz \ - && gunzip GeoIP.dat.gz \ - && gunzip GeoLiteCity.dat.gz \ - && mkdir /usr/local/share/GeoIP/ \ - && mv GeoIP.dat /usr/local/share/GeoIP/ \ - && mv GeoLiteCity.dat /usr/local/share/GeoIP/ \ - && chown -R www-data:www-data /usr/local/share/GeoIP/ \ - && curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \ - && mkdir -p /usr/src \ - && tar -zxC /usr/src -f nginx.tar.gz \ - && rm nginx.tar.gz \ - && cd /tmp \ - && git clone -b "v${NGX_PAGESPEED_VER}-stable" \ - --recurse-submodules \ - --shallow-submodules \ - --depth=1 \ - -c advice.detachedHead=false \ - -j$(getconf _NPROCESSORS_ONLN) \ - https://github.com/apache/incubator-pagespeed-ngx.git \ - /tmp/ngxpagespeed \ - \ - #&& psolurl="https://github.com/wodby/nginx-alpine-psol/releases/download/${MOD_PAGESPEED_VER}/psol.tar.gz" \ - #&& wget -qO- "${psolurl}" | tar xz -C /tmp/ngxpagespeed \ - && cd /tmp \ - && tar -zxC /tmp/ngxpagespeed -f psol.tar.gz \ - && git clone https://github.com/openresty/echo-nginx-module.git \ - && wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.zip -O dev.zip \ - && wget https://github.com/openresty/set-misc-nginx-module/archive/v0.31.zip -O setmisc.zip \ - && wget https://people.freebsd.org/~osa/ngx_http_redis-0.3.8.tar.gz \ - && wget https://github.com/openresty/redis2-nginx-module/archive/v0.14.zip -O redis.zip \ - && wget https://github.com/openresty/srcache-nginx-module/archive/v0.31.zip -O cache.zip \ - && wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.zip -O purge.zip \ - && tar -zx -f ngx_http_redis-0.3.8.tar.gz \ - && unzip dev.zip \ - && unzip setmisc.zip \ - && unzip redis.zip \ - && unzip cache.zip \ - && unzip purge.zip \ - && cd /usr/src/nginx-$NGINX_VERSION \ - && ./configure \ - --prefix=/usr/share/nginx/ \ - --sbin-path=/usr/sbin/nginx \ - --add-module=/tmp/naxsi/naxsi_src \ - --modules-path=/usr/lib/nginx/modules \ - --conf-path=${CONF_PREFIX}/nginx.conf \ - --error-log-path=${LOG_PREFIX}/error.log \ - --http-log-path=${LOG_PREFIX}/access.log \ - --pid-path=${VAR_PREFIX}/nginx.pid \ - --lock-path=${VAR_PREFIX}/nginx.lock \ - --http-client-body-temp-path=${TEMP_PREFIX}/client_temp \ - --http-proxy-temp-path=${TEMP_PREFIX}/proxy_temp \ - --http-fastcgi-temp-path=${TEMP_PREFIX}/fastcgi_temp \ - --http-uwsgi-temp-path=${TEMP_PREFIX}/uwsgi_temp \ - --http-scgi-temp-path=${TEMP_PREFIX}/scgi_temp \ - --user=www-data \ - --group=www-data \ - --with-file-aio \ - --with-http_ssl_module \ - --with-pcre-jit \ - --with-http_realip_module \ - --with-http_addition_module \ - --with-http_sub_module \ - --with-http_dav_module \ - --with-http_flv_module \ - --with-http_mp4_module \ - --with-http_gunzip_module \ - --with-http_gzip_static_module \ - --with-http_random_index_module \ - --with-http_secure_link_module \ - --with-http_stub_status_module \ - --with-http_auth_request_module \ - --with-http_xslt_module=dynamic \ - --with-http_image_filter_module=dynamic \ - --with-http_geoip_module=dynamic \ - --with-threads \ - --with-stream \ - --with-stream_ssl_module \ - --with-stream_ssl_preread_module \ - --with-stream_realip_module \ - --with-stream_geoip_module=dynamic \ - --with-http_slice_module \ - --with-mail \ - --with-mail_ssl_module \ - --with-compat \ - --with-http_v2_module \ - --with-ld-opt="-Wl,-z,relro,--start-group -lapr-1 -laprutil-1 -licudata -licuuc -lpng -lturbojpeg -ljpeg" \ - --add-module=/tmp/ngx_cache_purge-2.3 \ - --add-module=/tmp/ngx_http_redis-0.3.8 \ - --add-module=/tmp/redis2-nginx-module-0.14 \ - --add-module=/tmp/srcache-nginx-module-0.31 \ - --add-module=/tmp/echo-nginx-module \ - --add-module=/tmp/ngx_devel_kit-0.3.0 \ - --add-module=/tmp/set-misc-nginx-module-0.31 \ - --add-module=/tmp/ngx_brotli \ - --add-module=/tmp/ngxpagespeed \ - \ - && make -j$(getconf _NPROCESSORS_ONLN) \ - && mv objs/nginx objs/nginx-debug \ - && mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \ - && mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \ - && mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \ - && ./configure \ - --prefix=/usr/share/nginx/ \ - --sbin-path=/usr/sbin/nginx \ - --add-module=/tmp/naxsi/naxsi_src \ - --modules-path=/usr/lib/nginx/modules \ - --conf-path=${CONF_PREFIX}/nginx.conf \ - --error-log-path=${LOG_PREFIX}/error.log \ - --http-log-path=${LOG_PREFIX}/access.log \ - --pid-path=${VAR_PREFIX}/nginx.pid \ - --lock-path=${VAR_PREFIX}/nginx.lock \ - --http-client-body-temp-path=${TEMP_PREFIX}/client_temp \ - --http-proxy-temp-path=${TEMP_PREFIX}/proxy_temp \ - --http-fastcgi-temp-path=${TEMP_PREFIX}/fastcgi_temp \ - --http-uwsgi-temp-path=${TEMP_PREFIX}/uwsgi_temp \ - --http-scgi-temp-path=${TEMP_PREFIX}/scgi_temp \ - --user=www-data \ - --group=www-data \ - --with-file-aio \ - --with-http_ssl_module \ - --with-pcre-jit \ - --with-http_realip_module \ - --with-http_addition_module \ - --with-http_sub_module \ - --with-http_dav_module \ - --with-http_flv_module \ - --with-http_mp4_module \ - --with-http_gunzip_module \ - --with-http_gzip_static_module \ - --with-http_random_index_module \ - --with-http_secure_link_module \ - --with-http_stub_status_module \ - --with-http_auth_request_module \ - --with-http_xslt_module=dynamic \ - --with-http_image_filter_module=dynamic \ - --with-http_geoip_module=dynamic \ - --with-threads \ - --with-stream \ - --with-stream_ssl_module \ - --with-stream_ssl_preread_module \ - --with-stream_realip_module \ - --with-stream_geoip_module=dynamic \ - --with-http_slice_module \ - --with-mail \ - --with-mail_ssl_module \ - --with-compat \ - --with-http_v2_module \ - --with-ld-opt="-Wl,-z,relro,--start-group -lapr-1 -laprutil-1 -licudata -licuuc -lpng -lturbojpeg -ljpeg" \ - --add-module=/tmp/ngx_cache_purge-2.3 \ - --add-module=/tmp/ngx_http_redis-0.3.8 \ - --add-module=/tmp/redis2-nginx-module-0.14 \ - --add-module=/tmp/srcache-nginx-module-0.31 \ - --add-module=/tmp/echo-nginx-module \ - --add-module=/tmp/ngx_devel_kit-0.3.0 \ - --add-module=/tmp/set-misc-nginx-module-0.31 \ - --add-module=/tmp/ngx_brotli \ - --add-module=/tmp/ngxpagespeed \ - \ - && make -j$(getconf _NPROCESSORS_ONLN) \ - && make install \ - && rm -rf /etc/nginx/html/ \ - && mkdir -p /etc/nginx/conf.d/ \ - && mkdir -p /usr/share/nginx/html/ \ - && install -m644 html/index.html /usr/share/nginx/html/ \ - && install -m644 html/50x.html /usr/share/nginx/html/ \ - && ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \ - && strip /usr/sbin/nginx* \ - && strip /usr/lib/nginx/modules/*.so \ - && mkdir -p /usr/local/bin/ \ - && mkdir -p ${CACHE_PREFIX} \ - && mkdir -p ${CERTS_PREFIX} \ - && cd ${CERTS_PREFIX} \ - && openssl dhparam 2048 -out ${CERTS_PREFIX}/dhparam.pem.default \ - && apk add --no-cache --virtual .gettext gettext \ - && mv /usr/bin/envsubst /tmp/ \ - \ - && runDeps="$( \ - scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \ - | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ - | sort -u \ - | xargs -r apk info --installed \ - | sort -u \ - )" \ - && apk add --no-cache --virtual .nginx-rundeps $runDeps \ - && apk del .build-deps \ - && apk del .gettext \ - && cd /tmp/naxsi \ - && mv naxsi_config/naxsi_core.rules /etc/nginx/naxsi_core.rules \ - && mv /tmp/envsubst /usr/local/bin/ \ - && rm -rf /tmp/* \ - && rm -rf /usr/src/* \ - && ln -sf /dev/stdout ${LOG_PREFIX}/access.log \ - && ln -sf /dev/stderr ${LOG_PREFIX}/error.log \ - && ln -sf /dev/stdout ${LOG_PREFIX}/blocked.log - -COPY conf/ /conf -COPY test/ /tmp/test -COPY error/ /tmp/error/ -COPY check_wwwdata.sh /usr/bin/check_wwwdata -COPY check_folder.sh /usr/bin/check_folder -COPY check_host.sh /usr/bin/check_host -COPY docker-entrypoint.sh /docker-entrypoint.sh -RUN chmod +x /docker-entrypoint.sh /usr/bin/check_wwwdata /usr/bin/check_folder /usr/bin/check_host - -STOPSIGNAL SIGQUIT -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 48f6475..e3a0da9 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -![Image of Nginx](https://cdn.openbridge.com/assets/images/openbridge-nginx-small.png) - # NGINX Accelerated including Reverse Proxy, Redis, CDN, Lets Encrypt and much more! This is a Docker image creates a high performance, optimized image for NGINX. Deliver sites and applications with performance, reliability, security, and scale. This NGINX server offers advanced performance, web and mobile acceleration, security controls, application monitoring, and management. @@ -24,7 +22,7 @@ The image includes configuration enhancements for; * Rate limited connections to slow down attackers * CDN support * Cache purge -* Pair with [high performance PHP-FPM container](https://hub.docker.com/r/openbridge/ob_php-fpm/) +* Pair with [high performance PHP-FPM container](https://hub.docker.com/r/openbridge/ob_php-fpm/) for [blazing fast Wordpress installs](https://github.com/openbridge/wordpress) There are many, many other benefits to this system. Give it a try! @@ -36,23 +34,14 @@ The first step is to build or pull the image: ### Build ```docker -docker build --build-arg "NGINX_VERSION=1.15.4" -t openbridge/nginx . +docker build --build-arg "NGINX_VERSION=1.27.4" -t openbridge/nginx . ``` -Replace `NGINX_VERSION=1.15.4` with your preferred version. You can aslo simply `pull` the images. See below. +Replace `NGINX_VERSION=1.27.4` with your preferred version. You can also simply `pull` the images. See below. ### Pull ```docker docker pull openbridge/nginx:latest ``` -You can also use a different version of NGINX simply by pulling a build with the NGINX version you want. For example; -```docker -docker pull openbridge/nginx:1.15.3 -docker pull openbridge/nginx:1.15.2 -docker pull openbridge/nginx:1.15.1 -``` -To see the available versions vist https://hub.docker.com/r/openbridge/nginx/tags/ - - ## Running Via Docker compose @@ -67,29 +56,33 @@ docker-compose -f ./compose/html.yml up -d --remove-orphans There are a sample HTML compose file at `./compose/html.yml` as well as PHP one `./compose/php.yml` to get you started. # Understanding Configurations -Please note that the config files included in `/conf/*` directory are opinionated. They are working examples of a specific implementation preferences and needs. +Please note that the config files inside the `/conf/*` directory are opinionated. They are the working examples of a specific implementation of preferences and needs. -We have provided two pre-built configurations. The first is for `html` based sites within `/conf/html/*` and the other is for `php` sites within `/conf/php/*`. The application will look for a config directory to use. This is done with the `NGINX_CONFIG` ENV variable. For example, if you are running a html based site and want to use the `/conf/html/*` configuration then set `NGINX_CONFIG=html`. If you want are running php and want to use the `/conf/php/*` configuration then set `NGINX_CONFIG=php`. If you have a custom config set like `/conf//*` then set `NGINX_CONFIG=my-custom-config`. +We provided two pre-built configurations. The first one is for `html` based sites within `/conf/html/*` and another one is for `php` sites within `/conf/php/*`. The application will look for a config directory to use that. This is done with the `NGINX_CONFIG` ENV variable. For example, if you are running a html-based site and want to use the `/conf/html/*` configuration, then set `NGINX_CONFIG=html`. If you are running php and want to use the `/conf/php/*` configuration, then set `NGINX_CONFIG=php`. If you have a custom config set like `/conf//*` then set `NGINX_CONFIG=my-custom-config`. -There is nginx default setup located here `/conf/basic/*`. Basic allows you to run nginx in a bare metal setup. Just set `NGINX_CONFIG=basic` +The nginx default setup located inside `/conf/basic/*`. Basic allows you to run nginx in a bare metal setup. Just set `NGINX_CONFIG=basic` ## Digging Into The `ENV` File -The following are the core variables for the `ENV` config in `/conf` +The following lines are the core variables for the `ENV` config inside `/conf` * `NGINX_DOCROOT` sets the default www directory. If you do not set this the images defaults to `/usr/share/nginx/html` -* `NGINX_SERVER_NAME` sets the default servern ame in `nginx.conf`. If you do not set this it will default to `localhost` -* `NGINX_CONFIG` sets the default configuration director for your image. See the `/conf` directory to review a `html` and `php` configuration -* `NGINX_PROXY_UPSTREAM` sets the upstream server(s) for the reverse proxy to connect with. Since the proxy is local to the container you should use something like `localhost.com:8080`. If this is NOT set, it will default to `localhost:8080` -* `REDIS_UPSTREAM` sets the upstream Redis cache server(s) to connect with. If you are using compose you might reference the `redis` container `server redis01:6379;server redis02:6378;`. You might also set it by IP `server 1.2.3.4:6379; server 4.3.2.1:6379;`. If this is NOT set, it will default to `server localhost:6379;`. +* `NGINX_SERVER_NAME` sets the default server name in `nginx.conf`. If you do not set this it will default to `localhost`. + +**NOTE**: *`NGINX_SERVER_NAME` is the address of your server. Hence, use the `localhost` if you are doing local development or using `openbridge.com` or `apple.com` or `mydomainname.com`. Also, you should set this to the root domain. For example, use `acme.com` vs `www.acme.com`. This will keep your Nginx `server_name` directive clean. If you don't understand how NGINX uses that, [read their docs](http://nginx.org/en/docs/http/server_names.html)*. +* `NGINX_CONFIG` sets the default configuration director for your image. See the `/conf` directory to review a `html` and `php` configuration. +* `NGINX_PROXY_UPSTREAM` sets the upstream server(s) for the reverse proxy to connect with. Since the proxy is local to the container, you should use something like `localhost.com:8080`. If this is NOT set, it will default to `localhost:8080` +* `REDIS_UPSTREAM_HOST` sets the upstream Redis cache server(s) to connect with. If you are using compose, you might reference the `redis` container `server redis01:6379;server redis02:6378;`. You might also set it by IP `server 1.2.3.4:6379; server 4.3.2.1:6379;`. If this is NOT set, it will default to `server localhost:6379;`. -If you are using PHP you will want to set the endpoint for `PHP-FPM`: + +If you are using PHP, you will want to set the endpoint for `PHP-FPM`: * `PHP_FPM_UPSTREAM` sets the upstream server(s) to connect with. If you are using compose you might reference the `php-fpm01` container `server php-fpm01:9000;server php-fpm01:9001;`. You might also set it by IP `server 1.2.3.4:9000; server 4.3.2.1:9001;`. If this is NOT set, it will default to `server localhost:9000;` You can set a collection of dummy files and certs for local testing: * `NGINX_DEV_INSTALL` Set to `true` if you want self-signed SSL certs installed and "hello world" HTML and PHP pages installed. This is useful for testing. -* NOTE: Self-signed SSL certificates are always installed if the system does not detect here in the default cert location at `/etc/letsencrypt/live/${NGINX_SERVER_NAME}/` + +**NOTE**: Self-signed SSL certificates are always installed if the system does not detect them within the default cert location: `/etc/letsencrypt/live/${NGINX_SERVER_NAME}/` Check our the `/env` for more examples @@ -101,7 +94,7 @@ Following is the convention we will be using for sites. * `/usr/share/nginx/html` – Your root site content/apps * `/usr/share/nginx/html/example.com` – (Optional) Domain specific content/apps -To mount your web app or html files you will need to mount the volume on the host that contains your files. Make sure you are setting the `NGINX_DOCROOT` in your run or `docker-compose.yml` file. If you do not set it the default is `/usr/share/nginx/html` +To mount your web app or html files, you will need to mount the volume on the host that contains your files. Make sure you are setting the `NGINX_DOCROOT` in your run or `docker-compose.yml` file. If you do not set it the default is `/usr/share/nginx/html` ```docker -v /your/webapp/path:{{NGINX_DOCROOT}}:ro ``` @@ -109,7 +102,7 @@ You can also set the cache directory to leverage in-memory cache like `tmpfs`: ```docker -v /tmpfs:{{CACHE_PREFIX}}:ro ``` -You can do the same thing for config files if you wanted to use versions of what we have provided. Just make sure you are mapping locations correctly as NGINX and PHP expect files to be in certain locations. +You can do the same to config the files, if you want to use versions of what we have provided. Just make sure you are mapping locations correctly as NGINX and PHP expect files to be in certain locations. # NGINX `/conf/` Configuration File Organization The following represents the structure of the configs used in this image. Please note the use of the nginx `map` settings for browser content caching and supporting content redirects. The content cache is done according to mime type. @@ -314,7 +307,9 @@ services: site: ``` -## Installing `certbot` for `letsencrypt` SSL certs + + +## Installing `certbot` for `letsencrypt` SSL certs on your host On your **host**, not in the Docker image, install `certbot`: * Download `certbot`: `curl -O https://dl.eff.org/certbot-auto` @@ -361,6 +356,13 @@ else echo "INFO: SSL files already exist. Not installing dev certs." fi ``` +When use self-signed certs you will likely see warnings in the logs like this: + +```bash +2018/10/25 18:23:53 [warn] 1#1: "ssl_stapling" ignored, no OCSP responder URL in the certificate "/etc/letsencrypt/live/localhost/fullchain.pem" +nginx: [warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate "/etc/letsencrypt/live/localhost/fullchain.pem" +``` +This is because nginx is attempting to use `ssl_stapling` which will not function correctly for self-signed certs. You can ignore these warnings in this case. However, if the same warning happens with real certs then there is a different problem with the SSL cert(s). ## Forward Secrecy & Diffie Hellman Ephemeral Parameters The default Ephemeral Diffie-Hellman (DHE) uses OpenSSL's defaults, which include a 1024-bit key for the key-exchange. Since we're using a 2048-bit certificate, DHE clients will use a weaker key-exchange than non-ephemeral DH clients. We need to fix this. We generate a stronger DHE parameter which can take a LONG time to generate: @@ -375,8 +377,6 @@ If you have already generated this, mount it to `/etc/pki/tls/dhparam.pem` and We have enabled HTTP Strict Transport Security (HSTS), which instructs browsers to communicate only over HTTPS. - - ## Qualsys Rating Using the Qualsys SSL Test (https://www.ssllabs.com/ssltest/) the current SSL configuration scores A+ @@ -384,7 +384,7 @@ We have enabled HTTP Strict Transport Security (HSTS), which instructs browsers # Permissions -We have standardized on the user, group and UID/GID to work seamlessly with other applications [like PHP-FPM](https://hub.docker.com/r/openbridge/ob_php-fpm/) +We had standardized on the user, group and UID/GID to work seamlessly with other applications [like PHP-FPM](https://hub.docker.com/r/openbridge/ob_php-fpm/) ```docker && addgroup -g 82 -S www-data \ @@ -394,6 +394,16 @@ We have standardized on the user, group and UID/GID to work seamlessly with othe # Bots & Spam Protection We have include "The Ultimate Nginx Bad Bot, User-Agent, Spam Referrer Blocker, Adware, Malware and Ransomware Blocker, Clickjacking Blocker, Click Re-Directing Blocker, SEO Companies and Bad IP Blocker with Anti DDOS System, Nginx Rate Limiting and Wordpress Theme Detector Blocking" +## Activating Bot Protection +If you want to activate bot protection, you need to set an environment variable called `NGINX_BAD_BOTS` to `true`. +```bash +NGINX_BAD_BOTS=true +``` +If you do not set this variable, then do not include it or set the value to `false` +```bash +NGINX_BAD_BOTS=false +``` + ## What Are Bad Bots? Why block bad bots? They can cause problems for your application, performance and allow pollute your performance data! What are some examples of bad bots and spam? Bots attempt to make themselves look like other software or web sites by disguising their user agent. Their user agent names may look harmless, perfectly legitimate even. @@ -439,7 +449,7 @@ There are over 4000 bad referers, spam referrers, user-agents, bad bots, bad IP' ### Verify Your Bot Protection -Run the following commands one by one from a terminal on another linux machine against your own domain name. +Run the following commands line by line inside a terminal on another linux machine against your own domain name. **Substitute yourdomain.com in the examples below with your REAL domain name:** @@ -472,53 +482,6 @@ This allows you to connect to `https://localhost/testing/test_info.php` to verif Noe: Using PHP assumes you have configured a PHP backend to test anything PHP related -# Monitoring -Services in the container are monitored via Monit. One thing to note is that if Monit detects a problem with Nginx it will issue a `STOP` command. This will shutdown your container because the image uses `CMD ["nginx", "-g", "daemon off;"]`. If you are using `--restart unless-stopped` in your docker run command the server will automatically restart. - -Here is an example monitoring config: -```nginx -check process nginx with pidfile "/var/run/nginx.pid" - if not exist for 5 cycles then restart - start program = "/usr/bin/env bash -c '/usr/sbin/nginx -g daemon off'" with timeout 60 seconds - stop program = "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - every 3 cycles - if cpu > 80% for 10 cycles then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - -check program wwwdata-permissions with path /usr/bin/env bash -c "check_wwwdata permission" - every 3 cycles - if status != 0 then exec "/usr/bin/env bash -c 'find {{NGINX_DOCROOT}} -type d -exec chmod 755 {} \; && find {{NGINX_DOCROOT}} -type f -exec chmod 644 {} \;'" - -check directory cache-permissions with path {{CACHE_PREFIX}} - every 3 cycles - if failed permission 755 then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chmod 755 {} \;'" - -check directory cache-owner with path {{CACHE_PREFIX}} - every 3 cycles - if failed uid www-data then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chown www-data:www-data {} \; && find {{CACHE_PREFIX}} -type f -exec chown www-data:www-data {} \;'" - -check file letsencrypt_certificate with path /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem - if changed checksum then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - -check host {{NGINX_SERVER_NAME}} with address {{NGINX_SERVER_NAME}} - if failed host {{NGINX_SERVER_NAME}} port 80 protocol http - and request "/health-check" - with timeout 25 seconds - for 3 times within 4 cycles - then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - if failed host {{NGINX_SERVER_NAME}} port 443 protocol https - request "/health-check" - status = 200 - content = "healthy" - with timeout 25 seconds - for 3 times within 4 cycles - then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - if failed port 8080 for 3 cycles then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - -check program cache-size with path /usr/bin/env bash -c "check_folder {{CACHE_PREFIX}} 500" - every 20 cycles - if status != 0 then exec "/usr/bin/env bash -c 'rm -Rf /var/cache/*'" -``` - The `check_folder`, `check_host` and `check_wwwdata` scripts provide additional health check utility of make sure that permissions, cache size and host respond correctly. For example, `check_host` will validate that SPA rendering service is properly serving the expected content. This can help detect if there are issues where certain user-agents that can not render SPA are being served the incorrect content. This can wreak havoc with your SEO if a pre-render service is not working as expected. Best to catch it as early as possible so you can mitigate any issues. # Content Delivery Network If you want to activate CDN for assets like images, you can set your location to redirect those requests to your CDN: @@ -532,6 +495,13 @@ This assumes you have a CDN distribution setup and the assets published there. T # Benchmarks Benchmarks were undertaken to spot check performance and uncover any issues. These tests were done on AWS Lightsail on a 512BM instance type (512 MB RAM, 1 vCPU, 20 GB SSD). +## `PageSpeed` Benchmark +This test was run using PageSpeed. This was running a full Wordpress stack and the default WP theme as detailed here: https://github.com/openbridge/wordpress + +The install scored a **100**, including exceptional performance on all the infrastructure benchmarks + +Pagespeed-wordpress + ## `ab` Benchmark This the Apache ab test command: `ab -k -n 50000 -c 10 -t 10 http://xxxxxx/testing/index.html` @@ -610,11 +580,17 @@ However, if you want to change this behavior, simply edit the `Dockerfile` to su && ln -sf /dev/stdout ${LOG_PREFIX}/blocked.log ``` # Versioning -| Docker Tag | Git Hub Release | Nginx Version | Alpine Version | -|-----|-------|-----|--------| -| latest | Master | 1.15.5 | 3.8 | +Here are the latest releases: + + +| Docker Tag | GitHub Release | Nginx Version | Alpine Version | +|------------|----------------|---------------|----------------| +| latest | master | latest | 3.12 | +| 1.19.0 | master | 1.19.0 | 3.12 | + + -To see the available versions visit https://hub.docker.com/r/openbridge/nginx/tags/ +To see the available versions visit: https://hub.docker.com/r/openbridge/nginx/tags/ # TODO diff --git a/conf/basic/monit/check_nginx b/conf/basic/monit/check_nginx deleted file mode 100644 index c395b5b..0000000 --- a/conf/basic/monit/check_nginx +++ /dev/null @@ -1,27 +0,0 @@ -check process nginx with pidfile "/var/run/nginx.pid" - if not exist for 10 cycles then restart - start program = "/usr/bin/env bash -c '/usr/sbin/nginx -g daemon off'" with timeout 90 seconds - stop program = "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - every 3 cycles - if failed port 443 then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - if failed port 443 for 5 cycles then stop - if cpu > 80% for 10 cycles then stop - -check program wwwdata-owner with path /usr/bin/env bash -c "check_wwwdata owner" - every 3 cycles - if status != 0 then exec "/usr/bin/env bash -c 'find {{NGINX_DOCROOT}} -type d -exec chown www-data:www-data {} \; && find {{NGINX_DOCROOT}} -type f -exec chown www-data:www-data {} \;'" - -check program wwwdata-permissions with path /usr/bin/env bash -c "check_wwwdata permission" - every 3 cycles - if status != 0 then exec "/usr/bin/env bash -c 'find {{NGINX_DOCROOT}} -type d -exec chmod 755 {} \; && find {{NGINX_DOCROOT}} -type f -exec chmod 644 {} \;'" - -check directory cache-permissions with path {{CACHE_PREFIX}} - every 3 cycles - if failed permission 755 then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chmod 755 {} \;'" - -check directory cache-owner with path {{CACHE_PREFIX}} - every 3 cycles - if failed uid www-data then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chown www-data:www-data {} \; && find {{CACHE_PREFIX}} -type f -exec chown www-data:www-data {} \;'" - -check file letsencrypt_certificate with path /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem - if changed checksum then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" diff --git a/conf/html/monit/check_nginx b/conf/html/monit/check_nginx deleted file mode 100644 index 93ec8b2..0000000 --- a/conf/html/monit/check_nginx +++ /dev/null @@ -1,44 +0,0 @@ -check process nginx with pidfile "/var/run/nginx.pid" - if not exist for 5 cycles then restart - start program = "/usr/bin/env bash -c '/usr/sbin/nginx -g daemon off'" with timeout 60 seconds - stop program = "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - every 3 cycles - if cpu > 80% for 10 cycles then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - -check program wwwdata-permissions with path /usr/bin/env bash -c "check_wwwdata permission" - every 3 cycles - if status != 0 then exec "/usr/bin/env bash -c 'find {{NGINX_DOCROOT}} -type d -exec chmod 755 {} \; && find {{NGINX_DOCROOT}} -type f -exec chmod 644 {} \;'" - -check directory cache-permissions with path {{CACHE_PREFIX}} - every 3 cycles - if failed permission 755 then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chmod 755 {} \;'" - -check directory cache-owner with path {{CACHE_PREFIX}} - every 3 cycles - if failed uid www-data then exec "/usr/bin/env bash -c 'find {{CACHE_PREFIX}} -type d -exec chown www-data:www-data {} \; && find {{CACHE_PREFIX}} -type f -exec chown www-data:www-data {} \;'" - -check file letsencrypt_certificate with path /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem - if changed checksum then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - -check host {{NGINX_SERVER_NAME}} with address {{NGINX_SERVER_NAME}} - if failed host {{NGINX_SERVER_NAME}} port 80 protocol http - and request "/health-check" - with timeout 25 seconds - for 3 times within 4 cycles - then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - if failed host {{NGINX_SERVER_NAME}} port 443 protocol https - request "/health-check" - status = 200 - content = "healthy" - with timeout 25 seconds - for 3 times within 4 cycles - then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s reload'" - if failed port 8080 for 3 cycles then exec "/usr/bin/env bash -c '/usr/sbin/nginx -s stop'" - -check program cache-size with path /usr/bin/env bash -c "check_folder {{CACHE_PREFIX}} 500" - every 20 cycles - if status != 0 then exec "/usr/bin/env bash -c 'rm -Rf /var/cache/*'" - -check program prerendering-service with path /usr/bin/env bash -c "check_host" - every 20 cycles - if status != 0 then alert diff --git a/conf/html/nginx/bots.d/whitelist-domains.conf b/conf/html/nginx/bots.d/whitelist-domains.conf deleted file mode 100644 index 0401a4f..0000000 --- a/conf/html/nginx/bots.d/whitelist-domains.conf +++ /dev/null @@ -1,10 +0,0 @@ -# EDIT THIS FILE AS YOU LIKE TO WHITELIST YOUR OWN DOMAIN NAMES AND SPARE THEM FROM ANY REFERRER CHECKING ### - -# Add One Entry Per Line - List all your own domains of the sites you host on the server -# This file must exist on your system or Nginx will fail a reload due to a missing file -# Automatic updates will never be able to remove this custom list of yours -# Add One Entry Per Line -"~*semrush*" 0; -"~*ahrefs*" 0; -"~*openbridge.com" 0; -"~*localhost" 0; diff --git a/conf/html/nginx/bots.d/whitelist-ips.conf b/conf/html/nginx/bots.d/whitelist-ips.conf deleted file mode 100644 index cac32f2..0000000 --- a/conf/html/nginx/bots.d/whitelist-ips.conf +++ /dev/null @@ -1,12 +0,0 @@ -# EDIT THIS FILE AS YOU LIKE TO WHITELIST ALL YOUR IP ADDRESSES AND IP RANGES ### - -# Add One Entry Per Line - List all your IP's and IP Ranges you want to whitelist -# This file must exist on your system or Nginx will fail a reload due to a missing file -# Automatic updates will never be able to remove this custom list of yours -# Add One Entry Per Line - No need to include 127.0.0.1 as it is covered elsewhere -# Only add actual IP addresses and ranges here -127.0.0.1 0; -52.4.233.57 0; -46.229.173.67 0; -46.229.173.66 0; -199.249.223.47 0; diff --git a/conf/html/nginx/conf.d/brotli.conf b/conf/html/nginx/conf.d/brotli.conf deleted file mode 100644 index a415205..0000000 --- a/conf/html/nginx/conf.d/brotli.conf +++ /dev/null @@ -1,52 +0,0 @@ -brotli on; -brotli_static on; -brotli_comp_level 6; -brotli_min_length 1000; -brotli_buffers 32 8k; -brotli_types - application/ecmascript - application/javascript - application/json - application/pdf - application/postscript - application/font-woff - application/font-woff2 - application/x-javascript - application/vnd.ms-fontobject - application/x-font-opentype - application/x-font-truetype - application/x-font-ttf - application/xml - image/gif - image/jpeg - image/png - image/svg+xml - image/tiff - image/vnd.microsoft.icon - image/x-icon - image/webp - text/x-component - text/x-js - text/css - text/csv - text/javascript - text/plain - text/xml - text/xsd - text/xsl - font/eot - font/opentype - font/otf - font/woff - font/woff2 - video/3gpp - video/mp4 - video/mpeg - video/ogg - video/quicktime - video/webm - video/x-flv - video/x-mng - video/x-ms-asf - video/x-ms-wmv - video/x-msvideo; diff --git a/conf/html/nginx/conf.d/cdn.conf b/conf/html/nginx/conf.d/cdn.conf deleted file mode 100644 index 8b13789..0000000 --- a/conf/html/nginx/conf.d/cdn.conf +++ /dev/null @@ -1 +0,0 @@ - diff --git a/conf/html/nginx/conf.d/error.conf b/conf/html/nginx/conf.d/error.conf deleted file mode 100644 index f319602..0000000 --- a/conf/html/nginx/conf.d/error.conf +++ /dev/null @@ -1,6 +0,0 @@ -error_page 401 403 404 /error/404.html; -error_page 405 /error/405.html; -error_page 500 501 503 504 /error/5xx.html; -location ^~ /error/ { - internal; -} diff --git a/conf/html/nginx/conf.d/failed.conf b/conf/html/nginx/conf.d/failed.conf deleted file mode 100644 index 5684c3b..0000000 --- a/conf/html/nginx/conf.d/failed.conf +++ /dev/null @@ -1,7 +0,0 @@ -location @failed { - default_type text/html; - return 200 " - -

HTTP 502 / No backend servers found at the moment

-

Refreshing automatically to reconnect to backend...

"; -} diff --git a/conf/html/nginx/conf.d/gzip.conf b/conf/html/nginx/conf.d/gzip.conf deleted file mode 100644 index 0558d16..0000000 --- a/conf/html/nginx/conf.d/gzip.conf +++ /dev/null @@ -1,53 +0,0 @@ -gzip on; -gzip_disable "MSIE [1-6].(?!.*SV1)"; -gzip_buffers 16 4k; -gzip_vary on; -gzip_proxied any; -gzip_min_length 256; -gzip_types - application/ecmascript - application/javascript - application/json - application/pdf - application/postscript - application/font-woff - application/font-woff2 - application/x-javascript - application/vnd.ms-fontobject - application/x-font-opentype - application/x-font-truetype - application/x-font-ttf - application/xml - image/gif - image/jpeg - image/png - image/svg+xml - image/tiff - image/vnd.microsoft.icon - image/x-icon - image/webp - text/x-component - text/x-js - text/css - text/csv - text/javascript - text/plain - text/xml - text/xsd - text/xsl - font/eot - font/opentype - font/otf - font/woff - font/woff2 - video/3gpp - video/mp4 - video/mpeg - video/ogg - video/quicktime - video/webm - video/x-flv - video/x-mng - video/x-ms-asf - video/x-ms-wmv - video/x-msvideo; diff --git a/conf/html/nginx/conf.d/health.conf b/conf/html/nginx/conf.d/health.conf deleted file mode 100644 index 1419c8b..0000000 --- a/conf/html/nginx/conf.d/health.conf +++ /dev/null @@ -1,6 +0,0 @@ -location /health-check -{ - return 200 "healthy\n"; - allow 127.0.0.1; - deny all; -} diff --git a/conf/html/nginx/conf.d/location.conf b/conf/html/nginx/conf.d/location.conf deleted file mode 100644 index a034b55..0000000 --- a/conf/html/nginx/conf.d/location.conf +++ /dev/null @@ -1,5 +0,0 @@ -location / { - try_files $uri /$uri; - aio threads; - include /etc/nginx/redis.d/cache.conf; -} diff --git a/conf/html/nginx/conf.d/monit.conf b/conf/html/nginx/conf.d/monit.conf deleted file mode 100644 index 64660ec..0000000 --- a/conf/html/nginx/conf.d/monit.conf +++ /dev/null @@ -1,12 +0,0 @@ -location /monit/ { - rewrite ^/monit/(.*) /$1 break; - proxy_ignore_client_abort on; - proxy_pass http://127.0.0.1:2849; - proxy_redirect http://127.0.0.1:2849 /monit; - proxy_cookie_path / /monit/; - allow 172.22.0.1; - allow 52.4.233.57; - deny all; - access_log off; - error_log off; -} diff --git a/conf/html/nginx/conf.d/naxsi.conf b/conf/html/nginx/conf.d/naxsi.conf deleted file mode 100644 index 80be0ec..0000000 --- a/conf/html/nginx/conf.d/naxsi.conf +++ /dev/null @@ -1,8 +0,0 @@ -SecRulesEnabled; -DeniedUrl "/error/500.html"; -CheckRule "$SQL >= 8" BLOCK; -CheckRule "$UWA >= 4" DROP; -CheckRule "$RFI >= 8" BLOCK; -CheckRule "$TRAVERSAL >= 4" BLOCK; -CheckRule "$EVADE >= 4" BLOCK; -CheckRule "$XSS >= 8" BLOCK; diff --git a/conf/html/nginx/conf.d/pagespeed-server.conf b/conf/html/nginx/conf.d/pagespeed-server.conf deleted file mode 100644 index c73a7f3..0000000 --- a/conf/html/nginx/conf.d/pagespeed-server.conf +++ /dev/null @@ -1,76 +0,0 @@ -pagespeed UseExperimentalJsMinifier on; - -pagespeed MaxCombinedCssBytes -1; -pagespeed MaxCombinedJsBytes -1; - -pagespeed CssInlineMaxBytes 16096; -pagespeed JsInlineMaxBytes 16096; - -pagespeed LazyloadImagesAfterOnload off; - -pagespeed RewriteDeadlinePerFlushMs 2000; -pagespeed MaxCacheableContentLength 2048000; - -pagespeed FetchHttps enable,allow_self_signed; -pagespeed SslCertDirectory /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}; -pagespeed SslCertFile /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem; -pagespeed RespectXForwardedProto on; - -# Implicit cache-lifetime for resources -pagespeed ImplicitCacheTtlMs 3600000; - -# File Cache -pagespeed FileCacheSizeKb 68400; -pagespeed FileCacheCleanIntervalMs 3600000; -pagespeed FileCacheInodeLimit 500000; - -# In-memory LRU Cache -pagespeed LRUCacheKbPerProcess 16192; -pagespeed LRUCacheByteLimit 64384; - -pagespeed EnableCachePurge on; -pagespeed PurgeMethod PURGE; - -pagespeed LoadFromFileMatch "^https://[^/]*.{{NGINX_SERVER_NAME}}/" "/usr/share/nginx/html/"; -pagespeed LoadFromFileRuleMatch disallow .*; -pagespeed LoadFromFileRuleMatch allow \.css$; -pagespeed LoadFromFileRuleMatch allow \.jpe?g$; -pagespeed LoadFromFileRuleMatch allow \.png$; -pagespeed LoadFromFileRuleMatch allow \.gif$; -pagespeed LoadFromFileRuleMatch allow \.js$; -pagespeed LoadFromFileRuleMatch allow \.ico$; -pagespeed LoadFromFileRuleMatch allow \.svg$; - -#pagespeed Disallow */js/buzz.js*; -#pagespeed Disallow */lost-password/lost; -#pagespeed Disallow */lost-password/*; -#pagespeed Disallow */cron.php*; -#pagespeed Disallow */admin.php*; - -pagespeed DownstreamCacheRebeaconingKey "{{PAGESPEED_BEACON}}"; - -pagespeed RespectVary on; -pagespeed RespectXForwardedProto on; - -pagespeed LowercaseHtmlNames on; -pagespeed RewriteLevel PassThrough; - -pagespeed EnableFilters inline_javascript,extend_cache,local_storage_cache,canonicalize_javascript_libraries,insert_dns_prefetch,add_head,inline_google_font_css,remove_comments,combine_heads,hint_preload_subresources,collapse_whitespace,rewrite_css,combine_css,fallback_rewrite_css_urls,flatten_css_imports,inline_css,inline_import_to_link,rewrite_style_attributes_with_url,responsive_images,lazyload_images,dedup_inlined_images,inline_images,rewrite_images; - -# redis storage backend -pagespeed RedisServer "{{REDIS_UPSTREAM}}"; -pagespeed RedisTimeoutUs 1000; - -pagespeed Statistics on; -pagespeed StatisticsLogging on; -pagespeed AdminPath /pagespeed_admin; - -location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; } -location ~ "^/ngx_pagespeed_static/" { } -location ~ "^/ngx_pagespeed_beacon$" { return 304; } -location ~ ^/ngx_pagespeed_statistics { allow 127.0.0.1; deny all; } -location ~ ^/ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; } -location ~ ^/ngx_pagespeed_message {allow 127.0.0.1;deny all;} -location ~ ^/pagespeed_console {deny all;} -location ~ ^/pagespeed_global_admin {deny all;} -location ~ ^/pagespeed_admin { deny all;} diff --git a/conf/html/nginx/conf.d/pagespeed.conf b/conf/html/nginx/conf.d/pagespeed.conf deleted file mode 100644 index 350155d..0000000 --- a/conf/html/nginx/conf.d/pagespeed.conf +++ /dev/null @@ -1,8 +0,0 @@ -pagespeed on; -pagespeed FileCachePath {{CACHE_PREFIX}}/ngx_pagespeed_cache; -pagespeed FetchWithGzip on; -pagespeed MessageBufferSize 100000; -pagespeed NumRewriteThreads 16; -pagespeed NumExpensiveRewriteThreads 64; -pagespeed IproMaxConcurrentRecordings 100; -pagespeed ImageMaxRewritesAtOnce 1000; diff --git a/conf/html/nginx/conf.d/proxy.conf b/conf/html/nginx/conf.d/proxy.conf deleted file mode 100644 index 1a7585d..0000000 --- a/conf/html/nginx/conf.d/proxy.conf +++ /dev/null @@ -1,27 +0,0 @@ -proxy_http_version 1.1; - -proxy_buffer_size 256k; -proxy_buffers 4 256k; -proxy_busy_buffers_size 256k; -proxy_temp_file_write_size 256k; -proxy_headers_hash_bucket_size 256; -proxy_headers_hash_max_size 1024; -proxy_read_timeout 30s; -proxy_send_timeout 30s; -proxy_connect_timeout 30s; - - -slice 1m; -proxy_cache proxycache; -proxy_cache_methods GET HEAD; -proxy_cache_lock on; -proxy_cache_lock_age 5s; -proxy_cache_lock_timeout 5s; -proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; -proxy_cache_valid 200 302 30s; -proxy_cache_valid 301 60s; -proxy_cache_valid any 1m; -proxy_cache_revalidate on; -proxy_cache_background_update on; -proxy_cache_bypass $http_pragma $no_cache $cookie_nocache $arg_nocache; -proxy_no_cache $no_cache; diff --git a/conf/html/nginx/conf.d/purge.conf b/conf/html/nginx/conf.d/purge.conf deleted file mode 100644 index 4a9dc5a..0000000 --- a/conf/html/nginx/conf.d/purge.conf +++ /dev/null @@ -1,7 +0,0 @@ -location ~ /purge(/.*) { - proxy_cache_purge proxycache $scheme$host$request_uri; - allow 172.22.0.1; - allow 173.48.130.247; - allow 52.4.233.57; - deny all; -} diff --git a/conf/html/nginx/conf.d/secure.conf b/conf/html/nginx/conf.d/secure.conf deleted file mode 100644 index a93f238..0000000 --- a/conf/html/nginx/conf.d/secure.conf +++ /dev/null @@ -1,7 +0,0 @@ -location ~ ^/.well-known { allow all; } -location ~* (?:\.(?:bak|conf|dist|fla|in[ci]|log|psd|sh|sql|sw[op])|~)$ { deny all; } -location ~* \.(pl|cgi|py|sh|lua)\$ { return 444; } -location ~* (w00tw00t) { return 444; } -location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)\$|^(\..*|Entries.*|Repository|Root|Tag|Template)\$|\.php_ { return 444; } -location = /robots.txt { access_log off; log_not_found off; } -location ~ /\. { deny all; access_log off; log_not_found off; } diff --git a/conf/html/nginx/conf.d/ssl.conf b/conf/html/nginx/conf.d/ssl.conf deleted file mode 100644 index 5dff93d..0000000 --- a/conf/html/nginx/conf.d/ssl.conf +++ /dev/null @@ -1,14 +0,0 @@ -ssl_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem; -ssl_certificate_key /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/privkey.pem; -ssl_trusted_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/chain.pem; -ssl_protocols TLSv1.2; -ssl_session_cache shared:SSL:50m; -ssl_session_timeout 30m; -ssl_dhparam /etc/pki/tls/dhparam.pem; -ssl_ecdh_curve secp384r1; -ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; -ssl_prefer_server_ciphers on; -ssl_buffer_size 1400; -ssl_session_tickets off; -ssl_stapling on; -ssl_stapling_verify on; diff --git a/conf/html/nginx/geo.d/purge.conf b/conf/html/nginx/geo.d/purge.conf deleted file mode 100644 index 09241b0..0000000 --- a/conf/html/nginx/geo.d/purge.conf +++ /dev/null @@ -1,3 +0,0 @@ -default 0; -127.0.0.1 1; -192.168.0.0/24 1; diff --git a/conf/html/nginx/geo.d/ratelimit.conf b/conf/html/nginx/geo.d/ratelimit.conf deleted file mode 100644 index f4dbc01..0000000 --- a/conf/html/nginx/geo.d/ratelimit.conf +++ /dev/null @@ -1,4 +0,0 @@ -default 1; -10.0.0.0/8 0; -192.168.0.0/24 0; -127.0.0.0/24 0; diff --git a/conf/html/nginx/geo.d/whitelist.conf b/conf/html/nginx/geo.d/whitelist.conf deleted file mode 100644 index 9181a3d..0000000 --- a/conf/html/nginx/geo.d/whitelist.conf +++ /dev/null @@ -1,3 +0,0 @@ -default 0; -# CIDR in the list below are not limited -127.0.0.1 1; diff --git a/conf/html/nginx/header.d/httpd.conf b/conf/html/nginx/header.d/httpd.conf deleted file mode 100644 index 13b2dd4..0000000 --- a/conf/html/nginx/header.d/httpd.conf +++ /dev/null @@ -1,9 +0,0 @@ -add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;" always; -add_header X-Frame-Options SAMEORIGIN; -add_header X-Content-Type-Options nosniff; -add_header X-XSS-Protection "1; mode=block"; -add_header "X-UA-Compatible" "IE=Edge"; -add_header X-Cache $upstream_cache_status; -add_header X-Robots-Tag "$noindex"; -#add_header Link "; as=style; rel=preload"; -#add_header Link "<$scheme://$host:$server_port$request_uri>; rel=\"canonical\""; diff --git a/conf/html/nginx/header.d/proxy.conf b/conf/html/nginx/header.d/proxy.conf deleted file mode 100644 index 000e9bf..0000000 --- a/conf/html/nginx/header.d/proxy.conf +++ /dev/null @@ -1,37 +0,0 @@ -proxy_set_header Connection ""; -proxy_set_header Proxy ""; -proxy_set_header Upgrade $http_upgrade; -proxy_set_header Host $http_host; -proxy_set_header Referer $http_referer; - -proxy_set_header REMOTE_ADDR $http_x_real_ip; -proxy_set_header X-Real-IP $proxy_protocol_addr; - -proxy_set_header X-Forwarded-For $proxy_protocol_addr; -proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; -proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; -proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; - -proxy_set_header X-Client-Verify SUCCESS; -proxy_set_header X-Client-DN $ssl_client_s_dn; - -proxy_set_header X-SSL-Subject $ssl_client_s_dn; -proxy_set_header X-SSL-Issuer $ssl_client_i_dn; - -proxy_set_header Range $slice_range; - -proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie; - -proxy_set_header GEOIP-COUNTRY-CODE $geoip_country_code; -proxy_set_header GEOIP-COUNTRY-CODE3 $geoip_country_code3; -proxy_set_header GEOIP-COUNTRY-NAME $geoip_country_name; - -proxy_set_header GEOIP-CITY-COUNTRY-CODE $geoip_city_country_code; -proxy_set_header GEOIP-CITY-COUNTRY-CODE3 $geoip_city_country_code3; -proxy_set_header GEOIP-CITY-COUNTRY-NAME $geoip_city_country_name; -proxy_set_header GEOIP-REGION $geoip_region; -proxy_set_header GEOIP-CITY $geoip_city; -proxy_set_header GEOIP-POSTAL-CODE $geoip_postal_code; -proxy_set_header GEOIP-CITY-CONTINENT-CODE $geoip_city_continent_code; -proxy_set_header GEOIP-LATITUDE $geoip_latitude; -proxy_set_header GEOIP-LONGITUDE $geoip_longitude; diff --git a/conf/html/nginx/map.d/access/access.map b/conf/html/nginx/map.d/access/access.map deleted file mode 100644 index 3a45eb1..0000000 --- a/conf/html/nginx/map.d/access/access.map +++ /dev/null @@ -1,2 +0,0 @@ -0 $binary_remote_addr; -1 ""; diff --git a/conf/html/nginx/map.d/cache/expires.map b/conf/html/nginx/map.d/cache/expires.map deleted file mode 100644 index 8d9e2b9..0000000 --- a/conf/html/nginx/map.d/cache/expires.map +++ /dev/null @@ -1,49 +0,0 @@ -default off; -~assets/ max; -application/ecmascript max; -application/javascript max; -application/json max; -application/pdf max; -application/postscript max; -application/font-woff max; -application/font-woff2 max; -application/x-javascript max; -application/vnd.ms-fontobject max; -application/x-font-opentype max; -application/x-font-truetype max; -application/x-font-ttf max; -application/xml max; -image/gif max; -image/jpeg max; -image/png max; -image/svg+xml max; -image/tiff max; -image/vnd.microsoft.icon max; -image/x-icon max; -image/webp max; -text/x-component max; -text/x-js max; -text/css max; -text/csv max; -text/html epoch; -text/javascript max; -text/plain epoch; -text/xml max; -text/xsd max; -text/xsl max; -font/eot max; -font/opentype max; -font/otf max; -font/woff max; -font/woff2 max; -video/3gpp max; -video/mp4 max; -video/mpeg max; -video/ogg max; -video/quicktime max; -video/webm max; -video/x-flv max; -video/x-mng max; -video/x-ms-asf max; -video/x-ms-wmv max; -video/x-msvideo max; diff --git a/conf/html/nginx/map.d/header/port.map b/conf/html/nginx/map.d/header/port.map deleted file mode 100644 index 2101c6f..0000000 --- a/conf/html/nginx/map.d/header/port.map +++ /dev/null @@ -1,2 +0,0 @@ -default $http_x_forwarded_port; -'' $server_port; diff --git a/conf/html/nginx/map.d/header/proto.map b/conf/html/nginx/map.d/header/proto.map deleted file mode 100644 index 6855454..0000000 --- a/conf/html/nginx/map.d/header/proto.map +++ /dev/null @@ -1,2 +0,0 @@ -default $http_x_forwarded_proto; -'' $scheme; diff --git a/conf/html/nginx/map.d/header/push.map b/conf/html/nginx/map.d/header/push.map deleted file mode 100644 index 5b2c092..0000000 --- a/conf/html/nginx/map.d/header/push.map +++ /dev/null @@ -1,2 +0,0 @@ -#"~*session=1" ""; -#default "; as=script; rel=preload"; diff --git a/conf/html/nginx/map.d/header/robot.map b/conf/html/nginx/map.d/header/robot.map deleted file mode 100644 index dba1809..0000000 --- a/conf/html/nginx/map.d/header/robot.map +++ /dev/null @@ -1,2 +0,0 @@ -#~\/*staging.openbridge*?$ "noindex, follow"; -~\/*.(html)?$ "all"; diff --git a/conf/html/nginx/map.d/header/scheme.map b/conf/html/nginx/map.d/header/scheme.map deleted file mode 100644 index 36ea4d8..0000000 --- a/conf/html/nginx/map.d/header/scheme.map +++ /dev/null @@ -1,2 +0,0 @@ -default off; -https on; diff --git a/conf/html/nginx/map.d/logs/ip.map b/conf/html/nginx/map.d/logs/ip.map deleted file mode 100644 index 6d68221..0000000 --- a/conf/html/nginx/map.d/logs/ip.map +++ /dev/null @@ -1,5 +0,0 @@ -default 1; -127.0.0.1 0; -10.0.0.2 0; -10.0.0.3 0; -172.22.0.1 0; diff --git a/conf/html/nginx/map.d/logs/ua.map b/conf/html/nginx/map.d/logs/ua.map deleted file mode 100644 index 174ca2e..0000000 --- a/conf/html/nginx/map.d/logs/ua.map +++ /dev/null @@ -1,2 +0,0 @@ -default 1; -"~*Monit*" 0; diff --git a/conf/html/nginx/map.d/nocache/nocache.map b/conf/html/nginx/map.d/nocache/nocache.map deleted file mode 100644 index 836c8eb..0000000 --- a/conf/html/nginx/map.d/nocache/nocache.map +++ /dev/null @@ -1,7 +0,0 @@ -default 0; -~*\/wp-admin\/.* 3; -~*\/wp-[a-zA-Z0-9-]+\.php 3; -~*\/feed\/.* 3; -~*\/administrator\/.* 3; -HEAD 0; -GET 0; diff --git a/conf/html/nginx/map.d/purge/purge.map b/conf/html/nginx/map.d/purge/purge.map deleted file mode 100644 index d62443f..0000000 --- a/conf/html/nginx/map.d/purge/purge.map +++ /dev/null @@ -1,2 +0,0 @@ -PURGE $purge_allowed; -default 0; diff --git a/conf/html/nginx/map.d/redirects/example.map b/conf/html/nginx/map.d/redirects/example.map deleted file mode 100644 index 395e0e8..0000000 --- a/conf/html/nginx/map.d/redirects/example.map +++ /dev/null @@ -1,10 +0,0 @@ -#Examples -#~*foo\.php?$ /app.php; -#~*foo\.html?$ /app.php; -#~\/blog\/* https://blog.openbridge.com; -#~\/adobe-clickstream\/?$ $scheme://$host/product/openbridge-adobe-clickstream; -#/marketplace/ $scheme://$host/products/; -#~\/marketplace/product/amazon-redshift-self-serve\/?$ $scheme://$host/warehouse/amazon-redshift; -#~\/marketplace/product/amazon-athena\/?$ $scheme://$host/warehouse/amazon-athena; -#/marketplace/product/google-bigquery $scheme://$host/warehouse/google-bigquery; -#~\/data-silos-data-canyons\/?$ https://blog.openbridge.com/beware-the-data-canyon-data-silos-big-brother-b005c187f35d; diff --git a/conf/html/nginx/map.d/redirects/pages.map b/conf/html/nginx/map.d/redirects/pages.map deleted file mode 100644 index 8b13789..0000000 --- a/conf/html/nginx/map.d/redirects/pages.map +++ /dev/null @@ -1 +0,0 @@ - diff --git a/conf/html/nginx/map.d/referrer/bot.map b/conf/html/nginx/map.d/referrer/bot.map deleted file mode 100644 index f6e1229..0000000 --- a/conf/html/nginx/map.d/referrer/bot.map +++ /dev/null @@ -1,42 +0,0 @@ -default 0; -"~Prerender" 0; -"~*baiduspider*" 1; -"bot" 1; -"~*twitterbot*" 1; -"~*Twitterbot*" 1; -"~*facebookexternalhit*" 1; -"~*Facebot*" 1; -"~*rogerbot*" 1; -"~*linkedinbot*" 1; -"~*embedly*" 1; -"~*Iframely*" 1; -"~*quora*" 1; -"~*showyoubot*" 1; -"~*outbrain*" 1; -"~*Pinterest*" 1; -"~*Slack-ImgProxy*" 1; -"~*Slackbot*" 1; -"~*vkShare*" 1; -"~*HipChat*" 1; -"~*W3C_Validator*" 1; -"~*quora link preview" 1; -"~*showyoubot" 1; -"~*pinterest" 1; -"~*slackbot" 1; -"~*Slackbot-LinkExpanding" 1; -"~*Site Analyzer" 1; -"~*SiteAnalyzerBot" 1; -"~*Viber" 1; -"~*Whatsapp" 1; -"~*Telegram" 1; -"~*Nuzzel" 1; -"~*Tumblr" 1; -"~*flipboard" 1; -"~*AwarioRssBot" 1; -"~*Slack-ImgProxy*" 1; -"~*Slack-ImgProxy*" 1; -"~*SemrushBot-SA*" 1; -"~*SemrushBot*" 1; -"~*semrushbot*" 1; -"~*Semrush*" 1; -"~*ahrefs*" 1; diff --git a/conf/html/nginx/map.d/referrer/crawler.map b/conf/html/nginx/map.d/referrer/crawler.map deleted file mode 100644 index a7261f4..0000000 --- a/conf/html/nginx/map.d/referrer/crawler.map +++ /dev/null @@ -1,9 +0,0 @@ -default 0; -"~*googlebot*" 1; -"~*googlebot-mobile*" 1; -"Semrush ContentAnalyzer*" 1; -"~*pinterest.*ios*" 1; -"~*mail\.ru*" 1; -"~*seznambot*" 1; -"~*screaming*" 1; -"~*nginx-amplify-agent*" 1; diff --git a/conf/html/nginx/map.d/srcache/srcache.map b/conf/html/nginx/map.d/srcache/srcache.map deleted file mode 100644 index 150ffc5..0000000 --- a/conf/html/nginx/map.d/srcache/srcache.map +++ /dev/null @@ -1,3 +0,0 @@ -default 0; -POST 1; -PUT 1; diff --git a/conf/html/nginx/mime.type b/conf/html/nginx/mime.type deleted file mode 100644 index 2d74f29..0000000 --- a/conf/html/nginx/mime.type +++ /dev/null @@ -1,93 +0,0 @@ -types { - application/atom+xml atom; - application/json json map topojson; - application/ld+json jsonld; - application/rss+xml rss; - application/vnd.geo+json geojson; - application/xml rdf xml; - application/javascript js; - application/manifest+json webmanifest; - application/x-web-app-manifest+json webapp; - text/cache-manifest appcache; - audio/midi mid midi kar; - audio/mp4 aac f4a f4b m4a; - audio/mpeg mp3; - audio/ogg oga ogg opus; - audio/x-realaudio ra; - audio/x-wav wav; - image/bmp bmp; - image/gif gif; - image/jpeg jpeg jpg; - image/jxr jxr hdp wdp; - image/png png; - image/svg+xml svg svgz; - image/tiff tif tiff; - image/vnd.wap.wbmp wbmp; - image/webp webp; - image/x-jng jng; - video/3gpp 3gp 3gpp; - video/mp4 f4p f4v m4v mp4; - video/mpeg mpeg mpg; - video/ogg ogv; - video/quicktime mov; - video/webm webm; - video/x-flv flv; - video/x-mng mng; - video/x-ms-asf asf asx; - video/x-ms-wmv wmv; - video/x-msvideo avi; - image/x-icon cur ico; - application/msword doc; - application/vnd.ms-excel xls; - application/vnd.ms-powerpoint ppt; - application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; - application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; - application/font-woff woff; - font/woff2 woff2; - application/vnd.ms-fontobject eot; - application/font-sfnt ttf otf; - application/java-archive ear jar war; - application/mac-binhex40 hqx; - application/octet-stream bin deb dll dmg exe img iso msi msm msp safariextz; - application/pdf pdf; - application/postscript ai eps ps; - application/rtf rtf; - application/vnd.google-earth.kml+xml kml; - application/vnd.google-earth.kmz kmz; - application/vnd.wap.wmlc wmlc; - application/x-7z-compressed 7z; - application/x-bb-appworld bbaw; - application/x-bittorrent torrent; - application/x-chrome-extension crx; - application/x-cocoa cco; - application/x-java-archive-diff jardiff; - application/x-java-jnlp-file jnlp; - application/x-makeself run; - application/x-opera-extension oex; - application/x-perl pl pm; - application/x-pilot pdb prc; - application/x-rar-compressed rar; - application/x-redhat-package-manager rpm; - application/x-sea sea; - application/x-shockwave-flash swf; - application/x-stuffit sit; - application/x-tcl tcl tk; - application/x-x509-ca-cert crt der pem; - application/x-xpinstall xpi; - application/xhtml+xml xhtml; - application/xslt+xml xsl; - application/zip zip; - text/css css; - text/csv csv; - text/html htm html shtml; - text/markdown md; - text/mathml mml; - text/plain txt; - text/vcard vcard vcf; - text/vnd.rim.location.xloc xloc; - text/vnd.sun.j2me.app-descriptor jad; - text/vnd.wap.wml wml; - text/vtt vtt; - text/x-component htc; -} diff --git a/conf/html/nginx/nginx.conf b/conf/html/nginx/nginx.conf deleted file mode 100644 index 272ed9b..0000000 --- a/conf/html/nginx/nginx.conf +++ /dev/null @@ -1,130 +0,0 @@ -load_module /etc/nginx/modules/ngx_http_geoip_module.so; - -user www-data; -worker_processes auto; -worker_rlimit_nofile 65535; -timer_resolution 100ms; -pcre_jit on; -thread_pool default threads=32 max_queue=65536; - -events { - worker_connections 65535; - multi_accept on; - use epoll; -} - -http { - include /etc/nginx/mime.type; - include /etc/nginx/naxsi_core.rules; - - default_type application/octet-stream; - charset UTF-8; - etag on; - sendfile off; - sendfile_max_chunk 512k; - send_timeout 10s; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 30; - keepalive_requests 1000; - lingering_time 20s; - lingering_timeout 5s; - keepalive_disable msie6; - reset_timedout_connection on; - request_pool_size 32k; - output_buffers 8 256k; - postpone_output 1460; - - client_max_body_size 100M; - client_body_buffer_size 128k; - client_header_buffer_size 3m; - large_client_header_buffers 4 256k; - - open_file_cache max=75000 inactive=60s; - open_file_cache_valid 120s; - open_file_cache_min_uses 2; - open_file_cache_errors off; - open_log_file_cache max=20000 inactive=30s min_uses=2; - - ignore_invalid_headers on; - - geoip_country /usr/local/share/GeoIP/GeoIP.dat; - geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat; - - map_hash_bucket_size 256; - map_hash_max_size 4096; - types_hash_max_size 2048; - variables_hash_max_size 2048; - - geo $rate_limit {include /etc/nginx/geo.d/ratelimit.conf;} - map $rate_limit $rate_limit_key {include /etc/nginx/map.d/access/*.map;} - map $http_user_agent $no_logs {include /etc/nginx/map.d/logs/ua.map;} - - limit_req_zone $rate_limit_key zone=req_zone:10m rate=200r/s; - - upstream proxy {include /etc/nginx/upstream.d/proxy.conf;} - upstream redis {include /etc/nginx/upstream.d/redis.conf;} - - log_format blocked '$time_local: Blocked request from $http_x_real_ip $request'; - log_format main_ext '{ "@timestamp": "$time_iso8601", ' - '"@fields": { ' - '"remote_addr": "$remote_addr", ' - '"remote_user": "$remote_user", ' - '"status": "$status", ' - '"request": "$request", ' - '"request_uri": "$request_uri", ' - '"request_method": "$request_method", ' - '"request_time": "$request_time", ' - '"request_uri_query": "$query_string", ' - '"http_referrer": "$http_referer", ' - '"http_user_agent": "$http_user_agent", ' - '"http_forward": "$http_x_forwarded_for", ' - '"http_header": "$http_x_header", ' - '"body_bytes_sent": "$body_bytes_sent", ' - '"geo_country": "$geoip_country_code", ' - '"geo_city": "$geoip_city", ' - '"server_name": "$server_name", ' - '"upstream_addr": "$upstream_addr", ' - '"upstream_status": "$upstream_status", ' - '"upstream_response_time": "$upstream_response_time", ' - '"upstream_response_length": "$upstream_response_length", ' - '"upstream_cache_status": "$upstream_cache_status" } }'; - - access_log {{LOG_PREFIX}}/access.log main_ext; - error_log {{LOG_PREFIX}}/access.log warn; - - resolver 1.1.1.1 8.8.8.8 8.8.4.4 valid=60s; - resolver_timeout 15s; - - map $http_x_forwarded_proto $proxy_x_forwarded_proto {include /etc/nginx/map.d/header/proto.map;} - map $http_x_forwarded_port $proxy_x_forwarded_port {include /etc/nginx/map.d/header/port.map;} - map $scheme $proxy_x_forwarded_ssl {include /etc/nginx/map.d/header/scheme.map;} - map $host:$server_port$request_uri $noindex {include /etc/nginx/map.d/header/robot.map;} - map $request_method $skip_fetch {include /etc/nginx/map.d/srcache/*.map;} - map $sent_http_content_type $expires {include /etc/nginx/map.d/cache/*.map;} - map $request_uri $redirect_uri {include /etc/nginx/map.d/redirects/*.map;} - map $request_uri $no_cache {include /etc/nginx/map.d/nocache/*.map;} - - map $http_user_agent $crawler_pre {include /etc/nginx/map.d/referrer/crawler.map;} - map $http_user_agent $bot_pre {include /etc/nginx/map.d/referrer/bot.map;} - map $args $prerender {default $bot_pre; "~(^|&)_escaped_fragment_=" 1;} - - proxy_cache_path {{CACHE_PREFIX}}/proxy keys_zone=proxycache:10m levels=1:2 inactive=30m max_size=128m; - proxy_cache_key $scheme$request_method$host$request_uri$slice_range; - - map $request_method $purge_method {include /etc/nginx/map.d/purge/*.map;} - geo $purge_allowed {include /etc/nginx/geo.d/purge.conf;} - - geo $whitelist {include /etc/nginx/geo.d/whitelist.conf;} - map $whitelist $limit_access {include /etc/nginx/map.d/access/*.map;} - expires $expires; - - index index.html default.html; - - include /etc/nginx/conf.d/brotli.conf; - include /etc/nginx/conf.d/gzip.conf; - include /etc/nginx/conf.d/proxy.conf; - include /etc/nginx/conf.d/botblocker-nginx-settings.conf; - include /etc/nginx/conf.d/globalblacklist.conf; - include /etc/nginx/sites-available/*; -} diff --git a/conf/html/nginx/redis.d/cache.conf b/conf/html/nginx/redis.d/cache.conf deleted file mode 100644 index a35fa9a..0000000 --- a/conf/html/nginx/redis.d/cache.conf +++ /dev/null @@ -1,8 +0,0 @@ -set $key $scheme$request_method$host$request_uri$is_args$args; -set_escape_uri $escaped_key $key; -srcache_fetch_skip $skip_fetch; -srcache_request_cache_control on; -srcache_default_expire 5s; - -srcache_fetch GET /redis_get $key; -srcache_store PUT /redis_put key=$escaped_key&exptime=5; diff --git a/conf/html/nginx/redis.d/location.conf b/conf/html/nginx/redis.d/location.conf deleted file mode 100644 index ce558e4..0000000 --- a/conf/html/nginx/redis.d/location.conf +++ /dev/null @@ -1,15 +0,0 @@ -location = /redis_get { - internal; - set_md5 $redis_key $args; - redis_pass redis; -} - -location = /redis_put { - internal; - set_unescape_uri $exptime $arg_exptime; - set_unescape_uri $key $arg_key; - set_md5 $key; - redis2_query set $key $echo_request_body; - redis2_query expire $key $exptime; - redis2_pass redis; -} diff --git a/conf/html/nginx/sites-available/default.vhost b/conf/html/nginx/sites-available/default.vhost deleted file mode 100644 index a72b3e5..0000000 --- a/conf/html/nginx/sites-available/default.vhost +++ /dev/null @@ -1,71 +0,0 @@ -server { - server_name {{NGINX_SERVER_NAME}}; - server_tokens off; - server_name_in_redirect off; - listen *:80 default_server; - listen [::]:80 default_server reuseport; - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; - include /etc/nginx/bots.d/blockbots.conf; - include /etc/nginx/bots.d/ddos.conf; - include /etc/nginx/header.d/httpd.conf; - return 301 https://$host$request_uri; -} - -server { - server_name {{NGINX_SERVER_NAME}}; - server_tokens off; - server_name_in_redirect off; - root {{NGINX_DOCROOT}}; - listen *:443 default_server ssl http2; - listen [::]:443 default_server ssl http2 reuseport; - limit_req zone=req_zone burst=20 nodelay; - set $naxsi_flag_enable 0; - - http2_push_preload on; - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; - - userid on; - userid_name _uid; - userid_path /; - userid_expires max; - userid_domain {{NGINX_SERVER_NAME}}; - - include /etc/nginx/conf.d/ssl.conf; - include /etc/nginx/bots.d/blockbots.conf; - include /etc/nginx/bots.d/ddos.conf; - - include /etc/nginx/header.d/httpd.conf; - include /etc/nginx/header.d/proxy.conf; - - include /etc/nginx/conf.d/cdn.conf; - - location / { - expires $expires; - proxy_pass http://proxy/; - proxy_redirect / /; - error_page 502 =200 @failed; - } - - include /etc/nginx/conf.d/secure.conf; - include /etc/nginx/conf.d/health.conf; - include /etc/nginx/conf.d/monit.conf; - include /etc/nginx/conf.d/purge.conf; - include /etc/nginx/conf.d/failed.conf; -} - -server { - server_tokens off; - server_name_in_redirect off; - server_name {{NGINX_SERVER_NAME}}; - - listen *:8080 default_server reuseport; - listen [::]:8080 default_server reuseport; - - expires $expires; - root {{NGINX_DOCROOT}}; - set $cache_uri $request_uri; - if ($redirect_uri) {return 301 $redirect_uri;} - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; - include /etc/nginx/conf.d/location.conf; - include /etc/nginx/redis.d/location.conf; -} diff --git a/conf/html/nginx/status.d/status.conf b/conf/html/nginx/status.d/status.conf deleted file mode 100644 index 004d775..0000000 --- a/conf/html/nginx/status.d/status.conf +++ /dev/null @@ -1,15 +0,0 @@ -location /testing { - access_log off; - sub_filter_once off; - sub_filter 'server_hostname' '$hostname'; - sub_filter 'server_address' '$server_addr:$server_port'; - sub_filter 'server_url' '$request_uri'; - sub_filter 'remote_addr' '$remote_addr:$remote_port'; - sub_filter 'server_date' '$time_local'; - sub_filter 'client_browser' '$http_user_agent'; - sub_filter 'request_id' '$request_id'; - sub_filter 'nginx_version' '$nginx_version'; - sub_filter 'document_root' '$document_root'; - sub_filter 'proxied_for_ip' '$http_x_real_ip'; - -} diff --git a/conf/html/nginx/upstream.d/proxy.conf b/conf/html/nginx/upstream.d/proxy.conf deleted file mode 100644 index 4231560..0000000 --- a/conf/html/nginx/upstream.d/proxy.conf +++ /dev/null @@ -1,3 +0,0 @@ -zone proxy 64k; -keepalive 32; -server {{NGINX_PROXY_UPSTREAM}} max_fails=3 fail_timeout=30s; diff --git a/conf/html/nginx/upstream.d/redis.conf b/conf/html/nginx/upstream.d/redis.conf deleted file mode 100644 index 9393949..0000000 --- a/conf/html/nginx/upstream.d/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -zone proxy 64k; -hash $scheme$request_uri; -keepalive 32; -server {{REDIS_UPSTREAM}} max_fails=3 fail_timeout=30s; diff --git a/conf/php/nginx/conf.d/allowed-ips.conf b/conf/php/nginx/conf.d/allowed-ips.conf new file mode 100644 index 0000000..e933d9d --- /dev/null +++ b/conf/php/nginx/conf.d/allowed-ips.conf @@ -0,0 +1,10 @@ +# Allow all IPs using the catch-all IP address +allow 0.0.0.0/0; + +# IPv6 equivalent (if needed) +allow ::/0; + +# You can keep your specific IP allows for reference or future use +# allow 34.205.100.51; +# allow 192.168.0.0/16; +# allow 10.0.0.0/8; \ No newline at end of file diff --git a/conf/html/nginx/map.d/header/canonical.map b/conf/php/nginx/conf.d/botblocker-nginx-settings.conf similarity index 100% rename from conf/html/nginx/map.d/header/canonical.map rename to conf/php/nginx/conf.d/botblocker-nginx-settings.conf diff --git a/conf/php/nginx/conf.d/brotli.conf b/conf/php/nginx/conf.d/brotli.conf index a415205..a3f1775 100644 --- a/conf/php/nginx/conf.d/brotli.conf +++ b/conf/php/nginx/conf.d/brotli.conf @@ -1,52 +1,57 @@ -brotli on; -brotli_static on; -brotli_comp_level 6; -brotli_min_length 1000; -brotli_buffers 32 8k; +# Enable Brotli compression and pre-compressed static file support +brotli on; +brotli_static on; + +# Compression settings +brotli_comp_level 5; # Compression level (1-11, higher values provide better compression at the cost of CPU usage) +brotli_min_length 256; # Only compress responses larger than 256 bytes +brotli_buffers 16 8k; # Increased number of buffers for better handling of concurrent requests +brotli_window 512k; # Explicitly set window size (default is 512k) + +# Specify MIME types for Brotli compression, grouped by category + brotli_types - application/ecmascript + # Application types + application/atom+xml application/javascript application/json - application/pdf - application/postscript - application/font-woff - application/font-woff2 - application/x-javascript + application/ld+json + application/manifest+json + application/rss+xml + application/vnd.geo+json application/vnd.ms-fontobject - application/x-font-opentype - application/x-font-truetype application/x-font-ttf + application/x-web-app-manifest+json + application/xhtml+xml application/xml - image/gif - image/jpeg - image/png - image/svg+xml - image/tiff - image/vnd.microsoft.icon - image/x-icon - image/webp - text/x-component - text/x-js - text/css - text/csv - text/javascript - text/plain - text/xml - text/xsd - text/xsl + application/wasm + + # Font types font/eot font/opentype font/otf + font/ttf font/woff font/woff2 - video/3gpp - video/mp4 - video/mpeg - video/ogg - video/quicktime - video/webm - video/x-flv - video/x-mng - video/x-ms-asf - video/x-ms-wmv - video/x-msvideo; + + # Image types + image/avif + image/bmp + image/svg+xml + image/webp + image/x-icon + + # Text types + text/cache-manifest + text/calendar + text/css + text/html + text/javascript + text/markdown + text/plain + text/vcard + text/vnd.rim.location.xloc + text/vtt + text/x-component + text/x-cross-domain-policy + text/xml; diff --git a/conf/php/nginx/conf.d/failed.conf b/conf/php/nginx/conf.d/failed.conf index 5684c3b..3aabbcc 100644 --- a/conf/php/nginx/conf.d/failed.conf +++ b/conf/php/nginx/conf.d/failed.conf @@ -1,7 +1,32 @@ location @failed { default_type text/html; return 200 " - -

HTTP 502 / No backend servers found at the moment

-

Refreshing automatically to reconnect to backend...

"; -} + + + + + + Backend Unavailable + + + +

HTTP 502 - Backend Servers Unavailable

+

We’re attempting to reconnect. This page will refresh automatically in 5 seconds.

+ + + "; +} \ No newline at end of file diff --git a/conf/php/nginx/conf.d/geo.conf b/conf/php/nginx/conf.d/geo.conf new file mode 100644 index 0000000..a2c7f3f --- /dev/null +++ b/conf/php/nginx/conf.d/geo.conf @@ -0,0 +1,24 @@ +# GeoIP2 database settings for HTTP context +geoip2 /usr/share/geoip/GeoLite2-Country.mmdb { + auto_reload 5m; + $geoip2_metadata_country_build metadata build_epoch; + $geoip2_data_country_code default=- country iso_code; + $geoip2_data_country_name default=- country names en; +} + +geoip2 /usr/share/geoip/GeoLite2-City.mmdb { + auto_reload 5m; + $geoip2_metadata_city_build metadata build_epoch; + $geoip2_data_city_name default=- city names en; + $geoip2_data_region_name default=- subdivisions 0 names en; + $geoip2_data_region_code default=- subdivisions 0 iso_code; + $geoip2_data_postal_code default=- postal code; + $geoip2_data_latitude default=- location latitude; + $geoip2_data_longitude default=- location longitude; +} + +geoip2 /usr/share/geoip/GeoLite2-ASN.mmdb { + auto_reload 5m; + $geoip2_data_asn default=- autonomous_system_number; + $geoip2_data_asn_org default=- autonomous_system_organization; +} \ No newline at end of file diff --git a/conf/php/nginx/conf.d/globalblacklist.conf b/conf/php/nginx/conf.d/globalblacklist.conf new file mode 100644 index 0000000..e69de29 diff --git a/conf/php/nginx/conf.d/gzip.conf b/conf/php/nginx/conf.d/gzip.conf index 0558d16..e1faf7c 100644 --- a/conf/php/nginx/conf.d/gzip.conf +++ b/conf/php/nginx/conf.d/gzip.conf @@ -1,53 +1,62 @@ +# Enable gzip compression gzip on; -gzip_disable "MSIE [1-6].(?!.*SV1)"; -gzip_buffers 16 4k; -gzip_vary on; -gzip_proxied any; -gzip_min_length 256; + +# Compression settings +gzip_comp_level 6; # Slightly reduced from 7 for better CPU balance +gzip_min_length 256; # Only compress responses larger than 256 bytes +gzip_buffers 16 8k; # Increased buffer size for better performance +gzip_http_version 1.1; # Only compress responses for HTTP/1.1 and above + +# Specify MIME types for gzip compression, grouped by category gzip_types - application/ecmascript + # Application types + application/atom+xml + application/geo+json application/javascript application/json - application/pdf - application/postscript - application/font-woff - application/font-woff2 - application/x-javascript + application/ld+json + application/manifest+json + application/rdf+xml + application/rss+xml application/vnd.ms-fontobject - application/x-font-opentype - application/x-font-truetype - application/x-font-ttf + application/wasm + application/x-javascript + application/x-web-app-manifest+json + application/xhtml+xml application/xml - image/gif - image/jpeg - image/png + application/octet-stream + + # Font types (include these if your fonts are not already compressed) + font/eot + font/otf + font/ttf + font/woff + font/woff2 + + # Image types + image/avif + image/bmp image/svg+xml - image/tiff - image/vnd.microsoft.icon - image/x-icon image/webp - text/x-component - text/x-js + image/x-icon + + # Text types + text/cache-manifest + text/calendar text/css - text/csv + text/html # Added critical text/html MIME type text/javascript + text/markdown text/plain text/xml - text/xsd - text/xsl - font/eot - font/opentype - font/otf - font/woff - font/woff2 - video/3gpp - video/mp4 - video/mpeg - video/ogg - video/quicktime - video/webm - video/x-flv - video/x-mng - video/x-ms-asf - video/x-ms-wmv - video/x-msvideo; + text/vcard + text/vnd.rim.location.xloc + text/vtt + text/x-component + text/x-cross-domain-policy; + +# Additional gzip settings +gzip_vary on; # Enable Vary header for proxies and clients +gzip_proxied any; # Enable compression for all proxied requests +gzip_static on; # Serve pre-compressed .gz files if available +gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # Disable gzip for old versions of Internet Explorer \ No newline at end of file diff --git a/conf/php/nginx/conf.d/health.conf b/conf/php/nginx/conf.d/health.conf index 281dc36..2508a5a 100644 --- a/conf/php/nginx/conf.d/health.conf +++ b/conf/php/nginx/conf.d/health.conf @@ -1,7 +1,6 @@ -location /health-check -{ - return 200 "healthy\n"; - allow 127.0.0.1; - deny all; - +location /health-check { + default_type text/plain; + return 200 "healthy\n"; + allow 127.0.0.1; + deny all; } diff --git a/conf/php/nginx/conf.d/location.conf b/conf/php/nginx/conf.d/location.conf index d2d26ef..a65fd57 100644 --- a/conf/php/nginx/conf.d/location.conf +++ b/conf/php/nginx/conf.d/location.conf @@ -1,29 +1,41 @@ -location / -{ - try_files $uri $uri/ /app.php$is_args$args /index.php$is_args$args; - # Direct common errors to the temp maintenance page assuming there are no PHP resources available. - error_page 502 =200 @maintenance; - error_page 403 =200 @maintenance; - aio threads; -} +############################################## +# Main Location Block for the Root Directory +############################################## +location / { + # Attempt to serve the requested URI as a file or directory. + # If not found, fallback to /index.php with query string parameters. + try_files $uri $uri/ /index.php$is_args$args; + + # On 502 (Bad Gateway) or 403 (Forbidden) errors, + # serve the maintenance page (with a 200 status) instead. + error_page 502 =200 @maintenance; + error_page 403 =200 @maintenance; -location ~ [^/]\.php(/|$) -{ - try_files $uri $uri/ /app.php$is_args$args /index.php$is_args$args @php-fpm; - fastcgi_pass php-fpm; - include /etc/nginx/fastcgi.d/fastcgi.conf; - include /etc/nginx/redis.d/cache.conf; + # Enable asynchronous I/O with threads for improved performance. + aio threads; } -location @php-fpm -{ - try_files $uri =404; - fastcgi_pass php-fpm; - include /etc/nginx/fastcgi.d/fastcgi.conf; - include /etc/nginx/redis.d/cache.conf; +############################################## +# Location Block for PHP Files +############################################## +location ~ [^/]\.php(/|$) { + # Pass PHP scripts to the PHP-FPM backend. + fastcgi_pass php-fpm; + + # Include FastCGI configuration parameters. + # This typically sets SCRIPT_FILENAME and other necessary variables. + include /etc/nginx/fastcgi.d/fastcgi.conf; } +############################################## +# Named Location for Maintenance Mode +############################################## location @maintenance { - default_type text/html; - try_files $uri $uri/ /install.html$is_args$args; + default_type text/html; + + # Disable caching for the maintenance response. + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate" always; + + # Attempt to serve a static maintenance page; if missing, return a 503. + try_files /maintenance.html =503; } diff --git a/conf/php/nginx/conf.d/modules.conf b/conf/php/nginx/conf.d/modules.conf new file mode 100644 index 0000000..4d9d9ec --- /dev/null +++ b/conf/php/nginx/conf.d/modules.conf @@ -0,0 +1,2 @@ +load_module modules/ngx_http_geoip2_module.so; +load_module modules/ngx_stream_geoip2_module.so; \ No newline at end of file diff --git a/conf/php/nginx/conf.d/pagespeed-server.conf b/conf/php/nginx/conf.d/pagespeed-server.conf deleted file mode 100644 index c73a7f3..0000000 --- a/conf/php/nginx/conf.d/pagespeed-server.conf +++ /dev/null @@ -1,76 +0,0 @@ -pagespeed UseExperimentalJsMinifier on; - -pagespeed MaxCombinedCssBytes -1; -pagespeed MaxCombinedJsBytes -1; - -pagespeed CssInlineMaxBytes 16096; -pagespeed JsInlineMaxBytes 16096; - -pagespeed LazyloadImagesAfterOnload off; - -pagespeed RewriteDeadlinePerFlushMs 2000; -pagespeed MaxCacheableContentLength 2048000; - -pagespeed FetchHttps enable,allow_self_signed; -pagespeed SslCertDirectory /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}; -pagespeed SslCertFile /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem; -pagespeed RespectXForwardedProto on; - -# Implicit cache-lifetime for resources -pagespeed ImplicitCacheTtlMs 3600000; - -# File Cache -pagespeed FileCacheSizeKb 68400; -pagespeed FileCacheCleanIntervalMs 3600000; -pagespeed FileCacheInodeLimit 500000; - -# In-memory LRU Cache -pagespeed LRUCacheKbPerProcess 16192; -pagespeed LRUCacheByteLimit 64384; - -pagespeed EnableCachePurge on; -pagespeed PurgeMethod PURGE; - -pagespeed LoadFromFileMatch "^https://[^/]*.{{NGINX_SERVER_NAME}}/" "/usr/share/nginx/html/"; -pagespeed LoadFromFileRuleMatch disallow .*; -pagespeed LoadFromFileRuleMatch allow \.css$; -pagespeed LoadFromFileRuleMatch allow \.jpe?g$; -pagespeed LoadFromFileRuleMatch allow \.png$; -pagespeed LoadFromFileRuleMatch allow \.gif$; -pagespeed LoadFromFileRuleMatch allow \.js$; -pagespeed LoadFromFileRuleMatch allow \.ico$; -pagespeed LoadFromFileRuleMatch allow \.svg$; - -#pagespeed Disallow */js/buzz.js*; -#pagespeed Disallow */lost-password/lost; -#pagespeed Disallow */lost-password/*; -#pagespeed Disallow */cron.php*; -#pagespeed Disallow */admin.php*; - -pagespeed DownstreamCacheRebeaconingKey "{{PAGESPEED_BEACON}}"; - -pagespeed RespectVary on; -pagespeed RespectXForwardedProto on; - -pagespeed LowercaseHtmlNames on; -pagespeed RewriteLevel PassThrough; - -pagespeed EnableFilters inline_javascript,extend_cache,local_storage_cache,canonicalize_javascript_libraries,insert_dns_prefetch,add_head,inline_google_font_css,remove_comments,combine_heads,hint_preload_subresources,collapse_whitespace,rewrite_css,combine_css,fallback_rewrite_css_urls,flatten_css_imports,inline_css,inline_import_to_link,rewrite_style_attributes_with_url,responsive_images,lazyload_images,dedup_inlined_images,inline_images,rewrite_images; - -# redis storage backend -pagespeed RedisServer "{{REDIS_UPSTREAM}}"; -pagespeed RedisTimeoutUs 1000; - -pagespeed Statistics on; -pagespeed StatisticsLogging on; -pagespeed AdminPath /pagespeed_admin; - -location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; } -location ~ "^/ngx_pagespeed_static/" { } -location ~ "^/ngx_pagespeed_beacon$" { return 304; } -location ~ ^/ngx_pagespeed_statistics { allow 127.0.0.1; deny all; } -location ~ ^/ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; } -location ~ ^/ngx_pagespeed_message {allow 127.0.0.1;deny all;} -location ~ ^/pagespeed_console {deny all;} -location ~ ^/pagespeed_global_admin {deny all;} -location ~ ^/pagespeed_admin { deny all;} diff --git a/conf/php/nginx/conf.d/pagespeed.conf b/conf/php/nginx/conf.d/pagespeed.conf deleted file mode 100644 index 350155d..0000000 --- a/conf/php/nginx/conf.d/pagespeed.conf +++ /dev/null @@ -1,8 +0,0 @@ -pagespeed on; -pagespeed FileCachePath {{CACHE_PREFIX}}/ngx_pagespeed_cache; -pagespeed FetchWithGzip on; -pagespeed MessageBufferSize 100000; -pagespeed NumRewriteThreads 16; -pagespeed NumExpensiveRewriteThreads 64; -pagespeed IproMaxConcurrentRecordings 100; -pagespeed ImageMaxRewritesAtOnce 1000; diff --git a/conf/php/nginx/conf.d/proxy.conf b/conf/php/nginx/conf.d/proxy.conf index 2865227..ac80712 100644 --- a/conf/php/nginx/conf.d/proxy.conf +++ b/conf/php/nginx/conf.d/proxy.conf @@ -1,26 +1,61 @@ -proxy_http_version 1.1; +############################################## +# General Proxy Settings +############################################## +# Use HTTP/1.1 for better support of keep-alive and WebSocket connections. +proxy_http_version 1.1; -proxy_buffer_size 256k; +############################################## +# Buffer and Header Settings +############################################## +# Adjust buffer sizes to optimize data flow from backend to client. +proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; -proxy_headers_hash_bucket_size 256; -proxy_headers_hash_max_size 1024; -proxy_read_timeout 30s; -proxy_send_timeout 30s; + +# Tweak header hash settings for large or many headers. +proxy_headers_hash_bucket_size 128; +proxy_headers_hash_max_size 512; + +############################################## +# Timeout Settings +############################################## +# Set timeouts to avoid hanging connections. +proxy_read_timeout 90s; +proxy_send_timeout 90s; proxy_connect_timeout 30s; +############################################## +# Slice Module +############################################## +# Enable slicing of large files (1m chunks) to improve caching efficiency. slice 1m; + +############################################## +# Proxy Cache Settings +############################################## +# Define the cache zone (named "proxycache") and control which methods to cache. proxy_cache proxycache; proxy_cache_methods GET HEAD; + +# Enable cache locking to prevent multiple requests hitting the backend simultaneously. proxy_cache_lock on; proxy_cache_lock_age 5s; proxy_cache_lock_timeout 5s; + +# Use stale content when errors occur, with multiple error conditions covered. proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; -proxy_cache_valid 200 302 30s; -proxy_cache_valid 301 60s; -proxy_cache_valid any 1m; + +# Set cache validity periods for different response statuses. +proxy_cache_valid 200 302 10m; +proxy_cache_valid 301 1h; +proxy_cache_valid 404 1m; +proxy_cache_valid any 5m; + +# Revalidate the cache when a stale copy exists, and allow background updates. proxy_cache_revalidate on; proxy_cache_background_update on; -proxy_cache_bypass $http_pragma $no_cache $cookie_nocache $arg_nocache; -proxy_no_cache $no_cache; + +# Bypass or disable caching based on specific request headers or variables. +proxy_cache_bypass $http_pragma $skip_cache $arg_nocache; +proxy_no_cache $skip_cache; diff --git a/conf/php/nginx/conf.d/secure.conf b/conf/php/nginx/conf.d/secure.conf index af4e792..f9106a9 100644 --- a/conf/php/nginx/conf.d/secure.conf +++ b/conf/php/nginx/conf.d/secure.conf @@ -1,55 +1,102 @@ -location ~ ^/.well-known { - allow all; -} -location ~* (?:\.(?:bak|conf|dist|fla|in[ci]|log|psd|sh|sql|sw[op])|~)$ { - deny all; -} -location ~* \.(pl|cgi|py|sh|lua)\$ { - return 444; -} -location ~* (w00tw00t) { - return 444; -} -location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)\$|^(\..*|Entries.*|Repository|Root|Tag|Template)\$|\.php_ { - return 444; -} +############################################## +# Utility Locations +############################################## + +# Favicon +location = /favicon.ico { + log_not_found off; + access_log off; + expires $expires; +} + +# Robots.txt location = /robots.txt { - access_log off; log_not_found off; -} -location ~ /\. { - deny all; access_log off; log_not_found off; -} -location ~* wp-includes/theme-compat/ { - deny all; -} -location ~* /(\.|wp-config\.php|wp-config\.txt|changelog\.txt|readme\.txt|readme\.html|license\.txt) { - deny all; -} -location ~* /wp-content/.*\.php\$ { - deny all; -} -location ~* /wp-includes/.*\.php\$ { - deny all; -} -location ~* wp-includes/js/tinymce/langs/.*.php { - deny all; -} -location ~* /(?:uploads|files|wp-content|wp-includes)/.*\.php\$ { - deny all; -} -location ~* /wp-content/uploads/nginx-helper/ { - internal; -} -location ~* ^/(wp-content)/(.*?)\.(zip|gz|tar|bzip2|7z)\$ { - deny all; -} -location ~ ^/wp-content/uploads/sucuri { - deny all; -} -location ~ ^/wp-content/updraft { - deny all; -} -location ~ ^/wp-content/uploads/.*.(php|pl|py|jsp|asp|htm|html|shtml|sh|cgi)$ { - types { } - default_type text/plain; -} + allow all; + log_not_found off; + access_log off; +} + +# ACME Challenge for Let's Encrypt +location ^~ /.well-known/acme-challenge/ { + allow all; +} + + +# # # WordPress Admin Area Access Control +location ~ ^/wp-admin($|/) { + # Check if the user is allowed based on geo location + if ($wp_admin_allowed = 0) { + return 403; + } + + # Regular WordPress handling + try_files $uri $uri/ /index.php$is_args$args; + + # PHP processing + location ~ \.php$ { + fastcgi_pass php-fpm; + include /etc/nginx/fastcgi.d/fastcgi.conf; + } +} + +# # Also protect wp-login.php +location = /wp-login.php { + # Check if the user is allowed based on geo location + if ($wp_admin_allowed = 0) { + return 403; + } + + # PHP processing + fastcgi_pass php-fpm; + include /etc/nginx/fastcgi.d/fastcgi.conf; +} + +location = /geoip-test { + add_header Content-Type text/plain; + return 200 "Remote Address: $remote_addr\n +IP Detection:\n +- X-Forwarded-For: $http_x_forwarded_for\n +- X-Real-IP: $http_x_real_ip\n +\n +GeoIP Information:\n +- Country Code: $geoip2_data_country_code\n +- Country Name: $geoip2_data_country_name\n +- City Name: $geoip2_data_city_name\n +- Region Name: $geoip2_data_region_name\n +- Region Code: $geoip2_data_region_code\n +- Postal Code: $geoip2_data_postal_code\n +- Latitude: $geoip2_data_latitude\n +- Longitude: $geoip2_data_longitude\n +- ASN: $geoip2_data_asn\n +- ASN Org: $geoip2_data_asn_org\n +\n +GeoIP Database Info:\n +- Country DB Build Epoch: $geoip2_metadata_country_build\n +- City DB Build Epoch: $geoip2_metadata_city_build\n"; +} + +# Also add a JSON version for programmatic testing +location = /geoip-test.json { + add_header Content-Type application/json; + return 200 '{ + "remote_addr": "$remote_addr", + "x_forwarded_for": "$http_x_forwarded_for", + "x_real_ip": "$http_x_real_ip", + "geoip2": { + "country_code": "$geoip2_data_country_code", + "country_name": "$geoip2_data_country_name", + "city_name": "$geoip2_data_city_name", + "region_name": "$geoip2_data_region_name", + "region_code": "$geoip2_data_region_code", + "postal_code": "$geoip2_data_postal_code", + "latitude": "$geoip2_data_latitude", + "longitude": "$geoip2_data_longitude", + "asn": "$geoip2_data_asn", + "asn_org": "$geoip2_data_asn_org" + }, + "database_info": { + "country_build": "$geoip2_metadata_country_build", + "city_build": "$geoip2_metadata_city_build" + } + }'; +} \ No newline at end of file diff --git a/conf/php/nginx/conf.d/seo.conf b/conf/php/nginx/conf.d/seo.conf index 80dca45..7b46276 100644 --- a/conf/php/nginx/conf.d/seo.conf +++ b/conf/php/nginx/conf.d/seo.conf @@ -1,11 +1,16 @@ -location ~ ([^/]*)sitemap(.*)\.x(m|s)l$ -{ - rewrite ^/sitemap\.xml$ /sitemap_index.xml permanent; - rewrite ^/([a-z]+)?-?sitemap\.xsl$ /index.php?xsl=$1 last; - rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last; - rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last; - rewrite ^/news_sitemap\.xml$ /index.php?sitemap=wpseo_news last; - rewrite ^/locations\.kml$ /index.php?sitemap=wpseo_local_kml last; - rewrite ^/geo_sitemap\.xml$ /index.php?sitemap=wpseo_local last; - rewrite ^/video-sitemap\.xsl$ /index.php?xsl=video last; +location ~ ([^/]*)sitemap(.*)\.x(m|s)l$ { + # Permanent redirect for the main sitemap + rewrite ^/sitemap\.xml$ /sitemap_index.xml permanent; + + # Redirect for sitemap stylesheets + rewrite ^/([a-z]+)?-?sitemap\.xsl$ /index.php?xsl=$1 last; + + # Handling specific sitemap types + rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last; + rewrite ^/news_sitemap\.xml$ /index.php?sitemap=wpseo_news last; + rewrite ^/locations\.kml$ /index.php?sitemap=wpseo_local_kml last; + rewrite ^/video-sitemap\.xsl$ /index.php?xsl=video last; + + # Handling sitemaps with pagination + rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last; } diff --git a/conf/php/nginx/conf.d/ssl.conf b/conf/php/nginx/conf.d/ssl.conf index 5dff93d..e267144 100644 --- a/conf/php/nginx/conf.d/ssl.conf +++ b/conf/php/nginx/conf.d/ssl.conf @@ -1,14 +1,57 @@ -ssl_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem; -ssl_certificate_key /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/privkey.pem; -ssl_trusted_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/chain.pem; -ssl_protocols TLSv1.2; -ssl_session_cache shared:SSL:50m; -ssl_session_timeout 30m; -ssl_dhparam /etc/pki/tls/dhparam.pem; -ssl_ecdh_curve secp384r1; -ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; -ssl_prefer_server_ciphers on; -ssl_buffer_size 1400; -ssl_session_tickets off; -ssl_stapling on; -ssl_stapling_verify on; +############################################## +# SSL/TLS Certificate Configuration +############################################## +ssl_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/privkey.pem; +ssl_trusted_certificate /etc/letsencrypt/live/{{NGINX_SERVER_NAME}}/chain.pem; + +############################################## +# SSL/TLS Protocols & Cipher Settings +############################################## +# Enable only secure protocols +ssl_protocols TLSv1.2 TLSv1.3; + +# Specify strong ciphers; the order is important for prioritizing secure algorithms +ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305'; + +ssl_prefer_server_ciphers on; + +# Use modern elliptic curves for ECDH key exchange +ssl_ecdh_curve X25519:secp384r1; + +############################################## +# SSL/TLS Session Settings +############################################## +ssl_session_cache shared:SSL:50m; +ssl_session_timeout 30m; +ssl_session_tickets off; + +############################################## +# HTTP/3 Specific Settings +############################################## +# These settings help optimize TLS for HTTP/3 +ssl_early_data on; # Enable 0-RTT for faster reconnections +quic_retry on; # Enable QUIC retry packets for DoS prevention +quic_gso on; # Enable Generic Segmentation Offload if available +ssl_reject_handshake off; # Allow HTTP/3 connection attempts even if SNI doesn't match + +# Set specific QUIC settings for transport parameters +http3_stream_buffer_size 2048; + +############################################## +# Diffie-Hellman Parameters +############################################## +# Use a strong DH parameter for added security during key exchange +ssl_dhparam /etc/pki/tls/dhparam.pem; + +############################################## +# SSL Buffer Settings +############################################## +ssl_buffer_size 8k; + +############################################## +# OCSP Stapling +############################################## +# Enable OCSP stapling to improve handshake speed and certificate validation +ssl_stapling on; +ssl_stapling_verify on; diff --git a/conf/php/nginx/conf.d/zstd.conf b/conf/php/nginx/conf.d/zstd.conf new file mode 100644 index 0000000..743ceaa --- /dev/null +++ b/conf/php/nginx/conf.d/zstd.conf @@ -0,0 +1,57 @@ +# Enable ZSTD compression +zstd on; +zstd_static on; # Serve pre-compressed .zst files if available + +# Compression settings +zstd_comp_level 5; # Compression level (1-22, higher values provide better compression at the cost of CPU usage) +zstd_min_length 256; # Only compress responses larger than 256 bytes +zstd_buffers 16 8k; # Number and size of buffers used for compression + +# Specify MIME types for ZSTD compression, grouped by category +zstd_types + # Application types + application/atom+xml + application/javascript + application/json + application/ld+json + application/manifest+json + application/rss+xml + application/vnd.geo+json + application/vnd.ms-fontobject + application/x-font-ttf + application/x-javascript + application/x-web-app-manifest+json + application/xhtml+xml + application/xml + application/wasm + application/octet-stream + + # Font types + font/eot + font/opentype + font/otf + font/ttf + font/woff + font/woff2 + + # Image types + image/avif + image/bmp + image/svg+xml + image/webp + image/x-icon + + # Text types + text/cache-manifest + text/calendar + text/css + text/html + text/javascript + text/markdown + text/plain + text/vcard + text/vnd.rim.location.xloc + text/vtt + text/x-component + text/x-cross-domain-policy + text/xml; \ No newline at end of file diff --git a/conf/php/nginx/fastcgi.d/fastcgi.conf b/conf/php/nginx/fastcgi.d/fastcgi.conf index 321aa3c..24bce59 100644 --- a/conf/php/nginx/fastcgi.d/fastcgi.conf +++ b/conf/php/nginx/fastcgi.d/fastcgi.conf @@ -1,32 +1,55 @@ +#----------------------------------------------------------- +# FastCGI Connection & Timeout Settings +#----------------------------------------------------------- fastcgi_split_path_info ^(.+\.php)(/.+)$; -fastcgi_connect_timeout 120s; -fastcgi_send_timeout 120s; -fastcgi_read_timeout 120s; - -fastcgi_buffer_size 256k; -fastcgi_buffers 4 256k; -fastcgi_busy_buffers_size 256k; -fastcgi_temp_file_write_size 4m; -fastcgi_max_temp_file_size 4m; -fastcgi_intercept_errors off; +fastcgi_connect_timeout 60s; +fastcgi_send_timeout 60s; +fastcgi_read_timeout 60s; + +#----------------------------------------------------------- +# FastCGI Buffer & Temporary File Settings +#----------------------------------------------------------- +fastcgi_buffer_size 32k; +fastcgi_buffers 8 32k; +fastcgi_busy_buffers_size 64k; +fastcgi_temp_file_write_size 8m; +fastcgi_max_temp_file_size 20m; +#----------------------------------------------------------- +# FastCGI Error Handling & Connection Options +#----------------------------------------------------------- +fastcgi_intercept_errors off; fastcgi_keep_conn on; +fastcgi_request_buffering on; -fastcgi_cache fastcgicache; +#----------------------------------------------------------- +# FastCGI Cache Settings +#----------------------------------------------------------- +fastcgi_cache fastcgicache; # Name of the cache zone fastcgi_cache_revalidate on; fastcgi_cache_background_update on; fastcgi_cache_lock on; fastcgi_cache_use_stale error timeout invalid_header updating http_500; -fastcgi_cache_valid 200 206 301 302 60s; +fastcgi_cache_valid 200 206 301 302 10m; +fastcgi_cache_valid 404 1m; fastcgi_cache_min_uses 1; fastcgi_cache_purge $purge_method; -fastcgi_cache_bypass $no_cache; -fastcgi_no_cache $no_cache; +fastcgi_cache_bypass $skip_cache; +fastcgi_no_cache $skip_cache; + +#----------------------------------------------------------- +# Include Additional FastCGI Headers +#----------------------------------------------------------- include /etc/nginx/header.d/fastcgi.conf; +#----------------------------------------------------------- +# FastCGI Environment Parameters +#----------------------------------------------------------- +# General CGI Parameters fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; +# Script & Request Details fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; @@ -34,30 +57,40 @@ fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; -fastcgi_param SCRIPT_NAME $fastcgi_script_name; +# Request & Document Information fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REQUEST_SCHEME $scheme; -fastcgi_param HTTPS $https if_not_empty; +# Connection & Client Information fastcgi_param REMOTE_ADDR $http_x_real_ip; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; -fastcgi_param GEOIP_ADDR $remote_addr; -fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code; -fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name; -fastcgi_param GEOIP_REGION $geoip_region; -fastcgi_param GEOIP_REGION_NAME $geoip_region_name; -fastcgi_param GEOIP_CITY $geoip_city; -fastcgi_param GEOIP_AREA_CODE $geoip_area_code; -fastcgi_param GEOIP_LATITUDE $geoip_latitude; -fastcgi_param GEOIP_LONGITUDE $geoip_longitude; -fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code; - -# PHP only, required if PHP was built with --enable-force-cgi-redirect +# PHP-Specific Parameter +# (Required if PHP was built with --enable-force-cgi-redirect) fastcgi_param REDIRECT_STATUS 200; +fastcgi_param HTTP_AUTHORIZATION $http_authorization; + + +# Country information +fastcgi_param GEOIP2_DATA_COUNTRY_CODE $geoip2_data_country_code; +fastcgi_param GEOIP2_DATA_COUNTRY_NAME $geoip2_data_country_name; +fastcgi_param GEOIP2_METADATA_COUNTRY_BUILD $geoip2_metadata_country_build; + +# City information +fastcgi_param GEOIP2_DATA_CITY_NAME $geoip2_data_city_name; +fastcgi_param GEOIP2_DATA_REGION_NAME $geoip2_data_region_name; +fastcgi_param GEOIP2_DATA_REGION_CODE $geoip2_data_region_code; +fastcgi_param GEOIP2_DATA_POSTAL_CODE $geoip2_data_postal_code; +fastcgi_param GEOIP2_DATA_LATITUDE $geoip2_data_latitude; +fastcgi_param GEOIP2_DATA_LONGITUDE $geoip2_data_longitude; +fastcgi_param GEOIP2_METADATA_CITY_BUILD $geoip2_metadata_city_build; + +# ASN information +fastcgi_param GEOIP2_DATA_ASN $geoip2_data_asn; +fastcgi_param GEOIP2_DATA_ASN_ORG $geoip2_data_asn_org; \ No newline at end of file diff --git a/conf/php/nginx/geo.d/whitelist.conf b/conf/php/nginx/geo.d/whitelist.conf index 32b19ee..4b82354 100644 --- a/conf/php/nginx/geo.d/whitelist.conf +++ b/conf/php/nginx/geo.d/whitelist.conf @@ -1,3 +1,5 @@ default 0; # CIDR in the list below are not limited -52.4.233.57 1;127.0.0.1 1;172.19.0.1 1; +52.4.233.57 1; +127.0.0.1 1; +172.19.0.1 1; diff --git a/conf/php/nginx/header.d/fastcgi.conf b/conf/php/nginx/header.d/fastcgi.conf index 4758b86..f3c4fe9 100644 --- a/conf/php/nginx/header.d/fastcgi.conf +++ b/conf/php/nginx/header.d/fastcgi.conf @@ -1,6 +1,34 @@ -fastcgi_pass_request_headers on; -fastcgi_pass_request_body on; -fastcgi_pass_header Set-Cookie; -fastcgi_pass_header Cookie; -fastcgi_ignore_headers Cache-Control Expires Set-Cookie; -fastcgi_hide_header X-Powered-By; +#----------------------------------------------------------- +# FastCGI Request Forwarding +#----------------------------------------------------------- +fastcgi_pass_request_headers on; # Forward all client request headers to FastCGI +fastcgi_pass_request_body on; # Forward the request body to FastCGI + +#----------------------------------------------------------- +# FastCGI Header Management +#----------------------------------------------------------- +# Explicitly pass these headers from the FastCGI server to the client +fastcgi_pass_header Authorization; +fastcgi_pass_header Set-Cookie; +fastcgi_pass_header Cookie; + +# Ignore these headers from FastCGI responses to avoid interfering with caching +fastcgi_ignore_headers Cache-Control Expires; + +# Hide sensitive headers from FastCGI responses +fastcgi_hide_header X-Powered-By; + +#----------------------------------------------------------- +# FastCGI Parameter Overrides +#----------------------------------------------------------- +# Prevent potential misuse by clearing the HTTP_PROXY parameter +fastcgi_param HTTP_PROXY ""; + +# Ensure HTTPS detection works properly (sets HTTPS if $https variable is non-empty) +fastcgi_param HTTPS $https if_not_empty; + +#----------------------------------------------------------- +# Additional Response Headers +#----------------------------------------------------------- +# Add a custom header to display FastCGI cache status (helpful for debugging) +add_header X-FastCGI-Cache $upstream_cache_status; diff --git a/conf/php/nginx/header.d/httpd.conf b/conf/php/nginx/header.d/httpd.conf index d0d5022..9dade62 100644 --- a/conf/php/nginx/header.d/httpd.conf +++ b/conf/php/nginx/header.d/httpd.conf @@ -1,9 +1,23 @@ -add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;" always; -add_header X-Frame-Options SAMEORIGIN; -add_header X-Content-Type-Options nosniff; -add_header X-XSS-Protection "1; mode=block"; -add_header "X-UA-Compatible" "IE=Edge"; -add_header X-Cache $upstream_cache_status; -add_header X-Robots-Tag "$noindex"; +############################################## +# Basic Security Headers +############################################## +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;" always; +add_header X-Frame-Options "SAMEORIGIN" always; +add_header X-Content-Type-Options "nosniff" always; +add_header X-XSS-Protection "1; mode=block" always; # Note: This header is deprecated in some modern browsers. +add_header X-UA-Compatible "IE=Edge" always; # Only needed for legacy IE support +add_header Content-Security-Policy "object-src 'none'; base-uri 'self'; upgrade-insecure-requests;" always; -#add_header Link "<$scheme://$host:$server_port$request_uri>; rel=\"canonical\""; +############################################## +# Custom & Caching Headers +############################################## +add_header X-Http-Cache-Status $upstream_cache_status always; +add_header X-Robots-Tag "$noindex" always; + +############################################## +# Additional Security Headers +############################################## +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" always; +add_header Cross-Origin-Opener-Policy "same-origin" always; +add_header Cross-Origin-Resource-Policy "same-origin" always; diff --git a/conf/php/nginx/header.d/proxy.conf b/conf/php/nginx/header.d/proxy.conf index 845b0ff..2dcc37e 100644 --- a/conf/php/nginx/header.d/proxy.conf +++ b/conf/php/nginx/header.d/proxy.conf @@ -1,37 +1,46 @@ -proxy_set_header Connection ""; -proxy_set_header Proxy ""; -proxy_set_header Host $http_host; -proxy_set_header Referer $http_referer; -proxy_set_header Upgrade $http_upgrade; - -proxy_set_header REMOTE_ADDR $http_x_real_ip; -proxy_set_header X-Real-IP $proxy_protocol_addr; - -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; -proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; -proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; - -proxy_set_header X-Client-Verify SUCCESS; -proxy_set_header X-Client-DN $ssl_client_s_dn; - -proxy_set_header X-SSL-Subject $ssl_client_s_dn; -proxy_set_header X-SSL-Issuer $ssl_client_i_dn; - -proxy_set_header Range $slice_range; - -proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie; - -proxy_set_header GEOIP-COUNTRY-CODE $geoip_country_code; -proxy_set_header GEOIP-COUNTRY-CODE3 $geoip_country_code3; -proxy_set_header GEOIP-COUNTRY-NAME $geoip_country_name; - -proxy_set_header GEOIP-CITY-COUNTRY-CODE $geoip_city_country_code; -proxy_set_header GEOIP-CITY-COUNTRY-CODE3 $geoip_city_country_code3; -proxy_set_header GEOIP-CITY-COUNTRY-NAME $geoip_city_country_name; -proxy_set_header GEOIP-REGION $geoip_region; -proxy_set_header GEOIP-CITY $geoip_city; -proxy_set_header GEOIP-POSTAL-CODE $geoip_postal_code; -proxy_set_header GEOIP-CITY-CONTINENT-CODE $geoip_city_continent_code; -proxy_set_header GEOIP-LATITUDE $geoip_latitude; -proxy_set_header GEOIP-LONGITUDE $geoip_longitude; +############################################## +# Standard Proxy Headers +############################################## +proxy_set_header Host $host; +proxy_set_header X-Real-IP $http_x_forwarded_for; +proxy_set_header X-Forwarded-For $http_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; +proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; +proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; + +############################################## +# SSL Client Headers (if applicable) +############################################## +proxy_set_header X-Client-Verify "SUCCESS"; +proxy_set_header X-Client-DN $ssl_client_s_dn; +proxy_set_header X-SSL-Subject $ssl_client_s_dn; +proxy_set_header X-SSL-Issuer $ssl_client_i_dn; + +############################################## +# WebSocket Support +############################################## +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection "upgrade"; + +############################################## +# Slice Module Support +############################################## +proxy_set_header Range $slice_range; + +############################################## +# Preserve Original Headers +############################################## +proxy_set_header User-Agent $http_user_agent; +proxy_set_header Authorization $http_authorization; +proxy_set_header X-Original-Scheme $scheme; + +############################################## +# Backend Response Header Overrides +############################################## +# Ignore these headers coming from the backend to avoid conflicts with caching and client behavior. +proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie; + +############################################## +# Custom Debug/Cache Status Header +############################################## +add_header X-Proxy-Cache-Status $upstream_cache_status; diff --git a/conf/php/nginx/map.d/cache/bypass.map b/conf/php/nginx/map.d/cache/bypass.map new file mode 100644 index 0000000..dd6686f --- /dev/null +++ b/conf/php/nginx/map.d/cache/bypass.map @@ -0,0 +1,2 @@ +default $php_session_cookie; +GET ""; \ No newline at end of file diff --git a/conf/php/nginx/map.d/cache/expires.map b/conf/php/nginx/map.d/cache/expires.map index 0d6fb99..dd9209b 100644 --- a/conf/php/nginx/map.d/cache/expires.map +++ b/conf/php/nginx/map.d/cache/expires.map @@ -1,49 +1,55 @@ -default off; -~assets/ max; -application/ecmascript max; -application/javascript max; -application/json max; -application/pdf max; -application/postscript max; -application/font-woff max; -application/font-woff2 max; -application/x-javascript max; -application/vnd.ms-fontobject max; -application/x-font-opentype max; -application/x-font-truetype max; -application/x-font-ttf max; -application/xml max; -image/gif max; -image/jpeg max; -image/png max; -image/svg+xml max; -image/tiff max; -image/x-icon max; -image/vnd.microsoft.icon max; -image/webp max; -text/x-component max; -text/x-js max; -text/css max; -text/csv max; -text/html epoch; -text/javascript max; -text/plain epoch; -text/xml max; -text/xsd max; -text/xsl max; -font/eot max; -font/opentype max; -font/otf max; -font/woff max; -font/woff2 max; -video/3gpp max; -video/mp4 max; -video/mpeg max; -video/ogg max; -video/quicktime max; -video/webm max; -video/x-flv max; -video/x-mng max; -video/x-ms-asf max; -video/x-ms-wmv max; -video/x-msvideo max; +# Default setting +default off; + +# Path-based caching +~^/assets/ max; + +# JavaScript and JSON +application/javascript max; +application/json 1h; + +# Fonts - modernized MIME types +font/woff max; +font/woff2 max; +application/vnd.ms-fontobject max; +font/ttf max; +font/otf max; + +# Images - using standard MIME types +image/gif max; +image/jpeg max; +image/png max; +image/svg+xml max; +image/webp max; +image/x-icon max; +image/avif max; + +# CSS +text/css max; + +# HTML and XML +text/html epoch; +application/xml 1h; +text/xml 1h; + +# Plain text +text/plain epoch; + +# PDFs +application/pdf max; + +# Audio and Video +audio/* max; +video/* max; + +# Modern web application types +application/manifest+json 1h; +application/wasm max; + +# Specific file types +~^/.*\.(rss|atom)$ 1h; +~^/.*\.(txt|log)$ epoch; +~^/.*\.(json|jsonld)$ 1h; + +# Avoid caching dynamic content +~^/.*\.(php|py|cgi|pl)$ off; \ No newline at end of file diff --git a/conf/php/nginx/map.d/cache/phpsession.map b/conf/php/nginx/map.d/cache/phpsession.map index aa8d015..ceb5fb0 100644 --- a/conf/php/nginx/map.d/cache/phpsession.map +++ b/conf/php/nginx/map.d/cache/phpsession.map @@ -1,2 +1,4 @@ default ""; -~PHPSESSID=(?[a-zA-Z0-9]+) $sessionkey; +~PHPSESSID=(?[a-zA-Z0-9]+) $sessionid; +~JSESSIONID=(?[a-zA-Z0-9]+) $sessionid; +~SESS(?[a-zA-Z0-9]+) $sessionid; \ No newline at end of file diff --git a/conf/php/nginx/map.d/geo/access.map b/conf/php/nginx/map.d/geo/access.map new file mode 100644 index 0000000..1e2c00c --- /dev/null +++ b/conf/php/nginx/map.d/geo/access.map @@ -0,0 +1,38 @@ +# First, ensure GeoIP2 variables are defined +# Add this to the http context of your nginx.conf or in conf.d/geoip2.conf + +# Check if the GeoIP2 region is either MA or NY +map $geoip2_data_region_code $region_ok { + default 0; + "MA" 1; + "NY" 1; +} + +# Check if the GeoIP2 country is US +map $geoip2_data_country_code $country_ok { + default 0; + "US" 1; +} + +# Combine the geo checks: allowed only if both pass ("11") +map "$region_ok$country_ok" $geo_allowed { + default 0; + "11" 1; +} + +# Add this before your final map for $wp_admin_allowed +map $remote_addr $ip_whitelist { + default 0; + 127.0.0.1 1; # Local access + 192.168.0.0/16 1; # Your office IP + 173.48.114.33 1; # Your office IP + # Add more IPs as needed +} + +# Final decision: allow access if the client is from an allowed IP or passes geo checks +map "$ip_whitelist$geo_allowed" $wp_admin_allowed { + default 0; + "10" 1; # Allowed by IP whitelist (first digit is 1) + "01" 1; # Allowed by geo (second digit is 1) + "11" 1; # Allowed by both +} \ No newline at end of file diff --git a/conf/php/nginx/map.d/method/method.map b/conf/php/nginx/map.d/method/method.map new file mode 100644 index 0000000..71ef2ac --- /dev/null +++ b/conf/php/nginx/map.d/method/method.map @@ -0,0 +1,41 @@ +# Method-based controls +# 0 = Allow caching/normal operation +# 1 = Skip cache/bypass +# $purge_allowed = Allow purge if from allowed IP + +# HTTP Methods +default 0; +"GET" 0; +"POST" 1; +"PUT" 1; +"DELETE" 1; +"PATCH" 1; +"OPTIONS" 1; +"PURGE" $purge_allowed; + +# WordPress Admin & System paths +~^/wp-admin 1; +~^/wp-admin/.*\.php 1; +~^/wp-admin/.*\.(css|js) 1; +~^/wp-includes/.*\.php 1; +~^/wp-login\.php 1; +~^/xmlrpc\.php 1; +~^/wp-[a-zA-Z0-9-]+\.php 1; +~^/preview=true 1; +~^/wp-json/ 1; + +# Dynamic plugin content +~^/wp-content/plugins/.+\.php$ 1; + +# Dynamic Content +~^/feed/ 1; +~^/sitemap(_index)?\.xml 1; +~^/index\.php 1; + +# Query string based bypass +~.*preview=true 1; +~.*_wpnonce= 1; + +# Load-specific resources +~^/wp-admin/load-scripts\.php 1; +~^/wp-admin/load-styles\.php 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/nocache/cookie.map b/conf/php/nginx/map.d/nocache/cookie.map new file mode 100644 index 0000000..48c2f6f --- /dev/null +++ b/conf/php/nginx/map.d/nocache/cookie.map @@ -0,0 +1,9 @@ +default 0; +"~PHPSESSID=" 1; +"~JSESSIONID=" 1; +"~SESS=" 1; +"~*comment_author" 1; +"~*wp-postpass" 1; +"~*wordpress_test_cookie" 1; +"~*wordpress_no_cache" 1; +"~*wordpress_logged_in" 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/nocache/method.map b/conf/php/nginx/map.d/nocache/method.map new file mode 100644 index 0000000..3a3f005 --- /dev/null +++ b/conf/php/nginx/map.d/nocache/method.map @@ -0,0 +1,6 @@ +default 0; +POST 1; +PUT 1; +DELETE 1; +PATCH 1; +OPTIONS 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/nocache/nocache.map b/conf/php/nginx/map.d/nocache/nocache.map deleted file mode 100644 index 437156d..0000000 --- a/conf/php/nginx/map.d/nocache/nocache.map +++ /dev/null @@ -1,10 +0,0 @@ -default 0; -~*\/wp-admin\/.* 1; -~*\/wp-content/plugins\/.* 1; -~*\/wp-[a-zA-Z0-9-]+\.php 1; -~*\/feed\/.* 1; -~*\/administrator\/.* 1; -~*\/sitemap(_index)?.xml 1; -~*\/xmlrpc.php 1; -HEAD 0; -GET 0; diff --git a/conf/php/nginx/map.d/nocache/uri.map b/conf/php/nginx/map.d/nocache/uri.map new file mode 100644 index 0000000..828e4c4 --- /dev/null +++ b/conf/php/nginx/map.d/nocache/uri.map @@ -0,0 +1,16 @@ +default 0; +~^/wp-admin 1; +~^/wp-admin/.*\.php 1; +~^/wp-admin/.*\.(css|js) 1; +~^/wp-includes/.*\.php 1; +~^/wp-login\.php 1; +~^/xmlrpc\.php 1; +~^/wp-[a-zA-Z0-9-]+\.php 1; +~^/preview=true 1; +~^/wp-json/ 1; +~^/wp-content/plugins/.+\.php$ 1; +~^/feed/ 1; +~^/sitemap(_index)?\.xml 1; +~^/index\.php 1; +~.*preview=true 1; +~.*_wpnonce= 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/referrer/bot.map b/conf/php/nginx/map.d/referrer/bot.map index f6e1229..d9d220d 100644 --- a/conf/php/nginx/map.d/referrer/bot.map +++ b/conf/php/nginx/map.d/referrer/bot.map @@ -1,42 +1,47 @@ +# Default for non-matching user agents default 0; -"~Prerender" 0; + +# Search Engine Bots +"~*googlebot(-mobile)?" 1; "~*baiduspider*" 1; -"bot" 1; -"~*twitterbot*" 1; -"~*Twitterbot*" 1; -"~*facebookexternalhit*" 1; -"~*Facebot*" 1; -"~*rogerbot*" 1; +"~*seznambot*" 1; + +# SEO Tools +"~*semrush(bot)?(-sa)?|Semrush ContentAnalyzer*" 1; +"~*ahrefs*" 1; +"~*screaming*" 1; +"~*Site Analyzer|SiteAnalyzerBot" 1; + +# Social Media Bots +"~*twitterbot*|Twitterbot*" 1; +"~*facebookexternalhit*|Facebot*" 1; +"~*pinterest.*ios*|Pinterest*|pinterest" 1; "~*linkedinbot*" 1; -"~*embedly*" 1; -"~*Iframely*" 1; -"~*quora*" 1; -"~*showyoubot*" 1; -"~*outbrain*" 1; -"~*Pinterest*" 1; -"~*Slack-ImgProxy*" 1; -"~*Slackbot*" 1; "~*vkShare*" 1; -"~*HipChat*" 1; -"~*W3C_Validator*" 1; -"~*quora link preview" 1; -"~*showyoubot" 1; -"~*pinterest" 1; -"~*slackbot" 1; -"~*Slackbot-LinkExpanding" 1; -"~*Site Analyzer" 1; -"~*SiteAnalyzerBot" 1; +"~*tumblr" 1; +"~*flipboard" 1; + +# Messaging Platform Bots +"~*Slack(-ImgProxy|-LinkExpanding)?|Slackbot*" 1; "~*Viber" 1; "~*Whatsapp" 1; "~*Telegram" 1; + +# Content/Preview Services +"~*embedly*" 1; +"~*Iframely*" 1; +"~*showyoubot" 1; +"~*outbrain*" 1; "~*Nuzzel" 1; -"~*Tumblr" 1; -"~*flipboard" 1; "~*AwarioRssBot" 1; -"~*Slack-ImgProxy*" 1; -"~*Slack-ImgProxy*" 1; -"~*SemrushBot-SA*" 1; -"~*SemrushBot*" 1; -"~*semrushbot*" 1; -"~*Semrush*" 1; -"~*ahrefs*" 1; + +# Monitoring/Validation +"~*nginx-amplify-agent*" 1; +"~*W3C_Validator*" 1; +"~*mail\.ru*" 1; + +# General Bot Identifier +"bot" 1; + +# Allowed Bots +"~Prerender" 0; \ No newline at end of file diff --git a/conf/php/nginx/map.d/security/block_wp_specific_php.map b/conf/php/nginx/map.d/security/block_wp_specific_php.map new file mode 100644 index 0000000..4ea5cb8 --- /dev/null +++ b/conf/php/nginx/map.d/security/block_wp_specific_php.map @@ -0,0 +1,2 @@ +default 0; +~*^/(wp-config\.php|wp-config-sample\.php)$ 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/security/blocked_attack_pattern.map b/conf/php/nginx/map.d/security/blocked_attack_pattern.map new file mode 100644 index 0000000..3f92193 --- /dev/null +++ b/conf/php/nginx/map.d/security/blocked_attack_pattern.map @@ -0,0 +1,38 @@ +default 0; + +# Basic string matches +~*eval\( 1; +~*127\.0\.0\.1 1; +~*javascript: 1; +~*base64_encode 1; +~*GLOBALS 1; +~*REQUEST_FILENAME 1; + +# Special character handling +~*\(\(/\(|\.\.\.|\+\+\+ 1; +~*[\`<>|] 1; +~*\{\$itemURL\} 1; + +# File paths and sensitive files +~*boot\.ini 1; +~*etc/passwd 1; +~*self/environ 1; + +# Image processing scripts +~*timthumb 1; + +# SQL and code injection patterns +~*(drop[^-]|insert\s+into|select\s+from|union\s+select) 1; +~*=\%27|/\'/? 1; + +# File extensions and paths - modified to be more specific +~*\.(bak|conf|dist|fla|in[ci]|log|psd|sh|sql|sw[op]|engine|make|module|tpl\.php|php_|pl|cgi|py|lua|asp|jsp)$ 1; + +# Modified sensitive files pattern +~*^(\..*|Entries.*|Repository|Root|Tag|Template|wp-config\.php|wp-config\.txt|changelog\.txt|license\.txt) 1; + +# Removed protocol matching as it's not needed + +# Miscellaneous patterns - made more specific +~*&pws=0|_vti_|\(null\) 1; +~*(phpinfo\.php|shell\.php|webshell\.php) 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/security/deny_access.map b/conf/php/nginx/map.d/security/deny_access.map new file mode 100644 index 0000000..3c461a1 --- /dev/null +++ b/conf/php/nginx/map.d/security/deny_access.map @@ -0,0 +1,3 @@ +default 0; +~*^/readme\.html$ 1; +~*^/license\.txt$ 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/security/deny_wp_directories.map b/conf/php/nginx/map.d/security/deny_wp_directories.map new file mode 100644 index 0000000..81cd0d6 --- /dev/null +++ b/conf/php/nginx/map.d/security/deny_wp_directories.map @@ -0,0 +1,2 @@ +default 0; +~*^/(wp-content|wp-content/uploads/sucuri|wp-content/updraft)/.*\.(php|zip|gz|tar|bzip2|7z|txt|log|md)$ 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/srcache/path.map b/conf/php/nginx/map.d/srcache/path.map new file mode 100644 index 0000000..c567439 --- /dev/null +++ b/conf/php/nginx/map.d/srcache/path.map @@ -0,0 +1,12 @@ +# Skip caching for admin-related paths +~^/wp-admin/ 1; +~^/wp-login\.php 1; +~^/wp-json/ 1; + +# Avoid caching dynamic script/style loading +~^/wp-admin/load-scripts\.php 1; +~^/wp-admin/load-styles\.php 1; + +# Add other WordPress-specific exclusions +~^/xmlrpc\.php 1; +~^/index\.php 1; \ No newline at end of file diff --git a/conf/php/nginx/map.d/srcache/srcache.map b/conf/php/nginx/map.d/srcache/srcache.map index 150ffc5..7e6a64b 100644 --- a/conf/php/nginx/map.d/srcache/srcache.map +++ b/conf/php/nginx/map.d/srcache/srcache.map @@ -1,3 +1,4 @@ default 0; POST 1; -PUT 1; +PUT 1; +DELETE 1; \ No newline at end of file diff --git a/conf/php/nginx/mime.type b/conf/php/nginx/mime.type index 2d74f29..ca9c6cc 100644 --- a/conf/php/nginx/mime.type +++ b/conf/php/nginx/mime.type @@ -1,20 +1,41 @@ types { + # Application formats application/atom+xml atom; application/json json map topojson; application/ld+json jsonld; application/rss+xml rss; application/vnd.geo+json geojson; application/xml rdf xml; - application/javascript js; + application/javascript js mjs; application/manifest+json webmanifest; application/x-web-app-manifest+json webapp; + + # Text formats text/cache-manifest appcache; + text/css css; + text/csv csv; + text/html htm html shtml; + text/markdown md; + text/mathml mml; + text/plain txt; + text/vcard vcard vcf; + text/vnd.rim.location.xloc xloc; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/vtt vtt; + text/calendar ics; + text/x-component htc; + + # Audio formats audio/midi mid midi kar; audio/mp4 aac f4a f4b m4a; audio/mpeg mp3; audio/ogg oga ogg opus; audio/x-realaudio ra; audio/x-wav wav; + audio/flac flac; + + # Image formats image/bmp bmp; image/gif gif; image/jpeg jpeg jpg; @@ -24,7 +45,12 @@ types { image/tiff tif tiff; image/vnd.wap.wbmp wbmp; image/webp webp; - image/x-jng jng; + image/x-icon cur ico; + image/avif avif; + image/heic heic; + image/heif heif; + + # Video formats video/3gpp 3gp 3gpp; video/mp4 f4p f4v m4v mp4; video/mpeg mpeg mpg; @@ -36,26 +62,31 @@ types { video/x-ms-asf asf asx; video/x-ms-wmv wmv; video/x-msvideo avi; - image/x-icon cur ico; - application/msword doc; - application/vnd.ms-excel xls; - application/vnd.ms-powerpoint ppt; - application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; - application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + video/x-matroska mkv; + + # Font formats application/font-woff woff; font/woff2 woff2; application/vnd.ms-fontobject eot; application/font-sfnt ttf otf; - application/java-archive ear jar war; - application/mac-binhex40 hqx; - application/octet-stream bin deb dll dmg exe img iso msi msm msp safariextz; + + # Document formats + application/msword doc; + application/vnd.ms-excel xls; + application/vnd.ms-powerpoint ppt; + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; application/pdf pdf; application/postscript ai eps ps; application/rtf rtf; application/vnd.google-earth.kml+xml kml; application/vnd.google-earth.kmz kmz; - application/vnd.wap.wmlc wmlc; + + # Archive and miscellaneous formats + application/java-archive ear jar war; + application/mac-binhex40 hqx; + application/octet-stream bin deb dll dmg exe img iso msi msm msp safariextz; application/x-7z-compressed 7z; application/x-bb-appworld bbaw; application/x-bittorrent torrent; @@ -78,16 +109,7 @@ types { application/xhtml+xml xhtml; application/xslt+xml xsl; application/zip zip; - text/css css; - text/csv csv; - text/html htm html shtml; - text/markdown md; - text/mathml mml; - text/plain txt; - text/vcard vcard vcf; - text/vnd.rim.location.xloc xloc; - text/vnd.sun.j2me.app-descriptor jad; - text/vnd.wap.wml wml; - text/vtt vtt; - text/x-component htc; + + # WebAssembly + application/wasm wasm; } diff --git a/conf/php/nginx/nginx.conf b/conf/php/nginx/nginx.conf old mode 100644 new mode 100755 index 67a3a7d..4b98cbc --- a/conf/php/nginx/nginx.conf +++ b/conf/php/nginx/nginx.conf @@ -1,5 +1,3 @@ -load_module /etc/nginx/modules/ngx_http_geoip_module.so; - user www-data; worker_processes auto; worker_rlimit_nofile 65535; @@ -7,6 +5,9 @@ timer_resolution 100ms; pcre_jit on; thread_pool default threads=32 max_queue=65536; +load_module "/usr/lib/nginx/modules/ngx_http_geoip2_module.so"; +load_module "/usr/lib/nginx/modules/ngx_stream_geoip2_module.so"; + events { worker_connections 65535; multi_accept on; @@ -14,15 +15,30 @@ events { } http { + # Global MIME types, encoding, and default type include /etc/nginx/mime.type; - include /etc/nginx/naxsi_core.rules; - default_type application/octet-stream; charset UTF-8; etag on; - sendfile off; + + # Replace with your Docker network CIDR if needed + set_real_ip_from 172.0.0.0/8; + set_real_ip_from 192.168.0.0/16; + set_real_ip_from 10.0.0.0/8; + set_real_ip_from 127.0.0.1; + set_real_ip_from ::1; + + # Define which header to use for real IP (choose one) + real_ip_header X-Forwarded-For; + # real_ip_header X-Real-IP; + + # Process the last IP in X-Forwarded-For as the client IP + real_ip_recursive off; + + # File transfer and connection tuning + sendfile on; # Enable sendfile for performance sendfile_max_chunk 512k; - send_timeout 10s; + send_timeout 15s; tcp_nopush on; tcp_nodelay on; keepalive_timeout 30; @@ -35,11 +51,14 @@ http { output_buffers 8 256k; postpone_output 1460; + # SSL and client body settings + ssl_early_data on; client_max_body_size 100M; - client_body_buffer_size 128k; + client_body_buffer_size 512k; client_header_buffer_size 3m; large_client_header_buffers 4 256k; + # File caching for static assets and log files open_file_cache max=75000 inactive=60s; open_file_cache_valid 120s; open_file_cache_min_uses 2; @@ -48,91 +67,101 @@ http { ignore_invalid_headers on; - geoip_country /usr/local/share/GeoIP/GeoIP.dat; - geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat; - + # Hash settings for maps and variables map_hash_bucket_size 256; map_hash_max_size 4096; types_hash_max_size 2048; variables_hash_max_size 2048; - geo $rate_limit {include /etc/nginx/geo.d/ratelimit.conf;} - map $rate_limit $rate_limit_key {include /etc/nginx/map.d/access/*.map;} - map $http_user_agent $no_logs {include /etc/nginx/map.d/logs/ua.map;} - - limit_req_zone $rate_limit_key zone=req_zone:10m rate=200r/s; - - upstream php-fpm {include /etc/nginx/upstream.d/php-fpm.conf;} - upstream proxy {include /etc/nginx/upstream.d/proxy.conf;} - upstream redis {include /etc/nginx/upstream.d/redis.conf;} - - log_format blocked '$time_local: Blocked request from $http_x_real_ip $request'; - log_format main_ext '{ "@timestamp": "$time_iso8601", ' - '"@fields": { ' - '"remote_addr": "$remote_addr", ' - '"remote_user": "$remote_user", ' - '"status": "$status", ' - '"request": "$request", ' - '"request_uri": "$request_uri", ' - '"request_method": "$request_method", ' - '"request_time": "$request_time", ' - '"request_uri_query": "$query_string", ' - '"http_referrer": "$http_referer", ' - '"http_user_agent": "$http_user_agent", ' - '"http_forward": "$proxy_add_x_forwarded_for", ' - '"http_header": "$http_x_header", ' - '"body_bytes_sent": "$body_bytes_sent", ' - '"geo_country": "$geoip_country_code", ' - '"geo_city": "$geoip_city", ' - '"server_name": "$server_name", ' - '"upstream_addr": "$upstream_addr", ' - '"upstream_status": "$upstream_status", ' - '"upstream_response_time": "$upstream_response_time", ' - '"upstream_response_length": "$upstream_response_length", ' - '"upstream_cache_status": "$upstream_cache_status" } }'; + # Upstream definitions (shared by all vhosts) + upstream php-fpm { include /etc/nginx/upstream.d/php-fpm.conf; } + upstream proxy { include /etc/nginx/upstream.d/proxy.conf; } + upstream redis { include /etc/nginx/upstream.d/redis.conf; } + + # Global Logging Formats (used by all sites) + log_format blocked '$time_local: Blocked request from $http_x_real_ip $request'; + log_format main_ext '{ "@timestamp": "$time_iso8601", ' + '"@fields": { ' + '"remote_addr": "$remote_addr", ' + '"remote_user": "$remote_user", ' + '"status": "$status", ' + '"request": "$request", ' + '"request_uri": "$request_uri", ' + '"request_method": "$request_method", ' + '"request_time": "$request_time", ' + '"request_uri_query": "$query_string", ' + '"http_referrer": "$http_referer", ' + '"http_user_agent": "$http_user_agent", ' + '"http_forward": "$proxy_add_x_forwarded_for", ' + '"http_header": "$http_x_header", ' + '"body_bytes_sent": "$body_bytes_sent", ' + '"server_name": "$server_name", ' + '"upstream_addr": "$upstream_addr", ' + '"upstream_status": "$upstream_status", ' + '"upstream_response_time": "$upstream_response_time", ' + '"upstream_response_length": "$upstream_response_length", ' + '"upstream_cache_status": "$upstream_cache_status", ' + '"geoip2_country_code": "$geoip2_data_country_code", ' + '"geoip2_country_name": "$geoip2_data_country_name", ' + '"geoip2_city_name": "$geoip2_data_city_name", ' + '"geoip2_region_name": "$geoip2_data_region_name", ' + '"geoip2_latitude": "$geoip2_data_latitude", ' + '"geoip2_longitude": "$geoip2_data_longitude" } }'; access_log {{LOG_PREFIX}}/access.log main_ext; - error_log {{LOG_PREFIX}}/access.log error; + error_log {{LOG_PREFIX}}/access.log warn; # Use a higher level (e.g. warn) in production - resolver 1.1.1.1 8.8.8.8 8.8.4.4 valid=60s; - resolver_timeout 15s; + # DNS Resolver Settings + resolver 1.1.1.1 8.8.8.8 8.8.4.4 valid=300s; + resolver_timeout 30s; - map $http_x_forwarded_proto $proxy_x_forwarded_proto {include /etc/nginx/map.d/header/proto.map;} - map $http_x_forwarded_port $proxy_x_forwarded_port {include /etc/nginx/map.d/header/port.map;} - map $http_upgrade $proxy_connection {include /etc/nginx/map.d/header/upgrade.map;} - map $scheme $proxy_x_forwarded_ssl {include /etc/nginx/map.d/header/scheme.map;} - map $host:$server_port$request_uri $noindex {include /etc/nginx/map.d/header/robot.map;} - map $request_method $skip_fetch {include /etc/nginx/map.d/srcache/*.map;} + # Global header maps for proxy and SSL + map $http_x_forwarded_proto $proxy_x_forwarded_proto { include /etc/nginx/map.d/header/proto.map; } + map $http_x_forwarded_port $proxy_x_forwarded_port { include /etc/nginx/map.d/header/port.map; } + map $scheme $proxy_x_forwarded_ssl { include /etc/nginx/map.d/header/scheme.map; } + map $http_upgrade $proxy_connection { include /etc/nginx/map.d/header/upgrade.map; } - map $sent_http_content_type $expires {include /etc/nginx/map.d/cache/expires.map;} - map $http_cookie $php_session_cookie {include /etc/nginx/map.d/cache/phpsession.map;} + # Global bot/crawler detection maps + map $host:$server_port$request_uri $noindex { include /etc/nginx/map.d/header/robot.map; } + map $http_user_agent $bot_pre { include /etc/nginx/map.d/referrer/bot.map; } - map $request_uri $redirect_uri {include /etc/nginx/map.d/redirects/*.map;} - map $request_uri $no_cache {include /etc/nginx/map.d/nocache/*.map;} + # Global cache control maps + map $sent_http_content_type $expires { include /etc/nginx/map.d/cache/expires.map; } + map $request_uri $no_cache_uri { include /etc/nginx/map.d/nocache/uri.map; } + map $http_cookie $no_cookie { include /etc/nginx/map.d/nocache/cookie.map; } + map $request_method $no_cache_method { include /etc/nginx/map.d/nocache/method.map; } + map $no_cache_uri$no_cookie$no_cache_method $skip_cache { default 0; ~.*1.* 1; } - map $http_user_agent $crawler_pre {include /etc/nginx/map.d/referrer/crawler.map;} - map $http_user_agent $bot_pre {include /etc/nginx/map.d/referrer/bot.map;} - map $args $prerender {default $bot_pre; "~(^|&)_escaped_fragment_=" 1;} + # Global redirect handling maps + map $request_uri $redirect_uri { include /etc/nginx/map.d/redirects/*.map; } - fastcgi_cache_path {{CACHE_PREFIX}}/fastcgi keys_zone=fastcgicache:10m levels=1:2 inactive=30m max_size=64m; - fastcgi_cache_key $scheme$request_method$host$request_uri$php_session_cookie; + # Global Cache Configurations + fastcgi_cache_path {{CACHE_PREFIX}}/fastcgi keys_zone=fastcgicache:10m levels=1:2 inactive=30m max_size=128m; + fastcgi_cache_key $scheme$request_method$host$request_uri$is_args$args; - proxy_cache_path {{CACHE_PREFIX}}/proxy keys_zone=proxycache:10m levels=1:2 inactive=30m max_size=64m; - proxy_cache_key $scheme$request_method$host$request_uri; + proxy_cache_path {{CACHE_PREFIX}}/proxy keys_zone=proxycache:10m levels=1:2 inactive=30m max_size=128m; + proxy_cache_key $scheme$request_method$host$request_uri$is_args$args; - map $request_method $purge_method {include /etc/nginx/map.d/purge/*.map;} - geo $purge_allowed {include /etc/nginx/geo.d/purge.conf;} + # Global Purge Control + include /etc/nginx/conf.d/geo.conf; + geo $purge_allowed { include /etc/nginx/geo.d/purge.conf; } - geo $whitelist {include /etc/nginx/geo.d/whitelist.conf;} - map $whitelist $limit_access {include /etc/nginx/map.d/access/*.map;} + # Global Expiration Settings and Index Files expires $expires; - index app.php index.php index.html default.html; + # Include global modules for compression and security include /etc/nginx/conf.d/brotli.conf; include /etc/nginx/conf.d/gzip.conf; + include /etc/nginx/conf.d/zstd.conf; include /etc/nginx/conf.d/proxy.conf; include /etc/nginx/conf.d/botblocker-nginx-settings.conf; include /etc/nginx/conf.d/globalblacklist.conf; + include /etc/nginx/map.d/geo/access.map; + + # Include available sites (vhosts) include /etc/nginx/sites-available/*; + + + } diff --git a/conf/php/nginx/redis.d/cache.conf b/conf/php/nginx/redis.d/cache.conf index a35fa9a..b820d90 100644 --- a/conf/php/nginx/redis.d/cache.conf +++ b/conf/php/nginx/redis.d/cache.conf @@ -1,8 +1,24 @@ -set $key $scheme$request_method$host$request_uri$is_args$args; -set_escape_uri $escaped_key $key; -srcache_fetch_skip $skip_fetch; -srcache_request_cache_control on; -srcache_default_expire 5s; - -srcache_fetch GET /redis_get $key; -srcache_store PUT /redis_put key=$escaped_key&exptime=5; +# Cache settings +set $key $scheme$request_method$host$request_uri$is_args$args; + +set_escape_uri $escaped_key $key; +srcache_fetch_skip $skip_cache; +srcache_store_skip $skip_cache; + +srcache_request_cache_control on; +srcache_response_cache_control on; +srcache_default_expire 10m; + +srcache_store_statuses 200 201 204 301 302 303 304 307 308; + +# Headers handling +srcache_store_hide_header Cache-Control; +srcache_store_hide_header Set-Cookie; +srcache_store_hide_header X-Powered-By; + +srcache_store_private on; +srcache_store_no_store on; +srcache_store_no_cache on; + +srcache_fetch GET /redis_get $key; +srcache_store PUT /redis_put key=$escaped_key&exptime=$srcache_expire; diff --git a/conf/php/nginx/redis.d/location.conf b/conf/php/nginx/redis.d/location.conf index ce558e4..954b915 100644 --- a/conf/php/nginx/redis.d/location.conf +++ b/conf/php/nginx/redis.d/location.conf @@ -1,15 +1,47 @@ +# Redis GET operation location = /redis_get { - internal; - set_md5 $redis_key $args; - redis_pass redis; + internal; # Only accessible from inside nginx + + # Use a more specific key format for application data + set_unescape_uri $cache_type $arg_type; # e.g., session, query, computation + set_unescape_uri $cache_key $arg_key; # specific identifier + set_md5 $redis_key "$cache_type:$cache_key"; + + redis_pass redis; + + # Only add cache status header for debugging + add_header X-Redis-Cache-Status $upstream_cache_status always; + error_page 500 502 503 = @fallback; } +# Redis SET operation location = /redis_put { - internal; - set_unescape_uri $exptime $arg_exptime; - set_unescape_uri $key $arg_key; - set_md5 $key; - redis2_query set $key $echo_request_body; - redis2_query expire $key $exptime; - redis2_pass redis; + internal; + + # More specific key structure + set_unescape_uri $cache_type $arg_type; + set_unescape_uri $cache_key $arg_key; + set_unescape_uri $exptime $arg_exptime; + set_md5 $redis_key "$cache_type:$cache_key"; + + redis2_query set $redis_key $echo_request_body; + redis2_query expire $redis_key $exptime; + redis2_pass redis; } + +location @fallback { + internal; + return 404; # Let the application handle fallback logic +} + +location = /purge { + allow 127.0.0.1; + deny all; + + set_unescape_uri $cache_type $arg_type; + set_unescape_uri $cache_key $arg_key; + set_md5 $redis_key "$cache_type:$cache_key"; + + redis2_query del $redis_key; + redis2_pass redis; +} \ No newline at end of file diff --git a/conf/php/nginx/sites-available/default.vhost b/conf/php/nginx/sites-available/default.vhost index a777d79..7d8bab0 100644 --- a/conf/php/nginx/sites-available/default.vhost +++ b/conf/php/nginx/sites-available/default.vhost @@ -1,66 +1,87 @@ +# HTTP Server Block - Redirect HTTP to HTTPS server { - server_name {{NGINX_SERVER_NAME}}; - server_tokens off; - server_name_in_redirect off; - listen *:80 default_server; - listen [::]:80 default_server reuseport; - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; - include /etc/nginx/bots.d/blockbots.conf; - include /etc/nginx/bots.d/ddos.conf; - include /etc/nginx/header.d/httpd.conf; - return 301 https://$host$request_uri; + server_name {{NGINX_SERVER_NAME}} www.{{NGINX_SERVER_NAME}} *.{{NGINX_SERVER_NAME}}; + listen *:80 default_server; + listen [::]:80 default_server reuseport; + http2 on; + + # Use global headers and logging settings (do not duplicate server_tokens if set globally) + include /etc/nginx/header.d/httpd.conf; + + # Redirect all HTTP traffic to HTTPS + return 301 https://$host$request_uri; } +# HTTPS Server Block - Main Public Site Configuration server { - server_name {{NGINX_SERVER_NAME}}; - server_tokens off; - server_name_in_redirect off; - root {{NGINX_DOCROOT}}; - listen *:443 default_server ssl http2; - listen [::]:443 default_server ssl http2 reuseport; - limit_req zone=req_zone burst=100 nodelay; - set $naxsi_flag_enable 0; + server_name {{NGINX_SERVER_NAME}} www.{{NGINX_SERVER_NAME}} *.{{NGINX_SERVER_NAME}}; + listen *:443 default_server ssl; + listen [::]:443 default_server ssl reuseport; + listen *:443 quic; + listen [::]:443 quic reuseport; + http2 on; + http3 on; + + # Add HTTP/3 advertisement + add_header Alt-Svc 'h3=":443"; ma=86400'; + + # Domain-specific document root + root {{NGINX_DOCROOT}}; + + # (Optional) Override global logging if desired for this site + access_log {{LOG_PREFIX}}/access.log main_ext; + + # Domain-specific user identification settings + userid on; + userid_name _uid; + userid_path /; + userid_expires max; + userid_domain {{NGINX_SERVER_NAME}}; - http2_push_preload on; - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; + # Include site-specific SSL configuration + include /etc/nginx/conf.d/ssl.conf; - userid on; - userid_name _uid; - userid_path /; - userid_expires max; - userid_domain {{NGINX_SERVER_NAME}}; + # Include bot and DDoS protection rules unique to this site + include /etc/nginx/bots.d/blockbots.conf; + include /etc/nginx/bots.d/ddos.conf; - include /etc/nginx/conf.d/ssl.conf; - include /etc/nginx/bots.d/blockbots.conf; - include /etc/nginx/bots.d/ddos.conf; + # Include HTTP and proxy headers (if they need per-site customization) + include /etc/nginx/header.d/httpd.conf; + include /etc/nginx/header.d/proxy.conf; - include /etc/nginx/header.d/httpd.conf; - include /etc/nginx/header.d/proxy.conf; + # Include CDN settings (if used only by this site) + include /etc/nginx/conf.d/cdn.conf; - include /etc/nginx/conf.d/cdn.conf; + # Include SEO configuration + include /etc/nginx/conf.d/seo.conf; - location / { - proxy_pass http://proxy/; - proxy_redirect / /; - error_page 502 =200 @failed; - } + # Main Location Block - Proxy all Requests to the Upstream 'proxy' + location / { + proxy_pass http://proxy/; + proxy_redirect / /; + error_page 502 =200 @failed; + } - include /etc/nginx/conf.d/secure.conf; - include /etc/nginx/conf.d/health.conf; - include /etc/nginx/conf.d/monit.conf; - include /etc/nginx/conf.d/purge.conf; - include /etc/nginx/conf.d/failed.conf; + # Include additional security, health, purge, and error-handling configurations + include /etc/nginx/conf.d/secure.conf; + include /etc/nginx/conf.d/health.conf; + include /etc/nginx/conf.d/purge.conf; + include /etc/nginx/conf.d/failed.conf; } +# Internal Server Block - Backend / Admin Access server { - server_tokens off; - server_name_in_redirect off; - server_name {{NGINX_SERVER_NAME}}; - listen *:8080 default_server reuseport; - root {{NGINX_DOCROOT}}; - set $cache_uri $request_uri; - if ($redirect_uri) {return 301 $redirect_uri;} - access_log {{LOG_PREFIX}}/access.log main_ext if=$no_logs; - include /etc/nginx/conf.d/location.conf; - include /etc/nginx/redis.d/location.conf; -} + server_name {{NGINX_SERVER_NAME}} www.{{NGINX_SERVER_NAME}} *.{{NGINX_SERVER_NAME}}; + listen *:8080 default_server reuseport; + root {{NGINX_DOCROOT}}; + + # Set caching and expiration specific to admin/backend + expires $expires; + set $cache_uri $request_uri; + if ($redirect_uri) { return 301 $redirect_uri; } + + access_log {{LOG_PREFIX}}/access.log main_ext; + + include /etc/nginx/conf.d/location.conf; + include /etc/nginx/redis.d/location.conf; +} \ No newline at end of file diff --git a/conf/php/nginx/upstream.d/php-fpm.conf b/conf/php/nginx/upstream.d/php-fpm.conf index 6dd9063..21c1007 100644 --- a/conf/php/nginx/upstream.d/php-fpm.conf +++ b/conf/php/nginx/upstream.d/php-fpm.conf @@ -1,4 +1,4 @@ zone php-fpm 64k; -hash $scheme$request_uri; -keepalive 64; -server {{PHP_FPM_UPSTREAM}} max_fails=3 fail_timeout=30s; +hash $request_uri consistent; +keepalive 16; +server {{PHP_FPM_UPSTREAM_HOST}}:{{PHP_FPM_UPSTREAM_PORT}} max_fails=3 fail_timeout=30s; diff --git a/conf/php/nginx/upstream.d/proxy.conf b/conf/php/nginx/upstream.d/proxy.conf index cc75b34..e9d99ec 100644 --- a/conf/php/nginx/upstream.d/proxy.conf +++ b/conf/php/nginx/upstream.d/proxy.conf @@ -1,3 +1,3 @@ zone proxy 64k; keepalive 64; -server {{NGINX_PROXY_UPSTREAM}} max_fails=3 fail_timeout=30s; +server {{NGINX_PROXY_UPSTREAM}} max_fails=3 fail_timeout=30s; \ No newline at end of file diff --git a/conf/php/nginx/upstream.d/redis.conf b/conf/php/nginx/upstream.d/redis.conf index 0e9f40e..dd668e1 100644 --- a/conf/php/nginx/upstream.d/redis.conf +++ b/conf/php/nginx/upstream.d/redis.conf @@ -1,4 +1,4 @@ zone redis 64k; -hash $scheme$request_uri; -keepalive 64; -server {{REDIS_UPSTREAM}} max_fails=3 fail_timeout=30s; +hash $request_uri consistent; +keepalive 10; +server {{REDIS_UPSTREAM_HOST}}:{{REDIS_UPSTREAM_PORT}} max_fails=3 fail_timeout=10s; diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 6ec2e49..bfe6e0c 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,220 +1,236 @@ #!/usr/bin/env bash - -function environment() { - -# Set the ROOT directory for apps and content - if [[ -z $NGINX_DOCROOT ]]; then - export NGINX_DOCROOT=/usr/share/nginx/html - echo "OK: Creating the NGINX_DOCROOT directory ${NGINX_DOCROOT}" - mkdir -p "${NGINX_DOCROOT}" - else - echo "OK: NGINX docroot is set to ${NGINX_DOCROOT}" +environment() { + # Set the ROOT directory for apps and content + if [[ -z "${NGINX_DOCROOT}" ]]; then + NGINX_DOCROOT="/usr/share/nginx/html" + export NGINX_DOCROOT + mkdir -p "${NGINX_DOCROOT}" || { + echo "ERROR: Failed to create directory ${NGINX_DOCROOT}" >&2 + return 1 + } + echo "INFO: NGINX_DOCROOT set to ${NGINX_DOCROOT}" fi - if [[ -z $PHP_FPM_UPSTREAM ]]; then - export PHP_FPM_UPSTREAM="localhost:9000;" - echo "OK: PHP_FPM_UPSTREAM was not set. Defaulting to $PHP_FPM_UPSTREAM" - else - echo "OK: PHP_FPM_UPSTREAM was set to $PHP_FPM_UPSTREAM" + if [[ -z "${PHP_FPM_UPSTREAM_HOST}" ]]; then + PHP_FPM_UPSTREAM_HOST="localhost" + PHP_FPM_UPSTREAM_PORT="9000" + export PHP_FPM_UPSTREAM_HOST + export PHP_FPM_UPSTREAM_PORT + echo "INFO: PHP_FPM_UPSTREAM_HOST set to ${PHP_FPM_UPSTREAM_HOST}:${PHP_FPM_UPSTREAM_PORT}" fi - if [[ -z $NGINX_PROXY_UPSTREAM ]]; then - export NGINX_PROXY_UPSTREAM="localhost:8080;" - echo "OK: NGINX_PROXY_UPSTREAM was not set. Defaulting to $NGINX_PROXY_UPSTREAM" - else - echo "OK: NGINX_PROXY_UPSTREAM was set to $NGINX_PROXY_UPSTREAM" + if [[ -z "${NGINX_PROXY_UPSTREAM}" ]]; then + NGINX_PROXY_UPSTREAM="localhost:8080;" + export NGINX_PROXY_UPSTREAM + echo "INFO: NGINX_PROXY_UPSTREAM set to ${NGINX_PROXY_UPSTREAM}" fi - if [[ -z $REDIS_UPSTREAM ]]; then - export REDIS_UPSTREAM="127.0.0.1:6379;" - echo "OK: REDIS_UPSTREAM was not set. Defaulting to $REDIS_UPSTREAM" - else - echo "OK: REDIS_UPSTREAM was set to $REDIS_UPSTREAM" + if [[ -z "${REDIS_UPSTREAM_HOST}" ]]; then + REDIS_UPSTREAM_HOST="localhost:6379;" + export REDIS_UPSTREAM_HOST + echo "INFO: REDIS_UPSTREAM_HOST set to ${REDIS_UPSTREAM_HOST}" fi - } -function monit() { - -# Create Monit config file -cat << EOF > /etc/monitrc -set daemon 10 -set pidfile /var/run/monit.pid -set statefile /var/run/monit.state -set httpd port 2849 and - use address localhost - allow localhost -set logfile syslog -set eventqueue - basedir /var/run - slots 100 -include /etc/monit.d/* -EOF - - # Start Monit - chmod 700 /etc/monitrc - run="monit -c /etc/monitrc" && /usr/bin/env bash -c "${run}" +config() { + # Copy the configs to the main nginx and monit conf directories + if [[ -n "${NGINX_CONFIG}" ]]; then + local config_dir="/conf/${NGINX_CONFIG}" + + if [[ ! -d "${config_dir}" ]]; then + echo "INFO: The NGINX_CONF setting is not valid. Using the default configs..." + return 1 + fi + + echo "INFO: Copying configuration files from ${config_dir} to ${CONF_PREFIX}..." + + if ! cp -r "${config_dir}/nginx/." "${CONF_PREFIX}/"; then + echo "ERROR: Failed to copy configuration files." + return 1 + fi + + echo "INFO: Replacing placeholders in configuration files..." + find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e \ + "s|{{NGINX_DOCROOT}}|${NGINX_DOCROOT}|g" \ + -e "s|{{CACHE_PREFIX}}|${CACHE_PREFIX}|g" \ + -e "s|{{NGINX_SERVER_NAME}}|${NGINX_SERVER_NAME}|g" \ + -e "s|{{LOG_PREFIX}}|${LOG_PREFIX}|g" \ + -e "s|{{NGINX_CDN_HOST}}|${NGINX_CDN_HOST}|g" \ + -e "s|{{PHP_FPM_UPSTREAM_HOST}}|${PHP_FPM_UPSTREAM_HOST}|g" \ + -e "s|{{PHP_FPM_UPSTREAM_PORT}}|${PHP_FPM_UPSTREAM_PORT}|g" \ + -e "s|{{NGINX_PROXY_UPSTREAM}}|${NGINX_PROXY_UPSTREAM}|g" \ + -e "s|{{REDIS_UPSTREAM_HOST}}|${REDIS_UPSTREAM_HOST}|g" \ + -e "s|{{REDIS_UPSTREAM_PORT}}|${REDIS_UPSTREAM_PORT}|g" {} + + + if [[ $? -ne 0 ]]; then + echo "ERROR: Failed to replace placeholders in configuration files." + return 1 + fi + + echo "INFO: Configuration files processed successfully." + else + echo "INFO: NGINX_CONFIG is not set. Skipping configuration." + fi } +permissions() { + echo "Setting permissions for ${NGINX_DOCROOT}..." -function config() { - -# Copy the configs to the main nginx and monit conf directories -if [[ ! -z $NGINX_CONFIG ]]; then - if [[ ! -d /conf/$NGINX_CONFIG ]]; then - echo "INFO: The NGINX_CONF setting has not been set. Using the default configs..." - else - echo "OK: Installing NGINX_CONFIG=$NGINX_CONFIG..." - rsync -av --ignore-missing-args /conf/${NGINX_CONFIG}/nginx/* $CONF_PREFIX/ - rsync -av --ignore-missing-args /conf/${NGINX_CONFIG}/monit/* /etc/monit.d/ - PAGESPEED_BEACON=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) - - # Set the ENV variables in all configs - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{NGINX_DOCROOT}}|'"${NGINX_DOCROOT}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{CACHE_PREFIX}}|'"${CACHE_PREFIX}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{NGINX_SERVER_NAME}}|'"${NGINX_SERVER_NAME}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{LOG_PREFIX}}|'"${LOG_PREFIX}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{PAGESPEED_BEACON}}|'"${PAGESPEED_BEACON}"'|g' {} \; - - # Replace Upstream servers - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{PHP_FPM_UPSTREAM}}|'"${PHP_FPM_UPSTREAM}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{NGINX_PROXY_UPSTREAM}}|'"${NGINX_PROXY_UPSTREAM}"'|g' {} \; - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{REDIS_UPSTREAM}}|'"${REDIS_UPSTREAM}"'|g' {} \; - - # Replace SPA - find "${CONF_PREFIX}" -maxdepth 5 -type f -exec sed -i -e 's|{{NGINX_SPA_PRERENDER}}|'"${NGINX_SPA_PRERENDER}"'|g' {} \; - - # Replace monit variables - find "/etc/monit.d" -maxdepth 3 -type f -exec sed -i -e 's|{{NGINX_DOCROOT}}|'"${NGINX_DOCROOT}"'|g' {} \; - find "/etc/monit.d" -maxdepth 3 -type f -exec sed -i -e 's|{{CACHE_PREFIX}}|'"${CACHE_PREFIX}"'|g' {} \; - find "/etc/monit.d" -maxdepth 5 -type f -exec sed -i -e 's|{{NGINX_SERVER_NAME}}|'"${NGINX_SERVER_NAME}"'|g' {} \; - fi - else - echo "OK: NGINX_CONFIG was empty. Using the bare metal config for NGINX..." -fi + mkdir -p /var/cache/fastcgi /var/cache/proxy /var/cache/fastcgi_temp -} + chown -R www-data:www-data "${NGINX_DOCROOT}" -function permissions() { + echo "Setting directory permissions..." + find "${NGINX_DOCROOT}" -type d -exec chmod 755 {} + + find "${CACHE_PREFIX}" -type d -exec chmod 755 {} + - echo "Setting ownership and permissions on NGINX_DOCROOT and CACHE_PREFIX... " - find ${NGINX_DOCROOT} ! -user www-data -exec /usr/bin/env bash -c "chown www-data:www-data {}" \; - find ${NGINX_DOCROOT} ! -perm 755 -type d -exec /usr/bin/env bash -c "chmod 755 {}" \; - find ${NGINX_DOCROOT} ! -perm 644 -type f -exec /usr/bin/env bash -c "chmod 644 {}" \; - find ${CACHE_PREFIX} ! -perm 755 -type d -exec /usr/bin/env bash -c "chmod 755 {}" \; - find ${CACHE_PREFIX} ! -perm 755 -type f -exec /usr/bin/env bash -c "chmod 755 {}" \; + echo "Setting file permissions..." + find "${NGINX_DOCROOT}" -type f -exec chmod 644 {} + + find "${CACHE_PREFIX}" -type f -exec chmod 644 {} + + echo "Permissions update complete" } -function dev() { - +dev() { # Typically these will be mounted via volume, but in case someone # needs a dev context this will set the certs so the server will # have the basics it needs to run - if [[ ! -f /etc/letsencrypt/live/${NGINX_SERVER_NAME}/privkey.pem ]] || [[ ! -f /etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem ]]; then - - echo "OK: Installing development SSL certificates..." - mkdir -p /etc/letsencrypt/live/${NGINX_SERVER_NAME} - - /usr/bin/env bash -c "openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj /C=US/ST=MA/L=Boston/O=ACMECORP/CN=${NGINX_SERVER_NAME} -keyout /etc/letsencrypt/live/${NGINX_SERVER_NAME}/privkey.pem -out /etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem" - - cp /etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem /etc/letsencrypt/live/${NGINX_SERVER_NAME}/chain.pem - - else - echo "INFO: SSL files already exist. Not installing dev certs." - fi - - # Typically the web apps will be mounted via volume. If it cannot locate those files it throws in test files so the server can prove itself ;) - if [[ ! -f ${NGINX_DOCROOT}/testing/index.php ]]; then - echo "OK: Install test PHP and HTML pages to /testing/" - mkdir -p "${NGINX_DOCROOT}"/testing/ - mkdir -p "${NGINX_DOCROOT}"/error/ - rsync -av --ignore-missing-args /tmp/test/* ${NGINX_DOCROOT}/testing/ - rsync -av --ignore-missing-args /tmp/error/* ${NGINX_DOCROOT}/error/ - else - echo "INFO: Do not install test pages" - fi + if [[ ! -f "/etc/letsencrypt/live/${NGINX_SERVER_NAME}/privkey.pem" ]] || [[ ! -f "/etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem" ]]; then + echo "OK: Installing development SSL certificates..." + mkdir -p "/etc/letsencrypt/live/${NGINX_SERVER_NAME}" + /usr/bin/env bash -c "openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj /C=US/ST=MA/L=Boston/O=ACMECORP/CN=${NGINX_SERVER_NAME} -keyout \"/etc/letsencrypt/live/${NGINX_SERVER_NAME}/privkey.pem\" -out \"/etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem\"" + cp "/etc/letsencrypt/live/${NGINX_SERVER_NAME}/fullchain.pem" "/etc/letsencrypt/live/${NGINX_SERVER_NAME}/chain.pem" + fi } -function bots() { - # https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker - echo "OK: Installing bot and spam protection settigns for NGINX.... " - # Change the install direcotry: - cd /usr/sbin - # Download the config, install and update applications - wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/install-ngxblocker -O install-ngxblocker - wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/setup-ngxblocker -O setup-ngxblocker - wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/update-ngxblocker -O update-ngxblocker - # Set permissions - chmod +x install-ngxblocker - chmod +x setup-ngxblocker - chmod +x update-ngxblocker - # Run installer and configuration - install-ngxblocker -x - setup-ngxblocker -x -w ${NGINX_DOCROOT} +bots() { + mkdir -p /etc/nginx/conf.d /etc/nginx/bots.d /usr/local/sbin + + base_url="https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master" + + declare -A paths=( + ["$base_url/conf.d/globalblacklist.conf"]="/etc/nginx/conf.d/globalblacklist.conf" + ["$base_url/bots.d/blockbots.conf"]="/etc/nginx/bots.d/blockbots.conf" + ["$base_url/bots.d/ddos.conf"]="/etc/nginx/bots.d/ddos.conf" + ["$base_url/bots.d/blacklist-user-agents.conf"]="/etc/nginx/bots.d/blacklist-user-agents.conf" + ["$base_url/bots.d/custom-bad-referrers.conf"]="/etc/nginx/bots.d/custom-bad-referrers.conf" + ["$base_url/bots.d/blacklist-ips.conf"]="/etc/nginx/bots.d/blacklist-ips.conf" + ["$base_url/bots.d/bad-referrer-words.conf"]="/etc/nginx/bots.d/bad-referrer-words.conf" + ["$base_url/conf.d/botblocker-nginx-settings.conf"]="/etc/nginx/conf.d/botblocker-nginx-settings.conf" + ["$base_url/install-ngxblocker"]="/usr/local/sbin/install-ngxblocker" + ["$base_url/update-ngxblocker"]="/usr/local/sbin/update-ngxblocker" + ) + + for url in "${!paths[@]}"; do + wget -O "${paths[$url]}" "$url" || { + echo "Failed to download $url" + exit 1 + } + done + + chmod +x /usr/local/sbin/install-ngxblocker /usr/local/sbin/update-ngxblocker + + /usr/local/sbin/update-ngxblocker -c /etc/nginx/conf.d -b /etc/nginx/bots.d + sed -i -e 's|^variables_hash_max_|#variables_hash_max_|g' /etc/nginx/conf.d/botblocker-nginx-settings.conf + + CRON_JOB="30 0 * * * /usr/local/sbin/update-ngxblocker -c /etc/nginx/conf.d -b /etc/nginx/bots.d -i /usr/local/sbin" + (crontab -l 2>/dev/null | grep -Fq "$CRON_JOB") || ( + crontab -l 2>/dev/null + echo "$CRON_JOB" + ) | crontab - + + echo "Setup complete." } -function openssl() { - - # The first argument is the bit depth of the dhparam, or 2048 if unspecified - DHPARAM_BITS=${1:-2048} +openssl() { + local DHPARAM_BITS="${1:-2048}" # If a dhparam file is not available, use the pre-generated one and generate a new one in the background. - PREGEN_DHPARAM_FILE="${CERTS_PREFIX}/dhparam.pem.default" - DHPARAM_FILE="${CERTS_PREFIX}/dhparam.pem" - GEN_LOCKFILE="/tmp/dhparam_generating.lock" - - if [[ ! -f ${DHPARAM_FILE} ]]; then - # Put the default dhparam file in place so we can start immediately - cp ${PREGEN_DHPARAM_FILE} ${DHPARAM_FILE} - touch ${GEN_LOCKFILE} - else - # The hash of the pregenerated dhparam file is used to check if the pregen dhparam is already in use - PREGEN_HASH=$(md5sum ${PREGEN_DHPARAM_FILE} | cut -d" " -f1) - CURRENT_HASH=$(md5sum ${DHPARAM_FILE} | cut -d" " -f1) - if [[ "${PREGEN_HASH}" != "${CURRENT_HASH}" ]]; then + local PREGEN_DHPARAM_FILE="${CERTS_PREFIX}/dhparam.pem.default" + local DHPARAM_FILE="${CERTS_PREFIX}/dhparam.pem" + local GEN_LOCKFILE="/tmp/dhparam_generating.lock" + + if [[ ! -f "${PREGEN_DHPARAM_FILE}" ]]; then + echo "OK: NO PREGEN_DHPARAM_FILE is present. Generate ${PREGEN_DHPARAM_FILE}..." + nice -n +5 openssl dhparam -out "${DHPARAM_FILE}" 2048 2>&1 + fi + + if [[ ! -f "${DHPARAM_FILE}" ]]; then + # Put the default dhparam file in place so we can start immediately + echo "OK: NO DHPARAM_FILE present. Copy ${PREGEN_DHPARAM_FILE} to ${DHPARAM_FILE}..." + cp "${PREGEN_DHPARAM_FILE}" "${DHPARAM_FILE}" + touch "${GEN_LOCKFILE}" + + # The hash of the pregenerated dhparam file is used to check if the pregen dhparam is already in use + local PREGEN_HASH + PREGEN_HASH=$(md5sum "${PREGEN_DHPARAM_FILE}" | cut -d" " -f1) + local CURRENT_HASH + CURRENT_HASH=$(md5sum "${DHPARAM_FILE}" | cut -d" " -f1) + if [[ "${PREGEN_HASH}" != "${CURRENT_HASH}" ]]; then # Generate a new dhparam in the background in a low priority and reload nginx when finished (grep removes the progress indicator). - ( - ( - nice -n +5 openssl dhparam -out ${DHPARAM_FILE} ${DHPARAM_BITS} 2>&1 \ - && echo "dhparam generation complete, reloading nginx" \ - && /usr/bin/env bash -c '/usr/sbin/nginx -s reload' - ) | grep -vE '^[\.+]+' - rm ${GEN_LOCKFILE} - ) &disown - fi + ( + ( + nice -n +5 openssl dhparam -out "${DHPARAM_FILE}" "${DHPARAM_BITS}" 2>&1 + ) | grep -vE '^[\.+]+' + rm "${GEN_LOCKFILE}" + ) & + disown + fi fi -# Add Let's Encrypt CA in case it is needed - mkdir -p /etc/ssl/private + # Add Let's Encrypt CA in case it is needed + mkdir -p /etc/ssl/private /var/cache/proxy cd /etc/ssl/private || exit - wget -O - https://letsencrypt.org/certs/isrgrootx1.pem https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem https://letsencrypt.org/certs/letsencryptauthorityx1.pem https://www.identrust.com/certificates/trustid/root-download-x3.html | tee -a ca-certs.pem> /dev/null - + wget -O - https://letsencrypt.org/certs/isrgrootx1.pem \ + https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem \ + https://letsencrypt.org/certs/letsencryptauthorityx1.pem \ + https://www.identrust.com/certificates/trustid/root-download-x3.html | tee -a ca-certs.pem >/dev/null } -function cdn () { -{ +cdn() { + local cdn_conf="/etc/nginx/conf.d/cdn.conf" + + # Check if NGINX_CDN_HOST is set + if [[ -z "${NGINX_CDN_HOST}" ]]; then + echo "ERROR: NGINX_CDN_HOST is not set. Cannot create CDN configuration." >&2 + return 1 + fi + + echo "INFO: Creating CDN configuration at ${cdn_conf}..." + + # Write the CDN configuration + { echo 'location ~* \.(gif|png|jpg|jpeg|svg)$ {' - echo ' return 301 https://{{NGINX_CDN_HOST}}$request_uri; ' - echo '}' -} | tee /etc/nginx/conf.d/cdn.conf + echo " return 301 https://${NGINX_CDN_HOST}\$request_uri;" + echo '}' + } >"${cdn_conf}" + + # Verify that the configuration was written successfully + if [[ $? -ne 0 ]]; then + echo "ERROR: Failed to write CDN configuration to ${cdn_conf}." >&2 + return 1 + fi + echo "INFO: CDN configuration successfully written to ${cdn_conf}." } -function run() { - environment - openssl - if [[ -z $NGINX_CDN_HOST ]]; then echo "OK: NGINX_CDN_HOST was not set. CDN is NOT active."; else echo "OK: NGINX_CDN_HOST was set to $NGINX_CDN_HOST. CDN is ACTIVE" && cdn;fi - config - if [[ $NGINX_CONFIG != "basic" ]]; then bots else echo "OK: Bot protection will not be activated in dev mode"; fi - #dev - permissions - if [[ $NGINX_CONFIG != "basic" ]]; then monit else echo "OK: Monit will not be activated in dev mode"; fi - echo "OK: All setup processes have completed. NGINX Service is now running..." +run() { + # Environment setup + openssl "$@" + if [[ -z ${NGINX_CDN_HOST} ]]; then echo "CDN was not set"; else cdn; fi + config + if [[ ${NGINX_BAD_BOTS} = "true" ]]; then bots; else echo "BOTS was not set"; fi + if [[ ${NGINX_DEV_INSTALL} = "true" ]]; then dev; fi + permissions } -run - +# Ensure run is called with arguments if needed +run "$@" -exec "$@" +# Execute the passed command +if [[ $# -eq 0 ]]; then + echo "No command provided for exec." +else + exec "$@" +fi \ No newline at end of file diff --git a/env/php.env b/env/php.env index 62257b1..0797fa9 100644 --- a/env/php.env +++ b/env/php.env @@ -1,6 +1,7 @@ NGINX_SERVER_NAME=localhost NGINX_APP_PLUGIN= NGINX_CONFIG=php +NGINX_BAD_BOTS=true NGINX_DEV_INSTALL=true PHP_FPM_UPSTREAM=localhost:9000 REDIS_UPSTREAM=redis:6379 diff --git a/geoip/GeoLite2-ASN.mmdb b/geoip/GeoLite2-ASN.mmdb new file mode 100644 index 0000000..620fd8f Binary files /dev/null and b/geoip/GeoLite2-ASN.mmdb differ diff --git a/psol/psol.tar.gz b/geoip/GeoLite2-City.mmdb similarity index 55% rename from psol/psol.tar.gz rename to geoip/GeoLite2-City.mmdb index e771213..9c8beb7 100644 Binary files a/psol/psol.tar.gz and b/geoip/GeoLite2-City.mmdb differ diff --git a/geoip/GeoLite2-Country.mmdb b/geoip/GeoLite2-Country.mmdb new file mode 100644 index 0000000..1212f58 Binary files /dev/null and b/geoip/GeoLite2-Country.mmdb differ diff --git a/hooks/build b/hooks/build old mode 100644 new mode 100755 index acafd6d..b13ba16 --- a/hooks/build +++ b/hooks/build @@ -1,14 +1,64 @@ #!/bin/bash -RELEASES=$(curl -qsL https://api.github.com/repos/nginxinc/docker-nginx/tags | grep \"name\"| sed "s/^ *\"name\" *: *\"\(\([0-9]\+\.\)\+[0-9]\+\\)\" *,/\1/g") +set -euo pipefail + +# Function to log messages +log() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to handle errors +handle_error() { + log "Error occurred on line $1" + exit 1 +} + +trap 'handle_error $LINENO' ERR + +# Configuration +GITHUB_API_URL="https://api.github.com/repos/nginxinc/docker-nginx/tags" DOCKER_REPO="openbridge/nginx" -IMG=$(basename $DOCKER_REPO) -for tag in ${RELEASES}; do - echo "============== Building ${IMG}:$tag" - docker build --build-arg "NGINX_VERSION=$tag" -t ${DOCKER_REPO}:$tag . +IMG=$(basename "$DOCKER_REPO") +DOCKERFILE_PATH="./Dockerfile" + +# Check if Dockerfile exists +if [[ ! -f "$DOCKERFILE_PATH" ]]; then + log "Error: Dockerfile not found at $DOCKERFILE_PATH" + log "Current working directory: $(pwd)" + log "Contents of current directory:" + ls -la + exit 1 +fi + +# Fetch NGINX releases +log "Fetching NGINX releases..." +RELEASES=$(curl -qsL "$GITHUB_API_URL" | jq -r '.[].name' | sort -rV) + +if [[ -z "$RELEASES" ]]; then + log "Error: Failed to fetch releases" + exit 1 +fi + +# Build images for each release +for tag in $RELEASES; do + log "Building ${IMG}:${tag}" + if ! docker build -f "$DOCKERFILE_PATH" --build-arg NGINX_VERSION="$tag" -t "${DOCKER_REPO}:${tag}" .; then + log "Error: Failed to build ${IMG}:${tag}" + log "Dockerfile contents:" + cat "$DOCKERFILE_PATH" + continue + fi done -latest=$(echo ${RELEASES}|cut -d" " -f1) -echo "============== Building ${IMG}:latest" -docker build --build-arg "NGINX_VERSION=$latest" -t ${DOCKER_REPO}:latest . -exit 0 +# Build latest image +latest=$(echo "$RELEASES" | head -n1) +log "Building ${IMG}:latest (version ${latest})" +if ! docker build -f "$DOCKERFILE_PATH" --build-arg NGINX_VERSION="$latest" -t "${DOCKER_REPO}:latest" .; then + log "Error: Failed to build ${IMG}:latest" + log "Dockerfile contents:" + cat "$DOCKERFILE_PATH" + exit 1 +fi + +log "Build process completed successfully" +exit 0 \ No newline at end of file diff --git a/hooks/push b/hooks/push old mode 100644 new mode 100755 index 30635cb..bac681f --- a/hooks/push +++ b/hooks/push @@ -1,14 +1,50 @@ #!/bin/bash -GITHUB_REPO="nginxinc/docker-nginx" -RELEASES=$(curl -qsL https://api.github.com/repos/nginxinc/docker-nginx/tags | grep \"name\"| sed "s/^ *\"name\" *: *\"\(\([0-9]\+\.\)\+[0-9]\+\\)\" *,/\1/g") +set -euo pipefail + +# Function to log messages +log() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to handle errors +handle_error() { + log "Error occurred on line $1" + exit 1 +} + +trap 'handle_error $LINENO' ERR + +# Configuration +GITHUB_API_URL="https://api.github.com/repos/nginxinc/docker-nginx/tags" DOCKER_REPO="openbridge/nginx" -IMG=$(basename $DOCKER_REPO) -for tag in ${RELEASES}; do - echo "============== Pushing ${IMG}:$tag" - docker push ${DOCKER_REPO}:$tag +IMG=$(basename "$DOCKER_REPO") + +# Fetch NGINX releases +log "Fetching NGINX releases..." +RELEASES=$(curl -qsL "$GITHUB_API_URL" | jq -r '.[].name' | sort -rV) + +if [[ -z "$RELEASES" ]]; then + log "Error: Failed to fetch releases" + exit 1 +fi + +# Push images for each release +for tag in $RELEASES; do + log "Pushing ${IMG}:$tag" + if ! docker push "${DOCKER_REPO}:$tag"; then + log "Warning: Failed to push ${IMG}:$tag" + continue + fi done -echo "============== Pushing ${IMG}:latest" -docker push ${DOCKER_REPO}:latest -exit 0 +# Push latest image +latest=$(echo "$RELEASES" | head -n1) +log "Pushing ${IMG}:latest (version $latest)" +if ! docker push "${DOCKER_REPO}:latest"; then + log "Error: Failed to push ${IMG}:latest" + exit 1 +fi + +log "Push process completed successfully" +exit 0 \ No newline at end of file diff --git a/images/developers.google.com-test.png b/images/developers.google.com-test.png new file mode 100644 index 0000000..daff055 Binary files /dev/null and b/images/developers.google.com-test.png differ diff --git a/test/test_cache.php b/testing/pages/test_cache.php similarity index 100% rename from test/test_cache.php rename to testing/pages/test_cache.php diff --git a/test/test_geo.php b/testing/pages/test_geo.php similarity index 100% rename from test/test_geo.php rename to testing/pages/test_geo.php diff --git a/test/test_info.php b/testing/pages/test_info.php similarity index 100% rename from test/test_info.php rename to testing/pages/test_info.php diff --git a/test/test_nginx.html b/testing/pages/test_nginx.html similarity index 100% rename from test/test_nginx.html rename to testing/pages/test_nginx.html diff --git a/check_folder.sh b/testing/scripts/check_folder.sh similarity index 100% rename from check_folder.sh rename to testing/scripts/check_folder.sh diff --git a/check_host.sh b/testing/scripts/check_host.sh similarity index 100% rename from check_host.sh rename to testing/scripts/check_host.sh diff --git a/check_wwwdata.sh b/testing/scripts/check_wwwdata.sh similarity index 100% rename from check_wwwdata.sh rename to testing/scripts/check_wwwdata.sh diff --git a/utilities/docker-clean.sh b/utilities/docker-clean.sh new file mode 100644 index 0000000..6df8dbd --- /dev/null +++ b/utilities/docker-clean.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Remove EVERYTHING! +docker stop $(docker ps -a -q) +docker rm -v $(docker ps -a -q -f status=exited) +docker volume rm $(docker volume ls -qf dangling=true) +docker rmi $(docker images -q) +rm -f wordpress.env wordpress.yml wordpress-login.txt + +rm -rf /opt/eff.org/* +rm -rf /etc/letsencrypt/* +rm -rf /etc/letsencrypt + +exit 0