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

This commit is contained in:
quackerd 2021-04-22 05:01:45 -04:00
parent 824a55ad97
commit 083057956a
15 changed files with 216 additions and 369 deletions

View File

@ -16,6 +16,13 @@ steps:
- echo -n "$VERSION,latest" > .tags
- sed -i -E "s/var_VERSION/$VERSION/" Dockerfile
- name: upload
image: alpine
commands:
- apk add openssl
- chmod +x ./encrypt_upload.sh
- encrypt_upload.sh
- name: build
image: plugins/docker
settings:
@ -28,5 +35,6 @@ steps:
- name: refresh
image: alpine
commands:
- apk add openssh
- chmod +x ./refresh.sh
- ./refresh.sh

View File

@ -5,9 +5,9 @@ ENV VERSION=var_VERSION
ENV URL https://github.com/XTLS/Xray-core/releases/download/v${VERSION}/Xray-linux-64.zip
COPY image/run.sh /opt/run.sh
COPY image/nginx.conf /opt/nginx.conf
COPY image/crypt.sh /opt/crypt.sh
COPY image/nginx /opt/nginx
COPY image/crontab /var/spool/cron/crontabs/root
COPY image/wait_for_it.sh /opt/wait_for_it.sh
RUN set -xe && \
mkdir -p /opt/config && \
@ -18,17 +18,16 @@ 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 bash && \
apk add --no-cache unzip wget nginx certbot openssl && \
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.conf && \
chmod +x /opt/run.sh /opt/wait_for_it.sh
chown -R www:www /opt/nginx && \
chmod +x /opt/run.sh /opt/crypt.sh && \
apk del unzip wget
EXPOSE 80 443
CMD ["/opt/wait_for_it.sh", "d2ray_nextcloud:80", "--", "sh", "/opt/run.sh"]
CMD ["/opt/run.sh"]

View File

@ -1,53 +0,0 @@
# d2ray
[![Build Status](https://ci.quacker.org/api/badges/d/d2ray/status.svg)](https://ci.quacker.org/d/d2ray)
Clean, dockerized xray(VLESS + TCP + XTLS) + Nginx + Let's Encrypt with official and well-maintained docker containers. No private containers.
d2ray opens 443 and 80. xray listens on 443 with VLESS fallback to Nginx. Nginx listens on 80 for regular webrequests. Nginx also redirects all HTTP traffic to 443 for HTTPS except for HTTP traffic coming from xray itself.
## Supports:
- xray with VLESS + TCP + XTLS protocol using [teddysun/xray](https://hub.docker.com/r/teddysun/xray/).
- Nginx frontend and **auto-renewing** Let's Encrypt certificate using the popular [linuxserver/swag](https://hub.docker.com/r/linuxserver/swag/).
- watchtower for automatic docker image updates (can be disabled) from [containrrr/watchtower](https://hub.docker.com/r/containrrr/watchtower)
- Easy multiuser configuration and user conf file generation.
## Usage:
### Required packages
- python3: On CentOS 7: `yum install python3`
- docker-ce
- docker-compose
- jinja2: A popular python template processor. Install with `pip3 install jinja2`.
- pyyaml: Python YAML parser. Install with `pip3 install pyyaml`.
### Building
- Clone this repo.
- Modify `config.yml` to your liking. Please see the comments in the file for documentation.
- Run `configure.py` with python 3.
- Generated files are located in the `build` directory. Run `docker-compose up -d` within that directory to start the stack.
- To start over or to update the existing configuration. Simply change `config.yml`, rerun `configure.py` and restart the stack `docker-compose down && docker-compose up -d`.
### Client connections
Client conf files are generated in `build/clients/[client name]/config.json`. Clients simply need to download the most recent xray release and replace `config.json` with the ones generated. The config file by default directly connects to CN mainland websites and proxies foreign websites. The same goes for DNS lookups.
You can customize the template file `client_conf.in` to generate custom client conf files.
### Updating
Currently you need to merge conflict yourself. Most likely only `config.yml` unless you customized other template files too. An auto script is WIP and for now please do the following:
1. Pull the latest change with `git pull`
2. If there are conflicts, stash your local changes with `git stash`
3. Run `git pull` again
4. Run `git stash pop` to pop your local changes
5. Manually merge the conflicting files
6. Run `git add -u` to mark them as conflict resolved
7. Restart the stack `docker-compose down && docker-compose up -d`
### Troubleshooting
#### Basics
- Make sure your subdomain.domain.tld points to the server.
- Use `docker logs d2ray_nginx` to check for nginx init errors. Detailed nginx logs and be found in `build/nginx/logs/nginx`
- Use `docker logs d2ray_xray` to check for v2ray init errors.
- Use `docker logs d2ray_watchtower` to check for watchtower errors.
- xray log files can be found in `build/xray`
#### Q: The nginx container is stuck?
A: Nginx needs to obtain certificate on its first launch so this is sort of expected. If it takes an unusual amount of time (>60 seconds), kindly Ctrl-C to interrupt docker-compose and check the nginx log. Most likely something is misconfigured.

50
concerto.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/concerto.quacker.net/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/concerto.quacker.net/privkey.pem"
}
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}

View File

@ -1,35 +0,0 @@
version: '3.0'
networks:
br-d2ray:
external: false
services:
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
networks:
- br-d2ray
restart: unless-stopped
environment:
- SQLITE_DATABASE=nextcloud
- NEXTCLOUD_ADMIN_USER=fgjhgthtrhha
- NEXTCLOUD_ADMIN_PASSWORD=fhrh5hhdsf876713gc7821974t5t65gg
- NEXTCLOUD_TRUSTED_DOMAINS=*

15
encrypt_upload.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
source image/crypt.sh
mkdir -p enc
for filename in confs/*; do
basename=$(basename $filename)
hash_sha256 $basename $(cat ./key)
output=$crypt_ret
encrypt "$(cat $filename)" $(cat ./key)
echo "$crypt_ret" > $output
scp -P77 -i ansible/id_root $output root@parrot.quacker.org:/dat/apps/nginx/http_dl/root/pub
rm $output
done

View File

@ -1 +1 @@
0 1 * * * certbot renew
0 */24 * * * certbot renew

21
image/crypt.sh Normal file
View File

@ -0,0 +1,21 @@
#!/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)
}
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")
}

