查看: 210|回复: 0

scp-next 实现 Node.js SSH 文件传输与部署脚本

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
scp-next 的定位与传输模型
scp-next 是一个 SCP 风格的 npm 包,提供命令行工具和 Node.js 库,用于通过 SSH 安全传输文件。包名里虽然有 SCP,但普通传输实际使用 SFTP,不会执行远程 Shell 命令。因此它适合被放进部署脚本、CI 流程或 Node.js 应用里,减少自己封装 SSH/SFTP 逻辑的重复工作。本文基于 scp-next v1.0.19 的项目介绍整理。

常见场景包括:把本地构建产物上传到服务器;从服务器下载日志或产物;用配置文件管理不同服务器环境;在应用代码中复用同一个传输客户端。

安装与 CLI 入口
全局安装后可以直接使用 scp-next 命令:
  1. npm install --global scp-next
复制代码
作为项目依赖安装后,可以在 Node.js 代码中导入 API:
  1. npm install scp-next
复制代码
如果项目只通过脚本调用 CLI,也可以把它装到项目依赖中,再用 npx scp-next 或 npm scripts 调用。

先理解 upload/download/run 的方向
命令行统一使用 <source> <destination> 两个位置参数:
  1. scp-next upload <source> <destination> [options]
  2. scp-next download <source> <destination> [options]
  3. scp-next run <job> [source] [destination] [options]
复制代码
方向规则是:upload 从本地到远程,download 从远程到本地。run 按配置中的 job 执行,也支持用位置参数临时覆盖路径。排查脚本问题时先确认操作类型和源/目标方向,可以避免把本地上传和远程下载写反。

命令行快速开始
上传本地目录到远程服务器:
  1. scp-next upload ./dist /var/www/example --host your-host --username your-username --password your-password --recursive
复制代码
下载远程文件到本地目录:
  1. scp-next download /var/log/example.log ./logs/example.log --host your-host --username your-username --password your-password
复制代码
如果目标目录不存在,scp-next 默认会创建目录,这符合日常 cp 和 scp 的使用习惯;可以用 --no-create-directories 关闭该行为。上传前想先检查参数和本地路径,可用 --dry-run:
  1. scp-next upload ./dist /var/www/example --host your-host --username your-username --password your-password --recursive --dry-run
复制代码
--dry-run 会解析配置并检查本地路径,不会连接远程服务器,也不会修改本地或远程文件。这个选项适合放在 CI 的前置校验步骤里。

凭据写法与常用选项
命令行 --password 适合本地快速试用。共享环境和生产环境建议使用环境变量,以降低密码进入 Shell 历史记录或进程列表的风险:
  1. export SCP_NEXT_HOST=your-host
  2. export SCP_NEXT_USERNAME=your-username
  3. export SCP_NEXT_PASSWORD=your-password
  4. scp-next upload ./dist /var/www/example --recursive
复制代码
也可以使用受保护的私钥文件,--private-key-file 支持 ~:
  1. scp-next upload ./dist /var/www/example --host your-host --username your-username --private-key-file ~/.ssh/id_ed25519 --recursive
复制代码
常用选项包括:--host 指定服务器地址;--port 指定 SSH 端口,默认 22;--username、--password 指定用户名和密码;--private-key-file 指定私钥文件路径;--passphrase 指定加密私钥口令;--config 指定配置文件路径;--profile 选择配置中的服务器配置;--recursive 递归传输目录,默认关闭;--overwrite 允许覆盖已有目标文件;--create-directories 创建缺失目标目录且默认开启;--no-create-directories 关闭自动创建;--dry-run 只解析和验证;--timeout 指定 SSH 握手超时毫秒数;--quiet 关闭进度和非错误输出;--verbose 输出不含敏感信息的诊断内容。

配置文件与 job 组织
CLI 会自动查找 scp-next.config.json、.scp-nextrc、.scp-nextrc.json。也可以显式指定路径,并通过 --profile 选择配置:
  1. scp-next upload ./dist /var/www/example --config ./scp-next.config.json --profile production
