Linux小课堂: SSH 免密登录原理与实现之基于公钥认证的安全连接机制

SSH 认证方式概述

在 Linux 系统中,SSH(Secure Shell)是一种用于安全远程登录和数据通信的加密协议。其核心功能是在不安全的网络环境中建立安全的通信通道。SSH 提供了多种身份验证方法,其中最常用的有两种:

  • 基于口令的身份验证(Password-based Authentication)
  • 基于密钥的身份验证(Public Key-based Authentication)

基于口令的身份验证

这是最常见的登录方式,用户通过输入用户名和密码完成身份校验。例如,在客户端执行以下命令:

bash 复制代码
ssh root@172.20.10.2

系统将提示输入 root 用户的密码。只有当提供的凭证正确时,才能成功登录目标服务器。

该方式虽然简单易用,但存在明显安全隐患:

  • 密码可能被暴力破解;
  • 易受中间人攻击(MITM);
  • 每次连接都需要重复输入,操作繁琐。

相比之下,基于密钥的验证提供了更高的安全性与自动化能力,也是现代 DevOps 实践中的标准配置。该方法利用非对称加密算法生成一对密钥:私钥(Private Key)保留在本地客户机,公钥(Public Key)上传至远程服务器。登录时,SSH 客户端使用私钥进行签名挑战,服务器则用存储的公钥验证签名,从而实现无密码认证

因此,在生产环境或自动化运维场景下,推荐使用更安全的基于密钥的认证方式

基于密钥的身份验证原理

基于密钥的身份验证依赖于非对称加密技术,即一对匹配的密钥:公钥(Public Key) 和 私钥(Private Key)。

  • 私钥:保存在客户端本地,必须严格保密,不可泄露。
  • 公钥:可公开分发,需上传至目标服务器的特定文件中。

其工作流程如下:

  1. 客户端生成一对密钥(公钥 + 私钥);
  2. 将公钥上传至服务器对应用户的 ~/.ssh/authorized_keys 文件中;
  3. 当客户端发起 SSH 连接请求时,服务器会查找是否存在匹配的公钥;
  4. 若存在,则服务器使用该公钥加密一段挑战信息并发送给客户端;
  5. 客户端使用本地私钥解密并返回响应;
  6. 服务器验证响应正确后,允许登录,无需输入密码。

这种方式被称为 公钥认证登录(Public Key Authentication Login),具有更高的安全性与便捷性。

关键术语强调:

  • 非对称加密(Asymmetric Encryption)
  • 公钥(Public Key)
  • 私钥(Private Key)
  • authorized_keys 文件
  • SSH 密钥对生成工具(ssh-keygen)

SSH 免密登录实施步骤详解

实现 SSH 免密码登录的第一步是在客户机上生成一对非对称加密密钥

1 ) 第一步:在客户端生成 SSH 密钥对

使用 ssh-keygen 命令生成密钥对。该命令全称为 SSH Key Generation,用于创建、管理和转换认证密钥。

默认情况下,ssh-keygen 使用 RSA 算法生成 2048 位长度的密钥对。执行命令如下:

bash 复制代码
ssh-keygen

该命令全称为 SSH Key Generation,用于生成、管理和转换认证密钥

默认情况下,ssh-keygen 使用 RSA 算法生成密钥对,等价于显式指定 -t rsa 参数:

系统将提示以下信息:

conf 复制代码
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

参数说明:

  • 保存路径:默认为当前用户家目录下的 ~/.ssh/id_rsa(私钥)和 ~/.ssh/id_rsa.pub(公钥)。建议使用默认路径以确保兼容性。
  • Passphrase:用于对私钥进行二次加密保护。若为空,则表示无加密,适用于自动化脚本;若设置,每次使用私钥时需输入此密码。

安全建议:在高安全要求环境下应设置强 passphrase;但在 CI/CD 自动化部署中通常留空以便免交互运行。

等效命令(显式指定算法):

bash 复制代码
ssh-keygen -t rsa

-t rsa 指定使用 RSA 算法;若省略,默认仍为 RSA

支持的密钥类型包括:

  • -t rsa:RSA 算法(默认,广泛兼容)
  • -t dsa:DSA 算法(已不推荐)
  • -t ecdsa:椭圆曲线 DSA
  • -t ed25519:EdDSA 高性能算法(现代首选)

