├── .github └── workflows │ └── auto-deploy.yml ├── .trivyignore ├── Dockerfile ├── README.md └── files ├── config.json ├── index.js ├── package.json ├── server ├── swith └── web /.github/workflows/auto-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Redeploy Choreo 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 */3 * * *' 7 | 8 | jobs: 9 | Redeploy: 10 | name: Redeploy Choreo 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4.0.0 16 | with: 17 | fetch-depth: 1 18 | 19 | - name: Renew README.md 20 | run: | 21 | DATE=$(date "+%Y/%m/%d %H:%M:%S") 22 | echo "${DATE}" > README.md 23 | git checkout --orphan tmp_work 24 | git branch -d main 25 | echo "DATE=${DATE}" >> $GITHUB_ENV 26 | 27 | - name: Upload to repository 28 | uses: stefanzweifel/git-auto-commit-action@v4.16.0 29 | with: 30 | commit_message: Auto deploy by Github Actions, ${{ env.DATE }} 31 | create_branch: true 32 | branch: main 33 | push_options: --force 34 | 35 | - name: Delete old workflow runs 36 | uses: MajorScruffy/delete-old-workflow-runs@v0.3.0 37 | env: 38 | GITHUB_TOKEN: ${{ github.token }} 39 | with: 40 | repository: ${{ github.repository }} 41 | older-than-seconds: 3600 42 | -------------------------------------------------------------------------------- /.trivyignore: -------------------------------------------------------------------------------- 1 | CVE-2022-2216 2 | CVE-2022-2900 3 | CVE-2023-25755 4 | CVE-2023-38408 5 | CVE-2023-28531 6 | CVE-2023-51385 7 | CVE-2023-43644 8 | CVE-2024-32002 9 | CVE-2024-45490 10 | CVE-2024-45491 11 | CVE-2024-45492 12 | CVE-2024-45490 13 | CVE-2024-45491 14 | CVE-2024-45492 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | WORKDIR /home/choreouser 4 | 5 | EXPOSE 3000 6 | 7 | COPY files/* /home/choreouser/ 8 | 9 | RUN apt-get update &&\ 10 | apt install --only-upgrade linux-libc-dev &&\ 11 | apt-get install -y iproute2 vim netcat-openbsd &&\ 12 | addgroup --gid 10008 choreo &&\ 13 | adduser --disabled-password --no-create-home --uid 10008 --ingroup choreo choreouser &&\ 14 | usermod -aG sudo choreouser &&\ 15 | chmod +x index.js swith web server &&\ 16 | npm install 17 | 18 | CMD [ "node", "index.js" ] 19 | 20 | USER 10008 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2025/06/02 09:09:44 2 | -------------------------------------------------------------------------------- /files/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "log":{ 3 | "access":"/dev/null", 4 | "error":"/dev/null", 5 | "loglevel":"none" 6 | }, 7 | "inbounds":[ 8 | { 9 | "port":8080, 10 | "protocol":"vless", 11 | "settings":{ 12 | "clients":[ 13 | { 14 | "id":"986e0d08-b275-4dd3-9e75-f3094b36fa2a", 15 | "flow":"xtls-rprx-vision" 16 | } 17 | ], 18 | "decryption":"none", 19 | "fallbacks":[ 20 | { 21 | "dest":3001 22 | }, 23 | { 24 | "path":"/vless-argo", 25 | "dest":3002 26 | }, 27 | { 28 | "path":"/vmess-argo", 29 | "dest":3003 30 | }, 31 | { 32 | "path":"/trojan-argo", 33 | "dest":3004 34 | } 35 | ] 36 | }, 37 | "streamSettings":{ 38 | "network":"tcp" 39 | } 40 | }, 41 | { 42 | "port":3001, 43 | "listen":"127.0.0.1", 44 | "protocol":"vless", 45 | "settings":{ 46 | "clients":[ 47 | { 48 | "id":"986e0d08-b275-4dd3-9e75-f3094b36fa2a" 49 | } 50 | ], 51 | "decryption":"none" 52 | }, 53 | "streamSettings":{ 54 | "network":"ws", 55 | "security":"none" 56 | } 57 | }, 58 | { 59 | "port":3002, 60 | "listen":"127.0.0.1", 61 | "protocol":"vless", 62 | "settings":{ 63 | "clients":[ 64 | { 65 | "id":"986e0d08-b275-4dd3-9e75-f3094b36fa2a", 66 | "level":0 67 | } 68 | ], 69 | "decryption":"none" 70 | }, 71 | "streamSettings":{ 72 | "network":"ws", 73 | "security":"none", 74 | "wsSettings":{ 75 | "path":"/vless-argo" 76 | } 77 | }, 78 | "sniffing":{ 79 | "enabled":true, 80 | "destOverride":[ 81 | "http", 82 | "tls", 83 | "quic" 84 | ], 85 | "metadataOnly":false 86 | } 87 | }, 88 | { 89 | "port":3003, 90 | "listen":"127.0.0.1", 91 | "protocol":"vmess", 92 | "settings":{ 93 | "clients":[ 94 | { 95 | "id":"986e0d08-b275-4dd3-9e75-f3094b36fa2a", 96 | "alterId":0 97 | } 98 | ] 99 | }, 100 | "streamSettings":{ 101 | "network":"ws", 102 | "wsSettings":{ 103 | "path":"/vmess-argo" 104 | } 105 | }, 106 | "sniffing":{ 107 | "enabled":true, 108 | "destOverride":[ 109 | "http", 110 | "tls", 111 | "quic" 112 | ], 113 | "metadataOnly":false 114 | } 115 | }, 116 | { 117 | "port":3004, 118 | "listen":"127.0.0.1", 119 | "protocol":"trojan", 120 | "settings":{ 121 | "clients":[ 122 | { 123 | "password":"986e0d08-b275-4dd3-9e75-f3094b36fa2a" 124 | } 125 | ] 126 | }, 127 | "streamSettings":{ 128 | "network":"ws", 129 | "security":"none", 130 | "wsSettings":{ 131 | "path":"/trojan-argo" 132 | } 133 | }, 134 | "sniffing":{ 135 | "enabled":true, 136 | "destOverride":[ 137 | "http", 138 | "tls", 139 | "quic" 140 | ], 141 | "metadataOnly":false 142 | } 143 | } 144 | ], 145 | "dns":{ 146 | "servers":[ 147 | "https+local://8.8.8.8/dns-query" 148 | ] 149 | }, 150 | "outbounds": [ 151 | { 152 | "protocol": "freedom", 153 | "tag": "direct" 154 | }, 155 | { 156 | "protocol": "blackhole", 157 | "tag": "block" 158 | } 159 | ] 160 | } 161 | -------------------------------------------------------------------------------- /files/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const { exec, execSync } = require('child_process'); 4 | const port = process.env.SERVER_PORT || process.env.PORT || 3000; 5 | const UUID = process.env.UUID || '986e0d08-b275-4dd3-9e75-f3094b36fa2a'; //若需要改UUID,需要在config.json里改为一致 6 | const NEZHA_SERVER = process.env.NEZHA_SERVER || 'nz.f4i.cn'; 7 | const NEZHA_PORT = process.env.NEZHA_PORT || '5555'; // 哪吒端口为{443,8443,2096,2087,2083,2053}其中之一开启tls 8 | const NEZHA_KEY = process.env.NEZHA_KEY || 'N9BVoBfucVIrIzCBt8'; // 没用哪吒,把这个参数空着 9 | const ARGO_DOMAIN = process.env.ARGO_DOMAIN || 'choreo.zzx.free.hr'; // 建议使用token,argo端口8080,cf后台设置需对应,使用json需上传json和yml文件至files目录 10 | const ARGO_AUTH = process.env.ARGO_AUTH || 'eyJhIjoiOGI5NzI0MDgwZTU1ZTcwMzcwZmI3NDI4NzkyMmYzMWIiLCJ0IjoiOGNlY2VlYzQtYzZiNi00N2VkLThhZjItY2I4MThmMDkxZWJkIiwicyI6Ik5XWTFNV1ZsWm1NdFpEYzJZeTAwWkdSaExUbGtZall0TnpneVpqZ3haVE00WkRBNSJ9'; 11 | const CFIP = process.env.CFIP || 'www.visa.com.tw'; 12 | const NAME = process.env.NAME || 'Choreo'; 13 | 14 | // root route 15 | app.get("/", function(req, res) { 16 | res.send("Hello world!"); 17 | }); 18 | 19 | const metaInfo = execSync( 20 | 'curl -s https://speed.cloudflare.com/meta | awk -F\\" \'{print $26"-"$18}\' | sed -e \'s/ /_/g\'', 21 | { encoding: 'utf-8' } 22 | ); 23 | const ISP = metaInfo.trim(); 24 | 25 | // sub subscription 26 | app.get('/sub', (req, res) => { 27 | const VMESS = { v: '2', ps: `${NAME}-${ISP}`, add: CFIP, port: '443', id: UUID, aid: '0', scy: 'none', net: 'ws', type: 'none', host: ARGO_DOMAIN, path: '/vmess-argo?ed=2048', tls: 'tls', sni: ARGO_DOMAIN, alpn: '' }; 28 | const vlessURL = `vless://${UUID}@${CFIP}:443?encryption=none&security=tls&sni=${ARGO_DOMAIN}&type=ws&host=${ARGO_DOMAIN}&path=%2Fvless-argo%3Fed%3D2048#${NAME}-${ISP}`; 29 | const vmessURL = `vmess://${Buffer.from(JSON.stringify(VMESS)).toString('base64')}`; 30 | const trojanURL = `trojan://${UUID}@${CFIP}:443?security=tls&sni=${ARGO_DOMAIN}&type=ws&host=${ARGO_DOMAIN}&path=%2Ftrojan-argo%3Fed%3D2048#${NAME}-${ISP}`; 31 | 32 | const base64Content = Buffer.from(`${vlessURL}\n\n${vmessURL}\n\n${trojanURL}`).toString('base64'); 33 | 34 | res.type('text/plain; charset=utf-8').send(base64Content); 35 | }); 36 | 37 | // run-nezha 38 | let NEZHA_TLS = ''; 39 | if (NEZHA_SERVER && NEZHA_PORT && NEZHA_KEY) { 40 | const tlsPorts = ['443', '8443', '2096', '2087', '2083', '2053']; 41 | if (tlsPorts.includes(NEZHA_PORT)) { 42 | NEZHA_TLS = '--tls'; 43 | } else { 44 | NEZHA_TLS = ''; 45 | } 46 | const command = `nohup ./swith -s ${NEZHA_SERVER}:${NEZHA_PORT} -p ${NEZHA_KEY} ${NEZHA_TLS} >/dev/null 2>&1 &`; 47 | try { 48 | exec(command); 49 | console.log('swith is running'); 50 | 51 | setTimeout(() => { 52 | runWeb(); 53 | }, 2000); 54 | } catch (error) { 55 | console.error(`swith running error: ${error}`); 56 | } 57 | } else { 58 | console.log('NEZHA variable is empty, skip running'); 59 | runWeb(); 60 | } 61 | 62 | // run-xr-ay 63 | function runWeb() { 64 | const command1 = `nohup ./web -c ./config.json >/dev/null 2>&1 &`; 65 | exec(command1, (error) => { 66 | if (error) { 67 | console.error(`web running error: ${error}`); 68 | } else { 69 | console.log('web is running'); 70 | 71 | setTimeout(() => { 72 | runServer(); 73 | }, 2000); 74 | } 75 | }); 76 | } 77 | 78 | // run-server 79 | function runServer() { 80 | let command2 = ''; 81 | if (ARGO_AUTH.match(/^[A-Z0-9a-z=]{120,250}$/)) { 82 | command2 = `nohup ./server tunnel --region us --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH} >/dev/null 2>&1 &`; 83 | } else { 84 | command2 = `nohup ./server tunnel --region us --edge-ip-version auto --config tunnel.yml run >/dev/null 2>&1 &`; 85 | } 86 | 87 | exec(command2, (error) => { 88 | if (error) { 89 | console.error(`server running error: ${error}`); 90 | } else { 91 | console.log('server is running'); 92 | } 93 | }); 94 | } 95 | 96 | app.listen(port, () => console.log(`App is listening on port ${port}!`)); 97 | -------------------------------------------------------------------------------- /files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Choreo", 3 | "version": "1.0.0", 4 | "description": "nodejs", 5 | "main": "index.js", 6 | "author": "eooce", 7 | "license": "MIT", 8 | "private": false, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "start": "node index.js" 12 | }, 13 | "dependencies": { 14 | "express": "^4.18.2" 15 | }, 16 | "engines": { 17 | "node": ">=14" 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /files/server: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eooce/choreo-2go/43f140e4e9843f3c15f87e042b4a76a1d8f670ad/files/server -------------------------------------------------------------------------------- /files/swith: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eooce/choreo-2go/43f140e4e9843f3c15f87e042b4a76a1d8f670ad/files/swith -------------------------------------------------------------------------------- /files/web: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eooce/choreo-2go/43f140e4e9843f3c15f87e042b4a76a1d8f670ad/files/web --------------------------------------------------------------------------------