This commit is contained in:
parent
c2148456ac
commit
206a920bf8
12
.drone.yml
12
.drone.yml
@ -7,11 +7,6 @@ trigger:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: prep
|
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- sh ./ci_prep.sh
|
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
settings:
|
settings:
|
||||||
@ -19,9 +14,4 @@ steps:
|
|||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
repo: quackerd/d2ray
|
repo: quackerd/d2ray
|
||||||
|
|
||||||
- name: reload
|
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- sh ./ci_reload.sh
|
|
42
Dockerfile
42
Dockerfile
@ -1,18 +1,33 @@
|
|||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
COPY image/ /opt/
|
ENV VER_XRAY 1.6.1
|
||||||
|
ENV VER_SO 2.5.20
|
||||||
|
ENV VER_NG 1.7.20
|
||||||
|
|
||||||
# install packages
|
# install packages
|
||||||
RUN set -xe && apk add --no-cache unzip wget nginx certbot openssl
|
RUN set -xe && apk add --no-cache zip unzip wget nginx certbot openssl python3 py3-jinja2 supervisor apache2-utils bash
|
||||||
|
|
||||||
# setup core files
|
COPY ./opt /opt/
|
||||||
RUN set -xe && mkdir -p /opt/xray && \
|
|
||||||
unzip /opt/Xray-linux-64.zip -d /opt/xray && \
|
|
||||||
rm /opt/Xray-linux-64.zip && \
|
|
||||||
chmod +x /opt/run.sh /opt/crypt.sh
|
|
||||||
|
|
||||||
# crond
|
# download packages
|
||||||
# RUN set -xe && mv /opt/crontab /var/spool/cron/crontabs/root
|
RUN set -xe && \
|
||||||
|
wget -P /opt/zip/windows/ https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-windows-64.zip && \
|
||||||
|
mkdir -p /opt/zip/linux && \
|
||||||
|
wget -P /opt/zip/linux/ https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-linux-64.zip && \
|
||||||
|
mkdir -p /opt/zip/chrome && \
|
||||||
|
wget -P /opt/zip/chrome/ https://github.com/FelisCatus/SwitchyOmega/releases/download/v$VER_SO/SwitchyOmega_Chromium.crx && \
|
||||||
|
wget -P /opt/zip/android/ https://github.com/2dust/v2rayNG/releases/download/$VER_NG/v2rayNG_"$VER_NG"_arm64-v8a.apk && \
|
||||||
|
wget -P /opt/zip/macos/ https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-macos-64.zip && \
|
||||||
|
wget -P /opt/zip/macos/ https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-macos-arm64-v8a.zip
|
||||||
|
|
||||||
|
# xray
|
||||||
|
RUN set -xe && unzip /opt/zip/linux/Xray-linux-64.zip -d /opt/xray
|
||||||
|
|
||||||
|
# create zip
|
||||||
|
RUN set -xe && \
|
||||||
|
zip -r /opt/d2ray.zip /opt/zip && \
|
||||||
|
mv /opt/d2ray.zip /opt/nginx/download/ && \
|
||||||
|
rm -r /opt/zip
|
||||||
|
|
||||||
# nginx
|
# nginx
|
||||||
RUN set -xe && addgroup www && \
|
RUN set -xe && addgroup www && \
|
||||||
@ -20,8 +35,7 @@ RUN set -xe && addgroup www && \
|
|||||||
chown -R www:www /opt/nginx
|
chown -R www:www /opt/nginx
|
||||||
|
|
||||||
# remove packages
|
# remove packages
|
||||||
RUN set -xe && apk del unzip wget
|
RUN set -xe && apk del zip unzip wget
|
||||||
|
EXPOSE 80
|
||||||
EXPOSE 80 443
|
VOLUME /etc/letsencrypt
|
||||||
|
CMD ["sh", "/opt/init.sh"]
|
||||||
CMD ["/opt/run.sh"]
|
|
62
ci_prep.sh
62
ci_prep.sh
@ -1,62 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
|
|
||||||
apk add openssh openssl wget unzip zip apache2-utils
|
|
||||||
|
|
||||||
source image/crypt.sh
|
|
||||||
|
|
||||||
chmod 600 ./id_root
|
|
||||||
|
|
||||||
# versions
|
|
||||||
VER_XRAY=1.6.1
|
|
||||||
VER_SO=2.5.20
|
|
||||||
VER_NG=1.7.20
|
|
||||||
|
|
||||||
# upload files
|
|
||||||
for filename in confs/*; do
|
|
||||||
basename=$(basename $filename)
|
|
||||||
hash_sha256 $basename $(cat ./key)
|
|
||||||
output=$crypt_ret
|
|
||||||
encrypt_file $filename $(cat ./key) $output
|
|
||||||
scp -P77 -o StrictHostKeychecking=no -i ./id_root $output root@parrot.quacker.org:/dat/apps/nginx/http_dl/root/pub
|
|
||||||
rm $output
|
|
||||||
done
|
|
||||||
|
|
||||||
# build zip
|
|
||||||
URL_SO=https://github.com/FelisCatus/SwitchyOmega/releases/download/v$VER_SO/SwitchyOmega_Chromium.crx
|
|
||||||
wget $URL_SO -O SwitchyOmega_Chromium.zip
|
|
||||||
mkdir zip/chrome
|
|
||||||
unzip ./SwitchyOmega_Chromium.zip -d zip/chrome || true
|
|
||||||
|
|
||||||
URL_NG=https://github.com/2dust/v2rayNG/releases/download/$VER_NG/v2rayNG_"$VER_NG"_arm64-v8a.apk
|
|
||||||
wget $URL_NG -P image/nginx/download/android/
|
|
||||||
|
|
||||||
URL_XRAY_WIN=https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-windows-64.zip
|
|
||||||
wget $URL_XRAY_WIN
|
|
||||||
unzip Xray-windows-64.zip -d zip/windows
|
|
||||||
|
|
||||||
URL_XRAY_MAC=https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-macos-64.zip
|
|
||||||
wget $URL_XRAY_MAC
|
|
||||||
unzip Xray-macos-64.zip -d zip/macos
|
|
||||||
|
|
||||||
URL_XRAY_LINUX=https://github.com/XTLS/Xray-core/releases/download/v$VER_XRAY/Xray-linux-64.zip
|
|
||||||
wget $URL_XRAY_LINUX -P image/
|
|
||||||
|
|
||||||
cd zip
|
|
||||||
zip -r -D ../windows_macos.zip .
|
|
||||||
cd ..
|
|
||||||
mv windows_macos.zip image/nginx/download/
|
|
||||||
|
|
||||||
# build htpassword
|
|
||||||
touch .htpasswd
|
|
||||||
htpasswd -b ./.htpasswd liangyifang liangyifang
|
|
||||||
htpasswd -b ./.htpasswd ruyuechun ruyuechun
|
|
||||||
htpasswd -b ./.htpasswd liuxiangdong liuxiangdong
|
|
||||||
htpasswd -b ./.htpasswd zhoubowen zhoubowen
|
|
||||||
htpasswd -b ./.htpasswd gaoyuchen gaoyuchen
|
|
||||||
htpasswd -b ./.htpasswd quackerd quackerd
|
|
||||||
htpasswd -b ./.htpasswd yushengde yushengde
|
|
||||||
htpasswd -b ./.htpasswd ivansun ivansun
|
|
||||||
encrypt_file ./.htpasswd "$(cat ./key)" image/htpasswd
|
|
32
ci_reload.sh
32
ci_reload.sh
@ -1,32 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
apk add openssh
|
|
||||||
|
|
||||||
key=$(cat ./key)
|
|
||||||
|
|
||||||
chmod 600 ./id_root
|
|
||||||
|
|
||||||
while read -r line
|
|
||||||
do
|
|
||||||
filename="confs/$line"
|
|
||||||
echo "Conf name: $filename"
|
|
||||||
addr=$(basename $filename)
|
|
||||||
echo "Refreshing $addr..."
|
|
||||||
ssh -p 77 -o StrictHostKeychecking=no -i ./id_root root@$addr -t "docker pull quackerd/d2ray:latest"
|
|
||||||
set +e
|
|
||||||
ssh -p 77 -o StrictHostKeychecking=no -i ./id_root root@$addr -t "docker stop d2ray && docker rm d2ray"
|
|
||||||
set -e
|
|
||||||
ssh -p 77 -o StrictHostKeychecking=no -i ./id_root root@$addr -t "docker run -d \
|
|
||||||
--restart unless-stopped \
|
|
||||||
-e KEY=$key \
|
|
||||||
-e FQDN=$addr \
|
|
||||||
-p 80:80 \
|
|
||||||
-p 8443:443 \
|
|
||||||
-v d2ray_volume:/opt/config \
|
|
||||||
--name d2ray \
|
|
||||||
quackerd/d2ray:latest"
|
|
||||||
ssh -p 77 -o StrictHostKeychecking=no -i ./id_root root@$addr -t "docker system prune -af"
|
|
||||||
done < ./reload_list
|
|
||||||
|
|
||||||
wait
|
|
@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
"log": {
|
|
||||||
"loglevel": "debug",
|
|
||||||
"access": "/opt/config/logs/xray/access.log",
|
|
||||||
"error": "/opt/config/logs/xray/error.log"
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"port": 443,
|
|
||||||
"protocol": "vless",
|
|
||||||
"settings": {
|
|
||||||
"clients": [
|
|
||||||
{
|
|
||||||
"id": "quackerd",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "7-1803",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"decryption": "none",
|
|
||||||
"fallbacks": [
|
|
||||||
{
|
|
||||||
"dest": "localhost:80"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"network": "tcp",
|
|
||||||
"security": "xtls",
|
|
||||||
"xtlsSettings": {
|
|
||||||
"alpn": ["http/1.1", "h2"],
|
|
||||||
"certificates": [
|
|
||||||
{
|
|
||||||
"certificateFile": "/etc/letsencrypt/live/concerto.quacker.net/fullchain.pem",
|
|
||||||
"keyFile": "/etc/letsencrypt/live/concerto.quacker.net/privkey.pem"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"protocol": "freedom",
|
|
||||||
"settings": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"log": {
|
|
||||||
"loglevel": "warn",
|
|
||||||
"access": "/opt/config/logs/xray/access.log",
|
|
||||||
"error": "/opt/config/logs/xray/error.log"
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"port": 443,
|
|
||||||
"protocol": "vless",
|
|
||||||
"settings": {
|
|
||||||
"clients": [
|
|
||||||
{
|
|
||||||
"id": "ivansun",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"decryption": "none",
|
|
||||||
"fallbacks": [
|
|
||||||
{
|
|
||||||
"dest": "localhost:80"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"network": "tcp",
|
|
||||||
"security": "xtls",
|
|
||||||
"xtlsSettings": {
|
|
||||||
"alpn": ["http/1.1", "h2"],
|
|
||||||
"certificates": [
|
|
||||||
{
|
|
||||||
"certificateFile": "/etc/letsencrypt/live/ivans.quacker.net/fullchain.pem",
|
|
||||||
"keyFile": "/etc/letsencrypt/live/ivans.quacker.net/privkey.pem"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"protocol": "freedom",
|
|
||||||
"settings": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
"log": {
|
|
||||||
"loglevel": "warn",
|
|
||||||
"access": "/opt/config/logs/xray/access.log",
|
|
||||||
"error": "/opt/config/logs/xray/error.log"
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"port": 443,
|
|
||||||
"protocol": "vless",
|
|
||||||
"settings": {
|
|
||||||
"clients": [
|
|
||||||
{
|
|
||||||
"id": "quackerd",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "e6569ab4-c0dd-4c29-9b29-5afef6a39a92",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "ruyuechun",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "liangyifang",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bowen",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "gaoyuchen",
|
|
||||||
"flow": "xtls-rprx-direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"decryption": "none",
|
|
||||||
"fallbacks": [
|
|
||||||
{
|
|
||||||
"dest": "localhost:80"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"streamSettings": {
|
|
||||||
"network": "tcp",
|
|
||||||
"security": "xtls",
|
|
||||||
"xtlsSettings": {
|
|
||||||
"alpn": ["http/1.1", "h2"],
|
|
||||||
"certificates": [
|
|
||||||
{
|
|
||||||
"certificateFile": "/etc/letsencrypt/live/nocturne.quacker.net/fullchain.pem",
|
|
||||||
"keyFile": "/etc/letsencrypt/live/nocturne.quacker.net/privkey.pem"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"protocol": "freedom",
|
|
||||||
"settings": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
24
docker-compose.yml
Normal file
24
docker-compose.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
networks:
|
||||||
|
d2ray_br:
|
||||||
|
external: false
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
d2ray_certs:
|
||||||
|
|
||||||
|
services:
|
||||||
|
d2ray:
|
||||||
|
image: quackerd/d2ray
|
||||||
|
container_name: d2ray
|
||||||
|
ports:
|
||||||
|
- ${PORT}:${PORT}
|
||||||
|
- 80:80
|
||||||
|
environment:
|
||||||
|
- PORT=${PORT}
|
||||||
|
- FQDN=${FQDN}
|
||||||
|
- USERS=${USERS}
|
||||||
|
restart: "no"
|
||||||
|
networks:
|
||||||
|
- d2ray_br
|
||||||
|
volumes:
|
||||||
|
- d2ray_certs:/etc/letsencrypt
|
||||||
|
- ${LOGDIR}:/etc/d2ray
|
7
id_root
7
id_root
@ -1,7 +0,0 @@
|
|||||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
|
||||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
|
||||||
QyNTUxOQAAACCZkiqqwNqxkOBmoaSiTqKfz6Vt8doQyFt8KhHRFAmXGAAAAKB/tAMff7QD
|
|
||||||
HwAAAAtzc2gtZWQyNTUxOQAAACCZkiqqwNqxkOBmoaSiTqKfz6Vt8doQyFt8KhHRFAmXGA
|
|
||||||
AAAECpU6mEunFZV2qLmgJHRlpj08fIR6b5Ndz23fde0Q9UN5mSKqrA2rGQ4GahpKJOop/P
|
|
||||||
pW3x2hDIW3wqEdEUCZcYAAAAHHF1YWNrZXJkQGJhbGxhZGUucXVhY2tlci5vcmcB
|
|
||||||
-----END OPENSSH PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmSKqrA2rGQ4GahpKJOop/PpW3x2hDIW3wqEdEUCZcY quackerd@ballade.quacker.org
|
|
@ -1 +0,0 @@
|
|||||||
# 0 */24 * * * certbot renew
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
decrypt()
|
|
||||||
{
|
|
||||||
input=$1
|
|
||||||
key=$2
|
|
||||||
crypt_ret=$(echo $input | openssl enc -d -salt -aes-256-cbc -a -A -md sha512 -pbkdf2 -pass pass:$key)
|
|
||||||
}
|
|
||||||
|
|
||||||
decrypt_file()
|
|
||||||
{
|
|
||||||
input=$1
|
|
||||||
key=$2
|
|
||||||
output=$3
|
|
||||||
openssl enc -d -salt -aes-256-cbc -a -md sha512 -pbkdf2 -pass pass:$key -in $input -out $output
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypt_file()
|
|
||||||
{
|
|
||||||
input=$1
|
|
||||||
key=$2
|
|
||||||
output=$3
|
|
||||||
openssl enc -e -salt -aes-256-cbc -a -md sha512 -pbkdf2 -pass pass:$key -in $input -out $output
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypt()
|
|
||||||
{
|
|
||||||
input=$1
|
|
||||||
key=$2
|
|
||||||
crypt_ret=$(echo $input | openssl enc -e -salt -aes-256-cbc -a -A -md sha512 -pbkdf2 -pass pass:$key)
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_sha256()
|
|
||||||
{
|
|
||||||
input=$1$2
|
|
||||||
crypt_ret=$(echo $input | openssl dgst -sha256 | sed -E "s/\(stdin\)= (.*)/\1/g")
|
|
||||||
}
|
|
59
image/run.sh
59
image/run.sh
@ -1,59 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
source /opt/crypt.sh
|
|
||||||
|
|
||||||
mkdir -p /opt/config
|
|
||||||
mkdir -p /opt/config/logs
|
|
||||||
mkdir -p /opt/config/logs/nginx
|
|
||||||
mkdir -p /opt/config/logs/xray
|
|
||||||
mkdir -p /opt/config/logs/crond
|
|
||||||
|
|
||||||
URL='U2FsdGVkX19/qz4kcbpQpJKz/iebXKih1BK3Cp1wGSoEyhLtoyAi0wewP5Tr++FbRLt/EG2f8zDF9cIEuoTLEA=='
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Checking Environment Variables ====="
|
|
||||||
if [ -z "$FQDN" ]; then
|
|
||||||
echo "FQDN must be set"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$KEY" ]; then
|
|
||||||
echo "KEY must be set"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Checking Certificates ===="
|
|
||||||
if [ ! -d "/etc/letsencrypt/live/$FQDN" ]; then
|
|
||||||
echo "Generating new certificates..."
|
|
||||||
certbot certonly -n --standalone -m dummy@dummy.com --agree-tos --no-eff-email -d $FQDN
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Fetching Configuration ====="
|
|
||||||
decrypt $URL $KEY
|
|
||||||
URL=$crypt_ret
|
|
||||||
|
|
||||||
echo "Fetching from $URL..."
|
|
||||||
hash_sha256 $FQDN $KEY
|
|
||||||
URL=$URL/$crypt_ret
|
|
||||||
wget $URL -O /opt/$FQDN
|
|
||||||
|
|
||||||
echo "Decrypting..."
|
|
||||||
decrypt_file /opt/$FQDN $KEY /opt/config.json
|
|
||||||
|
|
||||||
decrypt_file /opt/htpasswd $KEY /opt/nginx/.htpasswd
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Starting cron ====="
|
|
||||||
crond -L /opt/config/logs/crond/log.txt
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Starting Nginx ====="
|
|
||||||
nginx -c /opt/nginx/nginx.conf
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===== Starting xray ====="
|
|
||||||
exec /opt/xray/xray -c /opt/config.json
|
|
1
opt/crontabs/root
Normal file
1
opt/crontabs/root
Normal file
@ -0,0 +1 @@
|
|||||||
|
* * * * * certbot renew --post-hook "supervisorctl xray restart"
|
75
opt/init.py
Normal file
75
opt/init.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import os
|
||||||
|
import getopt
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import jinja2
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
def parse_comma_str(users : str) -> list[str]:
|
||||||
|
return users.split(",")
|
||||||
|
|
||||||
|
def build_users_json(users: list[str]) -> str:
|
||||||
|
ret : str= ""
|
||||||
|
for i in range(len(users)):
|
||||||
|
if (i > 0):
|
||||||
|
ret = ret + ","
|
||||||
|
u = users[i]
|
||||||
|
ret = ret + "{ \"id\": \"" + u + "\", \"flow\": \"xtls-rprx-direct\"}"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, _ = getopt.getopt(sys.argv[1:], "u:p:f:")
|
||||||
|
except getopt.GetoptError as err:
|
||||||
|
# print help information and exit:
|
||||||
|
print(err, flush=True) # will print something like "option -a not recognized"
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
port : int = 443
|
||||||
|
users : list[str] = [''.join(random.choices(string.ascii_uppercase + string.digits, k=24))]
|
||||||
|
fqdn : str = "example.com"
|
||||||
|
|
||||||
|
for o, a in opts:
|
||||||
|
if o == "-u":
|
||||||
|
users = parse_comma_str(a)
|
||||||
|
elif o == "-p":
|
||||||
|
port = int(a)
|
||||||
|
elif o == "-f":
|
||||||
|
fqdn = a
|
||||||
|
else:
|
||||||
|
print(f"Unknown option {o}, ignoring...", flush=True)
|
||||||
|
exit(1)
|
||||||
|
print("====== init.py ======", flush=True)
|
||||||
|
print("Configuration:\n" + \
|
||||||
|
f" port = {port}\n" + \
|
||||||
|
f" fqdn = {fqdn}\n" + \
|
||||||
|
f" users = {str(users)}", flush=True)
|
||||||
|
|
||||||
|
print(f"Checking certs for {fqdn}...", flush=True)
|
||||||
|
if (os.path.exists(f"/etc/letsencrypt/live/{fqdn}")):
|
||||||
|
print("Found existing certs, trying to renew...", flush=True)
|
||||||
|
subprocess.check_call(f"certbot renew", shell=True)
|
||||||
|
else:
|
||||||
|
print("Unable to locate certs, generating...", flush=True)
|
||||||
|
subprocess.check_call(f"certbot certonly -n --standalone -m dummy@dummy.com --agree-tos --no-eff-email -d {fqdn}", shell=True)
|
||||||
|
|
||||||
|
jinja_dict : dict[str,str] = dict()
|
||||||
|
jinja_dict["USERS"] = build_users_json(users)
|
||||||
|
jinja_dict["PORT"] = str(port)
|
||||||
|
jinja_dict["FQDN"] = str(fqdn)
|
||||||
|
|
||||||
|
print(f"Processing Xray config files...", flush=True)
|
||||||
|
with open("/opt/xray/d2ray.json.in", "r") as f:
|
||||||
|
with open("/opt/xray/d2ray.json", "w") as d:
|
||||||
|
template : jinja2.Template = jinja2.Template(f.read())
|
||||||
|
d.write(template.render(**jinja_dict))
|
||||||
|
|
||||||
|
print(f"Processing Nginx config files...", flush=True)
|
||||||
|
with open("/opt/nginx/nginx.conf.in", "r") as f:
|
||||||
|
with open("/opt/nginx/nginx.conf", "w") as d:
|
||||||
|
template : jinja2.Template = jinja2.Template(f.read())
|
||||||
|
d.write(template.render(**jinja_dict))
|
||||||
|
for u in users:
|
||||||
|
subprocess.check_call(f"htpasswd -b /opt/nginx/.htpasswd {u} {u}", shell=True)
|
||||||
|
|
||||||
|
exit(0)
|
13
opt/init.sh
Normal file
13
opt/init.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# create log directories
|
||||||
|
mkdir -p /etc/d2ray/logs/cron
|
||||||
|
mkdir -p /etc/d2ray/logs/xray
|
||||||
|
mkdir -p /etc/d2ray/logs/nginx
|
||||||
|
mkdir -p /etc/d2ray/logs/supervisor
|
||||||
|
|
||||||
|
python3 /opt/init.py -p $PORT -u $USERS -f $FQDN
|
||||||
|
retval=$?
|
||||||
|
if [ $retval -ne 0 ]; then
|
||||||
|
exit $retval
|
||||||
|
fi
|
||||||
|
exec /usr/bin/supervisord -c /opt/supervisord.conf
|
0
opt/nginx/.htpasswd
Normal file
0
opt/nginx/.htpasswd
Normal file
3
opt/nginx/download/配置说明.txt
Normal file
3
opt/nginx/download/配置说明.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Android用户请看 android 文件夹
|
||||||
|
iOS用户请看 ios 文件夹
|
||||||
|
其他系统用户请下载 d2ray.zip
|
@ -1,7 +1,8 @@
|
|||||||
user www www;
|
user www www;
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
error_log /opt/config/logs/nginx/error.log;
|
daemon off;
|
||||||
pid /tmp/nginx.pid;
|
pid /tmp/nginx.pid;
|
||||||
|
worker_rlimit_nofile 8192;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 4096; ## Default: 1024
|
worker_connections 4096; ## Default: 1024
|
||||||
@ -22,13 +23,16 @@ http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
charset utf-8;
|
charset utf-8;
|
||||||
|
access_log /etc/d2ray/logs/nginx/access.log;
|
||||||
|
error_log /etc/d2ray/logs/nginx/error.log;
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80 default_server;
|
listen 80 default_server;
|
||||||
server_name _;
|
server_name _;
|
||||||
access_log /opt/config/logs/nginx/access.log;
|
|
||||||
if ($external) {
|
if ($external) {
|
||||||
return 301 https://$host$request_uri:8443;
|
return 301 https://$host:{{ PORT }}$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
@ -39,7 +43,7 @@ http {
|
|||||||
location /download {
|
location /download {
|
||||||
root /opt/nginx/;
|
root /opt/nginx/;
|
||||||
autoindex on;
|
autoindex on;
|
||||||
auth_basic "Provide credentials to access downloads";
|
auth_basic "Please provide credentials to access this server";
|
||||||
auth_basic_user_file "/opt/nginx/.htpasswd";
|
auth_basic_user_file "/opt/nginx/.htpasswd";
|
||||||
}
|
}
|
||||||
}
|
}
|
42
opt/supervisord.conf
Normal file
42
opt/supervisord.conf
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
[unix_http_server]
|
||||||
|
file=/var/run/supervisord.sock
|
||||||
|
|
||||||
|
[rpcinterface:supervisor]
|
||||||
|
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||||
|
|
||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
loglevel=warn
|
||||||
|
logfile=/etc/d2ray/logs/supervisor/supervisord.log
|
||||||
|
logfile_maxbytes=0
|
||||||
|
|
||||||
|
[supervisorctl]
|
||||||
|
serverurl=unix:///var/run/supervisord.sock
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=nginx -c /opt/nginx/nginx.conf
|
||||||
|
autostart=true
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
redirect_stderr=true
|
||||||
|
|
||||||
|
[program:cron]
|
||||||
|
command=crond -f -L /etc/d2ray/logs/cron/crond.log -c /opt/crontabs
|
||||||
|
autostart=true
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=/etc/d2ray/logs/cron/crond.log
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
redirect_stderr=true
|
||||||
|
|
||||||
|
[program:xray]
|
||||||
|
command=/opt/xray/xray -c /opt/xray/d2ray.json
|
||||||
|
autostart=true
|
||||||
|
autorestart=false
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
redirect_stderr=true
|
||||||
|
|
||||||
|
[eventlistener:exit]
|
||||||
|
command=bash -c "printf 'READY\n' && while read line; do kill -SIGQUIT $PPID; done < /dev/stdin"
|
||||||
|
events=PROCESS_STATE_FATAL,PROCESS_STATE_STOPPED,PROCESS_STATE_EXITED
|
43
opt/xray/d2ray.json.in
Normal file
43
opt/xray/d2ray.json.in
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"loglevel": "warn",
|
||||||
|
"access": "/etc/d2ray/logs/xray/access.log",
|
||||||
|
"error": "/etc/d2ray/logs/xray/error.log"
|
||||||
|
},
|
||||||
|
"inbounds": [
|
||||||
|
{
|
||||||
|
"port": {{ PORT }},
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"clients": [
|
||||||
|
{{ USERS }}
|
||||||
|
],
|
||||||
|
"decryption": "none",
|
||||||
|
"fallbacks": [
|
||||||
|
{
|
||||||
|
"dest": "localhost:80"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "tcp",
|
||||||
|
"security": "xtls",
|
||||||
|
"xtlsSettings": {
|
||||||
|
"alpn": ["http/1.1", "h2"],
|
||||||
|
"certificates": [
|
||||||
|
{
|
||||||
|
"certificateFile": "/etc/letsencrypt/live/{{ FQDN }}/fullchain.pem",
|
||||||
|
"keyFile": "/etc/letsencrypt/live/{{ FQDN }}/privkey.pem"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbounds": [
|
||||||
|
{
|
||||||
|
"protocol": "freedom",
|
||||||
|
"settings": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -11,21 +11,25 @@ VPN陪置教程
|
|||||||
|
|
||||||
**** 1. 配置 VPN程序 ****
|
**** 1. 配置 VPN程序 ****
|
||||||
Windows系统请看这里:
|
Windows系统请看这里:
|
||||||
- 进入windows目录
|
- 进入当前文件夹 windows 目录
|
||||||
- 用文本编辑器打开config.json,搜索并替换 *所有* (划重点*所有*):
|
- 解压 Xray-windows-64.zip
|
||||||
|
- 用文本编辑器打开 config.json,搜索并替换 *所有* (划重点*所有*):
|
||||||
%PASSWORD% => 你的密码. 比如密码是12345的话 文件中所有的 "%PASSWORD%" 应该替换成 "12345", 以下同理
|
%PASSWORD% => 你的密码. 比如密码是12345的话 文件中所有的 "%PASSWORD%" 应该替换成 "12345", 以下同理
|
||||||
%SERVER% => 你的服务器地址(这个是你下载zip文件的地址,比如你从https://xxx.quacker.net/download下载你的服务器地址就是xxx.quacker.net)
|
%SERVER% => 你的服务器地址(这个是你下载zip文件的地址,比如你从https://xxx.quacker.net/download下载你的服务器地址就是xxx.quacker.net)
|
||||||
- 保存config.json
|
- 保存 config.json
|
||||||
- 双击run.bat运行VPN程序
|
- 拷贝 config.json 和 run.bat 进入解压后的文件夹
|
||||||
|
- 进入解压后文件夹双击 run.bat 运行VPN程序
|
||||||
|
|
||||||
MacOS系统请看这里:
|
MacOS系统请看这里:
|
||||||
- 进入macos目录
|
- 进入当前文件夹 macos 目录
|
||||||
- 用文本编辑器打开config.json,搜索并替换 *所有* (划重点*所有*):
|
- 解压 Xray-macos-64.zip 或者 Xray-macos-arm64-v8a.zip (Apple M系芯片请用arm64)
|
||||||
|
- 用文本编辑器打开 config.json,搜索并替换 *所有* (划重点*所有*):
|
||||||
%PASSWORD% => 你的密码(和你的网站下载密码相同). 比如密码是12345的话 文件中所有的 "%PASSWORD%" 应该替换成 "12345", 以下同理
|
%PASSWORD% => 你的密码(和你的网站下载密码相同). 比如密码是12345的话 文件中所有的 "%PASSWORD%" 应该替换成 "12345", 以下同理
|
||||||
%SERVER% => 你的服务器地址(这个是你下载zip文件的地址,比如你从https://xxx.quacker.net/download下载你的服务器地址就是xxx.quacker.net)
|
%SERVER% => 你的服务器地址(这个是你下载zip文件的地址,比如你从https://xxx.quacker.net/download下载你的服务器地址就是xxx.quacker.net)
|
||||||
- 保存config.json
|
- 保存 config.json
|
||||||
- 右键run.sh => 用应用程序打开(Open With) => 其他(Other) => 在新打开的窗口下方选择框里选"所有应用程序"(All Applications) => 找到 终端"Terminal" 并勾选 永久以程序打开(Always Open With) => 确定
|
- 右键 run.sh => 用应用程序打开(Open With) => 其他(Other) => 在新打开的窗口下方选择框里选"所有应用程序"(All Applications) => 找到 终端"Terminal" 并勾选 永久以程序打开(Always Open With) => 确定
|
||||||
- 上述设置后直接双击run.sh就可以打开VPN程序了
|
- 拷贝 config.json 和 run.sh 进入解压后的文件夹
|
||||||
|
- 进入解压后文件夹双击 run.sh 运行VPN程序
|
||||||
|
|
||||||
|
|
||||||
**** 2. 配置 浏览器 ****
|
**** 2. 配置 浏览器 ****
|
@ -1,3 +0,0 @@
|
|||||||
ivans.quacker.net
|
|
||||||
concerto.quacker.net
|
|
||||||
nocturne.quacker.net
|
|
Loading…
Reference in New Issue
Block a user