added initial commit

This commit is contained in:
Sangbum Kim 2024-03-17 00:30:57 +09:00
commit 0e5948b0dd
12 changed files with 1113 additions and 0 deletions

133
.gitignore vendored Normal file
View File

@ -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

202
Dockerfile Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

47
docker-entrypoint.sh Executable file
View File

@ -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 "$@"

114
nginx.conf Normal file
View File

@ -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;
}

20
nginx.vh.no-default.conf Normal file
View File

@ -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;
}

View File

@ -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;

1
patch_src Normal file
View File

@ -0,0 +1 @@
https://github.com/kn007/patch/blob/master/