我正在使用 jgit 从在 kubernetes 容器中运行的 java 应用程序运行 git 命令,因此我希望允许自定义 ssh 密钥存储位置等。
我的第一种方法是使用 jsch 实现支持 ssh,但遇到了麻烦(我在这里检查了方法Using Keys with JGit to Access a Git Repository Securely并且没有运气)所以我通过 org 添加了 ssh 支持.eclipse.jgit.ssh.apache 工件。由于打包/分发的方式,使用外部 ssh 应用程序并不是一个真正的选择。
我没有太多运气找到信息,但假设我只想模仿 jsch 方法并替换调用中使用的会话工厂。最初我采用的方法是使用所需的 ssh 路径设置会话工厂
final SshdSessionFactoryBuilder builder = new SshdSessionFactoryBuilder();
builder.setHomeDirectory(new File(homeDir))
.setConfigFile((f)-> new File(f, "config"))
.setSshDirectory(new File(sshDir));
return builder.build(null);
并将这个工厂传递给各种命令。
final CloneCommand cmd = Git.cloneRepository().setDirectory(new File(basePath))
.setURI(remotePath);
if (sshSessionFactory != null) {
cmd.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport transport) {
final SshTransport sshTransport = (SshTransport)transport;
((SshTransport) transport).setSshSessionFactory(sshSessionFactory);
}
});
}
git = cmd.call();
但是,使用这种方法,像 clone 这样的命令将无法通过 git repo 进行身份验证,试图使用默认的 ssh 密钥。在调试器中执行此操作后,我发现在 clone 命令中,它正在生成一个 fetch 命令,但没有将会话工厂或会话传递给它,因此 fetch 只是构建了一个默认配置并且无法进行身份验证。
2021-05-31 11:48:09,793 INFO GitChainRepository.java:114 - Couldn't find git dir, creating it
2021-05-31 11:48:10,748 INFO AbstractSecurityProviderRegistrar.java:112 - getOrCreateProvider(EdDSA) created instance of net.i2p.crypto.eddsa.EdDSASecurityProvider
2021-05-31 11:48:10,970 INFO DefaultIoServiceFactoryFactory.java:67 - No detected/configured IoServiceFactoryFactory using Nio2ServiceFactoryFactory
2021-05-31 11:48:12,206 INFO GitChainRepository.java:133 - Initialized by clone of remote
2021-05-31 11:48:12,207 INFO GitChainRepository.java:159 - Prepping remote repo git@ghe.snip/gitchainstore-synctest.git
2021-05-31 11:48:12,318 WARN LoggingUtils.java:634 - exceptionCaught(JGitClientSession[git@ghe.ca-tools.org/52.69.168.141:22])[state=Opened] SshException: Server key did not validate
org.apache.sshd.common.SshException: Server key did not validate
at org.apache.sshd.client.session.AbstractClientSession.checkKeys(AbstractClientSession.java:583) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.session.helpers.AbstractSession.handleKexMessage(AbstractSession.java:611) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:500) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:428) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1463) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:388) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.eclipse.jgit.internal.transport.sshd.JGitClientSession.messageReceived(JGitClientSession.java:197) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:358) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:335) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:332) ~[sshd-osgi-2.6.0.jar:2.6.0]
at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38) ~[sshd-osgi-2.6.0.jar:2.6.0]
at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37) [sshd-osgi-2.6.0.jar:2.6.0]
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127) [?:?]
at sun.nio.ch.Invoker$2.run(Invoker.java:219) [?:?]
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:834) [?:?]
2021-05-31 11:48:12,331 INFO SessionHelper.java:1034 - Disconnecting(JGitClientSession[git@ghe.ca-tools.org/52.69.168.141:22]): SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE - Server key did not validate
org.eclipse.jgit.api.errors.TransportException: git@ghe.snip/gitchainstore-synctest.git: Server key did not validate
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:224)
at org.eclipse.jgit.api.PullCommand.call(PullCommand.java:263)
at snip.GitChainRepository.setupRemote(GitChainRepository.java:173)
at snip.GitChainRepository.start(GitChainRepository.java:144)
at snip.GitChainRepositoryTest.setupGit(GitChainRepositoryTest.java:59)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.eclipse.jgit.errors.TransportException: git@ghe.snip/gitchainstore-synctest.git: Server key did not validate
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:248)
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:1)
at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:107)
at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:281)
at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:153)
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:142)
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:94)
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1309)
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:213)
... 31 more
Caused by: org.apache.sshd.common.SshException: Server key did not validate
at org.apache.sshd.common.future.AbstractSshFuture.verifyResult(AbstractSshFuture.java:126)
at org.apache.sshd.client.future.DefaultAuthFuture.verify(DefaultAuthFuture.java:39)
at org.apache.sshd.client.future.DefaultAuthFuture.verify(DefaultAuthFuture.java:32)
at org.apache.sshd.common.future.VerifiableFuture.verify(VerifiableFuture.java:68)
at org.eclipse.jgit.transport.sshd.SshdSession.connect(SshdSession.java:164)
at org.eclipse.jgit.transport.sshd.SshdSession.connect(SshdSession.java:99)
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:235)
... 39 more
Caused by: org.apache.sshd.common.SshException: Server key did not validate
at org.apache.sshd.client.session.AbstractClientSession.checkKeys(AbstractClientSession.java:583)
at org.apache.sshd.common.session.helpers.AbstractSession.handleKexMessage(AbstractSession.java:611)
at org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:500)
at org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:428)
at org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1463)
at org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:388)
at org.eclipse.jgit.internal.transport.sshd.JGitClientSession.messageReceived(JGitClientSession.java:197)
at org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64)
at org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:358)
at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:335)
at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:332)
at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37)
at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:219)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Process finished with exit code -1
最终我决定只覆盖默认的会话工厂,这很有效,但不是真的。
SshSessionFactory.setInstance(sshSessionFactory);
这最终工作了一段时间,但随后分崩离析,无法从工厂创建新会话(我不知道为什么,但我不想覆盖默认实例,因此发布这个问题)
org.eclipse.jgit.api.errors.TransportException: git@ghe.snip/gitchainstore-synctest.git: Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:224) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.api.PullCommand.call(PullCommand.java:263) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at snip.GitChainRepository.updateRemote(GitChainRepository.java:190) ~[core-0.1.0-28.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: org.eclipse.jgit.errors.TransportException: git@ghe.snip/gitchainstore-synctest.git: Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:248) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:1) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:107) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:281) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:153) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:142) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:94) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1309) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:213) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
... 8 more
Caused by: java.io.IOException: Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.register(SshdSessionFactory.java:272) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:234) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:1) ~[org.eclipse.jgit.ssh.apache-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:107) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:281) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:153) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:142) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:94) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1309) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:213) ~[org.eclipse.jgit-5.11.0.202103091610-r.jar:5.11.0.202103091610-r]
... 8 more
所以总而言之:自定义 ssh 会话创建并确保它通过调用其他命令的瓷命令持续存在的正确方法是什么?这是jgit的错误吗?我错过了什么,或者在这里做错了什么?