当前位置: 首页 > news >正文

Linux小课堂: SSH 服务部署与客户端连接实战详解

服务器端:安装并配置 SSH 服务(基于 CentOS)

在 Linux 服务器环境中,SSH(Secure Shell) 是远程管理系统的标准协议
它通过加密通道实现安全的命令行访问和文件传输
本节以 CentOS Server 环境为例,完整演示 SSH 服务端的确认、启动与开机自启配置

尽管最小化安装的 CentOS 通常已默认预装并启用 openssh-server,但仍需系统性验证其状态,确保服务可用

1 )安装 OpenSSH 服务端
使用 yum 包管理器检查并安装 openssh-server

sudo yum install -y openssh-server

若输出提示“Nothing to do”,表明该软件包已安装且为最新版本,无需重复操作。

2 )启动并重启 SSHD 服务
SSH 服务由守护进程 sshd 提供支持。可通过以下命令控制其运行状态:

启动 SSH 服务
sudo systemctl start sshd重启 SSH 服务(适用于配置变更后)
sudo systemctl restart sshd

3 )设置开机自启
为确保服务器重启后仍可远程接入,必须将 sshd 设为开机自启:

sudo systemctl enable sshd 

执行后,系统会在 /etc/systemd/system/multi-user.target.wants/ 目录下创建指向 sshd.service 的符号链接,完成注册。

4 )验证服务运行状态
使用 psgrep 组合查询当前运行中的 SSH 进程:

ps -ef | grep sshd

预期输出中应包含类似:

root      1234     1  0 10:00 ?        00:00:00 /usr/sbin/sshd -D

此外,也可使用 systemctl status sshd 查看详细服务状态,表明服务已在后台监听默认端口 22

5 ) 查看激活的开机启动单元
列出所有已激活的 systemd 单元,确认 sshd.service 是否处于 enabled 状态:

systemctl list-unit-files --type=service | grep sshd
# 或
systemctl list-unit-files --type=service | grep enabled | grep ssh
# 或
systemctl list-units --type=service --state=active | grep ssh

若显示 sshd.service enabled,表示已正确配置自启

获取服务器 IP 地址

在进行远程连接前,需明确服务器的网络地址。使用 ip addr 或传统 ifconfig 命令查看本机 IP:

ip addr show
# 或
ifconfig
# 或
ifconfig eth0

查找对应网卡(如 eth0ens33),记录其 IPv4 地址。示例输出中可能出现:

inet 172.20.10.2  netmask 255.255.255.0 

常见内网地址形如 172.20.10.2,具体值依网络环境而定
该地址即为客户端连接目标

客户端:安装 SSH 工具(跨平台支持)

不同操作系统平台对 SSH 客户端的支持情况各异,以下分别说明 Windows、Linux 与 macOS 平台的处理方式

1 ) Windows 客户端:安装第三方 SSH 工具

Windows 原生不自带完整 SSH 客户端(旧版除外),推荐使用以下工具之一:

  • PuTTY(免费开源)
  • Xshell
  • SecureCRT

下载与使用 PuTTY 示例:

  1. 打开浏览器访问 https://www.putty.org
  2. 下载 putty.exe(64位免安装版)
  3. 将其复制至桌面或指定目录
  4. 双击运行,无需安装

推荐将 putty.exe 固定到任务栏以便快速启动

PuTTY 配置流程:

  • 打开 PuTTY
  • 在 Session 分类下:
    • Host Name (or IP address): 输入服务器 IP,如 172.20.10.2
    • Port: 22(默认 SSH 端口)
    • Connection type: 选择 SSH
  • 可选:保存会话名称(如 centos-server)便于复用
  • 点击 Open 启动连接

首次连接时,PuTTY 会弹出安全警告,提示主机密钥未缓存。显示内容如下:

The server’s host key is not cached in the registry. Are you sure you want to continue connecting?

