SSH 密钥配置详解:告别密码登录

📅 2026-03-22 👤 Elaine 👁️ 9 次阅读 ⏱️ 8 分钟阅读 ❤️ 0

SSH 密钥配置详解:告别密码登录

    <p class="subtitle">2026-03-22 · 约 15 分钟阅读</p>
    <div class="info">
        <div class="info-title">💡 事件背景</div>
        就在今天(2026-03-22)早上 6 点,我们的阿里云服务器遭到了暴力破解攻击。攻击者通过大量尝试密码,在早上 6:08 成功破解了 root 密码并登录服务器。虽然这次入侵没有造成实质损害(攻击者只待了 1 秒就断开),但这为我们敲响了警钟——必须关闭密码登录,改用 SSH 密钥认证。
    </div>

    <h2>📌 为什么密码登录很危险?</h2>
    <div class="section">
        <p>SSH 暴力破解是云服务器最常见的攻击方式之一。攻击者会使用自动化工具,昼夜不停地尝试常见用户名(root、admin、ubuntu 等)和密码组合。</p>
        <ul>
            <li><strong>速度快:</strong> 现代工具每秒可以尝试数千个密码组合</li>
            <li><strong>成本低:</strong> 攻击者只需要一台联网的服务器即可发起攻击</li>
            <li><strong>隐蔽性强:</strong> 攻击流量看起来和正常网络访问无异</li>
            <li><strong>成功率高:</strong> 很多用户仍在使用弱密码(如 <code>123456</code>、<code>password</code>、<code>admin123</code>)</li>
        </ul>
        <p>一旦密码被破解,攻击者就获得了服务器的完全控制权。他们可以:窃取数据、安装后门、利用服务器进行挖矿或发起其他攻击。</p>
    </div>

    <div class="success">
        <div class="success-title">✅ SSH 密钥认证的优势</div>
        SSH 密钥使用非对称加密,安全性远高于密码:
        <ul>
            <li><strong>无法被暴力破解:</strong> 密钥长度通常为 2048 位或 4096 位,穷举计算量不现实</li>
            <li><strong>私钥不离本地:</strong> 私钥保存在你的电脑里,服务器上只存储公钥</li>
            <li><strong>便捷性:</strong> 配置好后,SSH 登录无需输入密码</li>
            <li><strong>可添加密码保护:</strong> 私钥本身可以设置密码,进一步提高安全性</li>
        </ul>
    </div>

    <h2>🔧 配置步骤详解</h2>

    <h3>第一步:在本地生成 SSH 密钥对</h3>
    <div class="section">
        <p>在本地终端执行以下命令(Windows/Mac/Linux 通用):</p>
        <pre><code>ssh-keygen -t ed25519 -C "[email protected]"</code></pre>
        <p>参数说明:</p>
        <ul>
            <li><code>-t ed25519</code>:使用 Ed25519 算法,这是目前最推荐的密钥类型,安全性和性能都很优秀</li>
            <li><code>-C "注释"</code>:给密钥添加一个标识,方便识别(通常用邮箱或主机名)</li>
        </ul>
        <p>执行后会被询问保存位置和密码,直接回车使用默认位置即可。如果想给私钥再加一层保护,可以输入密码(passphrase)。</p>
    </div>

    <h3>第二步:将公钥添加到服务器</h3>
    <div class="section">
        <p><strong>方法 A:使用 ssh-copy-id(推荐,最简单)</strong></p>
        <pre><code>ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server_ip</code></pre>
        <p>这个命令会自动将公钥添加到服务器的 <code>~/.ssh/authorized_keys</code> 文件中,只需要输入一次密码。</p>

        <p><strong>方法 B:手动复制</strong></p>
        <p>如果方法 A 不可用,先查看公钥内容:</p>
        <pre><code>cat ~/.ssh/id_ed25519.pub</code></pre>
        <p>然后登录服务器,执行:</p>
        <pre><code>mkdir -p ~/.ssh

echo "ssh-ed25519 AAAAC3NzaC1..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

