express 集成命令行工具
以下是在 Express 应用中集成命令行工具的完整实现方案,涵盖安全执行、异步处理和实时反馈等功能:
基础实现(安全版)
const express = require('express')
const { exec } = require('child_process')
const { promisify } = require('util')
const execAsync = promisify(exec)
const app = express()
const PORT = 3000
// 安全执行中间件
const validateInput = (req, res, next) => {
if (!/^[a-zA-Z0-9-_]+$/.test(req.params.command)) {
return res.status(400).json({ error: 'Invalid command format' })
}
next()
}
app.get('/cmd/:command', validateInput, async (req, res) => {
try {
const { stdout, stderr } = await execAsync(req.params.command, {
timeout: 5000,
env: { PATH: process.env.PATH }
})
res.json({
status: 'success',
output: stdout,
warnings: stderr
})
} catch (error) {
res.status(500).json({
status: 'error',
error: error.message,
code: error.code
})
}
})
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
高级功能实现
1. 实时流式输出
const { spawn } = require('child_process')
app.get('/stream/:command', validateInput, (req, res) => {
res.setHeader('Content-Type', 'text/plain')
res.setHeader('Transfer-Encoding', 'chunked')
const child = spawn(req.params.command, [], {
shell: true,
env: process.env
})
child.stdout.on('data', (data) => {
res.write(`STDOUT: ${data}`)
})
child.stderr.on('data', (data) => {
res.write(`STDERR: ${data}`)
})
child.on('close', (code) => {
res.end(`\nProcess exited with code ${code}`)
})
})
2. 后台任务队列
安装所需依赖:
npm install bull express-basic-auth
const Queue = require('bull')
const basicAuth = require('express-basic-auth')
const taskQueue = new Queue('cli-tasks', 'redis://127.0.0.1:6379')
// 认证中间件
const authMiddleware = basicAuth({
users: { 'admin': 'supersecret' },
challenge: true
})
app.post('/task', authMiddleware, async (req, res) => {
const job = await taskQueue.add({
command: req.body.command,
params: req.body.args
}, {
attempts: 3,
backoff: { type: 'exponential' }
})
res.json({ jobId: job.id })
})
// 任务处理器
taskQueue.process(async (job) => {
const { command, params } = job.data
return new Promise((resolve, reject) => {
const child = spawn(command, params, { stdio: 'pipe' })
let output = ''
child.stdout.on('data', (data) => output += data)
child.on('close', (code) => {
code === 0 ? resolve(output) : reject(new Error(`Exit code ${code}`))
})
})
})
安全增强措施
- 白名单命令控制
const ALLOWED_COMMANDS = {
'system-info': 'uname -a',
'network-check': 'ping -c 4 8.8.8.8'
}
app.get('/safe-cmd/:command', (req, res) => {
const validCommand = ALLOWED_COMMANDS[req.params.command]
if (!validCommand) {
return res.status(400).send('Invalid command')
}
exec(validCommand, (error, stdout) => {
if (error) return res.status(500).send(error.message)
res.type('text/plain').send(stdout)
})
})
- Docker 容器化执行(需安装 Docker SDK)
const Docker = require('dockerode')
const docker = new Docker()
app.post('/docker', async (req, res) => {
try {
const container = await docker.createContainer({
Image: 'alpine',
Cmd: ['echo', 'safe execution'],
AttachStdout: true
})
await container.start()
const output = await container.logs({ stdout: true, stderr: true })
await container.remove()
res.send(output.toString())
} catch (error) {
res.status(500).send(error.message)
}
})
监控与日志
const { createLogger, transports } = require('winston')
const logger = createLogger({
transports: [new transports.File({ filename: 'command.log' })]
})
app.use((req, res, next) => {
if (req.path.includes('/cmd/')) {
logger.info({
timestamp: new Date(),
command: req.params.command,
ip: req.ip
})
}
next()
})
最佳实践建议
- 权限控制:
const sudo = require('sudo-prompt')
app.post('/admin-cmd', authMiddleware, (req, res) => {
sudo.exec(req.body.command, { name: 'MyApp' }, (error, stdout) => {
if (error) return res.status(500).send(error.message)
res.send(stdout)
})
})
- 资源限制:
const execOpts = {
timeout: 10000,
maxBuffer: 1024 * 1024, // 1MB
killSignal: 'SIGTERM'
}
- 输入验证强化:
const validateComplex = (input) => {
return !/[;&|><]/.test(input) &&
input.length < 50 &&
!/\b(rm|shutdown|halt)\b/.test(input)
}
完整方案整合了以下关键要素:
- 多层级安全控制(白名单、输入验证、容器化隔离)
- 多种执行模式(同步、异步、流式)
- 企业级功能(队列管理、权限控制、日志审计)
- 资源管理(超时控制、内存限制)
- 错误处理(重试机制、友好错误提示)
部署时建议配合:
- 反向代理(Nginx)
- 进程管理(PM2)
- 监控系统(Prometheus + Grafana)
- 防火墙规则(限制访问IP)
根据实际需求选择适当的安全级别,生产环境建议至少使用白名单+容器化执行的组合方案。
欢迎大家学习,交流
浙公网安备 33010602011771号