Исправленный скрипт для сборки контейнера
build.sh
#!/bin/bash
DISTR_XRAY="https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-arm64-v8a.zip"
#DISTR_XRAY="https://github.com/XTLS/Xray-core/releases/download/v24.10.31/Xray-linux-arm64-v8a.zip"
DISTR_BDPI="https://github.com/hufrea/byedpi/releases/download/v0.17.3/byedpi-17.3-aarch64.tar.gz"
DISTR_WIREPROXY_AWG="https://github.com/artem-russkikh/wireproxy-awg/releases/latest/download/wireproxy_linux_arm64.tar.gz"
GEOSITE_RU_BLOCKED="https://github.com/runetfreedom/russia-blocked-geosite/releases/latest/download/geosite-ru-only.dat"
GEOIP_RU="https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/release/geoip.dat"
#-------------------------------------------------
download() {
if [ $download_enabled -eq 1 ]; then
rm -rf temp/*
wget ${1} -O temp/${2}
case `echo ${2} | awk -F. '{print $NF}'` in
"zip")
unzip temp/${2} -d temp/ ;;
*)
tar -xf temp/${2} -C temp/ ;;
esac
fi
}
precheck() {
echo "1. Checking installation..."
if [ ! `which docker` ]; then
echo "Install docker first"
exit 0;
fi
if [ ! `which wget` ]; then
echo "Install wget first"
exit 0;
fi
if [ ! `which unzip` ]; then
echo "Install unzip first"
exit 0;
fi
rm -rf temp prepare
mkdir -p temp
mkdir -p prepare/opt/xray-core/data
mkdir -p prepare/opt/config/
mkdir -p prepare/usr/share
echo "Installation OK"
download_enabled=1
}
#--------------------
xray_baseconf_gen() {
cat > prepare/opt/xray-core/00_base.json << EOF
{
"log":
{
"access": "none",
"dnsLog": false,
"loglevel": "warning"
},
"routing":
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private",
"192.168.88.0/24"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": "geosite:ru-available-only-inside",
"outboundTag": "direct"
},
{
"type": "field",
"protocol": "bittorrent",
"outboundTag": "direct"
},
{
"type": "field",
"ip": "geoip:ru",
"outboundTag": "bdpi"
},
{
"type": "field",
"inboundTag": "inbound-wg-bdpi:3124",
"outboundTag": "bdpi"
},
{
"type": "field",
"inboundTag": "inbound-wg-awg:3125",
"outboundTag": "awg"
}
]
},
"inbounds":
[
{
"listen": "\$MYIP",
"port": 3124,
"protocol": "wireguard",
"settings": {
"mtu": 1420,
"secretKey": "\$WG_BDPIIN_PRIVKEY",
"peers": [
{
"publicKey": "\$WG_BDPIIN_PUBKEY",
"allowedIPs": [
"0.0.0.0/0",
"::/0"
],
"keepAlive": 0
}
],
"noKernelTun": true
},
"streamSettings": null,
"tag": "inbound-wg-bdpi:3124",
"sniffing": {
"enabled": true,
"destOverride": "fakedns+others",
"metadataOnly": false
}
},
{
"listen": "\$MYIP",
"port": 3125,
"protocol": "wireguard",
"settings": {
"mtu": 1420,
"secretKey": "\$WG_WPIN_PRIVKEY",
"peers": [
{
"publicKey": "\$WG_WPIN_PUBKEY",
"allowedIPs": [
"0.0.0.0/0",
"::/0"
],
"keepAlive": 0
}
],
"noKernelTun": true
},
"streamSettings": null,
"tag": "inbound-wg-awg:3125",
"sniffing": {
"enabled": true,
"destOverride": "fakedns+others",
"metadataOnly": false
}
}
],
"outbounds":
[
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "AsIs"
}
},
{
"tag": "blocked",
"protocol": "blackhole",
"settings": {}
},
{
"tag": "awg",
"protocol": "socks",
"settings": {
"servers": [
{
"address": "\$MYIP",
"port": \$WP_PORT
}
]
}
},
{
"tag": "bdpi",
"protocol": "socks",
"settings": {
"servers": [
{
"address": "\$MYIP",
"port": \$BDPI_PORT
}
]
}
}
]
}
EOF
}
xray_prepare() {
echo "2. Preparing xray-core"
download $DISTR_XRAY xray.zip
mv temp/xray prepare/opt/xray-core/
chmod +x prepare/opt/xray-core/xray
cp geoip-ru.dat prepare/opt/xray-core/data/geoip.dat
wget $GEOSITE_RU_BLOCKED -O prepare/opt/xray-core/data/geosite.dat
# wget $GEOIP_RU -O prepare/opt/xray-core/data/geoip.dat
wget
ln -s /opt/xray-core/data prepare/usr/share/xray
if [ -e prepare/opt/xray-core/xray ]; then
echo "xray-core OK"
else
echo "Unable to prepare xray-core. Exiting"
exit 0
fi
}
#--------------------
bdpi_prepare(){
echo "3. Preparing byedpi"
download $DISTR_BDPI bdpi.tar.gz
tar -xf temp/bdpi.tar.gz -C temp/
mv temp/ciadpi-aarch64 prepare/opt/ciadpi
chmod +x prepare/opt/ciadpi
if [ -e prepare/opt/ciadpi ]; then
echo "byedpi OK"
else
echo "Unable to prepare byedpi. Exiting"
exit 0
fi
}
#--------------------
awg_prepare(){
echo "4. Preparing AWG"
download $DISTR_WIREPROXY_AWG awg.tar.gz
mv temp/wireproxy prepare/opt/
chmod +x prepare/opt/wireproxy
if [ -e prepare/opt/wireproxy ]; then
echo "AWG OK"
else
echo "Unable to prepare AWG. Exiting"
exit 0
fi
}
#--------------------
entrypoint_gen() {
cat > prepare/opt/entrypoint.sh << EOF2
#!/bin/busybox sh
#setting envs
export MYIP=\$(ip -4 addr show scope global | grep inet | awk -F' ' '{split(\$2, a, "/");print a[1]}') #because busybox needs some hacks
if hostname | grep -iq mikrotik; then MYHOST=\$MYIP; else MYHOST=\$(hostname); fi #if container hostname is not set, it will be router name
if [ ! "\$WP_PORT" ]; then export WP_PORT=9998; fi #setting wireproxy port
if [ ! "\$BDPI_PORT" ]; then export BDPI_PORT=9999; fi #setting byedpi port
if [ ! "\$WG_WPIN_PRIVKEY" ]; then echo "\$MYHOST: WG_WPIN_PRIVKEY is not set. Exiting"; exit 0 ; fi
if [ ! "\$WG_WPIN_PUBKEY" ]; then echo "\$MYHOST: WG_WPIN_PUBKEY is not set. Exiting"; exit 0 ; fi
if [ ! "\$WG_BDPIIN_PRIVKEY" ]; then echo "\$MYHOST: WG_BDPIIN_PRIVKEY is not set. Exiting"; exit 0 ; fi
if [ ! "\$WG_BDPIIN_PUBKEY" ]; then echo "\$MYHOST: WG_BDPIIN_PUBKEY is not set. Exiting"; exit 0 ; fi
#making container stop smoothly
trap 'echo wireproxy ciadpi xray | xargs killall; exit 0' SIGINT
trap 'echo wireproxy ciadpi xray | xargs killall; exit 0' SIGTERM
trap 'echo wireproxy ciadpi xray | xargs killall; exi t0' SIGHUP
#generating xray base conf from template
xray_conf_gen() {
mkfifo /opt/config/00_base_dyn.json
eval "cat <<EOF
\$(cat /opt/xray-core/00_base.json)
EOF
" > /opt/config/00_base_dyn.json &
}
xray_conf_gen
#generating config for wireproxy with socks block
wireproxy_conf_gen() {
mkfifo /opt/awg.conf
eval "cat <<EOF
\$(find /opt/config/ -maxdepth 1 -type f -name "*.conf" -exec cat {} \; -quit)
[Socks5]
BindAddress = \$MYIP:\$WP_PORT
EOF
" > /opt/awg.conf &
}
wireproxy_conf_gen
#starting all processes
log() { while read line; do echo "\$MYHOST: \${1}: \${line}"; done; }
run_wireproxy() {
if [ ! "\$LOGFILTER" ]; then #wireproxy produce too much logs. We can filter them
echo "Filеring logs for wireproxy disabled"
/opt/wireproxy -c /opt/awg.conf 2>&1 | log "WireproxyAWG" &
else
/opt/wireproxy -c /opt/awg.conf 2>&1 | grep -Eiv "\$LOGFILTER" | log "WireproxyAWG" &
fi
}
run_wireproxy
/opt/ciadpi --ip \$MYIP --port \$BDPI_PORT \$BDPI_ARGS 2>&1 | log "ByeDpi" &
/opt/xray-core/xray run -confdir /opt/config 2>&1 | log "Xray-core" &
while true; do
sleep 5
if [ \$(ps aux | grep wireproxy | grep -v grep | wc -l) -ne 1 ]; then
pkill -f wireproxy
wireproxy_conf_gen
echo "FATAL! Restarted on crash" | log "WireproxyAWG"
run_wireproxy
fi
if [ \$(ps aux | grep ciadpi | grep -v grep | wc -l) -ne 1 ]; then
pkill -f ciadpi
echo "FATAL! Restarted on crash" | log "ByeDpi"
/opt/ciadpi --ip \$MYIP --port \$BDPI_PORT \$BDPI_ARGS 2>&1 | log "ByeDpi" &
fi
if [ \$(ps aux | grep xray-core | grep -v grep | wc -l) -ne 1 ]; then
pkill -f xray-core
xray_conf_gen
echo "FATAL! Restarted on crash" | log "Xray-core"
/opt/xray-core/xray run -confdir /opt/config 2>&1 | log "Xray-core" &
fi
done
EOF2
}
dockerbuild () {
echo "5. Building docker image"
#cp -R /usr/share/ca-certificates prepare/usr/share
#cp -R /usr/share/zoneinfo prepare/usr/share
#echo 'FROM --platform=linux/arm64 alpine:3
echo 'FROM --platform=linux/arm64 busybox:stable
WORKDIR /opt/xray-core/data
COPY ./prepare/ /
ENTRYPOINT ["/opt/entrypoint.sh"]
' > Dockerfile
chmod +x prepare/opt/entrypoint.sh
docker build --rm -t xray_full_mikro .
docker save xray_full_mikro:latest -o xray_full_mikro.tar
docker image rm xray_full_mikro:latest
}
precheck
xray_prepare
xray_baseconf_gen
bdpi_prepare
awg_prepare
entrypoint_gen
dockerbuild
И обновлённый предсобранный образ
UPD. Маленькое обновление. Добален мониторинг и авторестарт дочерних процессов, сделана нормальная остановка по SIGHUP, SIGINT, SIGTERM