xray support
This commit is contained in:
parent
9276361ac5
commit
f1672986c4
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
"id": "{{ id }}",
|
"id": "{{ id }}",
|
||||||
"flow": "xtls-rprx-direct",
|
"flow": "{{ flow }}",
|
||||||
"level": 0,
|
"level": 0
|
||||||
"email": "dummy@dummy.com"
|
|
||||||
}
|
}
|
19
config.yml
19
config.yml
|
@ -22,20 +22,21 @@ server:
|
||||||
clients:
|
clients:
|
||||||
# name: the name of the client, cannot be null
|
# name: the name of the client, cannot be null
|
||||||
- name: example_user1
|
- name: example_user1
|
||||||
# id: the uuid of each user
|
# id: the password(uuid) of each user
|
||||||
# default: auto-generated uuid
|
# default: auto-generated random string
|
||||||
# comment: for a managed environment we recommend hardcoding the id:
|
# comment: for a managed environment we recommend hardcoding the id
|
||||||
# the generated id does NOT currently back-propagate to this file
|
# 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
|
# you WILL lose existing users if you run configure.py multiple times with blank ids as they will be regenerated with random ids
|
||||||
id: ahaha
|
# NOTE THAT id DOES NOT have to be UUID, can be any string (supported by upstream xray)
|
||||||
# alterid: the alterid as appeared in v2ray config file
|
id:
|
||||||
# default: 64
|
# flow: the flow parameter of each user
|
||||||
alterid:
|
# default: xtls-rprx-direct
|
||||||
|
flow:
|
||||||
# port: local socks5 proxy port on clients' machines
|
# port: local socks5 proxy port on clients' machines
|
||||||
# default: 1080
|
# default: 1080
|
||||||
port:
|
port:
|
||||||
# you can also set each field manually like below:
|
# you can also set each field manually like below:
|
||||||
- name: example_user2
|
- name: example_user2
|
||||||
id: 5058b990-6be5-438d-9c02-4b06b5d927d0
|
id: example_passwd2
|
||||||
alterid: 32
|
flow: xtls-rprx-direct
|
||||||
port: 6666
|
port: 6666
|
||||||
|
|
27
configure.py
27
configure.py
|
@ -13,18 +13,18 @@ CLIENT_OUTPUT_DIR = "clients"
|
||||||
DEFAULT_EMAIL = "dummy@dummy.org"
|
DEFAULT_EMAIL = "dummy@dummy.org"
|
||||||
CONF_FILE = "config.yml"
|
CONF_FILE = "config.yml"
|
||||||
SERVER_IN = "server.in"
|
SERVER_IN = "server.in"
|
||||||
SERVER_PATH = "v2ray"
|
SERVER_PATH = "xray"
|
||||||
SERVER_FN = "config.json"
|
SERVER_FN = "config.json"
|
||||||
NGINX_IN = "nginx.in"
|
NGINX_IN = "nginx.in"
|
||||||
NGINX_PATH = "nginx"
|
NGINX_PATH = "nginx"
|
||||||
NGINX_FN = "default"
|
NGINX_FN = "default"
|
||||||
DEFAULT_ALTERID = 64
|
|
||||||
CLIENT_OBJ_IN = "client_obj.in"
|
CLIENT_OBJ_IN = "client_obj.in"
|
||||||
CLIENT_CONF_IN = "client_conf.in"
|
CLIENT_CONF_IN = "client_conf.in"
|
||||||
DOCKER_IN = "docker-compose.in"
|
DOCKER_IN = "docker-compose.in"
|
||||||
WATCHTOWER_IN = "watchtower.in"
|
WATCHTOWER_IN = "watchtower.in"
|
||||||
DEFAULT_WATCHTOWER_ENABLE = False
|
DEFAULT_WATCHTOWER_ENABLE = False
|
||||||
DEFAULT_CLIENT_PORT = 1080
|
DEFAULT_CLIENT_PORT = 1080
|
||||||
|
DEFAULT_USER_FLOW = "xtls-rprx-direct"
|
||||||
|
|
||||||
def yaml_key_exists_else(mapping : [], name : str, other_val = None, nullable = True):
|
def yaml_key_exists_else(mapping : [], name : str, other_val = None, nullable = True):
|
||||||
if (name in mapping) and (mapping[name] != None):
|
if (name in mapping) and (mapping[name] != None):
|
||||||
|
@ -35,11 +35,15 @@ def yaml_key_exists_else(mapping : [], name : str, other_val = None, nullable =
|
||||||
else:
|
else:
|
||||||
return other_val
|
return other_val
|
||||||
|
|
||||||
|
def random_string(stringLength=16):
|
||||||
|
letters = string.ascii_lowercase
|
||||||
|
return ''.join(random.choice(letters) for i in range(stringLength))
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
def __init__(self, conf_obj):
|
def __init__(self, conf_obj):
|
||||||
self.name = str(yaml_key_exists_else(conf_obj, 'name', nullable=False))
|
self.name = str(yaml_key_exists_else(conf_obj, 'name', nullable=False))
|
||||||
self.id = str(yaml_key_exists_else(conf_obj, 'id', other_val=uuid.uuid4()))
|
self.id = str(yaml_key_exists_else(conf_obj, 'id', other_val=random_string()))
|
||||||
self.alterid = int(yaml_key_exists_else(conf_obj,'alterid', other_val=DEFAULT_ALTERID))
|
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))
|
self.port = int(yaml_key_exists_else(conf_obj, 'port', other_val=DEFAULT_CLIENT_PORT))
|
||||||
|
|
||||||
def print(self, ident):
|
def print(self, ident):
|
||||||
|
@ -49,18 +53,13 @@ class Client:
|
||||||
|
|
||||||
print(pre + "{")
|
print(pre + "{")
|
||||||
print(pre + " id: " + self.id)
|
print(pre + " id: " + self.id)
|
||||||
print(pre + " alterid: " + str(self.alterid))
|
print(pre + " flow: " + self.flow)
|
||||||
print(pre + " port: " + str(self.port))
|
print(pre + " port: " + str(self.port))
|
||||||
print(pre + "}")
|
print(pre + "}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@staticmethod
|
|
||||||
def __randomString(stringLength=16):
|
|
||||||
letters = string.ascii_lowercase
|
|
||||||
return ''.join(random.choice(letters) for i in range(stringLength))
|
|
||||||
|
|
||||||
def print(self):
|
def print(self):
|
||||||
print("Server configuration:")
|
print("Server configuration:")
|
||||||
print(" domain: " + self.domain)
|
print(" domain: " + self.domain)
|
||||||
|
@ -83,7 +82,7 @@ class Config:
|
||||||
self.subdomain_only = len(self.subdomain) > 0
|
self.subdomain_only = len(self.subdomain) > 0
|
||||||
self.uid = int(yaml_key_exists_else(conf_srv, 'uid', other_val=os.getuid()))
|
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.gid = int(yaml_key_exists_else(conf_srv, 'gid', other_val=os.getgid()))
|
||||||
self.path = str(yaml_key_exists_else(conf_srv, 'path', other_val=self.__randomString()))
|
self.path = str(yaml_key_exists_else(conf_srv, 'path', other_val=random_string()))
|
||||||
self.watchtower = bool(yaml_key_exists_else(conf_srv, 'watchtower', other_val=DEFAULT_WATCHTOWER_ENABLE))
|
self.watchtower = bool(yaml_key_exists_else(conf_srv, 'watchtower', other_val=DEFAULT_WATCHTOWER_ENABLE))
|
||||||
|
|
||||||
self.clients = []
|
self.clients = []
|
||||||
|
@ -118,7 +117,7 @@ def main():
|
||||||
if i > 0:
|
if i > 0:
|
||||||
clients += ",\n"
|
clients += ",\n"
|
||||||
clients += jinja2.Template(client_obj).render(id = conf.clients[i].id,
|
clients += jinja2.Template(client_obj).render(id = conf.clients[i].id,
|
||||||
alterid = conf.clients[i].alterid)
|
flow = conf.clients[i].flow)
|
||||||
template_dict['clients'] = clients
|
template_dict['clients'] = clients
|
||||||
|
|
||||||
print("Generating files...")
|
print("Generating files...")
|
||||||
|
@ -150,8 +149,8 @@ def main():
|
||||||
for i in range(len(conf.clients)):
|
for i in range(len(conf.clients)):
|
||||||
template_dict['id'] = conf.clients[i].id
|
template_dict['id'] = conf.clients[i].id
|
||||||
template_dict['port'] = conf.clients[i].port
|
template_dict['port'] = conf.clients[i].port
|
||||||
template_dict['alterid'] = conf.clients[i].alterid
|
template_dict['flow'] = conf.clients[i].flow
|
||||||
epath = os.path.join(path, conf.clients[i].name + "_" + conf.clients[i].id)
|
epath = os.path.join(path, conf.clients[i].name)
|
||||||
os.makedirs(epath, exist_ok=True)
|
os.makedirs(epath, exist_ok=True)
|
||||||
with open(os.path.join(epath, SERVER_FN), "w") as f:
|
with open(os.path.join(epath, SERVER_FN), "w") as f:
|
||||||
f.write(client_conf_temp.render(template_dict))
|
f.write(client_conf_temp.render(template_dict))
|
||||||
|
|
|
@ -1,18 +1,26 @@
|
||||||
version: '3.0'
|
version: '3.0'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
br-xray:
|
br-d2ray:
|
||||||
external: false
|
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:
|
services:
|
||||||
nginx:
|
d2ray_nginx:
|
||||||
container_name: xray_nginx
|
container_name: d2ray_nginx
|
||||||
image: linuxserver/swag
|
image: linuxserver/swag
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
networks:
|
networks:
|
||||||
- br-xray
|
- br-d2ray
|
||||||
environment:
|
environment:
|
||||||
- PUID={{ uid }}
|
- PUID={{ uid }}
|
||||||
- PGID={{ gid }}
|
- PGID={{ gid }}
|
||||||
|
@ -27,17 +35,26 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
volumes:
|
volumes:
|
||||||
- ./certs:/etc/letsencrypt/live/{{ domain }}
|
- ./nginx:/config
|
||||||
v2ray:
|
healthcheck:
|
||||||
container_name: xray_xray
|
test: ["CMD", "curl", "-f", "http://{{ subdomain }}.{{ domain }}:80"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 30
|
||||||
|
|
||||||
|
d2ray_xray:
|
||||||
|
container_name: d2ray_xray
|
||||||
image: teddysun/xray
|
image: teddysun/xray
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
d2ray_nginx:
|
||||||
|
condition: service_healthy
|
||||||
networks:
|
networks:
|
||||||
- br-v2ray
|
- br-v2ray
|
||||||
ports:
|
ports:
|
||||||
- 443:443
|
- 443:443
|
||||||
volumes:
|
volumes:
|
||||||
- ./xray/config.json:/etc/xray/config.json
|
- ./nginx/etc:/le-etc
|
||||||
- ./certs:/certs
|
- ./xray:/etc/xray
|
||||||
|
|
||||||
{{ watchtower }}
|
{{ watchtower }}
|
||||||
|
|
14
nginx.in
Normal file
14
nginx.in
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name {{ subdomain }}.{{ domain }};
|
||||||
|
|
||||||
|
if ($remote_addr = 127.0.0.1) {
|
||||||
|
root /config/www;
|
||||||
|
index index.html index.htm index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($remote_addr != 127.0.0.1) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
server.in
14
server.in
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"log": {
|
||||||
|
"loglevel": "warning",
|
||||||
|
"access": "/etc/xray/access.log",
|
||||||
|
"error": "/etc/xray/error.log"
|
||||||
|
},
|
||||||
"inbounds": [
|
"inbounds": [
|
||||||
{
|
{
|
||||||
"port": 443,
|
"port": 443,
|
||||||
|
@ -10,7 +15,7 @@
|
||||||
"decryption": "none",
|
"decryption": "none",
|
||||||
"fallbacks": [
|
"fallbacks": [
|
||||||
{
|
{
|
||||||
"dest": "xray_nginx:80"
|
"dest": "d2ray_nginx:80"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -18,10 +23,11 @@
|
||||||
"network": "tcp",
|
"network": "tcp",
|
||||||
"security": "xtls",
|
"security": "xtls",
|
||||||
"xtlsSettings": {
|
"xtlsSettings": {
|
||||||
"certificates:": [
|
"alpn": ["http/1.1", "h2"],
|
||||||
|
"certificates": [
|
||||||
{
|
{
|
||||||
"certificateFile": "/certs/fullchain.pem",
|
"certificateFile": "/le-etc/letsencrypt/live/{{ subdomain }}.{{ domain }}/fullchain.pem",
|
||||||
"keyFile": "/certs/privkey.pem"
|
"keyFile": "/le-etc/letsencrypt/live/{{ subdomain }}.{{ domain }}/privkey.pem"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user