Laravel中如何配置安全的远程SSH命令执行
关于laravelcollective/remote包SSH密钥配置的说明
当前场景
- 日常通过
laravelcollective/remote包连接外部生产服务器执行Docker命令,示例调用代码为:SSH::into('production')->run(["docker inspect --format='{{.Name}}' {$id}"], function($container) { // ... }); - 目前可检索的包文档仅覆盖Laravel 4.2适配版本的历史说明,暂未找到6.x版本的官方公开配置文档
- 现有可正常运行的基础SSH连接配置为纯密码登录模式:
'connections' => [ 'production' => [ 'host' => 'xx.xx.xxx.x', 'username' => 'xxx', 'password' => 'xxx', 'key' => '', 'keytext' => '', 'keyphrase' => '', 'agent' => '', 'timeout' => 10, ], ], - 已验证基础命令执行正常:
SSH::into('production')->run(['ls'], function($x) { echo $x; });
核心问题
- 纯密码登录的SSH连接模式安全性水平如何
- 配置项里预留的
key、keytext、keyphrase、agent字段具体含义是什么 - 如何生成对应字段所需的参数
配置字段实际作用
- key:存储本地SSH私钥文件的绝对路径。当切换为密钥认证模式时,包会从这个指定路径读取私钥文件完成SSH握手,不再需要依赖密码字段认证
- keytext:直接传入SSH私钥的完整文本内容,和
key字段为互斥二选一关系。如果不希望把私钥固定存在磁盘的可暴露路径下(比如需要对配置做加密版本管理、避免文件路径泄漏带来的风险),可以直接把私钥全文填入这个字段,无需读取本地磁盘文件 - keyphrase:SSH私钥的保护口令。如果你在生成密钥对时给私钥设置了独立的访问口令,连接时必须传入这个值才能正常加载私钥完成认证——就算私钥文件泄漏,没有这个口令也无法用私钥登录服务器
- agent:系统SSH Agent进程的套接字路径。如果你的应用服务器已经把私钥加载到系统级的SSH Agent进程中,直接填入对应的套接字路径,包就会直接调用Agent中已加载的私钥完成连接,不需要在配置文件里存储任何私钥明文、密码内容
纯密码登录的安全风险
生产环境长期使用纯密码登录的SSH连接存在明确的安全短板:
- 密码以明文形式存在配置文件中,一旦配置文件泄漏,任何拿到文件的主体都可以直接登录生产服务器,没有二次防护
- 公网暴露SSH端口的场景下,密码认证极易被暴力破解、撞库攻击扫描
- 静态密码的轮换成本极高,一旦泄漏需要同时修改服务器密码和应用端配置,容易影响线上业务
密钥配置生成步骤
- 在运行Laravel应用的服务器上执行密钥生成命令,生成专门用于该远程连接的独立密钥对(不要复用个人日常登录的密钥):
生成过程中按提示设置强保护口令,这个口令值就是后续需要填入ssh-keygen -t ed25519 -C "laravel-remote-docker-access"keyphrase字段的内容 - 把生成的公钥文件(默认路径为
~/.ssh/id_ed25519.pub)的全部内容,追加到目标生产服务器的~/.ssh/authorized_keys文件中 - 根据实际部署场景选择对应的配置填充方式,填充后记得把配置里的
password字段置空,避免密码认证通道保留带来的风险:- 如果私钥存在应用服务器的固定安全路径下:把私钥的绝对路径填入
key字段,填入对应的keyphrase,其余密钥相关字段留空 - 如果不希望暴露磁盘上的私钥文件路径:打开私钥文件(默认路径为
~/.ssh/id_ed25519)复制全文,填入keytext字段,填入对应的keyphrase,key字段留空 - 如果应用服务器已配置系统级SSH Agent:执行
echo $SSH_AUTH_SOCK获取套接字路径,把路径填入agent字段,不需要在配置里存储任何私钥、密码内容
- 如果私钥存在应用服务器的固定安全路径下:把私钥的绝对路径填入
内容的提问来源于stack exchange,提问作者Jaquarh
相关产品推荐
相关产品推荐