推荐使用 Ed25519:

bash 复制代码
ssh-keygen -t ed25519 -C "your_email@example.com"

建议直接按回车使用默认路径。随后系统会询问是否为私钥设置访问密码(passphrase),若希望完全免交互登录,则可留空,直接回车跳过

执行后,系统提示:

text 复制代码
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
  • 可按回车使用默认路径 /home/user/.ssh/id_rsa
  • Passphrase 可留空(实现完全免交互),但在高安全场景建议设置

执行后,系统会提示用户选择密钥保存路径。默认路径为当前用户的家目录下的隐藏 .ssh 文件夹:

~/.ssh/ 目录下创建两个文件:

文件名 类型 说明
id_rsa 私钥 不得泄露
id_rsa.pub 公钥 可安全上传至远程主机

生成完成后,可通过以下命令查看公钥内容:

bash 复制代码
cat ~/.ssh/id_rsa.pub 

输出形如:

conf 复制代码
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArV... root@client-host 

这是一段以 ssh-rsa 开头的标准 SSH 公钥字符串,包含编码后的密钥数据及注释部分(通常是 user@host 格式)

重要安全提示:私钥文件 id_rsa 必须严格保护,权限应设为 600,防止其他用户读取:

bash 复制代码
chmod 600 ~/.ssh/id_rsa

2 ) 第二步:将公钥传输至服务器

将客户端生成的公钥写入目标服务器的 ~/.ssh/authorized_keys 文件中,是实现免密登录的核心步骤。

方法一:使用 ssh-copy-id 命令(推荐)

bash 复制代码
ssh-copy-id root@172.20.10.2

该命令等价于:

bash 复制代码
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.20.10.2

-i 参数用于指定要上传的公钥文件路径,若不指定则默认使用 ~/.ssh/id_rsa.pub

该命令的作用等价于手动执行以下流程:

  1. 建立 SSH 连接至目标主机(仍需首次输入密码)
  2. 在目标主机的 ~/.ssh/authorized_keys 文件末尾追加本机公钥内容
  3. 确保 .ssh 目录和 authorized_keys 文件权限正确

首次运行需输入远程用户的密码:

text 复制代码
root@172.20.10.2's password: 
Number of keys added: 1
Now try logging into the machine...

成功后,目标服务器会在 /root/.ssh/authorized_keys 文件末尾追加客户端的公钥

成功后即表示公钥已注册

该命令的作用是:

  • 以指定用户身份登录远程主机;
  • 自动创建 ~/.ssh 目录(如不存在);
  • 将本地公钥追加到 ~/.ssh/authorized_keys 文件末尾;
  • 设置正确的文件权限(600 for authorized_keys, 700 for .ssh directory)

技术细节解析:

ssh-copy-id 实际上是封装了如下操作:

bash 复制代码
> cat ~/.ssh/id_rsa.pub | ssh root@172.20.10.2 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

首次运行时仍需输入一次密码,之后即可实现免密登录

方法二:手动方式(适用于无法使用 ssh-copy-id 的环境)

若目标系统未安装 ssh-copy-id(如某些最小化安装的容器或旧版系统),可手动完成:

1 ) 在客户端输出公钥:

bash 复制代码
cat ~/.ssh/id_rsa.pub

2 )登录服务器,编辑授权密钥文件:

bash 复制代码
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

3 )将客户端公钥内容粘贴至 ~/.ssh/authorized_keys 中,每行一个公钥

关键点总结:

  • authorized_keys 是复数形式,意味着一个用户可以接受来自多个客户机的公钥
  • 每个公钥独占一行,格式必须完整且无换行截断
  • 若文件不存在需手动创建;若目录不存在需先创建 .ssh 目录

4 ) authorized_keys 文件详解与多客户端管理

~/.ssh/authorized_keys 是 SSH 服务用于存储可信公钥的关键文件。其特点包括:

  • 每行保存一个公钥,格式为:<key-type> <base64-encoded-public-key> [comment]
  • 支持多个客户端公钥共存,实现"一台服务器被多个用户免密访问"
  • 权限必须为 600(即仅所有者可读写),否则 SSH 会拒绝加载

示例内容:

text 复制代码
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArV1... client1@local
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqX9... client2@dev