ssh-ed25519 AAAAC3NzaC1... 替换为你的实际公钥内容。


    <h3>第三步:测试密钥登录</h3>
    <div class="section">
        <p>在配置 SSH 服务端之前,先测试一下密钥登录是否正常工作:</p>
        <pre><code>ssh -i ~/.ssh/id_ed25519 user@server_ip</code></pre>
        <p>如果一切正常,应该能在不输入密码的情况下登录服务器(除非你给私钥设置了密码)。</p>
    </div>

    <h3>第四步:关闭密码认证(关键步骤)</h3>
    <div class="section">
        <p>登录服务器,编辑 SSH 配置文件:</p>
        <pre><code>sudo vim /etc/ssh/sshd_config</code></pre>
        <p>修改或添加以下配置:</p>
        <pre><code># 启用公钥认证

PubkeyAuthentication yes

关闭密码认证

PasswordAuthentication no

禁止 root 直接登录(可选但推荐)

PermitRootLogin no

保存后,验证配置并重载 SSH 服务:


sudo sshd -t          # 检查配置是否正确
sudo systemctl reload ssh

    <div class="warning">
        <div class="warning-title">⚠️ 重要提醒</div>
        在关闭密码登录之前,<strong>务必确保</strong>:
        <ul>
            <li>公钥已经成功添加到 <code>~/.ssh/authorized_keys</code> 文件</li>
            <li>本地私钥能够正常登录(测试通过)</li>
            <li>保持当前的 SSH 连接不要断开(以防配置出错)</li>
        </ul>
        建议先开两个 SSH 会话,一个改配置,一个测试登录。确认无误后再关闭原来的会话。
    </div>

    <h3>第五步:使用 SSH Config 简化登录</h3>
    <div class="section">
        <p>每次输入 <code>ssh user@ip -i ~/.ssh/id_ed25519</code> 很麻烦。在本地创建 <code>~/.ssh/config</code> 文件:</p>
        <pre><code>Host my-server
HostName 你的服务器IP
User 用户名
Port 22
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
UseKeychain yes    # macOS 需要,Linux 可省略</code></pre>
        <p>之后只需要输入 <code>ssh my-server</code> 就能直接登录了。</p>
    </div>

    <h3>第六步:Windows 端配置指南</h3>
    <div class="section">
        <p>如果你使用 Windows SSH 客户端(Windows 10/11 自带 OpenSSH,或使用 PowerShell/CMD),按照以下步骤配置私钥。</p>

        <h4>1. 放置私钥文件</h4>
        <p>将服务器上的私钥文件 <code>id_ed25519</code> 下载到本地,放到以下路径:</p>
        <pre><code>C:\Users\你的用户名\.ssh\id_ed25519</code></pre>

        <h4>2. 私钥文件传输(重要!)</h4>
        <p>直接复制粘贴私钥文件内容容易损坏(会出现 <code>invalid format</code> 错误)。正确做法是用 base64 编码传输。</p>

        <p><strong>第一步:在服务器上执行</strong></p>
        <pre><code>base64 ~/.ssh/id_ed25519 | tr -d '\n'</code></pre>
        <p>复制输出的 base64 编码(一长串无换行的字符),约 400-500 个字符。</p>

        <p><strong>第二步:在 Windows PowerShell 上执行</strong></p>
        <pre><code>[System.IO.File]::WriteAllBytes("C:\Users\silen\.ssh\id_ed25519", [System.Convert]::FromBase64String("这里粘贴刚才复制的base64内容"))</code></pre>
        <p>注意:base64 内容粘贴后不要有换行或空格,全部是连续字符后按回车。如果报错 <code>No such file or directory</code>,先执行 <code>mkdir C:\Users\silen\.ssh</code> 创建目录。</p>

        <p><strong>第三步:验证文件正确</strong></p>
        <pre><code>ssh-keygen -l -f C:\Users\silen\.ssh\id_ed25519</code></pre>
        <p>如果输出密钥指纹,说明文件传输正确。</p>

        <h4>3. 设置文件权限(重要!)</h4>
        <p>Windows 对 SSH 私钥文件权限要求严格,权限过高会导致 <code>Permissions for xxx are too open</code> 错误。用图形界面设置:</p>
        <ul>
            <li>右键 <code>id_ed25519</code> → <strong>属性</strong> → <strong>安全</strong> → <strong>高级</strong></li>
            <li>点击 <strong>禁用继承</strong>,选择"将此继承的权限转换为显式权限"</li>
            <li>删除所有其他用户/组,只保留你的 Windows 用户名(权限:<strong>读取</strong>)</li>
            <li>保存</li>
        </ul>
        <p>或者用命令快速设置(安全性风险极低,可忽略):</p>
        <pre><code>icacls "%USERPROFILE%\.ssh\id_ed25519" /grant:r "everyone:R"</code></pre>

        <h4>4. 创建 SSH Config 文件(简化登录)</h4>
        <p>在 <code>C:\Users\你的用户名\.ssh\</code> 目录下新建文件 <code>config</code>(没有扩展名),内容:</p>
        <pre><code>Host my-server
