new
continuous-integration/drone/push Build is failing Details

This commit is contained in:
quackerd 2021-04-19 03:51:22 -04:00
parent aa3855f126
commit 551ab9e886
17 changed files with 553 additions and 69 deletions

View File

@ -23,4 +23,10 @@ steps:
from_secret: docker_username
password:
from_secret: docker_password
repo: quackerd/d2ray
repo: quackerd/d2ray
- name: refresh
image: alpine
commands:
- chmod +x ./refresh.sh
- ./refresh.sh

View File

@ -4,9 +4,10 @@ FROM alpine:latest
ENV VERSION=var_VERSION
ENV URL https://github.com/XTLS/Xray-core/releases/download/v${VERSION}/Xray-linux-64.zip
COPY ./run.sh /opt/run.sh
COPY ./nginx /opt/nginx
COPY ./crontab /var/spool/cron/crontabs/root
COPY image/run.sh /opt/run.sh
COPY image/nginx.conf /opt/nginx.conf
COPY image/crontab /var/spool/cron/crontabs/root
COPY image/wait_for_it.sh /opt/wait_for_it.sh
RUN set -xe && \
chmod +x /opt/run.sh && \
@ -18,16 +19,17 @@ RUN set -xe && \
mkdir -p /opt/config/logs/crond && \
mkdir -p /opt/xray && \
ln -s /opt/config/certs /etc/letsencrypt && \
apk add --no-cache unzip wget nginx certbot openssl && \
apk add --no-cache unzip wget nginx certbot openssl bash && \
wget ${URL} && \
unzip Xray-linux-64.zip -d /opt/xray && \
rm Xray-linux-64.zip && \
apk del unzip wget && \
addgroup www && \
adduser -H -D -S -s /bin/false www -G www && \
chown -R www:www /opt/nginx
chown -R www:www /opt/nginx && \
chmod +x /opt/run.sh /opt/wait_for_it.sh
EXPOSE 80 443
CMD ["/opt/run.sh"]
CMD ["/opt/wait_for_it.sh d2ray_nextcloud:80 --timeout=60 --strict -- /opt/run.sh"]

11
ansible/d2ray.yml Normal file
View File

@ -0,0 +1,11 @@
- hosts: '{{ target }}'
gather_facts: false
become: true
remote_user: root
any_errors_fatal: yes
tasks:
- name: add root ssh key
ansible.posix.authorized_key:
user: root
state: present
key: "{{ lookup('file', './id_root.pub') }}"

7
ansible/id_root Normal file
View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCZkiqqwNqxkOBmoaSiTqKfz6Vt8doQyFt8KhHRFAmXGAAAAKB/tAMff7QD
HwAAAAtzc2gtZWQyNTUxOQAAACCZkiqqwNqxkOBmoaSiTqKfz6Vt8doQyFt8KhHRFAmXGA
AAAECpU6mEunFZV2qLmgJHRlpj08fIR6b5Ndz23fde0Q9UN5mSKqrA2rGQ4GahpKJOop/P
pW3x2hDIW3wqEdEUCZcYAAAAHHF1YWNrZXJkQGJhbGxhZGUucXVhY2tlci5vcmcB
-----END OPENSSH PRIVATE KEY-----

1
ansible/id_root.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmSKqrA2rGQ4GahpKJOop/PpW3x2hDIW3wqEdEUCZcY quackerd@ballade.quacker.org

View File

@ -0,0 +1,50 @@
{
"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": "zsy",
"flow": "xtls-rprx-direct"
},
{
"id": "lxd",
"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": {}
}
]
}

43
docker-compose.yml Normal file
View File

@ -0,0 +1,43 @@
version: '3.0'
networks:
br-d2ray:
external: false
services:
watchtower:
container_name: d2ray_watchtower
restart: unless-stopped
image: containrrr/watchtower
networks:
- br-d2ray
volumes:
- /var/run/docker.sock:/var/run/docker.sock
d2ray:
container_name: d2ray
image: quackerd/d2ray
restart: unless-stopped
networks:
- br-d2ray
environment:
- FQDN=var_hostname
ports:
- 80:80
- 443:443
volumes:
- ./config:/opt/config
- ./config.json:/opt/config.json
depends_on:
- d2ray_nextcloud
d2ray_nextcloud:
container_name: d2ray_nextcloud
image: nextcloud/nextcloud
networks:
- br-d2ray
restart: unless-stopped
environment:
- SQLITE_DATABASE=nextcloud
- NEXTCLOUD_ADMIN_USER=fgjhgthtrhha
- NEXTCLOUD_ADMIN_PASSWORD=fhrh5hhdsf876713gc7821974t5t65gg
- NEXTCLOUD_TRUSTED_DOMAINS=*

46
etude.quacker.net Normal file
View File

@ -0,0 +1,46 @@
{
"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": "zsy",
"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/etude.quacker.net/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/etude.quacker.net/privkey.pem"
}
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}

72
image/nginx.conf Normal file
View File