注意事项:

  • 若文件权限错误(如 644),SSH 守护进程将忽略该文件,导致密钥登录失败
  • 推荐执行以下修复命令:
bash 复制代码
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown $USER:$USER ~/.ssh -R

验证免密登录效果

配置完成后,尝试直接登录服务器:

bash 复制代码
ssh root@172.20.10.2

若未提示输入密码且成功进入 shell,则表示配置成功

完成上述步骤后,即可尝试免密登录:

bash 复制代码
ssh root@172.20.10.2

若配置正确,系统将不再要求输入密码,直接进入远程 shell。

强制启用密码登录(临时切换)

有时需要临时恢复密码登录进行调试或故障排查,可通过以下命令显式指定认证方式:

bash 复制代码
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@172.20.10.2

参数说明:

参数 含义
PreferredAuthentications=password 优先使用密码认证
PubkeyAuthentication=no 明确禁用公钥认证

此命令可用于验证账户密码是否有效,或排除密钥配置问题

此外,常用调试命令:

  • 查看当前连接使用的认证方式:
bash 复制代码
ssh -v root@172.20.10.2
  • 验证公钥一致性:
bash 复制代码
客户端查看公钥指纹
ssh-keygen -l -f ~/.ssh/id_rsa.pub
 
服务器端查看已注册公钥指纹
ssh-keygen -l -f /root/.ssh/authorized_keys

日志与排错建议

若登录失败,可在服务器端检查 SSH 服务日志:

bash 复制代码
sudo tail -f /var/log/auth.log
或 CentOS/RHEL 系统:
sudo tail -f /var/log/secure

常见错误包括:

错误现象 可能原因
Permission denied (publickey) 公钥未正确写入 authorized_keys
Bad permissions on ~/.ssh or ~/.ssh/authorized_keys 权限设置不当(必须为 700 / 600)
No supported authentication methods available 客户端未发送公钥或服务器拒绝所有方式

故障排查提示:

  • 确保服务器端 SSH 服务允许公钥认证(检查 /etc/ssh/sshd_configPubkeyAuthentication yes
  • 检查 ~/.sshauthorized_keys 的权限是否正确
  • 查看日志:tail -f /var/log/auth.logjournalctl -u sshd

灵活控制认证方式:按需切换密码或密钥登录

尽管公钥认证提升了便利性和安全性,但在某些调试场景下仍可能需要临时启用密码登录。

强制使用密码认证

可通过 -o 参数覆盖默认配置,强制使用密码方式进行认证:

bash 复制代码
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@172.20.10.2

参数解释:

  • PreferredAuthentications=password:优先使用密码认证;
  • PubkeyAuthentication=no:禁用公钥认证。

此命令可用于:

  • 测试账户密码有效性;
  • 在密钥损坏或丢失时应急登录;
  • 安全审计过程中的多因素验证测试。

提示:此类参数仅对本次连接生效,不会修改全局配置

跨平台适配:Windows 用户实现 SSH 免密登录

对于 Windows 用户,可通过第三方工具实现类似功能。

工具推荐:PuTTY 及 PuTTYgen(PuTTY Key Generator)

PuTTY 是一款流行的 Windows SSH 客户端,其配套工具 PuTTYgen 可用于生成 SSH 密钥对。

操作流程:

  1. 下载 PuTTY 官网 提供的 putty.exeputtygen.exe
  2. 启动 puttygen.exe,点击"Generate"生成密钥对
  3. 选择加密算法(推荐 RSA,2048 位以上)
  4. 保存私钥为 .ppk 格式(PuTTY 私钥格式)
  5. 复制右侧显示的公钥内容
  6. 登录 Linux 服务器,将公钥粘贴至 ~/.ssh/authorized_keys 文件中
  7. 使用 PuTTY 加载 .ppk 私钥进行连接,即可实现免密登录

使用 Xshell、SecureCRT 等商业终端

主流终端软件均支持公钥认证机制,基本流程一致:

  1. 在软件内生成密钥对(通常基于 RSA)
  2. 导出公钥内容
  3. 手动上传至服务器的 ~/.ssh/authorized_keys
  4. 配置会话使用对应私钥进行认证

注意事项:

  • .ppk 文件为 PuTTY 特有格式,标准 OpenSSH 不识别
  • 如需与其他工具互通,可在 PuTTYgen 中导出 OpenSSH 格式的私钥
  • 推荐现代 Windows 用户使用 WSL2 + 原生 OpenSSH 工具链,获得最佳兼容性

统一核心原理:无论操作系统或客户端工具如何变化,SSH 公钥认证的本质始终不变------服务器信任预先登记的公钥,客户端持有对应的私钥完成身份挑战

企业级工具支持:Xshell、SecureCRT 等终端软件配置

主流商业 SSH 客户端如 Xshell、SecureCRT 等也支持公钥认证。

通用配置流程:

  1. 在软件界面中生成或导入密钥对;
  2. 设置会话属性,启用"Public Key"认证方式;
  3. 指定私钥文件路径;
  4. 将生成的公钥手动添加至服务器 authorized_keys 文件;
  5. 保存会话配置,下次连接自动完成认证。

相关搜索关键词:

  • Xshell 配置 SSH 免密码登录
  • SecureCRT 使用密钥登录 Linux
  • PuTTY 免输密码自动登录 Linux

原理完全一致,均为实现 客户端持有私钥 + 服务器存储公钥 的信任模型

基于 NestJS + TypeScript 的 SSH 密钥管理模块示例

1 ) 方案1