复制代码
下面示例包含服务器 profile 和任务 job,可用于固定部署与日志下载流程:
  1. {
  2.   "profiles": {
  3.     "production": {
  4.       "host": "your-host",
  5.       "username": "your-username",
  6.       "privateKeyFile": "~/.ssh/id_ed25519"
  7.     }
  8.   },
  9.   "jobs": {
  10.     "deploy": {
  11.       "operation": "upload",
  12.       "profile": "production",
  13.       "source": "./dist",
  14.       "destination": "/var/www/example",
  15.       "recursive": true,
  16.       "overwrite": true
  17.     },
  18.     "download-logs": {
  19.       "operation": "download",
  20.       "profile": "production",
  21.       "source": "/var/log/example",
  22.       "destination": "./logs",
  23.       "recursive": true
  24.     }
  25.   }
  26. }
复制代码
运行配置好的任务:
  1. scp-next run deploy
  2. scp-next run download-logs
  3. scp-next run deploy ./dist-canary /var/www/canary
复制代码
run 可用位置参数临时覆盖 job 中的路径。配置优先级从高到低为:显式 CLI 选项、位置参数、环境变量、选中的配置 profile、根级配置值、配置的 job 值、内部默认值。排查「为什么某台主机没生效」时,按这个顺序检查覆盖关系最直接。不要把包含真实密码的配置文件提交到公开仓库;共享仓库和部署环境应优先使用 SCP_NEXT_PASSWORD 或受保护的密钥文件。

Node.js 库 API 用法
ESM 项目可以直接导入 upload:
  1. import { upload } from 'scp-next';
  2. await upload({
  3.   host: process.env.SCP_NEXT_HOST,
  4.   username: process.env.SCP_NEXT_USERNAME,
  5.   password: process.env.SCP_NEXT_PASSWORD,
  6.   localPath: './dist',
  7.   remotePath: '/var/www/example',
  8.   recursive: true,
  9.   overwrite: true
  10. });
复制代码
CommonJS 项目可以使用 require 调用 download:
  1. const { download } = require('scp-next');
  2. async function main() {
  3.   await download({
  4.     host: process.env.SCP_NEXT_HOST,
  5.     username: process.env.SCP_NEXT_USERNAME,
  6.     password: process.env.SCP_NEXT_PASSWORD,
  7.     remotePath: '/var/log/example.log',
  8.     localPath: './logs/example.log'
  9.   });
  10. }
  11. main().catch((error) => {
  12.   console.error(error.message);
  13.   process.exitCode = 1;
  14. });
复制代码
如果一次连接内要执行多个操作,可以创建可复用客户端,避免每次操作都重新创建客户端:
  1. import { createClient } from 'scp-next';
  2. const client = createClient({
  3.   host: process.env.SCP_NEXT_HOST,
  4.   username: process.env.SCP_NEXT_USERNAME,
  5.   password: process.env.SCP_NEXT_PASSWORD
  6. });
  7. try {
  8.   await client.connect();
  9.   await client.upload('./dist', '/var/www/example', { recursive: true });
  10.   await client.download('/var/log/example.log', './logs/example.log');
  11. } finally {
  12.   await client.close();
  13. }
复制代码
主要导出为 upload(options)、download(options)、createClient(options)、copy(options)。错误对象包含稳定的 code、可读的 message 和经过脱敏的上下文。常见错误类型有 ConfigurationError、AuthenticationError、ConnectionError、TransferError 和 HostVerificationError。脚本里可以根据 code 做分支处理,但不要把敏感信息直接打印到日志。

主机验证与接手检查
scp-next 支持通过 hostFingerprint 或 knownHostsFile 验证主机。没有显式配置时会读取 ~/.ssh/known_hosts。在 CI 或部署环境里如果没有可用的 known-hosts 文件,建议配置 hostFingerprint;如果无法建立主机验证,scp-next 会失败退出。新人接手相关项目时,可以按顺序确认:Node.js 版本不低于 18.18.0;用 npm install --global scp-next 安装 CLI;用 scp-next upload ... --dry-run 验证参数和路径。确认这几点后,再把 scp-next 接入部署脚本、日志下载任务和 Node.js 文件传输流程。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-27 16:30 , Processed in 0.025128 second(s), 29 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部