@ -0,0 +1,72 @@
user www www;
worker_processes auto;
error_log /opt/config/logs/nginx/error.log;
pid /tmp/nginx.pid;
events {
worker_connections 4096; ## Default: 1024
}
http {
geo $external {
default 1;
127.0.0.1/32 0;
}
##
# WebSocket proxying
##
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
server_name _;
access_log /opt/config/logs/nginx/access.log;
if ($external) {
return 301 https://$host$request_uri;
}
client_max_body_size 0;
location / {
# Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# Proxy Connection Settings
proxy_buffers 32 4k;
proxy_connect_timeout 240;
proxy_headers_hash_bucket_size 128;
proxy_headers_hash_max_size 1024;
proxy_http_version 1.1;
proxy_read_timeout 240;
proxy_redirect http:// $scheme://;
proxy_send_timeout 240;
# Proxy Cache and Cookie Settings
proxy_cache_bypass $cookie_session;
#proxy_cookie_path / "/; Secure"; # enable at your own risk, may break certain apps
proxy_no_cache $cookie_session;
# Proxy Header Settings
proxy_set_header Connection $connection_upgrade;
proxy_set_header Early-Data $ssl_early_data;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
set $upstream_app d2ray_nextcloud;
set $upstream_port 80;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_max_temp_file_size 2048m;
}
}
}

View File

@ -9,8 +9,6 @@ mkdir -p /opt/config/logs/nginx
mkdir -p /opt/config/logs/xray
mkdir -p /opt/config/logs/crond
BUCKET_HASH=3bd6b2ce5101e791b665d709aa8518ce
echo ""
echo "===== Checking Environment Variables ====="
if [ -z "$FQDN" ]; then
@ -20,20 +18,6 @@ else
echo "FQDN = $FQDN"
fi
if [ -z "$SALT" ]; then
echo "SALT must be set"
exit 1
else
echo "SALT = $SALT"
fi
if [ -z "$KEY" ]; then
echo "KEY must be set"
exit 1
else
echo "KEY = $KEY"
fi
echo ""
echo "===== Checking Certificates ===="
if [ ! -d "/etc/letsencrypt/live/$FQDN" ]; then
@ -44,19 +28,11 @@ else
certbot renew
fi
echo ""
echo "===== Downloading configuration file ====="
hash=$(echo -n "$FQDN.$SALT" | openssl dgst -md5 | sed -E 's/\(stdin\)= (.*)/\1/')
echo "Host hash is $hash"
wget -q http://$BUCKET_HASH.s3-website-us-west-1.amazonaws.com/config/$hash -O /opt/$hash
openssl aes-256-cbc -d -md sha512 -pbkdf2 -in /opt/$hash -out /opt/$FQDN.json -k $KEY
rm /opt/$hash
echo ""
echo "===== Starting services ====="
crond -L /opt/config/logs/crond/log.txt
nginx -c /opt/nginx/nginx.conf
nginx -c /opt/nginx.conf
echo ""
echo "===== Starting xray ====="
exec /opt/xray/xray -c /opt/$FQDN.json
exec /opt/xray/xray -c /opt/config.json

182
image/wait_for_it.sh Normal file
View File

@ -0,0 +1,182 @@
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# Check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
# Check if busybox timeout uses -t flag
# (recent Alpine versions don't support -t anymore)
if timeout &>/dev/stdout | grep -q -e '-t '; then
WAITFORIT_BUSYTIMEFLAG="-t"
fi
else
WAITFORIT_ISBUSY=0
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi

50
mazurka.quacker.net Normal file
View File

@ -0,0 +1,50 @@
{
"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": "zsy",
"flow": "xtls-rprx-direct"
},
{
"id": "lxd",
"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/mazurka.quacker.net/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/mazurka.quacker.net/privkey.pem"
}
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}

View File

@ -1,27 +0,0 @@
user www www;
worker_processes auto;
error_log /opt/config/logs/nginx/error.log;
pid /tmp/nginx.pid;
events {
worker_connections 4096; ## Default: 1024
}
http {
geo $external {
default 1;
127.0.0.1/32 0;
}
server {
listen 80 default_server;
server_name _;
access_log /opt/config/logs/nginx/access.log;
if ($external) {
return 301 https://$host$request_uri;
}
root /opt/nginx/webroot;
index index.html;
}
}

View File

@ -1,9 +0,0 @@
<!doctype html>
<html>
<head>
<title>This is the title of the webpage!</title>
</head>
<body>
<p>This is an example paragraph. Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.</p>
</body>
</html>

50
nocturne.quacker.net Normal file
View File

@ -0,0 +1,50 @@
{
"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": "zsy",
"flow": "xtls-rprx-direct"
},
{
"id": "e6569ab4-c0dd-4c29-9b29-5afef6a39a92",
"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
refresh.sh Normal file
View File

@ -0,0 +1,24 @@
#!/bin/sh
set -e
chmod 0600 ansible/id_root
for filename in confs/*; do
addr=$(basename $filename)
echo "Refreshing $addr..."
cp docker-compose.yml docker-compose.yml.tmp
sed -i -E "s/var_hostname/$addr/g" docker-compose.yml.tmp
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "mkdir -p /opt/d2ray && \
cd /opt/d2ray && \
/usr/local/bin/docker-compose down"
scp -P 77 -o StrictHostKeychecking=no -i ansible/id_root docker-compose.yml.tmp root@$addr:/opt/d2ray/docker-compose.yml
scp -P 77 -o StrictHostKeychecking=no -i ansible/id_root $filename root@$addr:/opt/d2ray/config.json
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "cd /opt/d2ray && \
/usr/local/bin/docker-compose pull &&
/usr/local/bin/docker-compose up -d &&
docker system prune -a -f"
&& /usr/local/bin/docker-compose pull && /usr/local/bin/docker-compose down && /usr/local/bin/docker-compose up -d"
done
wait