为便于 DevOps 工程师集成 SSH 功能至 Node.js 应用,以下提供一个基于 NestJS 框架的模块示例,用于生成密钥对、读取公钥、推送至远程服务器等功能。

项目结构

tree 复制代码
src/
├── ssh/
│   ├── ssh.service.ts
│   ├── ssh.controller.ts
│   └── dto/
│       └── generate-key.dto.ts

DTO 定义:GenerateKeyDto

ts 复制代码
// src/ssh/dto/generate-key.dto.ts
export class GenerateKeyDto {
  algorithm: 'rsa' | 'ed25519' = 'rsa';
  bits?: number = 2048;
  passphrase?: string;
  comment?: string;
}

SSH Service(核心逻辑)

ts 复制代码
// src/ssh/ssh.service.ts
import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';
 
@Injectable()
export class SshService {
  private readonly sshDir = path.join(process.env.HOME || '', '.ssh');
 
  ensureSshDir() {
    if (!fs.existsSync(this.sshDir)) {
      fs.mkdirSync(this.sshDir, { mode: 0o700 });
    }
  }
 
  generateKeyPair(dto: GenerateKeyDto): { publicKey: string; privateKeyPath: string } {
    this.ensureSshDir();
 
    const { algorithm, bits, passphrase, comment } = dto;
    const keyName = `id_${algorithm}`;
    const privateKeyPath = path.join(this.sshDir, keyName);
    const publicKeyPath = `${privateKeyPath}.pub`;
 
    // 清除旧密钥
    [privateKeyPath, publicKeyPath].forEach(p => {
      if (fs.existsSync(p)) fs.unlinkSync(p);
    });
 
    let cmd = `ssh-keygen -t ${algorithm} -b ${bits} -f "${privateKeyPath}" -N "${passphrase || ''}"`;
    if (comment) cmd += ` -C "${comment}"`;
 
    try {
      execSync(cmd, { stdio: 'pipe' });
      const publicKey = fs.readFileSync(publicKeyPath, 'utf-8').trim();
      fs.chmodSync(privateKeyPath, 0o600);
      fs.chmodSync(publicKeyPath, 0o644);
 
      return { publicKey, privateKeyPath };
    } catch (error) {
      throw new Error(`Key generation failed: ${error.message}`);
    }
  }
 
  appendPublicKeyToRemote(publicKey: string, host: string, username: string, port = 22) {
    const script = `
      mkdir -p ~/.ssh 
      chmod 700 ~/.ssh
      echo '${publicKey}' >> ~/.ssh/authorized_keys
      chmod 600 ~/.ssh/authorized_keys
    `;
    const encodedScript = Buffer.from(script).toString('base64');
    const fullCmd = `echo '${encodedScript}' | base64 -d | ssh -p ${port} ${username}@${host} '/bin/bash'`;
 
    try {
      execSync(fullCmd, { stdio: 'inherit' });
    } catch (error) {
      throw new Error(`Failed to upload public key: ${error.message}`);
    }
  }
}

Controller 示例

ts 复制代码
// src/ssh/ssh.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { SshService } from './ssh.service';
import { GenerateKeyDto } from './dto/generate-key.dto';
 
