From 976648fdc322775ff722771e2150153171975c8b Mon Sep 17 00:00:00 2001 From: mercury Date: Mon, 19 Feb 2024 11:56:07 +0400 Subject: [PATCH] NaiveProxy --- app/bot.php | 122 +++++++++++++++++++++++++++++++++++- app/i18n.php | 8 +++ config/Caddyfile | 19 ++++++ config/upstream.conf | 8 +++ docker-compose.yml | 27 ++++++++ dockerfile/naive.dockerfile | 9 +++ makefile | 2 + scripts/start_np.sh | 5 ++ 8 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 config/Caddyfile create mode 100644 dockerfile/naive.dockerfile create mode 100644 scripts/start_np.sh diff --git a/app/bot.php b/app/bot.php index c2897f9..471bf24 100644 --- a/app/bot.php +++ b/app/bot.php @@ -117,7 +117,7 @@ class Bot case preg_match('~^/menu (?Paddpeer) (?P(?:-)?\d+)$~', $this->input['callback'], $m): case preg_match('~^/menu (?Pwg) (?P(?:-)?\d+)$~', $this->input['callback'], $m): case preg_match('~^/menu (?Pclient) (?P\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m): - case preg_match('~^/menu (?Ppac|adguard|config|ss|lang|oc)$~', $this->input['callback'], $m): + case preg_match('~^/menu (?Ppac|adguard|config|ss|lang|oc|naive)$~', $this->input['callback'], $m): case preg_match('~^/menu (?Psubzoneslist|reverselist|includelist|excludelist) (?P(?:-)?\d+)$~', $this->input['callback'], $m): $this->menu(type: $m['type'] ?? false, arg: $m['arg'] ?? false); break; @@ -187,6 +187,12 @@ class Bot case preg_match('~^/changeOcPass$~', $this->input['callback'], $m): $this->changeOcPass(); break; + case preg_match('~^/changeNaiveUser$~', $this->input['callback'], $m): + $this->changeNaiveUser(); + break; + case preg_match('~^/changeNaivePass$~', $this->input['callback'], $m): + $this->changeNaivePass(); + break; case preg_match('~^/changeOcDns$~', $this->input['callback'], $m): $this->changeOcDns(); break; @@ -562,6 +568,38 @@ class Bot ]; } + public function changeNaiveUser() + { + $r = $this->send( + $this->input['chat'], + "@{$this->input['username']} enter login", + $this->input['message_id'], + reply: 'enter password', + ); + $_SESSION['reply'][$r['result']['message_id']] = [ + 'start_message' => $this->input['message_id'], + 'start_callback' => $this->input['callback_id'], + 'callback' => 'chnplogin', + 'args' => [], + ]; + } + + public function changeNaivePass() + { + $r = $this->send( + $this->input['chat'], + "@{$this->input['username']} enter pass", + $this->input['message_id'], + reply: 'enter password', + ); + $_SESSION['reply'][$r['result']['message_id']] = [ + 'start_message' => $this->input['message_id'], + 'start_callback' => $this->input['callback_id'], + 'callback' => 'chnppass', + 'args' => [], + ]; + } + public function addOcUser() { $r = $this->send( @@ -585,6 +623,16 @@ class Bot $this->ssh('ocserv -c /etc/ocserv/ocserv.conf', 'oc'); } + public function restartNaive() + { + $pac = $this->getPacConf(); + $this->ssh('pkill caddy', 'np'); + $c = file_get_contents('/config/Caddyfile'); + $t = preg_replace('~^(\t+)?basic_auth[^\n]+~sm', '$1basic_auth ' . ($pac['naive']['user'] ?? '_') . ' ' . ($pac['naive']['pass'] ?? '__'), $c); + file_put_contents('/config/Caddyfile', $t); + $this->ssh('caddy run -c /config/Caddyfile > /dev/null 2>&1 &', 'np', false); + } + public function chocdns($dns) { $c = file_get_contents('/config/ocserv.conf'); @@ -593,6 +641,24 @@ class Bot $this->menu('oc'); } + public function chnplogin($user) + { + $pac = $this->getPacConf(); + $pac['naive']['user'] = $user; + $this->setPacConf($pac); + $this->restartNaive(); + $this->menu('naive'); + } + + public function chnppass($pass) + { + $pac = $this->getPacConf(); + $pac['naive']['pass'] = $pass; + $this->setPacConf($pac); + $this->restartNaive(); + $this->menu('naive'); + } + public function chockey($pass) { $c = file_get_contents('/config/ocserv.conf'); @@ -965,6 +1031,9 @@ class Bot $switch_amnezia = 1; } $this->setPacConf($json['pac']); + $out[] = 'update naiveproxy'; + $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); + $this->restartNaive(); $this->pacUpdate('1'); } // wg @@ -1019,6 +1088,7 @@ class Bot } if (!empty($json['pac']['domain'])) { $this->setUpstreamDomainOcserv($json['pac']['domain']); + $this->setUpstreamDomainNaive($json['pac']['domain']); } // nginx $out[] = 'reset nginx'; @@ -1344,6 +1414,7 @@ class Bot $this->setPacConf($conf); $this->chocdomain($domain); $this->setUpstreamDomainOcserv($domain); + $this->setUpstreamDomainNaive($domain); } else { file_put_contents('/config/nginx.conf', $nginx); } @@ -1426,7 +1497,7 @@ class Bot $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); $adguardClient = $this->getPacConf()['adguardkey']; $adguardClient = $adguardClient ? "-d $adguardClient.{$conf['domain']}" : ''; - exec("certbot certonly --force-renew --preferred-chain 'ISRG Root X1' -n --agree-tos --email mail@{$conf['domain']} -d {$conf['domain']} -d oc.{$conf['domain']} $adguardClient --webroot -w /certs/ --logs-dir /logs --max-log-backups 0 2>&1", $out, $code); + exec("certbot certonly --force-renew --preferred-chain 'ISRG Root X1' -n --agree-tos --email mail@{$conf['domain']} -d {$conf['domain']} -d oc.{$conf['domain']} -d np.{$conf['domain']} $adguardClient --webroot -w /certs/ --logs-dir /logs --max-log-backups 0 2>&1", $out, $code); if ($code > 0) { $this->send($this->input['chat'], "ERROR\n" . implode("\n", $out)); break; @@ -1461,6 +1532,9 @@ class Bot $out[] = 'Restart ocserv'; $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); $this->restartOcserv(file_get_contents('/config/ocserv.conf')); + $out[] = 'Restart NaiveProxy'; + $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); + $this->restartNaive(); $out[] = 'Restart Adguard Home'; $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); $out[] = $this->stopAd(); @@ -2862,10 +2936,16 @@ DNS-over-HTTPS with IP: 'callback_data' => "/menu pac", ], ], + [ + [ + 'text' => $this->i18n('naive'), + 'callback_data' => "/menu naive", + ], + ], [ [ 'text' => $this->i18n('chat'), - 'url' => "https://t.me/vpnbot_group", + 'url' => "https://t.me/+bUuWfsKzaMZhNjQy", ], [ 'text' => $this->i18n('donate'), @@ -2887,6 +2967,7 @@ DNS-over-HTTPS with IP: 'ss' => $type == 'ss' ? $this->menuSS() : false, 'lang' => $type == 'lang' ? $this->menuLang() : false, 'oc' => $type == 'oc' ? $this->ocMenu() : false, + 'naive' => $type == 'naive' ? $this->naiveMenu() : false, ]; $text = $menu[$type ?: 'main' ]['text']; @@ -2926,6 +3007,34 @@ DNS-over-HTTPS with IP: return "vless://{$c['inbounds'][0]['settings']['clients'][0]['id']}@$domain:443?security=reality&sni={$c['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0]}&fp=chrome&pbk={$pac['xray']}&sid={$c['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0]}&type=tcp&flow=xtls-rprx-vision#vpnbot"; } + public function naiveMenu() + { + $pac = $this->getPacConf(); + $text[] = "Menu -> NaiveProxy"; + $text[] = "user: {$pac['naive']['user']}"; + $text[] = "password: {$pac['naive']['pass']}"; + $data[] = [ + [ + 'text' => $this->i18n('change login'), + 'callback_data' => "/changeNaiveUser", + ], + [ + 'text' => $this->i18n('change password'), + 'callback_data' => "/changeNaivePass", + ], + ]; + $data[] = [ + [ + 'text' => $this->i18n('back'), + 'callback_data' => "/menu", + ], + ]; + return [ + 'text' => implode("\n", $text), + 'data' => $data, + ]; + } + public function ocMenu() { $pac = $this->getPacConf(); @@ -3094,6 +3203,13 @@ DNS-over-HTTPS with IP: file_put_contents('/config/upstream.conf', $t); $this->ssh("nginx -s reload 2>&1", 'up'); } + public function setUpstreamDomainNaive($domain) + { + $nginx = file_get_contents('/config/upstream.conf'); + $t = preg_replace('~#naive.+#naive~s', $domain ? "#naive\nnp.$domain naive;\n#naive" : "#naive\n#np.\$domain naive;\n#naive", $nginx); + file_put_contents('/config/upstream.conf', $t); + $this->ssh("nginx -s reload 2>&1", 'up'); + } public function addWg($page) { diff --git a/app/i18n.php b/app/i18n.php index 29bac9a..0caa44b 100644 --- a/app/i18n.php +++ b/app/i18n.php @@ -277,6 +277,14 @@ $i = [ 'en' => 'OpenConnect', 'ru' => 'OpenConnect', ], + 'naive' => [ + 'en' => 'NaiveProxy', + 'ru' => 'NaiveProxy', + ], + 'change login' => [ + 'en' => 'change login', + 'ru' => 'изменить логин', + ], 'change secret' => [ 'en' => 'change secret', 'ru' => 'секретное слово', diff --git a/config/Caddyfile b/config/Caddyfile new file mode 100644 index 0000000..9985a85 --- /dev/null +++ b/config/Caddyfile @@ -0,0 +1,19 @@ +{ + order forward_proxy before file_server + servers { + listener_wrappers { + proxy_protocol + tls + } + } +} + +:443 { + tls /certs/cert_public /certs/cert_private + forward_proxy { + basic_auth _ __ + hide_ip + hide_via + probe_resistance + } +} diff --git a/config/upstream.conf b/config/upstream.conf index 4e2c249..05906fa 100644 --- a/config/upstream.conf +++ b/config/upstream.conf @@ -23,6 +23,10 @@ stream { server oc:443; } + upstream naive { + server np:443; + } + map_hash_bucket_size 128; map $ssl_preread_server_name $sni_name { #domain @@ -32,6 +36,10 @@ stream { #ocserv #oc.domain ocserv; #ocserv + + #naive + #np.domain naive; + #naive default other; } diff --git a/docker-compose.yml b/docker-compose.yml index 4d7fae7..b8580ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -314,3 +314,30 @@ services: default: ipv4_address: 10.10.0.11 logging: *default-logging + np: + build: + dockerfile: dockerfile/naive.dockerfile + args: + image: ${IMAGE} + volumes: + - ./config/.profile:/root/.ashrc:ro + - ./ssh:/ssh + - ./config/sshd_config:/etc/ssh/sshd_config + - ./config:/config + - ./certs:/certs + - ./scripts/start_np.sh:/start_np.sh + hostname: naive + depends_on: + php: + condition: service_healthy + environment: + TZ: ${TZ} + ENV: /root/.ashrc + stop_grace_period: 1s + command: ["/bin/sh", "/start_np.sh"] + cap_add: + - NET_ADMIN + networks: + default: + ipv4_address: 10.10.0.12 + logging: *default-logging diff --git a/dockerfile/naive.dockerfile b/dockerfile/naive.dockerfile new file mode 100644 index 0000000..e772791 --- /dev/null +++ b/dockerfile/naive.dockerfile @@ -0,0 +1,9 @@ +ARG image +FROM $image +RUN apk add openssh \ + && mkdir /root/.ssh \ + && wget https://github.com/klzgrad/forwardproxy/releases/download/v2.7.6-naive/caddy-forwardproxy-naive.tar.xz -O naive.tar.xz \ + && tar -xf naive.tar.xz \ + && mv caddy-forwardproxy-naive/caddy /usr/local/bin \ + && rm naive.tar.xz \ + && rm -rf caddy-forwardproxy-naive diff --git a/makefile b/makefile index 6fa4178..8029b89 100644 --- a/makefile +++ b/makefile @@ -19,6 +19,8 @@ ss: # консоль сервиса docker compose exec ss /bin/sh ng: # консоль сервиса docker compose exec ng /bin/sh +np: # консоль сервиса + docker compose exec np /bin/sh up: # консоль сервиса docker compose exec up /bin/sh ad: # консоль сервиса diff --git a/scripts/start_np.sh b/scripts/start_np.sh new file mode 100644 index 0000000..a19e6c6 --- /dev/null +++ b/scripts/start_np.sh @@ -0,0 +1,5 @@ +cat /ssh/key.pub > /root/.ssh/authorized_keys +ssh-keygen -A +exec /usr/sbin/sshd -D -e "$@" & +caddy run -c /config/Caddyfile > /dev/null 2>&1 & +tail -f /dev/null