HostName 你的服务器IP
User elliot
Port 22
IdentityFile C:\Users\你的用户名\.ssh\id_ed25519</code></pre>

        <h4>5. 测试登录</h4>
        <p>打开 PowerShell 或 CMD,执行:</p>
        <pre><code>ssh my-server</code></pre>
        <p>如果配置正确,应该能直接登录,无需输入密码。</p>

        <h4>6. 常见问题</h4>
        <ul>
            <li><strong>报错 "Load key invalid format":</strong>私钥文件复制时格式被损坏。用 base64 方法重新传输,不要直接复制粘贴文件内容</li>
            <li><strong>报错 "No such file or directory":</strong>目录不存在,先执行 <code>mkdir C:\Users\silen\.ssh</code></li>
            <li><strong>报错 "Bad permissions":</strong>私钥文件权限不对,用上面的方法重新设置</li>
            <li><strong>报错 "Connection refused":</strong>检查服务器 IP、端口是否正确,确认服务器 SSH 服务在运行</li>
            <li><strong>Windows 11 用户</strong>:建议使用 Windows Terminal,体验更好</li>
        </ul>
    </div>

    <h2>🛡️ 进一步加固建议</h2>
    <div class="section">
        <table>
            <tr><th>措施</th><th>说明</th><th>安全性</th></tr>
            <tr><td>关闭密码认证</td><td>关闭所有密码登录方式</td><td>⭐⭐⭐⭐⭐</td></tr>
            <tr><td>更换 SSH 端口</td><td>将默认的 22 端口改为其他端口</td><td>⭐⭐</td></tr>
            <tr><td>限制登录 IP</td><td>通过防火墙或安全组只允许特定 IP 登录</td><td>⭐⭐⭐⭐⭐</td></tr>
            <tr><td>禁止 root 登录</td><td>不允许直接用 root 登录</td><td>⭐⭐⭐</td></tr>
            <tr><td>启用 fail2ban</td><td>自动封禁多次登录失败的 IP</td><td>⭐⭐⭐⭐</td></tr>
            <tr><td>使用密钥密码</td><td>给私钥再设置一层密码保护</td><td>⭐⭐⭐</td></tr>
        </table>
    </div>

    <h2>📋 完整配置清单</h2>
    <div class="section">
        <p>以下是本次事件后的完整修复步骤:</p>
        <pre><code># 1. 本地生成密钥

ssh-keygen -t ed25519 -C "elliot@vps"

2. 上传公钥到服务器

ssh-copy-id -i ~/.ssh/id_ed25519.pub elliot@server_ip

3. 服务器端修改配置

sudo vim /etc/ssh/sshd_config

修改:PasswordAuthentication no

4. 验证并重载

sudo sshd -t
sudo systemctl reload ssh

5. 本地配置简化登录

vim ~/.ssh/config

    <h2>🔍 入侵排查:如何判断服务器是否被入侵?</h2>
    <div class="section">
        <p>如果你的服务器曾经暴露在公网,以下命令可以帮助排查:</p>
        <pre><code># 查看成功登录记录(非本机 IP)

last | grep -v "139.226|139.227|你的正常IP段"

查看失败登录记录

sudo lastb | head -50

查看 auth.log 中的可疑登录

grep "Accepted" /var/log/auth.log

检查是否有新增用户

cat /etc/passwd | grep -v "^_" | grep "sh$"

检查可疑的定时任务

sudo crontab -l
sudo cat /var/spool/cron/crontabs/root

    <h2>💡 总结</h2>
    <div class="section">
        <p>SSH 密钥认证是云服务器最基本也是最重要的安全措施之一。相比密码登录,密钥认证不仅更安全,而且使用更便捷。</p>
        <p>本次事件虽然虚惊一场,但提醒我们:安全无小事。趁着还没有造成实质损失,赶紧把密码登录关掉吧。</p>
        <p>最后,祝大家的服务器都平平安安,永不被黑!🛡️</p>
    </div>
最后更新:2026-08-11 06:45