Vert.x Shell SSH认证连接报Permission denied问题求助
Vert.x Shell SSH连接Permission denied问题排查
问题根因定位
你遇到的SSH认证失败核心原因是Shiro认证配置加载失败,结合你贴的日志和代码,具体问题点按概率从高到低排列:
- 你构造的认证配置JsonObject结构异常:从你打印的日志
{"map":{"properties_path":"classpath:shell.properties"},"empty":false}可以看到,配置外层多了一层map节点,正常Vert.x JsonObject序列化后应该直接输出{"properties_path":"classpath:shell.properties"}。这说明你要么导错了JsonObject的包(没有用io.vertx.core.json.JsonObject),要么构造配置时错误传入了内部map对象,导致Shiro认证提供者根本读不到properties_path配置,没有加载你写的shell.properties用户文件,所有认证请求自然被拒绝。 - 配置键名和Vert.x版本不匹配:Vert.x 3.x版本Shiro Properties认证的路径配置键是
properties_path(下划线命名),Vert.x 4.x版本改成了驼峰命名的propertiesPath,如果版本不对应,同样会加载不到用户配置文件。 shell.properties文件不在classpath下:如果文件没有放在src/main/resources目录,或者构建时被过滤掉没有打入jar包/运行目录,Shiro读不到配置也会导致认证失败。- 额外说明:你配置的JKS服务端密钥是正常的,从日志可以看到5001端口已经成功绑定,SSH握手流程正常,问题完全出在用户认证层。
代码逻辑校验
你的ShellVerticle整体逻辑没有致命问题,修复认证问题后命令可以正常运行,但有两个细节需要调整:
- 命令注册时机不对:你是在调用
shellServer.listen()之后才执行registerCommandResolver,可能出现服务启动完成但命令还没注册的情况,把命令注册逻辑移到listen()调用之前即可。 - 异步启动处理:你使用
CoroutineVerticle时,没有挂起等待ShellServer启动完成,建议把回调方式的listen换成协程扩展方法listenAwait(),避免Vert.x误判Verticle启动状态。 - 你提到Telnet下命令可以正常运行,说明命令本身的实现没有问题,SSH认证打通后可以直接复用。
多次密码提示说明
连接时多次弹出密码输入提示不是你输入错误,是SSH协议认证方式协商的正常流程:
- SSH客户端默认会按
publickey->keyboard-interactive->password的顺序依次尝试认证方式,你当前没有配置公钥认证,前两种认证方式失败时都会触发一次密码提示,最后才会走到常规密码认证流程,总共会弹出3-4次输入请求。 - 正确输入规则:等提示出现
billy@localhost's password:时,输入你配置的密码test即可。如果想跳过前面的无效提示,可以在连接时加参数指定只用密码认证:
ssh -o PreferredAuthentications=password -p 5001 billy@localhost
执行后只会弹出一次密码输入框。
快速验证步骤
- 修正认证配置JsonObject的结构,确保序列化后没有多余的外层map节点。
- 确认你使用的Vert.x版本对应的Shiro配置键名,4.x版本把
properties_path改成propertiesPath。 - 在代码中加一行调试代码,验证
shell.properties能被正常读取:
// 加在构造authProps之前,打印流对象不为null说明路径正确 println(this::class.java.getResourceAsStream("/shell.properties"))
- 把命令注册逻辑移到
listen()调用之前,重启服务后再尝试连接即可。
内容的提问来源于stack exchange,提问作者BigFoot
相关产品推荐
相关产品推荐

