qr
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
e6c6e90619
commit
56401b1391
|
@ -3,7 +3,7 @@ FROM alpine:latest
|
||||||
ENV VER_XRAY 1.8.3
|
ENV VER_XRAY 1.8.3
|
||||||
|
|
||||||
# install packages
|
# install packages
|
||||||
RUN set -xe && apk add --no-cache unzip wget openssl python3 py3-jinja2 supervisor apache2-utils bash
|
RUN set -xe && apk add --no-cache unzip wget openssl python3 py3-jinja2 supervisor apache2-utils bash libqrencode
|
||||||
|
|
||||||
# download packages
|
# download packages
|
||||||
RUN set -xe && \
|
RUN set -xe && \
|
||||||
|
@ -14,11 +14,6 @@ RUN set -xe && \
|
||||||
|
|
||||||
COPY ./opt /opt/
|
COPY ./opt /opt/
|
||||||
|
|
||||||
# nginx
|
|
||||||
# RUN set -xe && addgroup www && \
|
|
||||||
# adduser -H -D -S -s /bin/false www -G www && \
|
|
||||||
# chown -R www:www /opt/nginx
|
|
||||||
|
|
||||||
# remove packages
|
# remove packages
|
||||||
RUN set -xe && apk del unzip wget
|
RUN set -xe && apk del unzip wget
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ d2ray is a single Docker container that provides easy 5-minute setups and braind
|
||||||
## Quickstart
|
## Quickstart
|
||||||
1. You can start with the example `docker-compose.yml` from this repo.
|
1. You can start with the example `docker-compose.yml` from this repo.
|
||||||
2. Adjust environment variables:
|
2. Adjust environment variables:
|
||||||
|
- `HOST`: the hostname/IP of the server. `REQUIRED`.
|
||||||
- `PORT`: the port Xray listens on. `Optional, default = 443`.
|
- `PORT`: the port Xray listens on. `Optional, default = 443`.
|
||||||
- `TARGET_HOST`: the target host to redirect non proxy connections. `Required`.
|
- `TARGET_HOST`: the target host to redirect non proxy connections. `Required`.
|
||||||
- `TARGET_PORT`: the target port to redirect non proxy connections. `Optional, default = 443`.
|
- `TARGET_PORT`: the target port to redirect non proxy connections. `Optional, default = 443`.
|
||||||
|
@ -14,13 +15,14 @@ d2ray is a single Docker container that provides easy 5-minute setups and braind
|
||||||
- `USERS`: comma separated list of usernames that can access Xray. `Required`.
|
- `USERS`: comma separated list of usernames that can access Xray. `Required`.
|
||||||
- `LOG_LEVEL`: the verbosity of Xray logs. `Optional, default = warn`.
|
- `LOG_LEVEL`: the verbosity of Xray logs. `Optional, default = warn`.
|
||||||
3. `docker compose up -d`
|
3. `docker compose up -d`
|
||||||
4. Test your connection.
|
4. Check the container log using `docker logs` for per user shareable links and QR codes supported by most Xray apps. These can also be found under `/etc/xray/users/[USERNAME]` folders.
|
||||||
|
5. Test your connection.
|
||||||
|
|
||||||
## Docker Volume
|
## Docker Volume
|
||||||
The logs and private key are stored in `/etc/d2ray` in the container. You can mount an external folder to that location to persist settings. Otherwise d2ray creates an anonymous Docker volume.
|
The logs and private key are stored in `/etc/d2ray` in the container. You can mount an external folder to that location to persist settings. Otherwise d2ray creates an anonymous Docker volume.
|
||||||
|
|
||||||
## Key Generation
|
## Key Generation
|
||||||
If `PRIVATE_KEY` is provided, d2ray uses that key. Otherwise, d2ray generates a new key pair and persists it in `/etc/xray/certs/keys`. The corresponding public key is always printed to the container log (`docker logs`), which clients use to connect.
|
If `PRIVATE_KEY` is provided, d2ray uses that key. Otherwise, d2ray generates a new key pair and persists it in `/etc/xray/certs/keys`. The corresponding public key is always printed to the container log, which clients use to connect.
|
||||||
|
|
||||||
To make d2ray regenerate a new key pair, manually delete the key file `/etc/xray/certs/keys` from the mounted volume.
|
To make d2ray regenerate a new key pair, manually delete the key file `/etc/xray/certs/keys` from the mounted volume.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- 8443:8443
|
- 8443:8443
|
||||||
environment:
|
environment:
|
||||||
|
- HOST=myvps.com
|
||||||
- PORT=8443
|
- PORT=8443
|
||||||
- TARGET_HOST=www.apple.com
|
- TARGET_HOST=www.apple.com
|
||||||
- TARGET_PORT=443
|
- TARGET_PORT=443
|
||||||
|
|
36
opt/init.py
36
opt/init.py
|
@ -2,15 +2,18 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import jinja2
|
import jinja2
|
||||||
import random
|
import random
|
||||||
|
import sys
|
||||||
import string
|
import string
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
CONFIG_DIR = pathlib.Path("/etc/d2ray")
|
CONFIG_DIR = pathlib.Path("/etc/d2ray")
|
||||||
KEY_FILE = CONFIG_DIR.joinpath("certs/keys")
|
KEY_FILE = CONFIG_DIR.joinpath("certs/keys")
|
||||||
LOG_DIR = CONFIG_DIR.joinpath("logs")
|
LOG_DIR = CONFIG_DIR.joinpath("logs")
|
||||||
|
QR_DIR = CONFIG_DIR.joinpath("users")
|
||||||
XRAY_BIN = pathlib.Path("/opt/xray/xray")
|
XRAY_BIN = pathlib.Path("/opt/xray/xray")
|
||||||
|
|
||||||
class d2args:
|
class d2args:
|
||||||
|
host : str
|
||||||
port : int
|
port : int
|
||||||
target_port : int
|
target_port : int
|
||||||
target_host : str
|
target_host : str
|
||||||
|
@ -52,6 +55,7 @@ class d2args:
|
||||||
return (skey.strip(), pkey.strip())
|
return (skey.strip(), pkey.strip())
|
||||||
|
|
||||||
def _from_env(self) -> None:
|
def _from_env(self) -> None:
|
||||||
|
self.host = self._get_env("HOST")
|
||||||
self.target_host = self._get_env("TARGET_HOST")
|
self.target_host = self._get_env("TARGET_HOST")
|
||||||
self.target_sni = self._get_env("TARGET_SNI").split(",")
|
self.target_sni = self._get_env("TARGET_SNI").split(",")
|
||||||
self.users = self._get_env("USERS").split(",")
|
self.users = self._get_env("USERS").split(",")
|
||||||
|
@ -76,7 +80,8 @@ class d2args:
|
||||||
_ , self.public_key = self._parse_xray_x25519_output(subprocess.check_output(f"{XRAY_BIN} x25519 -i {self.private_key}", shell = True).decode())
|
_ , self.public_key = self._parse_xray_x25519_output(subprocess.check_output(f"{XRAY_BIN} x25519 -i {self.private_key}", shell = True).decode())
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
ret = (f"Port: {self.port}\n"
|
ret = (f"Host: {self.host}\n"
|
||||||
|
f"Port: {self.port}\n"
|
||||||
f"Target Port: {self.target_port}\n"
|
f"Target Port: {self.target_port}\n"
|
||||||
f"Target Host: {self.target_host}\n"
|
f"Target Host: {self.target_host}\n"
|
||||||
f"Target SNI: {', '.join(self.target_sni)}\n"
|
f"Target SNI: {', '.join(self.target_sni)}\n"
|
||||||
|
@ -85,6 +90,19 @@ class d2args:
|
||||||
f"Public Key: {self.public_key}"
|
f"Public Key: {self.public_key}"
|
||||||
)
|
)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_shareable_links(self) -> dict[str, str]:
|
||||||
|
ret = {}
|
||||||
|
for user in self.users:
|
||||||
|
ret[user] = (f"vless://{user}@{self.host}:{self.port}/?"
|
||||||
|
"flow=xtls-rprx-vision&"
|
||||||
|
"type=tcp&security=reality&"
|
||||||
|
"fp=chrome&"
|
||||||
|
f"sni={','.join(self.target_sni)}&"
|
||||||
|
f"pbk={self.public_key}#"
|
||||||
|
f"{self.host}"
|
||||||
|
)
|
||||||
|
return ret
|
||||||
|
|
||||||
def process_directory(path : str, vars : dict[str, str], delete_template : bool = True) -> None:
|
def process_directory(path : str, vars : dict[str, str], delete_template : bool = True) -> None:
|
||||||
for f in os.listdir(path):
|
for f in os.listdir(path):
|
||||||
|
@ -133,6 +151,22 @@ def main():
|
||||||
print(f"Processing config files...", flush=True)
|
print(f"Processing config files...", flush=True)
|
||||||
process_directory("/opt/xray", template)
|
process_directory("/opt/xray", template)
|
||||||
|
|
||||||
|
print(f"Generating shareable links...", flush=True)
|
||||||
|
links = args.get_shareable_links()
|
||||||
|
|
||||||
|
for user, link in links.items():
|
||||||
|
dir = QR_DIR.joinpath(user)
|
||||||
|
os.makedirs(str(dir), exist_ok=True)
|
||||||
|
linkf = dir.joinpath("link.txt")
|
||||||
|
with open(str(linkf), "w") as f:
|
||||||
|
f.write(link + "\n")
|
||||||
|
subprocess.check_output(f"qrencode -o {str(dir.joinpath('qrcode.png'))} < {linkf}", shell=True)
|
||||||
|
print("")
|
||||||
|
print(f"User \"{user}\":", flush=True)
|
||||||
|
print(f"{link}")
|
||||||
|
print(subprocess.check_output(f"qrencode -t ansiutf8 < {linkf}", shell=True).decode())
|
||||||
|
print("")
|
||||||
|
|
||||||
print(f"Initialization completed.\n", flush=True)
|
print(f"Initialization completed.\n", flush=True)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
mkdir -p /etc/d2ray/logs/xray
|
mkdir -p /etc/d2ray/logs/xray
|
||||||
mkdir -p /etc/d2ray/logs/supervisord
|
mkdir -p /etc/d2ray/logs/supervisord
|
||||||
mkdir -p /etc/d2ray/certs
|
mkdir -p /etc/d2ray/certs
|
||||||
|
rm -rf /etc/d2ray/users
|
||||||
|
|
||||||
python3 /opt/init.py
|
python3 /opt/init.py
|
||||||
retval=$?
|
retval=$?
|
||||||
|
|
Loading…
Reference in New Issue