View File

@ -1,72 +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;
}
##
# 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;
}
}
}

35
image/nginx/nginx.conf Normal file
View File

@ -0,0 +1,35 @@
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;
}
root /opt/nginx/webroot;
index index.html;
}
}

View File

@ -0,0 +1,38 @@
<header>Welcome to a webpage written entirely in Vanilla <strike>JS</strike> HTML.</header>
<!-- Heading -->
<h1>THE ROCKET BLOG FROM THE FUTURE 🚀</h1>
<p>My thoughts and ideas on rockets and the science behind them. <a href="https://about.me/vaibhav_khulbe" target="_blank">Learn more</a>.</p>
<br>
<!-- Article -->
<img src="https://images.pexels.com/photos/796206/pexels-photo-796206.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Space shuttle"/>
<kbd>FEATURED</kbd>
<h4><a href="#">Lorem ipsum dolor sit, amet consectetur adipisicing elit</a></h4>
<p>Optio, beatae! Aut quis id voluptate ullam repellendus. Et sit, ipsa, non consequuntur magnam quaerat temporibus at officiis ab, expedita molestiae liber...</p>
<a href="#"><button><b>READ MORE</b></button></a>
<br><br>
<!-- Article break -->
<details>
<summary>What was the secret behind this mission?</summary>
<img src="https://media.giphy.com/media/NdKVEei95yvIY/giphy.gif" alt="Secret GIF">
<p>Okay, go watch The Office.</p>
</details>
<br><br>
<!-- Article -->
<kbd>SPACE</kbd> <kbd>LUNA</kbd> <kbd>PRESSURE</kbd>
<h4><a href="#">Ad aspernatur, nemo unde neque laboriosam sequi?</a></h4>
<p>Nullam in lorem nec mi euismod pretium in eu erat. Nunc lacus tellus, sodales molestie sem id, tempor elementum turpis. Auris dapibus mi vitae libero luctus iaculis non non turpis. Mauris molestie ultrices...</p>
<a href="#"><button><b>READ MORE</b></button></a>
<br><br>
<!-- Article break -->
<blockquote>
“The Earth is the cradle of humanity, but mankind cannot stay in the cradle forever.” <i> - Konstantin Tsiolkovsky</i>
</blockquote>
<br><br>
<!-- Footer -->
<center>( ̄︶ ̄)↗</center> 

View File

@ -2,6 +2,8 @@
set +xe
source /opt/crypt.sh
mkdir -p /opt/config
mkdir -p /opt/config/logs
mkdir -p /opt/config/certs
@ -9,13 +11,18 @@ 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
else
echo "FQDN = $FQDN"
fi
if [ -z "$KEY" ]; then
echo "KEY must be set"
exit 1
fi
echo ""
@ -29,9 +36,26 @@ else
fi
echo ""
echo "===== Starting services ====="
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 $(cat /opt/$FQDN) $key
echo $crypt_ret > /opt/config.json
echo ""
echo "===== Starting cron ====="
crond -L /opt/config/logs/crond/log.txt
nginx -c /opt/nginx.conf
echo ""
echo "===== Starting Nginx ====="
nginx -c /opt/nginx/nginx.conf
echo ""
echo "===== Starting xray ====="

View File

@ -1,182 +0,0 @@
#!/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

1
key Normal file
View File

@ -0,0 +1 @@
K336yS5BAoQabLyxLvcnwrRxt5Vv

View File

@ -1,24 +1,22 @@
#!/bin/sh
set -e
apk add openssh
chmod 0600 ansible/id_root
key=$(cat ./key)
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"
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "docker pull quackerd/d2ray:latest"
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "docker stop d2ray"
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "docker run -d \
-e KEY=$key \
-e FQDN=$addr \
-p 80:80 \
-p 443:443 \
-v d2ray_volume:/opt/config \
--name d2ray \
quackerd/d2ray:latest"
ssh -p 77 -o StrictHostKeychecking=no -i ansible/id_root root@$addr -t "docker system prune -af"
done
wait