此时应核对指纹信息。若信任该主机,点击 是(Yes),密钥将被加入本地缓存,后续连接不再提示。

登录界面要求输入用户名与密码。例如:

login as: root
root@172.20.10.2's password:

成功登录后,即可执行任意命令,如:

ls               # 查看文件列表
touch file1.txt  # 创建测试文件
ip addr          # 查看网络配置
# 或
ifconfig         # 验证本地接口地址
exit             # 退出会话

关闭窗口或输入 exit / Ctrl+D 即断开连接

2 ) Linux 客户端:安装 OpenSSH 客户端

大多数 Linux 发行版默认已安装 openssh-clients,但桌面版可能未包含。可通过 yum 显式安装:

sudo yum install -y openssh-clients

验证是否已安装:

which ssh

预期返回路径 /usr/bin/ssh。若未安装,YUM 将自动解析依赖并补全

安装完成后,直接使用 ssh 命令连接服务器:

ssh root@172.20.10.2

首次连接时,终端会提示:

The authenticity of host '172.20.10.2 (172.20.10.2)' can't be established.
RSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

输入 yes 确认信任,系统自动将主机密钥写入 ~/.ssh/known_hosts 文件。

认证通过后,用户进入远程 shell 环境,主机名变为目标服务器名称(如 localhost.localdomain)。执行命令如:

ls
touch file2.txt
exit

均可实时反映在服务器上

3 ) macOS 客户端:原生支持 SSH

macOS 内置 OpenSSH 客户端,无需额外安装。打开 终端(Terminal) 应用即可使用 ssh 命令:

ssh root@172.20.10.2

行为逻辑与 Linux 客户端完全一致:首次连接需确认主机密钥指纹,输入 yes 后永久记录;随后输入密码完成登录

同样支持 ~/.ssh/known_hosts 记录机制,且支持密钥对免密登录等高级特性

创建测试文件验证连通性:

可在 macOS 终端中执行:

ls 
touch file3.txt
ifconfig  # 或 ipconfig getifaddr en0 查看本地IP

验证文件是否同步出现在服务器端。

技术要点总结与关键细节凝练


1 ) SSH 架构核心理解

  • 服务端(Server): openssh-server 提供 sshd 守护进程,监听 22 端口
  • 客户端(Client): 使用 ssh [user@host] 发起连接请求
  • 加密机制: 基于非对称密钥体系,保障通信安全
  • 身份认证: 支持密码、公钥等多种方式

2 ) 关键命令归纳

操作命令
安装服务端yum install -y openssh-server
安装客户端yum install -y openssh-clients
启动服务systemctl start sshd
重启服务systemctl restart sshd
开机自启systemctl enable sshd
查看状态systemctl status sshd
连接服务器ssh root@172.20.10.2
查看进程ps -ef | grep sshd

或换一种表达

步骤操作内容关键技术点
1服务端确认 sshd 运行状态使用 systemctl status sshd, ps -ef | grep sshd
2获取服务器局域网 IP 地址执行 ifconfigip addr
3客户端安装对应 SSH 工具Windows: PuTTY/Xshell; Linux/macOS: 原生命令行
4首次连接处理主机密钥验证接受指纹以建立信任链,防止中间人攻击
5成功登录并执行命令验证创建文件、查看网络配置,确认双向一致性

技术点说明
加密传输SSH采用非对称加密(RSA/DSA/ECDSA)协商会话密钥,后续通信使用对称加密(AES等)保障数据机密性与完整性
主机认证客户端通过比对服务器公钥指纹防止中间人攻击,首次连接需手动确认
用户认证支持密码认证与公钥认证(推荐后者以提升安全性)
端口默认值SSH服务监听TCP 22端口,可通过 /etc/ssh/sshd_config 修改
配置文件路径
服务端
/etc/ssh/sshd_config —— 控制登录权限、允许Root登录、密钥认证开关等
配置文件路径
客户端
~/.ssh/config —— 自定义别名、端口映射、跳板机配置

