ok
Browse files- Dockerfile +22 -5
- app.js +36 -23
- public/index.html +3 -1
- start.sh +25 -2
Dockerfile
CHANGED
@@ -4,9 +4,21 @@ FROM node:20
|
|
4 |
# 设置工作目录
|
5 |
WORKDIR /app
|
6 |
|
7 |
-
#
|
8 |
RUN apt-get update && apt-get install -y \
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
&& rm -rf /var/lib/apt/lists/*
|
11 |
|
12 |
# 复制 package.json 和 package-lock.json(如果存在)
|
@@ -16,23 +28,28 @@ COPY package*.json ./
|
|
16 |
# 安装依赖,包括 ssh2
|
17 |
RUN npm install
|
18 |
|
19 |
-
#
|
20 |
COPY . .
|
21 |
|
22 |
# 创建一个新用户,UID 为 1000
|
23 |
RUN if id 1000 >/dev/null 2>&1; then \
|
24 |
-
|
25 |
fi \
|
26 |
&& useradd -u 1000 -m -s /bin/bash user \
|
27 |
&& echo 'user:password' | chpasswd
|
28 |
|
29 |
# 设置 Dropbear
|
30 |
RUN mkdir -p /etc/dropbear
|
31 |
-
RUN dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key || true
|
32 |
|
33 |
# 更改目录所有权
|
34 |
RUN chown -R user:user /app /etc/dropbear
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
# 启动脚本
|
37 |
COPY start.sh /start.sh
|
38 |
RUN chmod +x /start.sh
|
|
|
4 |
# 设置工作目录
|
5 |
WORKDIR /app
|
6 |
|
7 |
+
# 安装必要的工具和最新版本的 Dropbear
|
8 |
RUN apt-get update && apt-get install -y \
|
9 |
+
build-essential \
|
10 |
+
zlib1g-dev \
|
11 |
+
libssl-dev \
|
12 |
+
wget \
|
13 |
+
&& wget https://matt.ucc.asn.au/dropbear/releases/dropbear-latest.tar.bz2 \
|
14 |
+
&& tar xjf dropbear-latest.tar.bz2 \
|
15 |
+
&& cd dropbear-* \
|
16 |
+
&& ./configure \
|
17 |
+
&& make \
|
18 |
+
&& make install \
|
19 |
+
&& cd .. \
|
20 |
+
&& rm -rf dropbear-* \
|
21 |
+
&& apt-get clean \
|
22 |
&& rm -rf /var/lib/apt/lists/*
|
23 |
|
24 |
# 复制 package.json 和 package-lock.json(如果存在)
|
|
|
28 |
# 安装依赖,包括 ssh2
|
29 |
RUN npm install
|
30 |
|
31 |
+
# 复制其余的源代码和公共文件
|
32 |
COPY . .
|
33 |
|
34 |
# 创建一个新用户,UID 为 1000
|
35 |
RUN if id 1000 >/dev/null 2>&1; then \
|
36 |
+
userdel -f $(id -nu 1000); \
|
37 |
fi \
|
38 |
&& useradd -u 1000 -m -s /bin/bash user \
|
39 |
&& echo 'user:password' | chpasswd
|
40 |
|
41 |
# 设置 Dropbear
|
42 |
RUN mkdir -p /etc/dropbear
|
|
|
43 |
|
44 |
# 更改目录所有权
|
45 |
RUN chown -R user:user /app /etc/dropbear
|
46 |
|
47 |
+
# 切换到新用户
|
48 |
+
USER user
|
49 |
+
|
50 |
+
# 暴露 Web 应用端口和 Dropbear SSH 端口
|
51 |
+
EXPOSE 7860 2202
|
52 |
+
|
53 |
# 启动脚本
|
54 |
COPY start.sh /start.sh
|
55 |
RUN chmod +x /start.sh
|
app.js
CHANGED
@@ -11,32 +11,45 @@ app.get('/', (req, res) => {
|
|
11 |
res.sendFile(__dirname + '/public/index.html');
|
12 |
});
|
13 |
|
14 |
-
app.post('/ssh', (req, res) => {
|
15 |
const conn = new Client();
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
});
|
31 |
});
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
});
|
40 |
});
|
41 |
|
42 |
app.listen(port, () => {
|
|
|
11 |
res.sendFile(__dirname + '/public/index.html');
|
12 |
});
|
13 |
|
14 |
+
app.post('/ssh', async (req, res) => {
|
15 |
const conn = new Client();
|
16 |
+
|
17 |
+
try {
|
18 |
+
await new Promise((resolve, reject) => {
|
19 |
+
conn.on('ready', resolve)
|
20 |
+
.on('error', reject)
|
21 |
+
.connect({
|
22 |
+
host: 'localhost',
|
23 |
+
port: 2202,
|
24 |
+
username: 'user',
|
25 |
+
password: 'password',
|
26 |
+
readyTimeout: 5000,
|
27 |
+
debug: console.log
|
28 |
+
});
|
29 |
+
});
|
30 |
+
|
31 |
+
console.log('SSH Connection established');
|
32 |
+
|
33 |
+
const { stdout, stderr } = await new Promise((resolve, reject) => {
|
34 |
+
conn.exec(req.body.command, (err, stream) => {
|
35 |
+
if (err) reject(err);
|
36 |
+
let stdout = '', stderr = '';
|
37 |
+
stream.on('close', (code, signal) => {
|
38 |
+
resolve({ stdout, stderr, code, signal });
|
39 |
+
}).on('data', (data) => {
|
40 |
+
stdout += data;
|
41 |
+
}).stderr.on('data', (data) => {
|
42 |
+
stderr += data;
|
43 |
+
});
|
44 |
});
|
45 |
});
|
46 |
+
|
47 |
+
conn.end();
|
48 |
+
res.json({ output: stdout, error: stderr });
|
49 |
+
} catch (error) {
|
50 |
+
console.error('SSH error:', error);
|
51 |
+
res.status(500).json({ error: error.message });
|
52 |
+
}
|
|
|
53 |
});
|
54 |
|
55 |
app.listen(port, () => {
|
public/index.html
CHANGED
@@ -6,7 +6,9 @@
|
|
6 |
<title>Web SSH</title>
|
7 |
<style>
|
8 |
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
|
9 |
-
#output { white-space: pre-wrap; background-color: #f0f0f0; padding: 10px; border-radius: 5px; }
|
|
|
|
|
10 |
</style>
|
11 |
</head>
|
12 |
<body>
|
|
|
6 |
<title>Web SSH</title>
|
7 |
<style>
|
8 |
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
|
9 |
+
#output { white-space: pre-wrap; background-color: #f0f0f0; padding: 10px; border-radius: 5px; max-height: 400px; overflow-y: auto; }
|
10 |
+
#command { width: 70%; padding: 5px; }
|
11 |
+
button { padding: 5px 10px; }
|
12 |
</style>
|
13 |
</head>
|
14 |
<body>
|
start.sh
CHANGED
@@ -1,12 +1,35 @@
|
|
1 |
#!/bin/bash
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
# 检查并生成 SSH 主机密钥(如果不存在)
|
4 |
if [ ! -f /etc/dropbear/dropbear_rsa_host_key ]; then
|
5 |
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
|
6 |
fi
|
7 |
|
8 |
-
# 启动 Dropbear,使用 2202
|
9 |
-
dropbear -R -p 2202
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
# 启动 Node.js 应用
|
12 |
npm start
|
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
+
echo "===== System Information ====="
|
4 |
+
uname -a
|
5 |
+
echo "CPU: $(lscpu | grep 'Model name' | cut -f 2 -d ":")"
|
6 |
+
echo "Memory: $(free -h | awk '/^Mem:/ {print $2}')"
|
7 |
+
echo "Disk: $(df -h / | awk 'NR==2 {print $2}')"
|
8 |
+
echo "==============================="
|
9 |
+
|
10 |
# 检查并生成 SSH 主机密钥(如果不存在)
|
11 |
if [ ! -f /etc/dropbear/dropbear_rsa_host_key ]; then
|
12 |
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
|
13 |
fi
|
14 |
|
15 |
+
# 启动 Dropbear,使用 2202 端口,允许密码认证
|
16 |
+
dropbear -R -p 2202 -w -F -E
|
17 |
+
|
18 |
+
# 检查 Dropbear 是否成功启动
|
19 |
+
for i in {1..5}; do
|
20 |
+
if netstat -tuln | grep :2202 > /dev/null; then
|
21 |
+
echo "Dropbear started successfully on port 2202"
|
22 |
+
break
|
23 |
+
fi
|
24 |
+
if [ $i -eq 5 ]; then
|
25 |
+
echo "Failed to start Dropbear after 5 attempts"
|
26 |
+
exit 1
|
27 |
+
fi
|
28 |
+
echo "Waiting for Dropbear to start... (attempt $i)"
|
29 |
+
sleep 1
|
30 |
+
done
|
31 |
+
|
32 |
+
echo "Dropbear version: $(dropbear -V 2>&1)"
|
33 |
|
34 |
# 启动 Node.js 应用
|
35 |
npm start
|