This commit is contained in:
parent
e6c6e90619
commit
56401b1391
@ -3,7 +3,7 @@ FROM alpine:latest
|
||||
ENV VER_XRAY 1.8.3
|
||||
|
||||
# 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
|
||||
RUN set -xe && \
|
||||
@ -14,11 +14,6 @@ RUN set -xe && \
|
||||
|
||||
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
|
||||
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
|
||||
1. You can start with the example `docker-compose.yml` from this repo.
|
||||
2. Adjust environment variables:
|
||||
- `HOST`: the hostname/IP of the server. `REQUIRED`.
|
||||
- `PORT`: the port Xray listens on. `Optional, default = 443`.
|
||||
- `TARGET_HOST`: the target host to redirect non proxy connections. `Required`.
|
||||
- `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`.
|
||||
- `LOG_LEVEL`: the verbosity of Xray logs. `Optional, default = warn`.
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
|
@ -9,6 +9,7 @@ services:
|
||||
ports:
|
||||
- 8443:8443
|
||||
environment:
|
||||
- HOST=myvps.com
|
||||
- PORT=8443
|
||||
- TARGET_HOST=www.apple.com
|
||||
- TARGET_PORT=443
|
||||
|
36
opt/init.py
36
opt/init.py
@ -2,15 +2,18 @@ import os
|
||||
import subprocess
|
||||
import jinja2
|
||||
import random
|
||||
import sys
|
||||
import string
|
||||
import pathlib
|
||||
|
||||
CONFIG_DIR = pathlib.Path("/etc/d2ray")
|
||||
KEY_FILE = CONFIG_DIR.joinpath("certs/keys")
|
||||
LOG_DIR = CONFIG_DIR.joinpath("logs")
|
||||
QR_DIR = CONFIG_DIR.joinpath("users")
|
||||
XRAY_BIN = pathlib.Path("/opt/xray/xray")
|
||||
|
||||
class d2args:
|
||||
host : str
|
||||
port : int
|
||||
target_port : int
|
||||
target_host : str
|
||||
@ -52,6 +55,7 @@ class d2args:
|
||||
return (skey.strip(), pkey.strip())
|
||||
|
||||
def _from_env(self) -> None:
|
||||
self.host = self._get_env("HOST")
|
||||
self.target_host = self._get_env("TARGET_HOST")
|
||||
self.target_sni = self._get_env("TARGET_SNI").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())
|
||||
|
||||
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 Host: {self.target_host}\n"
|
||||
f"Target SNI: {', '.join(self.target_sni)}\n"
|
||||
@ -85,6 +90,19 @@ class d2args:
|
||||
f"Public Key: {self.public_key}"
|
||||
)
|
||||
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:
|
||||
for f in os.listdir(path):
|
||||
@ -133,6 +151,22 @@ def main():
|
||||
print(f"Processing config files...", flush=True)
|
||||
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)
|
||||
|
||||
main()
|
||||
|
@ -3,6 +3,7 @@
|
||||
mkdir -p /etc/d2ray/logs/xray
|
||||
mkdir -p /etc/d2ray/logs/supervisord
|
||||
mkdir -p /etc/d2ray/certs
|
||||
rm -rf /etc/d2ray/users
|
||||
|
||||
python3 /opt/init.py
|
||||
retval=$?
|
||||
|
Loading…
Reference in New Issue
Block a user