重点强调:

  • SSH 默认端口为 22,除非特别配置防火墙规则或更改监听端口,否则不得修改
  • 主机密钥验证机制至关重要,它是抵御 MITM(Man-in-the-Middle)攻击的第一道防线
  • 所有客户端最终都通过 TCP/IP 协议栈连接至目标服务器的 0.0.0.0:22 监听套接字
  • 登录账户权限直接影响操作范围,root 用户拥有最高权限,应谨慎使用

3 ) 安全注意事项

  • 避免频繁使用 root 登录:建议创建普通用户并通过 sudo 提权
  • 禁用密码认证,启用密钥登录:提升安全性
  • 修改默认端口(非必要不改):防止自动化扫描攻击
  • 定期更新 SSH 软件包:修复潜在漏洞

补充 NestJS + TypeScript 示例:构建 SSH 管理模块


1 ) 方案1

虽然实际 SSH 操作多在 Shell 层完成,但在某些自动化运维系统中,可通过 Node.js 调用底层 SSH 功能。以下是基于 NestJS 框架封装的一个轻量级 SSH 工具服务。

安装依赖

npm install ssh2
npm install @types/node --save-dev

创建 SSH 服务(ssh.service.ts

import { Injectable } from '@nestjs/common';
import * as Client from 'ssh2';@Injectable()
export class SshService {private readonly config = {host: '172.20.10.2',port: 22,username: 'root',password: 'your_root_password', // 生产环境应使用密钥或环境变量};async executeCommand(command: string): Promise<string> {return new Promise((resolve, reject) => {const conn = new Client();let output = '';conn.on('ready', () => {conn.exec(command, (err, stream) => {if (err) {conn.end();return reject(err);}stream.on('close', (code, signal) => {conn.end();resolve(output);}).on('data', (data) => {output += data.toString();}).stderr.on('data', (data) => {console.error('STDERR:', data.toString());});});}).connect(this.config);});}async connectAndCreateFile(filename: string): Promise<void> {const commands = [`touch ${filename}`,'ls -la',];for (const cmd of commands) {try {const result = await this.executeCommand(cmd);console.log(`[SSH] Executed: ${cmd}\nOutput:\n${result}`);} catch (error) {console.error(`[SSH] Error executing: ${cmd}`, error.message);}}}
}

注册模块(ssh.module.ts

import { Module } from '@nestjs/common';
import { SshService } from './ssh.service';@Module({providers: [SshService],exports: [SshService],
})
export class SshModule {}

控制器调用示例(app.controller.ts

import { Controller, Get } from '@nestjs/common';
import { SshService } from './ssh.service';@Controller()
export class AppController {constructor(private readonly sshService: SshService) {}@Get('test-ssh')async testSsh() {await this.sshService.connectAndCreateFile('nest_test_file.txt');return { message: 'SSH command executed via NestJS' };}
}

注意事项:

  • 实际生产中禁止硬编码密码,应使用 dotenv 加载环境变量
  • 推荐使用私钥认证方式替代密码
  • 此方案适用于轻量级集成,大规模运维建议采用 Ansible、SaltStack 等专用工具

2 ) 方案2

虽然生产级 SSH 实现复杂,但可通过 Node.js 生态中的 ssh2 模块构建轻量级控制台工具
以下为一个基于 NestJS 架构理念封装的 SSH 连接服务示例

初始化项目结构

nest new ssh-client-demo
cd ssh-client-demo
npm install ssh2
npm install @types/ssh2 --save-dev

创建 SSH 服务类

// src/ssh/ssh.service.ts 
import { Injectable, Logger } from '@nestjs/common';
import { Client } from 'ssh2';@Injectable()
export class SshService {private readonly logger = new Logger(SshService.name);async connectAndExecute(host: string,port: number,username: string,password: string,commands: string[],): Promise<string[]> {return new Promise((resolve, reject) => {const conn = new Client();const results: string[] = [];conn.on('ready', () => {this.logger.log('SSH connection established.');let completed = 0;commands.forEach((cmd) => {conn.exec(cmd, (err, stream) => {if (err) {this.logger.error(`Command failed: ${cmd}`, err.message);results.push(`ERROR: ${err.message}`);if (++completed === commands.length) {conn.end();resolve(results);}return;}let stdout = '';let stderr = '';stream.on('close', (code, signal) => {this.logger.debug(`Command exited [${cmd}] code: ${code}, signal: ${signal}`);if (stderr) {results.push(`[${cmd}] ERROR: ${stderr}`);} else {results.push(`[${cmd}] OUTPUT:\n${stdout}`);}if (++completed === commands.length) {conn.end();resolve(results);}});stream.on('data', (data) => {stdout += data.toString();});stream.stderr.on('data', (data) => {stderr += data.toString();});});});});conn.on('error', (err) => {this.logger.error('SSH connection error', err.message);reject(err);});conn.connect({host,port,username,password,readyTimeout: 10000,});});}
}

注册模块并暴露 CLI 脚本

// src/ssh/ssh.module.ts
import { Module } from '@nestjs/common';
import { SshService } from './ssh.service';@Module({providers: [SshService],exports: [SshService],
})
export class SshModule {}
// src/app.service.ts
import { Injectable } from '@nestjs/common';
import { SshService } from './ssh/ssh.service';@Injectable()
export class AppService {constructor(private readonly sshService: SshService) {}async runRemoteTasks() {const host = '172.20.10.2';const port = 22;const username = 'root';const password = 'your_root_password'; // In practice, use ENV or vaultconst commands = ['whoami', 'ls -la', 'touch nestjs_test.txt', 'echo "Hello from NestJS SSH" > hello.txt'];try {const outputs = await this.sshService.connectAndExecute(host, port, username, password, commands);outputs.forEach((output, index) => {console.log(`Step ${index + 1} Result:\n${output}\n---`);});} catch (error) {console.error('Failed to execute remote commands:', error.message);}}
}
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AppService } from './app.service';async function bootstrap() {const app = await NestFactory.create(AppModule);const appService = app.get(AppService);// 执行 SSH 任务await appService.runRemoteTasks();await app.close(); // 自动退出 
}
bootstrap();

运行效果说明

执行 npm run start 后,程序将:

  • 连接到指定服务器
  • 依次执行 whoami, ls, touch, echo 四条命令
  • 收集每条命令的标准输出与错误信息
  • 输出至本地控制台
  • 自动关闭连接

注意:

  • 此仅为演示用途,不可用于生产环境替代真实 SSH 客户端
  • 实际场景中应结合密钥认证、连接池、日志审计等功能增强健壮性

3 )方案 3

为体现自动化运维场景下的编程整合能力,以下提供一个基于 NestJS 框架的SSH连接服务模拟实现,使用 node-libsshssh2 库进行底层调用。

安装依赖

npm install ssh2
npm install @nestjs/common @nestjs/core

创建SSH服务类

// ssh.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { Client } from 'ssh2';interface SshConnectionOptions {host: string;port?: number;username: string;password?: string;privateKey?: string;
}@Injectable()
export class SshService {private readonly logger = new Logger(SshService.name);async executeCommand(options: SshConnectionOptions,command: string,): Promise<string> {return new Promise((resolve, reject) => {const conn = new Client();conn.on('ready', () => {this.logger.log('SSH connection established');conn.exec(command, (err, stream) => {if (err) {conn.end();return reject(err);}let output = '';let errorOutput = '';stream.on('data', (data) => {output += data.toString();}).stderr.on('data', (data) => {errorOutput += data.toString();}).on('close', (code, signal) => {conn.end();if (code === 0) {resolve(output);} else {reject(new Error(`Command failed with code ${code}: ${errorOutput}`));}});});});conn.on('error', (err) => {reject(new Error(`SSH connection error: ${err.message}`));});conn.connect({host: options.host,port: options.port || 22,username: options.username,...(options.password ? { password: options.password } : {}),...(options.privateKey ? { privateKey: options.privateKey } : {}),});});}async createTestFile(ip: string, user: string, pass: string): Promise<void> {const cmd = 'touch /tmp/test_nestjs_ssh.txt && ls /tmp/ | grep test_nestjs_ssh.txt';try {const result = await this.executeCommand({ host: ip, username: user, password: pass },cmd,);this.logger.log(`File creation verified on ${ip}: ${result.trim()}`);} catch (err) {this.logger.error(`Failed to create file via SSH: ${(err as Error).message}`);}}
}

注册模块并调用

// app.module.ts
import { Module } from '@nestjs/common';
import { SshService } from './ssh.service';@Module({providers: [SshService],exports: [SshService],
})
export class SshModule {}

在控制器中测试

// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { SshService } from './ssh.service';@Controller()
export class AppController {constructor(private readonly sshService: SshService) {}@Get('ssh-test')async sshTest() {await this.sshService.createTestFile('172.20.10.2', 'root', 'your_password');return { status: 'SSH test initiated' };}
}

安全提醒:生产环境中应避免明文存储密码,建议结合Vault、环境变量或密钥对方式进行认证

SSH 构建安全运维基石

SSH 不仅是远程登录工具,更是现代 DevOps 流程的基础组件,支撑着自动化部署、配置管理(Ansible)、容器编排(Kubernetes 节点接入)等多种关键场景

通过对服务端 sshd 的正确配置与客户端多样化接入方式的理解,可构建稳定、安全、高效的服务器管理体系。无论是图形化工具还是命令行接口,亦或是程序化调用,底层均遵循相同的加密协议规范(SSH-2),保证了跨平台兼容性与安全性

掌握 SSH 全链路部署与调试能力,是每一位系统工程师、运维开发人员不可或缺的核心技能

http://www.dtcms.com/a/515499.html

相关文章:

  • 好看网站手机版南开做网站公司
  • 七日 Go 的自学笔记 (一)
  • Node.js 接入淘宝 API 实战:构建商品信息实时同步服务
  • Node.js SQL数据库:MySQL/PostgreSQL集成
  • 虚拟化网络连接与虚拟机嵌套
  • 无锡企业制作网站网站建设项目的费用做什么科目
  • Slack消息体->消息ID的设计
  • 如何轻松将 Outlook 联系人导出到 Excel
  • 图像尺寸测量仪应用Type-C接口:精准检测,赋能科技
  • C++仿mudo库高并发服务器项目:Buffer模块
  • 找能做网站的搜狗推广下架
  • 性能分析--perfetto工具使用
  • 【matlab】如何提取论文plot图中的数据
  • 手机网站开发的目的ppt免费背景图片
  • Java 核心知识点查漏补缺(一)
  • UE5 C++ CVar控制台命令字段使用
  • 从图像处理到AI识别:直播美颜sdk如何实现高效一键美颜?
  • ESD防护设计宝典(十三):电快速瞬变脉冲群(EFT)防护与整改
  • 做百度推广去些网站加客户二级域名免费申请网站
  • 婚介 东莞网站建设西部数码网站源码
  • 云计算实验4——CentOS中HBase的安装
  • Excel文件中的VBA脚本,在文件使用WPS编辑保存后无法执行
  • LLD(详细设计文档)输出标准模板
  • 【山西政务服务网-注册_登录安全分析报告】
  • 云原生安全深度实战:从容器安全到零信任架构
  • Java导出写入固定Excel模板数据
  • 合肥网站建设模板系统html怎么做商品页面
  • uniapp微信小程序页面跳转后定时器未清除问题解析与解决方案
  • 《从“直接对话”到 “集成开发调用”:智谱 GLM-4.6 引领 Coding 场景的效率跃迁》
  • 数据中心基础设施等级