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 公钥认证机制,开发者不仅能显著提升工作效率,更能构建更加安全、可靠的分布式系统运维环境

相关推荐
yunlong32671 小时前
吊装助理三维结构有限元分析操作教程
安全·有限元·方案·安全分析·吊装·起重·结构计算
hugerat1 小时前
在AI的帮助下,用C++构造微型http server
linux·c++·人工智能·http·嵌入式·嵌入式linux
ha20428941942 小时前
Linux操作系统学习记录之----自定义协议(网络计算器)
linux·网络·学习
想唱rap2 小时前
MYSQL在ubuntu下的安装
linux·数据库·mysql·ubuntu
糖~醋排骨2 小时前
DHCP服务的搭建
linux·服务器·网络
Kiyra2 小时前
虚拟机假死?SSH 能连却卡 Logo 界面
运维·ssh
dust_and_stars3 小时前
ubuntu24使用apt安装VS-code-server code-server
linux·服务器·windows
码农小韩3 小时前
基于Linux的C++学习——循环
linux·c语言·开发语言·c++·算法
ling-453 小时前
Linux-day09 11
linux·运维·服务器
202321336054 刘3 小时前
Linux常用命令分类整理
linux·运维·数据库