qr
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
quackerd 2023-08-24 08:50:22 -04:00
parent e6c6e90619
commit 56401b1391
5 changed files with 42 additions and 9 deletions

View File

@ -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

View File

@ -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.

View File

@ -9,6 +9,7 @@ services:
ports:
- 8443:8443
environment:
- HOST=myvps.com
- PORT=8443
- TARGET_HOST=www.apple.com
- TARGET_PORT=443

View File

@ -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()

View File

@ -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=$?