centralize
This commit is contained in:
parent
9f1a934066
commit
0ffb5804db
26
.drone.yml
Normal file
26
.drone.yml
Normal file
@ -0,0 +1,26 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Docker image build
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
|
||||
|
||||
steps:
|
||||
- name: config
|
||||
image: alpine
|
||||
commands:
|
||||
- echo -n "$VERSION,latest" > .tags
|
||||
- sed -i -E "s/var_FRP_VERSION/$FRP_VERSION/" Dockerfile
|
||||
- apk add openssl
|
||||
- ./gen_uploads.sh
|
||||
|
||||
- name: build
|
||||
image: plugins/docker
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: quackerd/rainloop
|
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@ -0,0 +1,30 @@
|
||||
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
|
||||
|
||||
RUN set -xe && \
|
||||
apk add --no-cache unzip wget nginx certbot openssl && \
|
||||
wget ${URL} && \
|
||||
mkdir -p /opt/xray && \
|
||||
unzip Xray-linux-64.zip -d /opt/xray && \
|
||||
rm Xray-linux-64.zip && \
|
||||
mkdir -p /opt/config && \
|
||||
mkdir -p /opt/config/logs && \
|
||||
mkdir -p /opt/config/certs && \
|
||||
mkdir -p /opt/config/logs/nginx && \
|
||||
mkdir -p /opt/config/logs/xray && \
|
||||
mkdir -p /opt/config/logs/crond && \
|
||||
chmod +x /opt/run.sh && \
|
||||
apk del unzip wget
|
||||
|
||||
COPY ./nginx.conf /opt/nginx.conf
|
||||
COPY ./crontab /var/spool/cron/crontabs/root
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
CMD ["/opt/run.sh"]
|
19
LICENSE
19
LICENSE
@ -1,19 +0,0 @@
|
||||
MIT License Copyright (c) 2021 quackerd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
118
client_conf.in
118
client_conf.in
@ -1,118 +0,0 @@
|
||||
{
|
||||
"dns": {
|
||||
"servers": [
|
||||
"223.5.5.5",
|
||||
"114.114.114.114",
|
||||
{
|
||||
"address": "8.8.8.8",
|
||||
"port": 53,
|
||||
"domains": [
|
||||
"geosite:geolocation-!cn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"address": "1.1.1.1",
|
||||
"port": 53,
|
||||
"domains": [
|
||||
"geosite:geolocation-!cn"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "direct",
|
||||
"ip": [
|
||||
"223.5.5.5",
|
||||
"114.114.114.114"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "proxy",
|
||||
"ip": [
|
||||
"8.8.8.8",
|
||||
"1.1.1.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "direct",
|
||||
"ip": [
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "direct",
|
||||
"domain": ["geosite:cn"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "proxy",
|
||||
"network": "udp,tcp"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"inbounds": [
|
||||
{
|
||||
"port": {{ port }},
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "socks",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls"]
|
||||
},
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "{{ subdomain }}.{{ domain }}",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "{{ id }}",
|
||||
"encryption": "none",
|
||||
"level": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "xtls",
|
||||
"xtlsSettings": {
|
||||
"serverName": "{{ subdomain }}.{{ domain }}",
|
||||
"allowInsecure": false,
|
||||
"alpn": ["h2","http/1.1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"settings": {},
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"protocol": "blackhole",
|
||||
"settings": {},
|
||||
"tag": "block"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"id": "{{ id }}",
|
||||
"flow": "{{ flow }}",
|
||||
"level": 0
|
||||
}
|
43
config.yml
43
config.yml
@ -1,43 +0,0 @@
|
||||
server:
|
||||
# domain: the domain name, e.g. google.com
|
||||
domain: domain.tld
|
||||
# subdomain: the subdomain name, e.g. write vps for vps.google.com. leave empty for naked domain.
|
||||
subdomain: example
|
||||
# loglevel: the log level of xray
|
||||
# default: warning
|
||||
loglevel:
|
||||
# email: your email for the registered SSL cert. leave empty for a dummy email.
|
||||
# default: dummy@dummy.org
|
||||
email:
|
||||
# uid/gid: the user/group to run the docker-compose stack.
|
||||
# default: the current user
|
||||
# comment: you can also manually set, e.g. uid: 1000 gid: 1000
|
||||
uid:
|
||||
gid:
|
||||
# watchtower: enable watchtower docker image auto-update
|
||||
# default: False
|
||||
watchtower: False
|
||||
|
||||
clients:
|
||||
# name: the name of the client, cannot be null
|
||||
- name: example_user1
|
||||
# id: the password(uuid) of each user, this can either be a string or an UUID. Please read the "comment" and "IMPORTANT" sections.
|
||||
# default: auto-generated random string
|
||||
# comment: for a managed environment we recommend hardcoding the id
|
||||
# the generated id does NOT currently back-propagate to this file
|
||||
# you WILL lose existing users if you run configure.py multiple times with blank ids as they will be regenerated with random ids
|
||||
#
|
||||
# ! IMPORTANT !: id DOES NOT have to be UUID, can be any string of length 1-30. This is supported by xray but not by some v2ray clients
|
||||
# if the script detects that the id is not a valid UUID, it will also output the equivalent UUID of that string
|
||||
id:
|
||||
# flow: the flow parameter
|
||||
# default: xtls-rprx-direct
|
||||
flow:
|
||||
# port: local socks5 proxy port on clients' machines
|
||||
# default: 1080
|
||||
port:
|
||||
# you can also set each field manually like below:
|
||||
# - name: example_user2
|
||||
# id: example_passwd2
|
||||
# flow: xtls-rprx-direct
|
||||
# port: 6666
|
188
configure.py
188
configure.py
@ -1,188 +0,0 @@
|
||||
import getopt
|
||||
import sys
|
||||
import uuid
|
||||
import pwd
|
||||
import jinja2
|
||||
import random
|
||||
import os
|
||||
import string
|
||||
import yaml
|
||||
|
||||
OUTPUT_DIR = "build"
|
||||
CLIENT_OUTPUT_DIR = "clients"
|
||||
DEFAULT_EMAIL = "dummy@dummy.org"
|
||||
CONF_FILE = "config.yml"
|
||||
SERVER_IN = "server.in"
|
||||
SERVER_PATH = "xray"
|
||||
SERVER_FN = "config.json"
|
||||
NGINX_IN = "nginx.in"
|
||||
NGINX_PATH = "nginx/nginx/site-confs"
|
||||
NGINX_FN = "default"
|
||||
CLIENT_OBJ_IN = "client_obj.in"
|
||||
CLIENT_CONF_IN = "client_conf.in"
|
||||
DOCKER_IN = "docker-compose.in"
|
||||
WATCHTOWER_IN = "watchtower.in"
|
||||
DEFAULT_WATCHTOWER_ENABLE = False
|
||||
DEFAULT_CLIENT_PORT = 1080
|
||||
DEFAULT_USER_FLOW = "xtls-rprx-direct"
|
||||
DEFAULT_LOGLEVEL= "warning"
|
||||
UUID_NAMESPACE = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
|
||||
def calc_uuid5(val):
|
||||
return str(uuid.uuid5(UUID_NAMESPACE, val))
|
||||
|
||||
def is_valid_uuid(val):
|
||||
try:
|
||||
uuid.UUID(str(val))
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def yaml_key_exists_else(mapping : [], name : str, other_val = None, nullable = True):
|
||||
if (name in mapping) and (mapping[name] != None):
|
||||
return mapping[name]
|
||||
else:
|
||||
if not nullable:
|
||||
raise Exception("Key " + name + " must not be null.")
|
||||
else:
|
||||
return other_val
|
||||
|
||||
def random_string(stringLength=16):
|
||||
letters = string.ascii_lowercase
|
||||
return ''.join(random.choice(letters) for i in range(stringLength))
|
||||
|
||||
class Client:
|
||||
def __init__(self, conf_obj):
|
||||
self.name = str(yaml_key_exists_else(conf_obj, 'name', nullable=False))
|
||||
self.id = str(yaml_key_exists_else(conf_obj, 'id', other_val=random_string()))
|
||||
self.flow = str(yaml_key_exists_else(conf_obj, 'flow', other_val=DEFAULT_USER_FLOW))
|
||||
self.port = int(yaml_key_exists_else(conf_obj, 'port', other_val=DEFAULT_CLIENT_PORT))
|
||||
|
||||
def print(self, ident):
|
||||
pre = ""
|
||||
for i in range(ident):
|
||||
pre += " "
|
||||
|
||||
print(pre + "{")
|
||||
print(pre + " id: " + self.id)
|
||||
print(pre + " uuid: " + (self.id if is_valid_uuid(self.id) else calc_uuid5(self.id)))
|
||||
print(pre + " flow: " + self.flow)
|
||||
print(pre + " port: " + str(self.port))
|
||||
print(pre + "}")
|
||||
|
||||
|
||||
|
||||
class Config:
|
||||
def print(self):
|
||||
print("Server configuration:")
|
||||
print(" domain: " + self.domain)
|
||||
print(" email: " + self.email)
|
||||
print(" subdomain: " + self.subdomain)
|
||||
print(" uid: " + str(self.uid))
|
||||
print(" gid: " + str(self.gid))
|
||||
print(" loglevel: " + self.loglevel)
|
||||
print(" clients:")
|
||||
for i in range(len(self.clients)):
|
||||
self.clients[i].print(8)
|
||||
|
||||
def __init__(self, f):
|
||||
conf = yaml.safe_load(f)
|
||||
conf_srv = conf['server']
|
||||
|
||||
self.domain = str(yaml_key_exists_else(conf_srv, 'domain', nullable=False))
|
||||
self.email = str(yaml_key_exists_else(conf_srv, 'email', other_val=DEFAULT_EMAIL))
|
||||
self.subdomain = str(yaml_key_exists_else(conf_srv, 'subdomain', other_val=""))
|
||||
self.subdomain_only = len(self.subdomain) > 0
|
||||
self.uid = int(yaml_key_exists_else(conf_srv, 'uid', other_val=os.getuid()))
|
||||
self.gid = int(yaml_key_exists_else(conf_srv, 'gid', other_val=os.getgid()))
|
||||
self.loglevel = str(yaml_key_exists_else(conf_srv, 'loglevel', other_val=DEFAULT_LOGLEVEL))
|
||||
self.watchtower = bool(yaml_key_exists_else(conf_srv, 'watchtower', other_val=DEFAULT_WATCHTOWER_ENABLE))
|
||||
|
||||
self.clients = []
|
||||
conf_clients = conf['clients']
|
||||
for i in range(len(conf_clients)):
|
||||
self.clients.append(Client(conf_clients[i]))
|
||||
|
||||
def main():
|
||||
with open(CONF_FILE, 'r') as f:
|
||||
conf = Config(f)
|
||||
conf.print()
|
||||
|
||||
template_dict = {}
|
||||
template_dict['uid'] = conf.uid
|
||||
template_dict['gid'] = conf.gid
|
||||
template_dict['subdomain'] = conf.subdomain
|
||||
template_dict['subdomain_only'] = str(conf.subdomain_only).lower()
|
||||
template_dict['domain'] = conf.domain
|
||||
template_dict['email'] = conf.email
|
||||
template_dict['loglevel'] = conf.loglevel
|
||||
|
||||
if conf.watchtower:
|
||||
with open(WATCHTOWER_IN, "r") as f:
|
||||
template_dict['watchtower'] = f.read()
|
||||
else:
|
||||
template_dict['watchtower'] = ""
|
||||
|
||||
clients = ""
|
||||
with open(CLIENT_OBJ_IN, "r") as f:
|
||||
client_obj = f.read()
|
||||
for i in range(len(conf.clients)):
|
||||
if i > 0:
|
||||
clients += ",\n"
|
||||
clients += jinja2.Template(client_obj).render(id = conf.clients[i].id,
|
||||
flow = conf.clients[i].flow)
|
||||
template_dict['clients'] = clients
|
||||
|
||||
print("Generating files...")
|
||||
|
||||
# create output dir
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
# generate docker-compose.yml
|
||||
path = os.path.join(OUTPUT_DIR, "docker-compose.yml")
|
||||
with open(DOCKER_IN, "r") as f:
|
||||
template = jinja2.Template(f.read())
|
||||
with open(path, "w") as f:
|
||||
f.write(template.render(template_dict))
|
||||
|
||||
# generate NGINX conf
|
||||
with open(NGINX_IN, "r") as f:
|
||||
template = jinja2.Template(f.read())
|
||||
path = os.path.join(OUTPUT_DIR, NGINX_PATH)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
path = os.path.join(path, NGINX_FN)
|
||||
with open(path, "w") as f:
|
||||
f.write(template.render(template_dict))
|
||||
|
||||
# generate xray conf
|
||||
with open(SERVER_IN, "r") as f:
|
||||
template = jinja2.Template(f.read())
|
||||
path = os.path.join(OUTPUT_DIR, SERVER_PATH)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
path = os.path.join(path, SERVER_FN)
|
||||
with open(path, "w") as f:
|
||||
f.write(template.render(template_dict))
|
||||
|
||||
# generate client confs
|
||||
path = os.path.join(OUTPUT_DIR, CLIENT_OUTPUT_DIR)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
with open(CLIENT_CONF_IN, "r") as f:
|
||||
client_conf_temp = jinja2.Template(f.read())
|
||||
for i in range(len(conf.clients)):
|
||||
template_dict['id'] = conf.clients[i].id
|
||||
template_dict['port'] = conf.clients[i].port
|
||||
template_dict['flow'] = conf.clients[i].flow
|
||||
epath = os.path.join(path, conf.clients[i].name)
|
||||
os.makedirs(epath, exist_ok=True)
|
||||
with open(os.path.join(epath, SERVER_FN), "w") as f:
|
||||
f.write(client_conf_temp.render(template_dict))
|
||||
|
||||
# chown
|
||||
os.chown(OUTPUT_DIR, conf.uid, conf.gid)
|
||||
for dirpath, dirnames, filenames in os.walk(OUTPUT_DIR):
|
||||
os.chown(dirpath, conf.uid, conf.gid)
|
||||
for fname in filenames:
|
||||
os.chown(os.path.join(dirpath, fname), conf.uid, conf.gid)
|
||||
print("Please find the generated files in the build directory. To start the stack, run docker-compose up -d in the build directory.")
|
||||
|
||||
main()
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "{{ loglevel }}",
|
||||
"access": "/etc/xray/access.log",
|
||||
"error": "/etc/xray/error.log"
|
||||
"loglevel": "debug",
|
||||
"access": "/opt/config/xray/access.log",
|
||||
"error": "/opt/config/xray/error.log"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
@ -10,12 +10,15 @@
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{{ clients }}
|
||||
{
|
||||
"id": "zsy",
|
||||
"flow": "xtls-rprx-direct"
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": [
|
||||
{
|
||||
"dest": "d2ray_nginx:80"
|
||||
"dest": "localhost:80"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -26,8 +29,8 @@
|
||||
"alpn": ["http/1.1", "h2"],
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/le-etc/letsencrypt/live/{{ subdomain }}.{{ domain }}/fullchain.pem",
|
||||
"keyFile": "/le-etc/letsencrypt/live/{{ subdomain }}.{{ domain }}/privkey.pem"
|
||||
"certificateFile": "/etc/letsencrypt/live/concerto.quacker.net/fullchain.pem",
|
||||
"keyFile": "/etc/letsencrypt/live/concerto.quacker.net/privkey.pem"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
version: '3.0'
|
||||
|
||||
networks:
|
||||
br-d2ray:
|
||||
external: false
|
||||
driver: bridge
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: br-d2ray
|
||||
enable_ipv6: false
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 172.127.127.0/24
|
||||
|
||||
services:
|
||||
d2ray_nginx:
|
||||
container_name: d2ray_nginx
|
||||
image: linuxserver/swag
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
networks:
|
||||
- br-d2ray
|
||||
environment:
|
||||
- PUID={{ uid }}
|
||||
- PGID={{ gid }}
|
||||
- TZ=US/Eastern
|
||||
- URL={{ domain }}
|
||||
- SUBDOMAINS={{ subdomain }}
|
||||
- VALIDATION=http
|
||||
- EMAIL=dummy@dummy.com
|
||||
- DHLEVEL=2048
|
||||
- ONLY_SUBDOMAINS={{ subdomain_only }}
|
||||
- STAGING=false
|
||||
ports:
|
||||
- 80:80
|
||||
volumes:
|
||||
- ./nginx:/config
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://{{ subdomain }}.{{ domain }}:80"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
d2ray_xray:
|
||||
container_name: d2ray_xray
|
||||
image: teddysun/xray
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
d2ray_nginx:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- br-d2ray
|
||||
ports:
|
||||
- 443:443
|
||||
volumes:
|
||||
- ./nginx/etc:/le-etc
|
||||
- ./xray:/etc/xray
|
||||
|
||||
{{ watchtower }}
|
11
gen_upload.sh
Normal file
11
gen_upload.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
set +e
|
||||
|
||||
mkdir -p ./uploads
|
||||
|
||||
for filename in ./confs/*; do
|
||||
fname=$(basename $filename)
|
||||
fhash=$(echo -n '$fname' | openssl dgst -md5 | sed -E 's/\(stdin\)= (.*)/\1/')
|
||||
openssl aes-256-cbc -md sha512 -pbkdf2 -in $filename -out ./uploads/$fhash.conf -k "sergeygorbunov"
|
||||
done
|
@ -1,17 +1,17 @@
|
||||
geo $external {
|
||||
default 1;
|
||||
172.127.127.0/24 0;
|
||||
localhost 0;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 80 http http2 default_server;
|
||||
server_name {{subdomain}}.{{domain}};
|
||||
|
||||
if ($external) {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
root /config/www;
|
||||
index index.html index.htm index.php;
|
||||
root /var/lib/nginx/html;
|
||||
index index.html;
|
||||
}
|
||||
|
55
run.sh
Normal file
55
run.sh
Normal file
@ -0,0 +1,55 @@
|
||||
#!/bin/sh
|
||||
|
||||
set +e
|
||||
|
||||
BUCKET_NAME="config.quacker.net"
|
||||
|
||||
echo "===== Checking Environment Variables ====="
|
||||
if [ -z "$FQDN" ]; then
|
||||
echo "FQDN must be set"
|
||||
exit 1
|
||||
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
|
||||
|
||||
BUCKET_HASH=$(echo -n "$BUCKET_NAME" | openssl dgst -md5 | sed -E 's/\(stdin\)= (.*)/\1/')
|
||||
echo "BUCKET_HASH= $BUCKET_HASH"
|
||||
|
||||
echo "===== Setting Up Environment ======"
|
||||
ln -s /opt/config/certs /etc/letsencrypt
|
||||
|
||||
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"
|
||||
else
|
||||
echo "Certificate exists. Checking renewal..."
|
||||
certbot renew
|
||||
fi
|
||||
|
||||
echo "===== Downloading configuration file ====="
|
||||
hash=$(echo -n "$FQDN.$SALT" | openssl dgst -sha256 | sed -E 's/\(stdin\)= (.*)/\1/')
|
||||
echo "Host hash is $hash"
|
||||
wget http://$BUCKET_HASH.s3-website-us-west-1.amazonaws.com/config/$hash.conf -P /opt/
|
||||
openssl aes-256-cbc -d -md sha512 -pbkdf2 -in /opt/$hash.conf -out /opt/$FQDN.conf -k $KEY
|
||||
|
||||
echo "===== Starting services ====="
|
||||
crond -L /opt/config/logs/crond/log.txt
|
||||
nginx -c /opt/nginx.conf
|
||||
|
||||
echo "===== Starting xray ====="
|
||||
/opt/xray/xray -c /opt/$FQDN.conf
|
@ -1,8 +0,0 @@
|
||||
watchtower:
|
||||
container_name: d2ray_watchtower
|
||||
image: containrrr/watchtower
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- br-d2ray
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
Loading…
Reference in New Issue
Block a user