added initial commit
This commit is contained in:
commit
0e5948b0dd
|
@ -0,0 +1,133 @@
|
||||||
|
### Git ###
|
||||||
|
# Created by git for backups. To disable backups in Git:
|
||||||
|
# $ git config --global mergetool.keepBackup false
|
||||||
|
*.orig
|
||||||
|
|
||||||
|
# Created by git when using merge tools for conflicts
|
||||||
|
*.BACKUP.*
|
||||||
|
*.BASE.*
|
||||||
|
*.LOCAL.*
|
||||||
|
*.REMOTE.*
|
||||||
|
*_BACKUP_*.txt
|
||||||
|
*_BASE_*.txt
|
||||||
|
*_LOCAL_*.txt
|
||||||
|
*_REMOTE_*.txt
|
||||||
|
### Intellij ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
|
||||||
|
### JetBrains+all Patch ###
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
modules.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### OSX ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
.ionide
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,202 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
##
|
||||||
|
## Build
|
||||||
|
##
|
||||||
|
FROM harbor.repository.lb.home.dc.internal.amuz.es/infrastructure/alpine-base:3.19-latest AS build
|
||||||
|
|
||||||
|
WORKDIR /usr/local/src
|
||||||
|
ARG VERSION="1.25.4"
|
||||||
|
|
||||||
|
### Fetch Build Dependencies
|
||||||
|
COPY patch /usr/local/src/patch
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
apk --no-cache add \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
build-base \
|
||||||
|
libtool \
|
||||||
|
musl-utils \
|
||||||
|
util-linux \
|
||||||
|
util-linux-dev \
|
||||||
|
tar \
|
||||||
|
openssl-dev \
|
||||||
|
pcre2-dev \
|
||||||
|
linux-headers \
|
||||||
|
libatomic_ops-dev \
|
||||||
|
zlib-dev \
|
||||||
|
libaio-dev \
|
||||||
|
bash \
|
||||||
|
alpine-sdk \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
findutils
|
||||||
|
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli && \
|
||||||
|
cd ngx_brotli/deps/brotli && \
|
||||||
|
mkdir out && \
|
||||||
|
cd out && \
|
||||||
|
# -DCMAKE_CXX_FLAGS="-O3 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" \
|
||||||
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
|
-DCMAKE_C_FLAGS="-O3 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=./installed .. \
|
||||||
|
&& \
|
||||||
|
cmake --build . --config Release --target brotlienc
|
||||||
|
|
||||||
|
# git clone https://github.com/yaoweibin/nginx_upstream_check_module && \
|
||||||
|
RUN set -xeu && \
|
||||||
|
git clone https://github.com/openresty/headers-more-nginx-module
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
mkdir -p /usr/local/src/nginx && \
|
||||||
|
wget -O - "https://nginx.org/download/nginx-${VERSION}.tar.gz" | tar -zxf - --strip-components=1 -C /usr/local/src/nginx && \
|
||||||
|
cd /usr/local/src/nginx && \
|
||||||
|
for i in /usr/local/src/patch/*.patch; do \
|
||||||
|
echo "Applying ${i}..." && \
|
||||||
|
patch -Np1 -i "$i"; \
|
||||||
|
done && \
|
||||||
|
# patch -Np1 -i /usr/local/src/nginx_upstream_check_module/check_1.16.1+.patch
|
||||||
|
# --add-module=/usr/local/src/nginx_http_upstream_check_module \
|
||||||
|
./configure \
|
||||||
|
--build="amazing from here" \
|
||||||
|
--with-cc-opt="-Wno-error -DTCP_FASTOPEN=23 -O2 -flto -ffat-lto-objects -funsafe-math-optimizations -fstack-protector -fcode-hoisting -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2" \
|
||||||
|
--with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -Wl,--as-needed -pie -Wl,-z,relro -Wl,-z,now -Wl,-Bsymbolic -Wl,--gc-sections -fPIC -flto=auto -ffat-lto-objects' \
|
||||||
|
--prefix=/opt/nginx \
|
||||||
|
--add-module=/usr/local/src/headers-more-nginx-module \
|
||||||
|
--add-module=/usr/local/src/ngx_brotli \
|
||||||
|
--conf-path=etc/nginx.conf \
|
||||||
|
--pid-path=tmp/nginx.pid \
|
||||||
|
--lock-path=tmp/nginx.lock \
|
||||||
|
--without-select_module \
|
||||||
|
--without-poll_module \
|
||||||
|
--with-threads \
|
||||||
|
--with-file-aio \
|
||||||
|
--with-http_ssl_module \
|
||||||
|
--with-http_v2_module \
|
||||||
|
--with-http_v3_module \
|
||||||
|
--with-http_realip_module \
|
||||||
|
--with-http_gzip_static_module \
|
||||||
|
--without-http_ssi_module \
|
||||||
|
--without-http_userid_module \
|
||||||
|
--without-http_auth_basic_module \
|
||||||
|
--without-http_fastcgi_module \
|
||||||
|
--without-http_uwsgi_module \
|
||||||
|
--without-http_scgi_module \
|
||||||
|
--without-http_memcached_module \
|
||||||
|
--without-http_browser_module \
|
||||||
|
--http-client-body-temp-path=tmp/client_body \
|
||||||
|
--http-proxy-temp-path=tmp/proxy \
|
||||||
|
--without-mail_smtp_module \
|
||||||
|
--without-mail_imap_module \
|
||||||
|
--without-mail_pop3_module \
|
||||||
|
--with-stream \
|
||||||
|
--with-stream_ssl_module \
|
||||||
|
--with-stream_realip_module \
|
||||||
|
--with-stream_ssl_preread_module \
|
||||||
|
--with-pcre \
|
||||||
|
--with-pcre-jit \
|
||||||
|
--with-libatomic && \
|
||||||
|
make -j `nproc` && \
|
||||||
|
make install && \
|
||||||
|
ldd /opt/nginx/sbin/nginx && \
|
||||||
|
find /opt/nginx && \
|
||||||
|
cat /opt/nginx/etc/nginx.conf && \
|
||||||
|
rm -r /opt/nginx/html/ && \
|
||||||
|
mkdir /opt/nginx/etc/conf.d/ && \
|
||||||
|
mkdir -p /opt/nginx/html/ && \
|
||||||
|
install -m644 html/index.html /opt/nginx/html/ && \
|
||||||
|
install -m644 html/50x.html /opt/nginx/html/ && \
|
||||||
|
ln -sf /dev/stdout /opt/nginx/logs/access.log && \
|
||||||
|
ln -sf /dev/stderr /opt/nginx/logs/error.log && \
|
||||||
|
cd /opt/nginx && \
|
||||||
|
rm \
|
||||||
|
etc/fastcgi_params \
|
||||||
|
etc/fastcgi_params.default \
|
||||||
|
etc/fastcgi.conf \
|
||||||
|
etc/fastcgi.conf.default \
|
||||||
|
etc/uwsgi_params \
|
||||||
|
etc/uwsgi_params.default \
|
||||||
|
etc/scgi_params \
|
||||||
|
etc/scgi_params.default && \
|
||||||
|
ldd sbin/nginx && \
|
||||||
|
strip -X -x -s -v sbin/nginx
|
||||||
|
|
||||||
|
##
|
||||||
|
## PKG
|
||||||
|
##
|
||||||
|
FROM harbor.repository.lb.home.dc.internal.amuz.es/infrastructure/alpine-base:3.19-latest AS pkg
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
mkdir pkgs output &&\
|
||||||
|
apk --no-cache \
|
||||||
|
fetch -R -o pkgs \
|
||||||
|
openssl \
|
||||||
|
pcre2 \
|
||||||
|
zlib \
|
||||||
|
musl-utils \
|
||||||
|
&& \
|
||||||
|
rm -f \
|
||||||
|
pkgs/busybox-*.apk \
|
||||||
|
pkgs/ca-certificates-*.apk \
|
||||||
|
pkgs/libcrypto3-*.apk \
|
||||||
|
pkgs/libssl3-*.apk \
|
||||||
|
pkgs/ssl_client-*.apk && \
|
||||||
|
find pkgs -type f -name '*.apk' -print0 |awk -F'\0' '{printf("echo \"extracting %s\";tar -zxf \"%s\" -C output || exit 1\n",$0,$0)}' |sh && \
|
||||||
|
find output -type f -name '.*' -delete
|
||||||
|
|
||||||
|
##
|
||||||
|
## Deploy
|
||||||
|
##
|
||||||
|
FROM harbor.repository.lb.home.dc.internal.amuz.es/infrastructure/minimal-toolbox:3.19-latest
|
||||||
|
|
||||||
|
COPY --from=build /opt/nginx /opt/nginx
|
||||||
|
COPY --from=pkg output /pkg
|
||||||
|
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
cp -af /pkg/* / && \
|
||||||
|
rm -rf /pkg
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
mkdir /docker-entrypoint.d
|
||||||
|
|
||||||
|
COPY nginx.conf /opt/nginx/etc/nginx.conf
|
||||||
|
COPY nginx.vh.no-default.conf /opt/nginx/etc/conf.d/default.conf
|
||||||
|
COPY docker-entrypoint.sh /
|
||||||
|
COPY /docker-entrypoint.d /docker-entrypoint.d
|
||||||
|
|
||||||
|
RUN set -xeu && \
|
||||||
|
mkdir -p /usr/local/sbin && \
|
||||||
|
ln -sf /opt/nginx/sbin/nginx /usr/local/sbin/nginx && \
|
||||||
|
mkdir -p /opt/nginx/etc/templates \
|
||||||
|
/opt/nginx/etc/stream-conf.d \
|
||||||
|
/opt/nginx/etc/conf.d \
|
||||||
|
/opt/nginx/tmp \
|
||||||
|
/opt/nginx/logs && \
|
||||||
|
chown -R 1000:1000 \
|
||||||
|
/opt/nginx/etc \
|
||||||
|
/opt/nginx/tmp \
|
||||||
|
/opt/nginx/logs
|
||||||
|
|
||||||
|
|
||||||
|
WORKDIR /opt/nginx
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.authors="Sangbum Kim <sangbumkim@amuz.es>"
|
||||||
|
|
||||||
|
EXPOSE 8080 8443 8443/udp
|
||||||
|
|
||||||
|
STOPSIGNAL SIGQUIT
|
||||||
|
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/sbin/tini", "-s", "--", "/docker-entrypoint.sh"]
|
||||||
|
|
||||||
|
USER 1000:1000
|
||||||
|
|
||||||
|
VOLUME ["/opt/nginx/etc/conf.d", "/opt/nginx/html", "/opt/nginx/tmp", "/opt/nginx/logs"]
|
||||||
|
ENV PATH="/opt/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]ca
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim:sw=4:ts=4:et
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
entrypoint_log() {
|
||||||
|
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ME=$(basename "$0")
|
||||||
|
DEFAULT_CONF_FILE="/opt/nginx/etc/conf.d/default.conf"
|
||||||
|
|
||||||
|
# check if we have ipv6 available
|
||||||
|
if [ ! -f "/proc/net/if_inet6" ]; then
|
||||||
|
entrypoint_log "$ME: info: ipv6 not available"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "/$DEFAULT_CONF_FILE" ]; then
|
||||||
|
entrypoint_log "$ME: info: /$DEFAULT_CONF_FILE is not a file or does not exist"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if the file can be modified, e.g. not on a r/o filesystem
|
||||||
|
touch /$DEFAULT_CONF_FILE 2>/dev/null || { entrypoint_log "$ME: info: can not modify /$DEFAULT_CONF_FILE (read-only file system?)"; exit 0; }
|
||||||
|
|
||||||
|
# check if the file is already modified, e.g. on a container restart
|
||||||
|
grep -q "listen \[::]\:8080;" /$DEFAULT_CONF_FILE && { entrypoint_log "$ME: info: IPv6 listen already enabled"; exit 0; }
|
||||||
|
|
||||||
|
entrypoint_log "$ME: info: Getting the checksum of /$DEFAULT_CONF_FILE"
|
||||||
|
|
||||||
|
# enable ipv6 on default.conf listen sockets
|
||||||
|
sed -i -E 's,listen 8080;,listen 8080;\n listen [::]:8080;,' /$DEFAULT_CONF_FILE
|
||||||
|
|
||||||
|
entrypoint_log "$ME: info: Enabled listen on IPv6 in /$DEFAULT_CONF_FILE"
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim:sw=2:ts=2:sts=2:et
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
|
[ "${NGINX_ENTRYPOINT_LOCAL_RESOLVERS:-}" ] || return 0
|
||||||
|
|
||||||
|
NGINX_LOCAL_RESOLVERS=$(awk 'BEGIN{ORS=" "} $1=="nameserver" {if ($2 ~ ":") {print "["$2"]"} else {print $2}}' /etc/resolv.conf)
|
||||||
|
export NGINX_LOCAL_RESOLVERS
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ME=$(basename "$0")
|
||||||
|
|
||||||
|
entrypoint_log() {
|
||||||
|
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add_stream_block() {
|
||||||
|
local conffile="/opt/nginx/etc/nginx.conf"
|
||||||
|
|
||||||
|
if grep -q -E "\s*stream\s*\{" "$conffile"; then
|
||||||
|
entrypoint_log "$ME: $conffile contains a stream block; include $stream_output_dir/*.conf to enable stream templates"
|
||||||
|
else
|
||||||
|
# check if the file can be modified, e.g. not on a r/o filesystem
|
||||||
|
touch "$conffile" 2>/dev/null || { entrypoint_log "$ME: info: can not modify $conffile (read-only file system?)"; exit 0; }
|
||||||
|
entrypoint_log "$ME: Appending stream block to $conffile to include $stream_output_dir/*.conf"
|
||||||
|
cat << END >> "$conffile"
|
||||||
|
# added by "$ME" on "$(date)"
|
||||||
|
stream {
|
||||||
|
include $stream_output_dir/*.conf;
|
||||||
|
}
|
||||||
|
END
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_renvsubst() {
|
||||||
|
local template_dir="${NGINX_RENVSUBST_TEMPLATE_DIR:-/opt/nginx/etc/templates}"
|
||||||
|
local suffix="${NGINX_RENVSUBST_TEMPLATE_SUFFIX:-.template}"
|
||||||
|
local output_dir="${NGINX_RENVSUBST_OUTPUT_DIR:-/opt/nginx/etc/conf.d}"
|
||||||
|
local stream_suffix="${NGINX_RENVSUBST_STREAM_TEMPLATE_SUFFIX:-.stream-template}"
|
||||||
|
local stream_output_dir="${NGINX_RENVSUBST_STREAM_OUTPUT_DIR:-/opt/nginx/etc/stream-conf.d}"
|
||||||
|
local filter="${NGINX_RENVSUBST_FILTER:-}"
|
||||||
|
|
||||||
|
local template defined_envs relative_path output_path subdir
|
||||||
|
defined_envs=$(printf '${%s} ' $(awk "END { for (name in ENVIRON) { print ( name ~ /${filter}/ ) ? name : \"\" } }" < /dev/null ))
|
||||||
|
[ -d "$template_dir" ] || return 0
|
||||||
|
if [ ! -w "$output_dir" ]; then
|
||||||
|
entrypoint_log "$ME: ERROR: $template_dir exists, but $output_dir is not writable"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
find "$template_dir" -follow -type f -name "*$suffix" -print | while read -r template; do
|
||||||
|
relative_path="${template#"$template_dir/"}"
|
||||||
|
output_path="$output_dir/${relative_path%"$suffix"}"
|
||||||
|
subdir=$(dirname "$relative_path")
|
||||||
|
# create a subdirectory where the template file exists
|
||||||
|
mkdir -p "$output_dir/$subdir"
|
||||||
|
entrypoint_log "$ME: Running renvsubst on $template to $output_path"
|
||||||
|
renvsubst "$defined_envs" < "$template" > "$output_path"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Print the first file with the stream suffix, this will be false if there are none
|
||||||
|
if test -n "$(find "$template_dir" -name "*$stream_suffix" -print -quit)"; then
|
||||||
|
mkdir -p "$stream_output_dir"
|
||||||
|
if [ ! -w "$stream_output_dir" ]; then
|
||||||
|
entrypoint_log "$ME: ERROR: $template_dir exists, but $stream_output_dir is not writable"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
add_stream_block
|
||||||
|
find "$template_dir" -follow -type f -name "*$stream_suffix" -print | while read -r template; do
|
||||||
|
relative_path="${template#"$template_dir/"}"
|
||||||
|
output_path="$stream_output_dir/${relative_path%"$stream_suffix"}"
|
||||||
|
subdir=$(dirname "$relative_path")
|
||||||
|
# create a subdirectory where the template file exists
|
||||||
|
mkdir -p "$stream_output_dir/$subdir"
|
||||||
|
entrypoint_log "$ME: Running renvsubst on $template to $output_path"
|
||||||
|
renvsubst "$defined_envs" < "$template" > "$output_path"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_renvsubst
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,188 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim:sw=2:ts=2:sts=2:et
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
ME=$(basename "$0")
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
|
[ "${NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE:-}" ] || exit 0
|
||||||
|
|
||||||
|
touch /opt/nginx/etc/nginx.conf 2>/dev/null || { echo >&2 "$ME: error: can not modify /opt/nginx/etc/nginx.conf (read-only file system?)"; exit 0; }
|
||||||
|
|
||||||
|
ceildiv() {
|
||||||
|
num=$1
|
||||||
|
div=$2
|
||||||
|
echo $(( (num + div - 1) / div ))
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cpuset() {
|
||||||
|
cpusetroot=$1
|
||||||
|
cpusetfile=$2
|
||||||
|
ncpu=0
|
||||||
|
[ -f "$cpusetroot/$cpusetfile" ] || return 1
|
||||||
|
for token in $( tr ',' ' ' < "$cpusetroot/$cpusetfile" ); do
|
||||||
|
case "$token" in
|
||||||
|
*-*)
|
||||||
|
count=$( seq $(echo "$token" | tr '-' ' ') | wc -l )
|
||||||
|
ncpu=$(( ncpu+count ))
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
ncpu=$(( ncpu+1 ))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
echo "$ncpu"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_quota() {
|
||||||
|
cpuroot=$1
|
||||||
|
ncpu=0
|
||||||
|
[ -f "$cpuroot/cpu.cfs_quota_us" ] || return 1
|
||||||
|
[ -f "$cpuroot/cpu.cfs_period_us" ] || return 1
|
||||||
|
cfs_quota=$( cat "$cpuroot/cpu.cfs_quota_us" )
|
||||||
|
cfs_period=$( cat "$cpuroot/cpu.cfs_period_us" )
|
||||||
|
[ "$cfs_quota" = "-1" ] && return 1
|
||||||
|
[ "$cfs_period" = "0" ] && return 1
|
||||||
|
ncpu=$( ceildiv "$cfs_quota" "$cfs_period" )
|
||||||
|
[ "$ncpu" -gt 0 ] || return 1
|
||||||
|
echo "$ncpu"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_quota_v2() {
|
||||||
|
cpuroot=$1
|
||||||
|
ncpu=0
|
||||||
|
[ -f "$cpuroot/cpu.max" ] || return 1
|
||||||
|
cfs_quota=$( cut -d' ' -f 1 < "$cpuroot/cpu.max" )
|
||||||
|
cfs_period=$( cut -d' ' -f 2 < "$cpuroot/cpu.max" )
|
||||||
|
[ "$cfs_quota" = "max" ] && return 1
|
||||||
|
[ "$cfs_period" = "0" ] && return 1
|
||||||
|
ncpu=$( ceildiv "$cfs_quota" "$cfs_period" )
|
||||||
|
[ "$ncpu" -gt 0 ] || return 1
|
||||||
|
echo "$ncpu"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cgroup_v1_path() {
|
||||||
|
needle=$1
|
||||||
|
found=
|
||||||
|
foundroot=
|
||||||
|
mountpoint=
|
||||||
|
|
||||||
|
[ -r "/proc/self/mountinfo" ] || return 1
|
||||||
|
[ -r "/proc/self/cgroup" ] || return 1
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
case "$needle" in
|
||||||
|
"cpuset")
|
||||||
|
case "$line" in
|
||||||
|
*cpuset*)
|
||||||
|
found=$( echo "$line" | cut -d ' ' -f 4,5 )
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"cpu")
|
||||||
|
case "$line" in
|
||||||
|
*cpuset*)
|
||||||
|
;;
|
||||||
|
*cpu,cpuacct*|*cpuacct,cpu|*cpuacct*|*cpu*)
|
||||||
|
found=$( echo "$line" | cut -d ' ' -f 4,5 )
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
done << __EOF__
|
||||||
|
$( grep -F -- '- cgroup ' /proc/self/mountinfo )
|
||||||
|
__EOF__
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
controller=$( echo "$line" | cut -d: -f 2 )
|
||||||
|
case "$needle" in
|
||||||
|
"cpuset")
|
||||||
|
case "$controller" in
|
||||||
|
cpuset)
|
||||||
|
mountpoint=$( echo "$line" | cut -d: -f 3 )
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"cpu")
|
||||||
|
case "$controller" in
|
||||||
|
cpu,cpuacct|cpuacct,cpu|cpuacct|cpu)
|
||||||
|
mountpoint=$( echo "$line" | cut -d: -f 3 )
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done << __EOF__
|
||||||
|
$( grep -F -- 'cpu' /proc/self/cgroup )
|
||||||
|
__EOF__
|
||||||
|
|
||||||
|
case "${found%% *}" in
|
||||||
|
"/")
|
||||||
|
foundroot="${found##* }$mountpoint"
|
||||||
|
;;
|
||||||
|
"$mountpoint")
|
||||||
|
foundroot="${found##* }"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$foundroot"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cgroup_v2_path() {
|
||||||
|
found=
|
||||||
|
foundroot=
|
||||||
|
mountpoint=
|
||||||
|
|
||||||
|
[ -r "/proc/self/mountinfo" ] || return 1
|
||||||
|
[ -r "/proc/self/cgroup" ] || return 1
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
found=$( echo "$line" | cut -d ' ' -f 4,5 )
|
||||||
|
done << __EOF__
|
||||||
|
$( grep -F -- '- cgroup2 ' /proc/self/mountinfo )
|
||||||
|
__EOF__
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
mountpoint=$( echo "$line" | cut -d: -f 3 )
|
||||||
|
done << __EOF__
|
||||||
|
$( grep -F -- '0::' /proc/self/cgroup )
|
||||||
|
__EOF__
|
||||||
|
|
||||||
|
case "${found%% *}" in
|
||||||
|
"")
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
"/")
|
||||||
|
foundroot="${found##* }$mountpoint"
|
||||||
|
;;
|
||||||
|
"$mountpoint" | /../*)
|
||||||
|
foundroot="${found##* }"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$foundroot"
|
||||||
|
}
|
||||||
|
|
||||||
|
ncpu_online=$( getconf _NPROCESSORS_ONLN )
|
||||||
|
ncpu_cpuset=
|
||||||
|
ncpu_quota=
|
||||||
|
ncpu_cpuset_v2=
|
||||||
|
ncpu_quota_v2=
|
||||||
|
|
||||||
|
cpuset=$( get_cgroup_v1_path "cpuset" ) && ncpu_cpuset=$( get_cpuset "$cpuset" "cpuset.effective_cpus" ) || ncpu_cpuset=$ncpu_online
|
||||||
|
cpu=$( get_cgroup_v1_path "cpu" ) && ncpu_quota=$( get_quota "$cpu" ) || ncpu_quota=$ncpu_online
|
||||||
|
cgroup_v2=$( get_cgroup_v2_path ) && ncpu_cpuset_v2=$( get_cpuset "$cgroup_v2" "cpuset.cpus.effective" ) || ncpu_cpuset_v2=$ncpu_online
|
||||||
|
cgroup_v2=$( get_cgroup_v2_path ) && ncpu_quota_v2=$( get_quota_v2 "$cgroup_v2" ) || ncpu_quota_v2=$ncpu_online
|
||||||
|
|
||||||
|
ncpu=$( printf "%s\n%s\n%s\n%s\n%s\n" \
|
||||||
|
"$ncpu_online" \
|
||||||
|
"$ncpu_cpuset" \
|
||||||
|
"$ncpu_quota" \
|
||||||
|
"$ncpu_cpuset_v2" \
|
||||||
|
"$ncpu_quota_v2" \
|
||||||
|
| sort -n \
|
||||||
|
| head -n 1 )
|
||||||
|
|
||||||
|
sed -i.bak -r 's/^(worker_processes)(.*)$/# Commented out by '"$ME"' on '"$(date)"'\n#\1\2\n\1 '"$ncpu"';/' /opt/nginx/etc/nginx.conf
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim:sw=2:ts=2:sts=2:et
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
|
make_tmp_directories() {
|
||||||
|
local temp_dir="${NGINX_RENVSUBST_TEMPORARY_DIR:-/opt/nginx/tmp}"
|
||||||
|
local client_body_temp_dir="${NGINX_RENVSUBST_CLIENT_BODY_TEMP_DIR:-${temp_dir}/client_temp}"
|
||||||
|
local proxy_temp_dir="${NGINX_RENVSUBST_PROXY_TEMP_DIR:-${temp_dir}/proxy}"
|
||||||
|
|
||||||
|
local temp_dir client_body_temp_dir proxy_temp_dir
|
||||||
|
if [ ! -w "$temp_dir" ]; then
|
||||||
|
entrypoint_log "$ME: ERROR: $temp_dir is not writable"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
[ ! -d "$client_body_temp_dir" ] || mkdir -p "${client_body_temp_dir}"
|
||||||
|
[ ! -d "$proxy_temp_dir" ] || mkdir -p "${proxy_temp_dir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
make_tmp_directories
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim:sw=4:ts=4:et
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
entrypoint_log() {
|
||||||
|
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" = "nginx" ] || [ "$1" = "nginx-debug" ]; then
|
||||||
|
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
|
||||||
|
entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"
|
||||||
|
|
||||||
|
entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/"
|
||||||
|
find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
|
||||||
|
case "$f" in
|
||||||
|
*.envsh)
|
||||||
|
if [ -x "$f" ]; then
|
||||||
|
entrypoint_log "$0: Sourcing $f";
|
||||||
|
. "$f"
|
||||||
|
else
|
||||||
|
# warn on shell scripts without exec bit
|
||||||
|
entrypoint_log "$0: Ignoring $f, not executable";
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*.sh)
|
||||||
|
if [ -x "$f" ]; then
|
||||||
|
entrypoint_log "$0: Launching $f";
|
||||||
|
"$f"
|
||||||
|
else
|
||||||
|
# warn on shell scripts without exec bit
|
||||||
|
entrypoint_log "$0: Ignoring $f, not executable";
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) entrypoint_log "$0: Ignoring $f";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
entrypoint_log "$0: Configuration complete; ready for start up"
|
||||||
|
else
|
||||||
|
entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
|
@ -0,0 +1,114 @@
|
||||||
|
#user me;
|
||||||
|
worker_processes 1;
|
||||||
|
|
||||||
|
error_log /opt/nginx/logs/error.log warn;
|
||||||
|
pid /opt/nginx/tmp/nginx.pid;
|
||||||
|
|
||||||
|
pcre_jit on;
|
||||||
|
timer_resolution 100ms;
|
||||||
|
|
||||||
|
events {
|
||||||
|
use epoll;
|
||||||
|
worker_aio_requests 128;
|
||||||
|
worker_connections 1024;
|
||||||
|
multi_accept on;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
charset utf-8;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
client_body_temp_path /opt/nginx/tmp/client_temp;
|
||||||
|
proxy_temp_path /opt/nginx/tmp/proxy;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /opt/nginx/logs/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
aio threads;
|
||||||
|
aio_write on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
|
||||||
|
open_file_cache max=1000 inactive=20s;
|
||||||
|
open_file_cache_valid 30s;
|
||||||
|
open_file_cache_min_uses 2;
|
||||||
|
open_file_cache_errors on;
|
||||||
|
|
||||||
|
keepalive_timeout 15s;
|
||||||
|
send_timeout 60s;
|
||||||
|
client_header_timeout 15s;
|
||||||
|
client_body_timeout 600s;
|
||||||
|
client_max_body_size 500m;
|
||||||
|
client_body_buffer_size 8K;
|
||||||
|
client_header_buffer_size 1k;
|
||||||
|
large_client_header_buffers 4 8k;
|
||||||
|
output_buffers 5 8m;
|
||||||
|
resolver_timeout 5s;
|
||||||
|
read_ahead 256k;
|
||||||
|
|
||||||
|
keepalive_disable msie6;
|
||||||
|
disable_symlinks if_not_owner;
|
||||||
|
if_modified_since before;
|
||||||
|
reset_timedout_connection on;
|
||||||
|
server_tokens off;
|
||||||
|
more_set_headers 'Server: AmazingFromHere';
|
||||||
|
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
|
||||||
|
# ssl_dyn_rec_enable on;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
# ssl_ecdh_curve X25519:P-521:P-384;
|
||||||
|
# ssl_ciphers [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-RSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES256-GCM-SHA384|ECDHE-RSA-AES256-GCM-SHA384]:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_session_cache builtin:1000 shared:SSL:50m;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
gzip_static on;
|
||||||
|
gzip on;
|
||||||
|
gzip_comp_level 5;
|
||||||
|
gzip_min_length 512;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_disable "msie6";
|
||||||
|
gzip_types
|
||||||
|
text/plain
|
||||||
|
text/css
|
||||||
|
text/x-component
|
||||||
|
text/javascript application/x-javascript application/javascript text/x-js
|
||||||
|
image/svg+xml
|
||||||
|
text/plaintext/xsd text/xsl
|
||||||
|
text/xml application/xml application/rss+xml
|
||||||
|
application/json
|
||||||
|
font/truetype font/opentype application/x-font-otf application/x-font-ttf application/vnd.ms-opentype application/vnd.ms-fontobject application/font-woff application/font-woff2
|
||||||
|
audio/ogg
|
||||||
|
application/pdf
|
||||||
|
image/bmp image/x-icon image/webp image/tiff
|
||||||
|
audio/wav;
|
||||||
|
|
||||||
|
brotli_static on;
|
||||||
|
brotli on;
|
||||||
|
brotli_types
|
||||||
|
text/plain
|
||||||
|
text/css
|
||||||
|
text/x-component
|
||||||
|
text/javascript application/x-javascript application/javascript text/x-js
|
||||||
|
image/svg+xml
|
||||||
|
text/plaintext/xsd text/xsl
|
||||||
|
text/xml application/xml application/rss+xml
|
||||||
|
application/json
|
||||||
|
font/truetype font/opentype application/x-font-otf application/x-font-ttf application/vnd.ms-opentype application/vnd.ms-fontobject application/font-woff application/font-woff2
|
||||||
|
audio/ogg
|
||||||
|
application/pdf
|
||||||
|
image/bmp image/x-icon image/webp image/tiff
|
||||||
|
audio/wav;
|
||||||
|
|
||||||
|
include /opt/nginx/etc/conf.d/*.conf;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Drop requests for unknown hosts
|
||||||
|
#
|
||||||
|
# If no default server is defined, angie will use the first found server.
|
||||||
|
# To prevent host header attacks, or other potential problems when an unknown
|
||||||
|
# servername is used in a request, it's recommended to drop the request
|
||||||
|
# returning 444 "no response".
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8080 default_server deferred reuseport;
|
||||||
|
server_name _ "";
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8443 default_server quic reuseport;
|
||||||
|
listen 8443 default_server deferred ssl reuseport;
|
||||||
|
http2 on;
|
||||||
|
server_name _ "";
|
||||||
|
ssl_reject_handshake on;
|
||||||
|
}
|
|
@ -0,0 +1,254 @@
|
||||||
|
What we do now:
|
||||||
|
We use a static record size of 4K. This gives a good balance of latency and
|
||||||
|
throughput.
|
||||||
|
|
||||||
|
Optimize latency:
|
||||||
|
By initialy sending small (1 TCP segment) sized records, we are able to avoid
|
||||||
|
HoL blocking of the first byte. This means TTFB is sometime lower by a whole
|
||||||
|
RTT.
|
||||||
|
|
||||||
|
Optimizing throughput:
|
||||||
|
By sending increasingly larger records later in the connection, when HoL is not
|
||||||
|
a problem, we reduce the overhead of TLS record (29 bytes per record with
|
||||||
|
GCM/CHACHA-POLY).
|
||||||
|
|
||||||
|
Logic:
|
||||||
|
Start each connection with small records (1369 byte default, change with
|
||||||
|
ssl_dyn_rec_size_lo). After a given number of records (40, change with
|
||||||
|
ssl_dyn_rec_threshold) start sending larger records (4229, ssl_dyn_rec_size_hi).
|
||||||
|
Eventually after the same number of records, start sending the largest records
|
||||||
|
(ssl_buffer_size).
|
||||||
|
In case the connection idles for a given amount of time (1s,
|
||||||
|
ssl_dyn_rec_timeout), the process repeats itself (i.e. begin sending small
|
||||||
|
records again).
|
||||||
|
|
||||||
|
|
||||||
|
diff --color -uNr a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
|
||||||
|
--- a/src/event/ngx_event_openssl.c 2023-06-13 23:08:10.000000000 +0800
|
||||||
|
+++ b/src/event/ngx_event_openssl.c 2023-06-14 15:43:05.834243714 +0800
|
||||||
|
@@ -1674,6 +1674,7 @@
|
||||||
|
|
||||||
|
sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
|
||||||
|
sc->buffer_size = ssl->buffer_size;
|
||||||
|
+ sc->dyn_rec = ssl->dyn_rec;
|
||||||
|
|
||||||
|
sc->session_ctx = ssl->ctx;
|
||||||
|
|
||||||
|
@@ -2645,6 +2646,41 @@
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
|
||||||
|
+ /* Dynamic record resizing:
|
||||||
|
+ We want the initial records to fit into one TCP segment
|
||||||
|
+ so we don't get TCP HoL blocking due to TCP Slow Start.
|
||||||
|
+ A connection always starts with small records, but after
|
||||||
|
+ a given amount of records sent, we make the records larger
|
||||||
|
+ to reduce header overhead.
|
||||||
|
+ After a connection has idled for a given timeout, begin
|
||||||
|
+ the process from the start. The actual parameters are
|
||||||
|
+ configurable. If dyn_rec_timeout is 0, we assume dyn_rec is off. */
|
||||||
|
+
|
||||||
|
+ if (c->ssl->dyn_rec.timeout > 0 ) {
|
||||||
|
+
|
||||||
|
+ if (ngx_current_msec - c->ssl->dyn_rec_last_write >
|
||||||
|
+ c->ssl->dyn_rec.timeout)
|
||||||
|
+ {
|
||||||
|
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
|
||||||
|
+ c->ssl->dyn_rec_records_sent = 0;
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ if (c->ssl->dyn_rec_records_sent >
|
||||||
|
+ c->ssl->dyn_rec.threshold * 2)
|
||||||
|
+ {
|
||||||
|
+ buf->end = buf->start + c->ssl->buffer_size;
|
||||||
|
+
|
||||||
|
+ } else if (c->ssl->dyn_rec_records_sent >
|
||||||
|
+ c->ssl->dyn_rec.threshold)
|
||||||
|
+ {
|
||||||
|
+ buf->end = buf->start + c->ssl->dyn_rec.size_hi;
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
while (in && buf->last < buf->end && send < limit) {
|
||||||
|
if (in->buf->last_buf || in->buf->flush) {
|
||||||
|
flush = 1;
|
||||||
|
@@ -2784,6 +2820,9 @@
|
||||||
|
|
||||||
|
if (n > 0) {
|
||||||
|
|
||||||
|
+ c->ssl->dyn_rec_records_sent++;
|
||||||
|
+ c->ssl->dyn_rec_last_write = ngx_current_msec;
|
||||||
|
+
|
||||||
|
if (c->ssl->saved_read_handler) {
|
||||||
|
|
||||||
|
c->read->handler = c->ssl->saved_read_handler;
|
||||||
|
diff --color -uNr a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
|
||||||
|
--- a/src/event/ngx_event_openssl.h 2023-06-13 23:08:10.000000000 +0800
|
||||||
|
+++ b/src/event/ngx_event_openssl.h 2023-06-14 15:43:05.834243714 +0800
|
||||||
|
@@ -86,10 +86,19 @@
|
||||||
|
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
|
||||||
|
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ ngx_msec_t timeout;
|
||||||
|
+ ngx_uint_t threshold;
|
||||||
|
+ size_t size_lo;
|
||||||
|
+ size_t size_hi;
|
||||||
|
+} ngx_ssl_dyn_rec_t;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
struct ngx_ssl_s {
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
ngx_log_t *log;
|
||||||
|
size_t buffer_size;
|
||||||
|
+ ngx_ssl_dyn_rec_t dyn_rec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -128,6 +137,10 @@
|
||||||
|
unsigned in_ocsp:1;
|
||||||
|
unsigned early_preread:1;
|
||||||
|
unsigned write_blocked:1;
|
||||||
|
+
|
||||||
|
+ ngx_ssl_dyn_rec_t dyn_rec;
|
||||||
|
+ ngx_msec_t dyn_rec_last_write;
|
||||||
|
+ ngx_uint_t dyn_rec_records_sent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -137,7 +150,7 @@
|
||||||
|
#define NGX_SSL_DFLT_BUILTIN_SCACHE -5
|
||||||
|
|
||||||
|
|
||||||
|
-#define NGX_SSL_MAX_SESSION_SIZE 4096
|
||||||
|
+#define NGX_SSL_MAX_SESSION_SIZE 16384
|
||||||
|
|
||||||
|
typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
|
||||||
|
|
||||||
|
diff --color -uNr a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
|
||||||
|
--- a/src/http/modules/ngx_http_ssl_module.c 2023-06-13 23:08:10.000000000 +0800
|
||||||
|
+++ b/src/http/modules/ngx_http_ssl_module.c 2023-06-14 15:43:05.834243714 +0800
|
||||||
|
@@ -290,6 +290,41 @@
|
||||||
|
offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
+ { ngx_string("ssl_dyn_rec_enable"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_flag_slot,
|
||||||
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_enable),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
+ { ngx_string("ssl_dyn_rec_timeout"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_msec_slot,
|
||||||
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_timeout),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
+ { ngx_string("ssl_dyn_rec_size_lo"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_size_slot,
|
||||||
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_lo),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
+ { ngx_string("ssl_dyn_rec_size_hi"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_size_slot,
|
||||||
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_hi),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
+ { ngx_string("ssl_dyn_rec_threshold"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_num_slot,
|
||||||
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_threshold),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
ngx_null_command
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -629,6 +664,11 @@
|
||||||
|
sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
|
||||||
|
sscf->stapling = NGX_CONF_UNSET;
|
||||||
|
sscf->stapling_verify = NGX_CONF_UNSET;
|
||||||
|
+ sscf->dyn_rec_enable = NGX_CONF_UNSET;
|
||||||
|
+ sscf->dyn_rec_timeout = NGX_CONF_UNSET_MSEC;
|
||||||
|
+ sscf->dyn_rec_size_lo = NGX_CONF_UNSET_SIZE;
|
||||||
|
+ sscf->dyn_rec_size_hi = NGX_CONF_UNSET_SIZE;
|
||||||
|
+ sscf->dyn_rec_threshold = NGX_CONF_UNSET_UINT;
|
||||||
|
|
||||||
|
return sscf;
|
||||||
|
}
|
||||||
|
@@ -694,6 +734,20 @@
|
||||||
|
ngx_conf_merge_str_value(conf->stapling_responder,
|
||||||
|
prev->stapling_responder, "");
|
||||||
|
|
||||||
|
+ ngx_conf_merge_value(conf->dyn_rec_enable, prev->dyn_rec_enable, 0);
|
||||||
|
+ ngx_conf_merge_msec_value(conf->dyn_rec_timeout, prev->dyn_rec_timeout,
|
||||||
|
+ 1000);
|
||||||
|
+ /* Default sizes for the dynamic record sizes are defined to fit maximal
|
||||||
|
+ TLS + IPv6 overhead in a single TCP segment for lo and 3 segments for hi:
|
||||||
|
+ 1369 = 1500 - 40 (IP) - 20 (TCP) - 10 (Time) - 61 (Max TLS overhead) */
|
||||||
|
+ ngx_conf_merge_size_value(conf->dyn_rec_size_lo, prev->dyn_rec_size_lo,
|
||||||
|
+ 1369);
|
||||||
|
+ /* 4229 = (1500 - 40 - 20 - 10) * 3 - 61 */
|
||||||
|
+ ngx_conf_merge_size_value(conf->dyn_rec_size_hi, prev->dyn_rec_size_hi,
|
||||||
|
+ 4229);
|
||||||
|
+ ngx_conf_merge_uint_value(conf->dyn_rec_threshold, prev->dyn_rec_threshold,
|
||||||
|
+ 40);
|
||||||
|
+
|
||||||
|
conf->ssl.log = cf->log;
|
||||||
|
|
||||||
|
if (conf->certificates) {
|
||||||
|
@@ -890,6 +944,28 @@
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (conf->dyn_rec_enable) {
|
||||||
|
+ conf->ssl.dyn_rec.timeout = conf->dyn_rec_timeout;
|
||||||
|
+ conf->ssl.dyn_rec.threshold = conf->dyn_rec_threshold;
|
||||||
|
+
|
||||||
|
+ if (conf->buffer_size > conf->dyn_rec_size_lo) {
|
||||||
|
+ conf->ssl.dyn_rec.size_lo = conf->dyn_rec_size_lo;
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ conf->ssl.dyn_rec.size_lo = conf->buffer_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (conf->buffer_size > conf->dyn_rec_size_hi) {
|
||||||
|
+ conf->ssl.dyn_rec.size_hi = conf->dyn_rec_size_hi;
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ conf->ssl.dyn_rec.size_hi = conf->buffer_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ conf->ssl.dyn_rec.timeout = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --color -uNr a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
|
||||||
|
--- a/src/http/modules/ngx_http_ssl_module.h 2023-06-13 23:08:10.000000000 +0800
|
||||||
|
+++ b/src/http/modules/ngx_http_ssl_module.h 2023-06-14 15:43:38.264102815 +0800
|
||||||
|
@@ -62,6 +62,12 @@
|
||||||
|
ngx_flag_t stapling_verify;
|
||||||
|
ngx_str_t stapling_file;
|
||||||
|
ngx_str_t stapling_responder;
|
||||||
|
+
|
||||||
|
+ ngx_flag_t dyn_rec_enable;
|
||||||
|
+ ngx_msec_t dyn_rec_timeout;
|
||||||
|
+ size_t dyn_rec_size_lo;
|
||||||
|
+ size_t dyn_rec_size_hi;
|
||||||
|
+ ngx_uint_t dyn_rec_threshold;
|
||||||
|
} ngx_http_ssl_srv_conf_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue