Stream proxy-protocol support

This commit is contained in:
Samuel Huang
2024-09-16 14:45:57 +10:00
parent 8b8e03ea0c
commit e9ffe7016f
8 changed files with 135 additions and 55 deletions

View File

@@ -32,6 +32,8 @@ COPY nginx-proxy.tpl /etc/nginx/conf.d/
COPY nginx-grpc.tpl /etc/nginx/conf.d/
COPY nginx-ws.tpl /etc/nginx/conf.d/
COPY proxy-log-fmt.tpl /etc/nginx/conf.d/001-proxy-log-fmt.conf
ADD server-lgp.sh /server-lgp.sh
ADD server-lgr.sh /server-lgr.sh
ADD server-lgt.sh /server-lgt.sh

View File

@@ -1,15 +1,15 @@
#STSTUB
#STREAM_TAG
stream {
map $ssl_preread_server_name $stream_map {
#XMAP-TAG
#XMAP_TAG
}
#XUPSTREAM-TAG
#XUPSTREAM_TAG
server {
listen STPORT reuseport;
proxy_pass $stream_map;
# proxy_bind $remote_addr transparent;
#STPROXY_PASS_TAG
ssl_preread on;
}
}

3
proxy-log-fmt.tpl Normal file
View File

@@ -0,0 +1,3 @@
log_format proxy '$proxy_protocol_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

22
run.sh
View File

