iodine -> dnstt
This commit is contained in:
+86
-46
@@ -317,20 +317,23 @@ class Bot
|
||||
case preg_match('~^/logs$~', $this->input['callback'], $m):
|
||||
$this->logs();
|
||||
break;
|
||||
case preg_match('~^/iodine$~', $this->input['callback'], $m):
|
||||
$this->iodine();
|
||||
case preg_match('~^/dnstt$~', $this->input['callback'], $m):
|
||||
$this->dnstt();
|
||||
break;
|
||||
case preg_match('~^/iodineDomain$~', $this->input['callback'], $m):
|
||||
$this->iodineDomain();
|
||||
case preg_match('~^/dnsttDownload$~', $this->input['callback'], $m):
|
||||
$this->dnsttDownload();
|
||||
break;
|
||||
case preg_match('~^/iodinePassword$~', $this->input['callback'], $m):
|
||||
$this->iodinePassword();
|
||||
case preg_match('~^/dnsttDomain$~', $this->input['callback'], $m):
|
||||
$this->dnsttDomain();
|
||||
break;
|
||||
case preg_match('~^/setIodineDomain (\w+)$~', $this->input['callback'], $m):
|
||||
$this->setIodineDomain($m[1]);
|
||||
case preg_match('~^/dnsttPassword$~', $this->input['callback'], $m):
|
||||
$this->dnsttPassword();
|
||||
break;
|
||||
case preg_match('~^/setIodinePassword (\w+)$~', $this->input['callback'], $m):
|
||||
$this->setIodinePassword($m[1]);
|
||||
case preg_match('~^/setdnsttDomain (\w+)$~', $this->input['callback'], $m):
|
||||
$this->setdnsttDomain($m[1]);
|
||||
break;
|
||||
case preg_match('~^/setdnsttPassword (\w+)$~', $this->input['callback'], $m):
|
||||
$this->setdnsttPassword($m[1]);
|
||||
break;
|
||||
case preg_match('~^/getLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->getLog(...explode('_', $m['arg']));
|
||||
@@ -1138,7 +1141,7 @@ class Bot
|
||||
$t = preg_replace('~^(\t+)?basic_auth[^\n]+~sm', '$1basic_auth ' . ($pac['naive']['user'] ?? '_') . ' ' . ($pac['naive']['pass'] ?? '__'), $c);
|
||||
file_put_contents('/config/Caddyfile', $t);
|
||||
if (!empty($pac['naive']['pass'])) {
|
||||
$this->ssh('caddy run -c /config/Caddyfile > /dev/null 2>&1 &', 'np', false);
|
||||
$this->ssh('caddy run -c /config/Caddyfile', 'np', false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2829,7 +2832,7 @@ DNS-over-HTTPS with IP:
|
||||
|
||||
public function startAd()
|
||||
{
|
||||
return $this->ssh('/opt/adguardhome/AdGuardHome --no-check-update --pidfile /opt/adguardhome/pid -c /config/AdGuardHome.yaml -h 0.0.0.0 -w /opt/adguardhome/work > /dev/null 2>&1 &', 'ad', false);
|
||||
return $this->ssh('/opt/adguardhome/AdGuardHome --no-check-update --pidfile /opt/adguardhome/pid -c /config/AdGuardHome.yaml -h 0.0.0.0 -w /opt/adguardhome/work', 'ad', false);
|
||||
}
|
||||
|
||||
public function stopAd()
|
||||
@@ -4540,7 +4543,7 @@ DNS-over-HTTPS with IP:
|
||||
return implode("\n", $result);
|
||||
}
|
||||
|
||||
public function iodineDomain()
|
||||
public function dnsttDomain()
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
@@ -4550,12 +4553,12 @@ DNS-over-HTTPS with IP:
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'callback' => 'setIodineDomain',
|
||||
'callback' => 'setdnsttDomain',
|
||||
'args' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function iodinePassword()
|
||||
public function dnsttPassword()
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
@@ -4565,63 +4568,82 @@ DNS-over-HTTPS with IP:
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'callback' => 'setIodinePassword',
|
||||
'callback' => 'setdnsttPassword',
|
||||
'args' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function setIodinePassword($text)
|
||||
public function setdnsttPassword($text)
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
if ($text) {
|
||||
$c['iodinePassword'] = $text;
|
||||
$c['dnsttPassword'] = $text;
|
||||
} else {
|
||||
unset($c['iodinePassword']);
|
||||
unset($c['dnsttPassword']);
|
||||
}
|
||||
$this->setPacConf($c);
|
||||
$this->iodineRestart();
|
||||
$this->iodine();
|
||||
$this->dnsttStart();
|
||||
$this->dnstt();
|
||||
}
|
||||
|
||||
public function setIodineDomain($text)
|
||||
public function setdnsttDomain($text)
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
if ($text) {
|
||||
$c['iodineDomain'] = $text;
|
||||
$c['dnsttDomain'] = $text;
|
||||
} else {
|
||||
unset($c['iodineDomain']);
|
||||
unset($c['dnsttDomain']);
|
||||
}
|
||||
$this->setPacConf($c);
|
||||
$this->iodineRestart();
|
||||
$this->iodine();
|
||||
$this->dnsttStart();
|
||||
$this->dnstt();
|
||||
}
|
||||
|
||||
public function iodineRestart()
|
||||
public function dnsttStart()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$this->ssh('pkill iodine', 'io');
|
||||
if (!empty($c['iodineDomain']) && !empty($c['iodinePassword'])) {
|
||||
$this->ssh("iodined -c -P {$c['iodinePassword']} 10.0.0.1 {$c['iodineDomain']}", 'io');
|
||||
$this->ssh('pkill dnstt', 'dnstt');
|
||||
if (!empty($c['dnsttDomain']) && !empty($c['dnsttPassword'])) {
|
||||
$this->ssh("adduser -D -s /bin/sh vpnbot", 'dnstt');
|
||||
$this->ssh("echo 'vpnbot:{$c['dnsttPassword']}' | chpasswd", 'dnstt');
|
||||
if (!file_exists('/config/dnstt/server.key')) {
|
||||
$this->ssh("dnstt-server -gen-key -privkey-file /dnstt/server.key -pubkey-file /dnstt/server.pub", 'dnstt');
|
||||
}
|
||||
$this->ssh("dnstt-server -udp :53 -privkey-file /dnstt/server.key {$c['dnsttDomain']} 127.0.0.1:22", 'dnstt' , false);
|
||||
}
|
||||
}
|
||||
|
||||
public function iodine()
|
||||
public function dnsttDownload()
|
||||
{
|
||||
$this->sendFile($this->input['from'], curl_file_create('/config/dnstt/server.pub'));
|
||||
}
|
||||
|
||||
public function dnstt()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$text[] = 'Iodine';
|
||||
$text[] = "domain: {$c['iodineDomain']}";
|
||||
$text[] = "password: {$c['iodinePassword']}";
|
||||
$pubkey = file_get_contents('/config/dnstt/server.pub');
|
||||
$text[] = "dnstt";
|
||||
$text[] = "<pre>set the NS record for {$c['dnsttDomain']}: tns.{$c['domain']}\nset A record for tns.{$c['domain']}: {$this->ip}</pre>";
|
||||
$text[] = "domain: <code>{$c['dnsttDomain']}</code>";
|
||||
$text[] = "ssh: <code>vpnbot:{$c['dnsttPassword']}</code>";
|
||||
$text[] = "pubkey: <code>$pubkey</code>";
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('download pubkey'),
|
||||
'callback_data' => "/dnsttDownload",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('set domain'),
|
||||
'callback_data' => "/iodineDomain",
|
||||
'callback_data' => "/dnsttDomain",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('set password'),
|
||||
'callback_data' => "/iodinePassword",
|
||||
'callback_data' => "/dnsttPassword",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
@@ -4693,7 +4715,7 @@ DNS-over-HTTPS with IP:
|
||||
$this->i18n($this->ssh('pgrep mtproto-proxy', 'tg') ? 'on' : 'off') . ' ' . $this->i18n('mtproto'),
|
||||
$this->i18n(exec("JSON=1 timeout 2 dnslookup google.com ad") ? 'on' : 'off') . ' ' . $this->i18n('ad_title'),
|
||||
$this->i18n($this->ssh('pgrep ssserver', 'ss') ? 'on' : 'off') . ' ' . $this->i18n('sh_title'),
|
||||
$this->i18n($this->ssh('pgrep iodine', 'io') ? 'on' : 'off') . ' ' . $this->i18n('Iodine'),
|
||||
$this->i18n($this->ssh('pgrep dnstt', 'dnstt') ? 'on' : 'off') . ' ' . $this->i18n('dnstt'),
|
||||
$this->i18n($this->warpStatus()) . ' ' . $this->i18n('warp'),
|
||||
],
|
||||
[
|
||||
@@ -4705,7 +4727,7 @@ DNS-over-HTTPS with IP:
|
||||
$this->i18n($c['tg'] ? 'on' : 'off') . ' ' . getenv('TGPORT'),
|
||||
$this->i18n($c['ad'] ? 'on' : 'off') . ' 853',
|
||||
$this->i18n($c['ss'] ? 'on' : 'off') . ' ' . getenv('SSPORT'),
|
||||
$this->i18n($c['io'] ? 'on' : 'off') . ' 53',
|
||||
$this->i18n($c['dnstt'] ? 'on' : 'off') . ' 53',
|
||||
'',
|
||||
],
|
||||
]);
|
||||
@@ -4781,8 +4803,8 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('Iodine'),
|
||||
'callback_data' => "/iodine",
|
||||
'text' => $this->i18n('dnstt'),
|
||||
'callback_data' => "/dnstt",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -8380,8 +8402,8 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/hidePort ss",
|
||||
]],
|
||||
[[
|
||||
'text' => $this->i18n($c['io'] ? 'on' : 'off') . ' 53 Iodine',
|
||||
'callback_data' => "/hidePort io",
|
||||
'text' => $this->i18n($c['dnstt'] ? 'on' : 'off') . ' 53 dnstt',
|
||||
'callback_data' => "/hidePort dnstt",
|
||||
]],
|
||||
];
|
||||
if (!empty($pac['restart'])) {
|
||||
@@ -8414,7 +8436,7 @@ DNS-over-HTTPS with IP:
|
||||
'tg' => getenv('TGPORT') . ':' . getenv('TGPORT'),
|
||||
'ad' => '853:853',
|
||||
'ss' => '8388:8388',
|
||||
'io' => '53:53/udp',
|
||||
'dnstt' => '53:53/udp',
|
||||
];
|
||||
$f = '/docker/compose';
|
||||
$c = yaml_parse_file($f);
|
||||
@@ -9091,15 +9113,33 @@ DNS-over-HTTPS with IP:
|
||||
if (empty($a)) {
|
||||
throw new Exception("auth fail: \n$cmd\n" . var_export($a, true));
|
||||
}
|
||||
|
||||
// Оборачиваем команду для выполнения в фоновом режиме
|
||||
if (!$wait) {
|
||||
// nohup запускает процесс независимо от SSH-сессии
|
||||
// & переносит процесс в фон
|
||||
// </dev/null >/dev/null 2>&1 перенаправляет все потоки ввода-вывода
|
||||
$cmd = "nohup $cmd </dev/null >/dev/null 2>&1 &";
|
||||
}
|
||||
|
||||
$s = ssh2_exec($c, $cmd);
|
||||
if (empty($s)) {
|
||||
throw new Exception("exec fail: \n$cmd\n" . var_export($s, true));
|
||||
}
|
||||
stream_set_blocking($s, $wait);
|
||||
|
||||
$data = "";
|
||||
while ($buf = fread($s, 4096)) {
|
||||
$data .= $buf;
|
||||
if ($wait) {
|
||||
// Только для синхронных команд читаем вывод
|
||||
stream_set_blocking($s, true);
|
||||
while ($buf = fread($s, 4096)) {
|
||||
$data .= $buf;
|
||||
}
|
||||
} else {
|
||||
// Для фоновых команд просто даем время запуститься
|
||||
stream_set_blocking($s, false);
|
||||
usleep(100000); // 100ms для запуска процесса
|
||||
}
|
||||
|
||||
fclose($s);
|
||||
ssh2_disconnect($c);
|
||||
} catch (Exception | Error $e) {
|
||||
|
||||
+1
-1
@@ -24,4 +24,4 @@ $bot->adguardSync();
|
||||
$bot->cloakNginx();
|
||||
$bot->syncDeny();
|
||||
$bot->cleanDocker();
|
||||
$bot->iodineRestart();
|
||||
$bot->dnsttStart();
|
||||
|
||||
+8
-4
@@ -83,9 +83,9 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
|
||||
#AllowAgentForwarding yes
|
||||
# Feel free to re-enable these if your use case requires them.
|
||||
AllowTcpForwarding no
|
||||
GatewayPorts no
|
||||
X11Forwarding no
|
||||
# AllowTcpForwarding no
|
||||
# GatewayPorts no
|
||||
# X11Forwarding no
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PermitTTY yes
|
||||
@@ -117,4 +117,8 @@ Subsystem sftp internal-sftp
|
||||
# ForceCommand cvs server
|
||||
HostKeyAlgorithms +ssh-rsa
|
||||
PubkeyAcceptedKeyTypes +ssh-rsa
|
||||
PasswordAuthentication no
|
||||
PasswordAuthentication yes
|
||||
AllowTcpForwarding yes
|
||||
PermitTunnel yes
|
||||
GatewayPorts yes
|
||||
X11Forwarding yes
|
||||
+11
-11
@@ -211,6 +211,7 @@ services:
|
||||
- np
|
||||
- proxy
|
||||
- ss
|
||||
- dnstt
|
||||
wg:
|
||||
image: mercurykd/vpnbot-wg:1.1
|
||||
build:
|
||||
@@ -537,21 +538,20 @@ services:
|
||||
default:
|
||||
ipv4_address: 10.10.0.6
|
||||
logging: *default-logging
|
||||
io:
|
||||
image: mercurykd/vpnbot-io:1.0
|
||||
dnstt:
|
||||
image: mercurykd/vpnbot-dnstt:1.0
|
||||
build:
|
||||
dockerfile: dockerfile/iodine.dockerfile
|
||||
dockerfile: dockerfile/dnstt.dockerfile
|
||||
args:
|
||||
image: ${IMAGE}
|
||||
volumes:
|
||||
- ./config/.profile:/root/.ashrc:ro
|
||||
- ./ssh:/ssh
|
||||
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||
- ./scripts/start_io.sh:/start_io.sh
|
||||
hostname: iodine
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
container_name: iodine-${VER}
|
||||
- ./config/dnstt:/dnstt
|
||||
- ./scripts/start_dnstt.sh:/start_dnstt.sh
|
||||
hostname: dnstt
|
||||
container_name: dnstt-${VER}
|
||||
depends_on:
|
||||
php:
|
||||
condition: service_healthy
|
||||
@@ -561,7 +561,7 @@ services:
|
||||
- path: ./override.env
|
||||
required: false
|
||||
stop_grace_period: 1s
|
||||
command: ["/bin/sh", "/start_io.sh"]
|
||||
command: ["/bin/sh", "/start_dnstt.sh"]
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 10.10.0.16
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
ARG image
|
||||
FROM golang:alpine AS go
|
||||
RUN apk add --no-cache git \
|
||||
&& git clone https://www.bamsoftware.com/git/dnstt.git \
|
||||
&& cd /go/dnstt/dnstt-server \
|
||||
&& go build -ldflags="-s -w" -trimpath \
|
||||
&& rm -rf /go/dnstt/.git \
|
||||
&& apk del git
|
||||
FROM $image
|
||||
COPY --from=go /go/dnstt/dnstt-server/dnstt-server /usr/local/bin/
|
||||
RUN apk add --no-cache openssh iptables \
|
||||
&& mkdir -p /root/.ssh
|
||||
ENV ENV="/root/.ashrc"
|
||||
@@ -1,4 +0,0 @@
|
||||
FROM alpine:3.22
|
||||
RUN apk add iodine openssh iptables\
|
||||
&& mkdir /root/.ssh
|
||||
ENV ENV="/root/.ashrc"
|
||||
@@ -37,8 +37,8 @@ proxy: # консоль сервиса
|
||||
docker compose exec proxy /bin/sh
|
||||
tg: # консоль сервиса
|
||||
docker compose exec tg /bin/sh
|
||||
io: # консоль сервиса
|
||||
docker compose exec io /bin/sh
|
||||
dnstt: # консоль сервиса
|
||||
docker compose exec dnstt /bin/sh
|
||||
xr: # консоль сервиса
|
||||
docker compose exec xr /bin/sh
|
||||
oc: # консоль сервиса
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
cat /ssh/key.pub > /root/.ssh/authorized_keys
|
||||
ssh-keygen -A
|
||||
exec /usr/sbin/sshd -D -e "$@" &
|
||||
tail -f /dev/null
|
||||
@@ -1,7 +0,0 @@
|
||||
cat /ssh/key.pub > /root/.ssh/authorized_keys
|
||||
ssh-keygen -A
|
||||
exec /usr/sbin/sshd -D -e "$@" &
|
||||
iptables -A FORWARD -i dns0 -o eth0 -j ACCEPT
|
||||
iptables -A FORWARD -i eth0 -o dns0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
tail -f /dev/null
|
||||
@@ -1,6 +1,4 @@
|
||||
cat /ssh/key.pub > /root/.ssh/authorized_keys
|
||||
echo 'HostKeyAlgorithms +ssh-rsa' >> /etc/ssh/sshd_config
|
||||
echo 'PubkeyAcceptedKeyTypes +ssh-rsa' >> /etc/ssh/sshd_config
|
||||
service ssh start
|
||||
off=$(cat /config/pac.json | jq -r .warpoff)
|
||||
key=$(cat /config/pac.json | jq -r .warp)
|
||||
|
||||
Reference in New Issue
Block a user