@Controller('ssh')
export class SshController {
  constructor(private readonly sshService: SshService) {}
 
  @Post('generate-key')
  generateKey(@Body() dto: GenerateKeyDto) {
    const result = this.sshService.generateKeyPair(dto);
    return {
      message: 'Key pair generated successfully',
      publicKey: result.publicKey,
      privateKeyPath: result.privateKeyPath,
    };
  }
 
  @Post('setup-passwordless')
  setupPasswordless(@Body() body: { publicKey: string; host: string; username: string }) {
    this.sshService.appendPublicKeyToRemote(body.publicKey, body.host, body.username);
    return { message: 'Public key uploaded. Passwordless login enabled.' };
  }
}

使用说明

启动 NestJS 应用后,调用接口:

http 复制代码
POST /ssh/generate-key 
Content-Type: application/json
 
{
  "algorithm": "ed25519",
  "comment": "auto-generated-for-ci"
}

返回:

json 复制代码
{
  "message": "Key pair generated successfully",
  "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ...",
  "privateKeyPath": "/home/user/.ssh/id_ed25519"
}

再调用:

http 复制代码
POST /ssh/setup-passwordless
Content-Type: application/json
 
{
  "publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ...",
  "host": "172.20.10.2",
  "username": "root"
}

即可完成全自动化的 SSH 免密配置

2 )方案2

示例:使用 node-ssh 实现自动部署

安装依赖:

bash 复制代码
npm install node-ssh 

编写部署脚本 deploy.ts

typescript 复制代码
import { NodeSSH } from 'node-ssh';
 
async function deploy(): Promise<void> {
  const ssh = new NodeSSH();
 
  try {
    // 连接服务器(使用私钥认证)
    await ssh.connect({
      host: '172.20.10.2',
      username: 'root',
      privateKeyPath: '~/.ssh/id_rsa', // 确保路径正确
    });
 
    console.log('✅ SSH 连接成功');
 
    // 创建应用目录
    await ssh.execCommand('mkdir -p /opt/my-nest-app');
 
    // 上传构建文件
    await ssh.putDirectory('./dist', '/opt/my-nest-app/dist', {
      recursive: true,
      concurrency: 10,
    });
 
    // 重启服务(假设使用 pm2)
    const restartResult = await ssh.execCommand(
      'cd /opt/my-nest-app && pm2 restart main.js || pm2 start main.js'
    );
 
    if (restartResult.stderr) {
      console.error('❌ 服务重启失败:', restartResult.stderr);
    } else {
      console.log('🎉 部署完成,服务已重启');
    }
 
    // 关闭连接 
    ssh.dispose();
  } catch (error) {
    console.error('🚨 部署异常:', error.message);
  }
}
 
// 执行部署 
deploy();

编译并运行:

bash 复制代码
npx ts-node deploy.ts

此脚本依赖 SSH 免密登录配置,确保 ~/.ssh/id_rsa 对当前用户可读,并已在目标服务器注册公钥

3 )方案3

基于 Node.js 的 SSH 自动化示例代码,使用 node-libsshssh2 包实现

安装依赖

bash 复制代码
npm install ssh2

NestJS Service 示例:SSH 部署模块

typescript 复制代码
// ssh-deploy.service.ts
import { Injectable } from '@nestjs/common';
import { Client } from 'ssh2';
 
@Injectable()
export class SshDeployService {
  private readonly serverConfig = {
    host: '172.20.10.2',
    port: 22,
    username: 'root',
    privateKey: require('fs').readFileSync('/path/to/id_rsa'), // 私钥路径
  };
 
  async deployApp(): Promise<string> {
    return new Promise((resolve, reject) => {
      const conn = new Client();
 
      conn
        .on('ready', () => {
          console.log('SSH Connection established');
          conn.exec(
            'cd /var/www/myapp && git pull origin main && npm install && pm2 restart app',
            (err, stream) => {
              if (err) throw err;
 
              let output = '';
              stream 
                .on('data', (data) => {
                  output += data.toString();
                  console.log(data.toString());
                })
                .stderr.on('data', (data) => {
                  console.error('STDERR:', data.toString());
                })
                .on('close', (code, signal) => {
                  conn.end();
                  if (code === 0) {
                    resolve(`Deployment successful: ${output}`);
                  } else {
                    reject(new Error(`Deployment failed with code ${code}`));
                  }
                });
            },
          );
        })
        .connect(this.serverConfig);
    });
  }
 