@@ -12,10 +12,10 @@ usage() {
echo " --lgt <VLESS-GRPC-TLS option> p=13443,u=id1,u=id2...,s=svcname,d=domain.com"
echo " --lsp <VLESS-SPLT-PLN option> p=14443,u=id1,u=id2...,w=/webpath"
echo " --lst <VLESS-SPLT-TLS option> p=16443,u=id1,u=id2...,w=/webpath,d=domain.com"
echo " --ltr <VLESS-TCP-RLTY option> p=17443,u=id1,u=id2...,d=dest.com,pub=xx,prv=yy[,shortId=ab],[xtls]"
echo " --ltrx <VLESS-TCP-RLTY-XTLS option> p=17443,u=id1,u=id2...,d=dest.com,pub=xx,prv=yy[,shortId=ab]"
echo " --ltt <VLESS-TCP-TLS option> p=18443,u=id1,u=id2...,d=domain.com,[xtls]"
echo " --lttx <VLESS-TCP-TLS-XTLS option> p=18443,u=id1,u=id2...,d=domain.com"
echo " --ltr <VLESS-TCP-RLTY option> p=17443,u=id1,u=id2...,d=dest.com,pub=xx,prv=yy[,shortId=ab],[proxy_acpt],[xtls]"
echo " --ltrx <VLESS-TCP-RLTY-XTLS option> p=17443,u=id1,u=id2...,d=dest.com,pub=xx,prv=yy[,shortId=ab],[proxy_acpt]"
echo " --ltt <VLESS-TCP-TLS option> p=18443,u=id1,u=id2...,d=domain.com,[proxy_acpt],[xtls]"
echo " --lttx <VLESS-TCP-TLS-XTLS option> p=18443,u=id1,u=id2...,d=domain.com,[proxy_acpt]"
echo " --lwp <VLESS-WS-PLN option> p=19443,u=id1,u=id2...,w=/wskpath"
echo " --lwt <VLESS-WS-TLS option> p=22443,u=id1,u=id2...,w=/wskpath,d=domain.com"
echo " --mtt <VMESS-TCP-TLS option> p=23443,u=id1,u=id2...,d=domain.com"
@@ -24,9 +24,9 @@ usage() {
echo " --ttt <TROJAN-TCP-TLS option> p=26443,u=pw1,u=pw2...,d=domain.com"
echo " --twp <TROJAN-WS-PLN option> p=27443,u=pw1,u=pw2...,w=/wskpath"
echo " --twt <TROJAN-WS-TLS option> p=28443,u=pw1,u=pw2...,w=/wskpath,d=domain.com"
echo " --ng-server <nginx-server-options> p=8443,d=domain0.com,d=domain1.com..."
echo " --ng-server <nginx-server-options> p=8443,d=domain0.com,d=domain1.com...,[proxy_acpt]"
echo " --ng-proxy <nginx-proxy-options> d=domain0.com,d=domain1.com,p=port-backend,l=location,n=ws|grpc|splt"
echo " --st-port <stream-port-number> 443"
echo " --st-server <stream-port-number> [p=443],[proxy_pass]"
echo " --st-map <stream-map-options> sni=domain.com,ups=127.0.0.1:8443"
echo " --domain-block <domain-rule> Add a domain rule for routing-server block, like geosite:category-ads-all"
echo " --ip-block <ip-rule> Add a ip-addr rule for routing block, like geoip:private"
@@ -42,7 +42,7 @@ usage() {
Jrules='{"rules":[]}'
TEMP=`getopt -o u:k:r:c:j:di --long lgp:,lgr:,lgt:,lsp:,lst:,ltr:,ltrx:,ltt:,lttx:,lwp:,lwt:,mtt:,mwp:,mwt:,ttt:,twp:,twt:,user:,hook:,request-domain:,cert-home:,ip-block:,domain-block:,cn-block,ng-server:,ng-proxy:,st-port:,st-map:,json:,stdin,debug -n "$0" -- $@`
TEMP=`getopt -o u:k:r:c:j:di --long lgp:,lgr:,lgt:,lsp:,lst:,ltr:,ltrx:,ltt:,lttx:,lwp:,lwt:,mtt:,mwp:,mwt:,ttt:,twp:,twt:,user:,hook:,request-domain:,cert-home:,ip-block:,domain-block:,cn-block,ng-server:,ng-proxy:,st-server:,st-map:,json:,stdin,debug -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
@@ -114,8 +114,8 @@ while true ; do
NGPROXY+=("$2")
shift 2
;;
--st-port)
STPORT="$2"
--st-server)
STSVR="$2"
shift 2
;;
--st-map)
@@ -191,8 +191,8 @@ if [ -z "${SVCMD}" ]; then
fi
# Start Nginx if necessary
if [ -n "${STPORT}" ]; then
NGOPT="--st-port ${STPORT}"
if [ -n "${STSVR}" ]; then
NGOPT="--st-server ${STSVR}"
for mapopt in "${STMAP[@]}"
do
NGOPT="${NGOPT} --st-map $mapopt"

View File

@@ -4,7 +4,7 @@ DIR=`dirname $0`
usage() {
echo "VLESS-TCP-REALITY server builder"
echo "Usage: server-ltr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],<d=dest.com>,[pub=xx,prv=yy,shortId=zz],<u=id0>,<u=id1>..."
echo "Usage: server-ltr <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],[proxy_acpt],<d=dest.com>,[pub=xx,prv=yy,shortId=zz],<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -27,6 +27,9 @@ do
p|port)
port="${kv[1]}"
;;
proxy_acpt)
acceptProxyProtocol=true
;;
shortId)
shortIds+=("${kv[1]}")
;;
@@ -106,6 +109,13 @@ do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# StreamSettings
if [ -n "${acceptProxyProtocol}" ]; then
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"sockopt":{"acceptProxyProtocol":true}} ' \
|sponge $XCONF
fi
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \

View File

@@ -4,7 +4,7 @@ DIR=`dirname $0`
usage() {
echo "VLESS-TCP-TLS server builder"
echo "Usage: server-ltt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],<d=domain.com>,<u=id0>,<u=id1>..."
echo "Usage: server-ltt <x=xray-config-file>,<c=cert-home-dir>,<p=listen-port>,[xtls],[proxy_acpt],<d=domain.com>,<u=id0>,<u=id1>..."
}
options=(`echo $1 |tr ',' ' '`)
@@ -27,6 +27,9 @@ do
p|port)
port="${kv[1]}"
;;
proxy_acpt)
acceptProxyProtocol=true
;;
u|user)
xuser+=("${kv[1]}")
;;
@@ -106,6 +109,13 @@ do
cat $XCONF |${DIR}/fallback.sh -p $port -f ${fb} | sponge $XCONF
done
# StreamSettings
if [ -n "${acceptProxyProtocol}" ]; then
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"sockopt":{"acceptProxyProtocol":true}} ' \
|sponge $XCONF
fi
# Network settings
cat $XCONF |jq --arg port "${port}" \
'( .inbounds[] | select(.port == ($port|tonumber)) | .streamSettings ) += {"network":"tcp"} ' \

View File

@@ -2,40 +2,44 @@
DIR=`dirname $0`
DIR="$(cd $DIR; pwd)"
TPL="site-ssl.conf.tpl"
STPL="nginx-stream.tpl"
SITE_TPL="site-ssl.conf.tpl"
STREAM_TPL="nginx-stream.tpl"
NGCONF="/etc/nginx/nginx.conf"
usage() {
echo "server-nginx --ng-server <c=certhome,d=domain>[,p=443] --ng-proxy <p=xport,l=location,n=grpc|ws|splt>[,h=127.0.0.1]"
echo " --ng-proxy <p=port-backend,l=location-path,n=grpc|ws|splt>[,h=127.0.0.1][,d=host-domain]"
echo " --ng-server <c=cert-home-dir,d=host-domain>[,p=443]"
echo " --ng-server <c=cert-home-dir,d=host-domain>[,p=443],[proxy_acpt]"
echo " --st-map <sni=domain.com,ups=127.0.0.1:8443>"
echo " --st-port <port-num>"
echo " --st-server [p=443],[proxy_pass]"
}
TEMP=`getopt -o m:p:s:x: --long ng-server:,ng-proxy:,st-map:,st-port: -n "$0" -- $@`
TEMP=`getopt -o m:n:p:s:x: --long ng-server:,ng-proxy:,st-server:,st-map: -n "$0" -- $@`
if [ $? != 0 ] ; then usage; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
-m|--st-map)
STMAP+=("$2")
shift 2
;;
-p|--st-port)
STPORT="$2"
shift 2
;;
-s|--ng-server)
# Multiple Nginx domain servers Allowed
-n|--ng-server)
NGSVR+=("$2")
shift 2
;;
# Multiple Nginx proxy locations Allowed
-x|--ng-proxy)
NGPROXY+=("$2")
shift 2
;;
# Only SINGLE Stream server Allowed
-s|--st-server)
STSVR="$2"
shift 2
;;
# Multiple Nginx SNI map items Allowed
-m|--st-map)
STMAP+=("$2")
shift 2
;;
--)
shift
break
@@ -49,7 +53,7 @@ while true ; do
done
if [ -z "${NGSVR}" ] && [ -z "${STPORT}" ]; then
echo "No server/stream defined. Quit.";
echo "No Stream/Server defined. Quit.";
usage;
exit 1;
fi
@@ -63,16 +67,36 @@ if [ -f /etc/nginx/conf.d/default.conf ]; then
mv default.conf default.conf.disable
fi
# Remove all lines generated previously after #STSTUB tag.
sed -i '/\#STSTUB/q' /etc/nginx/nginx.conf
# Remove #STSTUB tag
sed -i '/\#STSTUB/d' /etc/nginx/nginx.conf
# Remove all lines generated previously after #STREAM_TAG tag.
sed -i '/\#STREAM_TAG/q' /etc/nginx/nginx.conf
# Remove #STREAM_TAG tag
sed -i '/\#STREAM_TAG/d' /etc/nginx/nginx.conf
# Remove temp files generated previously.
rm /tmp/stmap.conf; rm /tmp/stups.conf; rm /tmp/stproxy.conf
if [ -n "${STSVR}" ]; then
options=(`echo $STSVR |tr ',' ' '`)
for option in "${options[@]}"
do
kv=(`echo $option |tr '=' ' '`)
case "${kv[0]}" in
p|port)
STPORT="${kv[1]}"
;;
x|proxy_pass)
STPROXY_PASS=1
;;
esac
done
if [ -z "${STPORT}" ]; then STPORT=443; fi
if ! [ "${STPORT}" -eq "${STPORT}" ] 2>/dev/null; then
>&2 echo "Stream port number must be numeric";
exit 1;
fi
if [ -n "${STPORT}" ]; then
rm /tmp/map.conf
rm /tmp/ups.conf
# Attach the stream configuration to the tail of nginx.conf
cat ${STPL} >> /etc/nginx/nginx.conf
cat ${STREAM_TPL} >> /etc/nginx/nginx.conf
for stmap in "${STMAP[@]}"
do
options=(`echo $stmap |tr ',' ' '`)
@@ -88,17 +112,26 @@ if [ -n "${STPORT}" ]; then
;;
esac
done
# Named the upstream as yahoo_com for SNI yahoo.com
upsname=`echo $sni|sed 's/\./_/g'`
echo " $sni $upsname;" >>/tmp/map.conf
echo " upstream $upsname {" >>/tmp/ups.conf
echo " server $upstream;" >>/tmp/ups.conf
echo " }" >>/tmp/ups.conf
echo " $sni $upsname;" >>/tmp/stmap.conf
echo " upstream $upsname {" >>/tmp/stups.conf
echo " server $upstream;" >>/tmp/stups.conf
echo " }" >>/tmp/stups.conf
done
# Add map.conf down to #MAPSTUB tag
sed -i '/#XMAP-TAG/r /tmp/map.conf' /etc/nginx/nginx.conf
# Add ups.conf down to #UPSSTUB tag
sed -i '/#XUPSTREAM-TAG/r /tmp/ups.conf' /etc/nginx/nginx.conf
# Add map.conf down to #XMAP_TAG tag
sed -i '/#XMAP_TAG/r /tmp/stmap.conf' /etc/nginx/nginx.conf
# Add ups.conf down to #XUPSTREAM_TAG tag
sed -i '/#XUPSTREAM_TAG/r /tmp/stups.conf' /etc/nginx/nginx.conf
sed -i "s/STPORT/${STPORT}/g" /etc/nginx/nginx.conf
# Add "proxy_protocol=on" down to #STPROXY_PASS_TAG tag
if [ -n "${STPROXY_PASS}" ]; then
echo " proxy_protocol on;" >/tmp/stproxy.conf
sed -i '/#STPROXY_PASS_TAG/r /tmp/stproxy.conf' /etc/nginx/nginx.conf
fi
echo "Generated /etc/nginx/nginx.conf ====>"
cat /etc/nginx/nginx.conf
fi
for ngsvr in "${NGSVR[@]}"
@@ -119,6 +152,9 @@ do
domain="${kv[1]}"
DOMAIN+=("${kv[1]}")
;;
proxy_acpt)
NGPROTOCOL="proxy_protocol"
;;
esac
done
@@ -137,12 +173,21 @@ do
ESC_CERTFILE=$(printf '%s\n' "${fullchain}" | sed -e 's/[]\/$*.^[]/\\&/g')
ESC_PRVKEYFILE=$(printf '%s\n' "${prvkey}" | sed -e 's/[]\/$*.^[]/\\&/g')
cat ${TPL} \
cat "${SITE_TPL}" \
| sed "s/CERTFILE/${ESC_CERTFILE}/g" \
| sed "s/PRVKEYFILE/${ESC_PRVKEYFILE}/g" \
| sed "s/NGDOMAIN/${domain}/g" \
| sed "s/NGPORT/${port}/g" \
| sed "s/NGPROTOCOL/${NGPROTOCOL}/g" \
>"${domain}.conf"
# Applying proxy log format instead of main format when --ng-server proxy_pass was set
if [ -n "${NGPROTOCOL}" ]; then
sed -i '/access_log/s/main/proxy/' "${domain}.conf"
sed -i 's/remote_addr/proxy_protocol_addr/g' "${domain}.conf"
sed -i 's/proxy_add_x_forwarded_for/proxy_protocol_addr/g' "${domain}.conf"
fi
echo "Generated /etc/nginx/conf.d/${domain}.conf ====>"
cat /etc/nginx/conf.d/${domain}.conf
done
for ngproxy in "${NGPROXY[@]}"
@@ -184,19 +229,27 @@ do
# Add tpl file content down to #LOCATION tag
case "${xnetwork}" in
ws|websocket)
sed -i '/#XLOCATION-TAG/r nginx-ws.tpl' ${domain}.conf
sed -i '/#XLOCATION_TAG/r nginx-ws.tpl' ${domain}.conf
;;
grpc)
sed -i '/#XLOCATION-TAG/r nginx-grpc.tpl' ${domain}.conf
sed -i '/#XLOCATION_TAG/r nginx-grpc.tpl' ${domain}.conf
;;
splt|proxy)
sed -i '/#XLOCATION-TAG/r nginx-proxy.tpl' ${domain}.conf
sed -i '/#XLOCATION_TAG/r nginx-proxy.tpl' ${domain}.conf
;;
esac
ESC_LOCATION=$(printf '%s\n' "${xlocation}" | sed -e 's/[]\/$*.^[]/\\&/g')
sed -i "s/HOST/${xhost}/g" ${domain}.conf
sed -i "s/PORT/${xport}/g" ${domain}.conf
sed -i "s/WEBPATH/${ESC_LOCATION}/g" ${domain}.conf
# Applying proxy log format instead of main format when --ng-server proxy_pass was set
if [ -n "${NGPROTOCOL}" ]; then
sed -i '/access_log/s/main/proxy/' "${domain}.conf"
sed -i 's/remote_addr/proxy_protocol_addr/g' "${domain}.conf"
sed -i 's/proxy_add_x_forwarded_for/proxy_protocol_addr/g' "${domain}.conf"
fi
echo "Generated /etc/nginx/conf.d/${domain}.conf ====>"
cat /etc/nginx/conf.d/${domain}.conf
done
done
exit 0

View File

@@ -1,7 +1,7 @@
server {
listen NGPORT quic;
listen NGPORT ssl;
listen [::]:NGPORT ssl;
listen NGPORT ssl NGPROTOCOL;
listen [::]:NGPORT ssl NGPROTOCOL;
http2 on;
server_name NGDOMAIN;
ssl_certificate CERTFILE;
@@ -15,9 +15,11 @@ server {
client_header_timeout 1071906480m;
keepalive_timeout 1071906480m;
access_log /var/log/nginx/access.log main;
location / {
return 404;
}
#XLOCATION-TAG
#XLOCATION_TAG
}