  async testConnection(): Promise<boolean> {
    return new Promise((resolve) => {
      const conn = new Client();
      conn 
        .on('ready', () => {
          console.log('Test connection OK');
          conn.end();
          resolve(true);
        })
        .on('error', (err) => {
          console.error('SSH Connection Failed:', err.message);
          resolve(false);
        })
        .connect(this.serverConfig);
    });
  }
}

控制器调用示例

typescript 复制代码
// deploy.controller.ts
import { Controller, Post } from '@nestjs/common';
import { SshDeployService } from './ssh-deploy.service';
 
@Controller('deploy')
export class DeployController {
  constructor(private readonly sshDeployService: SshDeployService) {}
 
  @Post('trigger')
  async triggerDeployment() {
    const isConnected = await this.sshDeployService.testConnection();
    if (!isConnected) {
      return { status: 'error', message: 'Cannot connect via SSH' };
    }
 
    try {
      const result = await this.sshDeployService.deployApp();
      return { status: 'success', message: result };
    } catch (error) {
      return { status: 'error', message: error.message };
    }
  }
}

此方案依赖 SSH 密钥认证,确保自动化流程无需人工输入密码,符合无人值守部署需求

构建安全高效的远程访问体系

要点 内容
核心机制 使用非对称加密实现公钥认证,取代明文密码
关键步骤 生成密钥对 → 上传公钥 → 修改 authorized_keys 权限
最佳实践 私钥加密(passphrase)、禁用密码登录、定期轮换密钥
跨平台兼容 OpenSSH 格式为通用标准,Windows 工具需导出兼容格式
自动化集成 结合 NestJS、CI/CD 实现无感部署,提升运维效率

最终建议:

在生产环境中,应进一步加固 SSH 安全策略:

bash 复制代码
# 编辑 /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin prohibit-password 
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM no

并重启服务:

bash 复制代码
sudo systemctl restart sshd

通过上述配置与实践,可构建一套兼具安全性、便捷性与自动化能力的 SSH 访问体系,成为 Linux 系统管理的基石之一

总结与最佳实践

核心要点回顾

  • SSH 支持两种认证方式:口令认证 与 公钥认证
  • 公钥认证基于非对称加密,安全性更高
  • 私钥必须妥善保管于本地客户机,不得泄露
  • 成功配置后,后续所有 SSH 连接(包括 scp、sftp、自动化脚本等)均可实现无缝免密码认证
  • 使用 ssh-keygen 生成密钥对,ssh-copy-id 推送公钥
  • 公钥存储于服务器端 ~/.ssh/authorized_keys 文件中
  • 权限设置至关重要:.ssh 目录为 700authorized_keys600
  • 可通过 -o 参数临时切换认证方式
  • Windows 平台可通过 PuTTYgen 等工具实现相同功能
  • 企业级工具如 Xshell、SecureCRT 同样遵循相同原理
  • 可结合 NestJS + TypeScript 构建自动化密钥管理系统

安全最佳实践

推荐做法:

  • 使用 ed25519 替代传统 rsa 算法;
  • 对敏感环境的私钥设置 strong passphrase;
  • 定期轮换密钥;
  • 限制 authorized_keys 中的 command 字段(高级用法);
  • 结合 Fail2ban 防止暴力试探。

避免行为:

  • 将私钥上传至版本控制系统(如 Git);
  • 使用弱 passphrase 或空 passphrase 在高风险环境;
  • 忽略文件权限导致 SSH 拒绝加载密钥

进阶建议:

  • 使用 ssh-agent 管理多个私钥,避免频繁加载
  • 配置 ~/.ssh/config 简化连接命令
  • 定期轮换密钥,提升长期安全性
  • 结合堡垒机或 Jump Server 构建多层访问控制体系

通过深入理解并熟练运用 SSH 公钥认证机制,开发者不仅能显著提升工作效率,更能构建更加安全、可靠的分布式系统运维环境

相关推荐
Johny_Zhao13 小时前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
用户9623779544818 小时前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机21 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机21 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954481 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star1 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954481 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
chlk1232 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑2 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件2 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux