我使用运行在kubernetes容器中的java应用程序的jgit运行git命令,因此我希望允许自定义ssh密钥存储位置等等。
我的第一种方法是使用jsch实现支持的ssh,但遇到了麻烦(我在这里检查了Using Keys with JGit to Access a Git Repository Securely方法,但没有找到它),所以我通过org.eclipse.jgit.ssh.apache工件添加了ssh支持。由于打包/分发的方式,使用外部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();
但是,使用这种方法,像克隆这样的命令将无法使用git,试图使用默认的ssh键。在调试器中,我发现它在克隆命令中生成了一个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的bug吗?我是错过了什么,还是做错了什么?
发布于 2021-09-22 08:22:04
File sshDir = new File(FS.DETECTED.userHome(), "/.ssh");
SshdSessionFactory sshSessionFactory = new SshdSessionFactoryBuilder()
.setPreferredAuthentications("publickey")
.setHomeDirectory(FS.DETECTED.userHome())
.setSshDirectory(sshDir)
.build(null);
上面的代码适用于我,只需要将id_rsa
文件放在.ssh
文件夹中即可。钥匙必须没有密码。还在寻找用钥匙传递密码的方法。
发布于 2021-06-04 00:06:04
我不认为你错过了什么。有一个回调钩子可以在命令上使用,您可以在其中插入配置代码。我从没和米娜合作过。我asked a similar question,但在这里一直没有得到答案。如果你知道怎么做,请张贴,因为这是一个特别具有挑战性的课题。
发布于 2022-01-10 02:33:51
使用JGit版本6.0.202111291000-r,我能够使用Apache执行传输命令。为了这个,
TransportCommand
.回调中的
CustomSshSessionFactory
cmd.setTransportConfigCallback(
transport -> {
if(transport instanceOf SshTransport) {
SshTransport sshTransport = (SshTransport) transport;
// Set passphrase using a CustomCredentialsProvider
sshTransport.setCredentialsProvider(new CustomCredentialProvider(passphrase));
// Provide private key to `CustomSshSessionFactory`
SshSessionFactory sshFactory = new CustomSshSessionFactory(privatekey);
sshTransport.setSshSessionFactory(sshFactory);
}
});
SshdSessionFactory
的实现。你也可以使用SshdSessionFactoryBuilder
。public final class CustomSshSessionFactory extends SshdSessionFactory {
public static final Path SSH_DIR = Path.of("some-path");
private final Path privateKeyFile;
private final byte[] sshKey;
public CustomSshSessionFactory(byte[] sshKey) {
this.sshKey = sshKey;
privateKeyFile = Path.of("some-name", SSH_DIR.toString());
}
@Override
public File getSshDirectory() {
try {
return Files.createDirectories(SSH_DIR).toFile();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Return paths to private key files
@Override
protected List<Path> getDefaultIdentities(File sshDir) {
try {
Files.write(privateKeyFile, sshKey);
return Collections.singletonList(privateKeyFile);
} catch (IOException e) {
e.printStackTrace();
}
return Collections.emptyList();
}
}
CredentialsProvider
的自定义实现
public class CustomCredentialProvider extends CredentialsProvider {
private final List<String> stringStore;
private final String passphrase;
public CustomCredentialProvider(String passphrase) {
this.passphrase = passphrase;
}
@Override
public boolean isInteractive() {
// Set this according to your requirement
return false;
}
@Override
public boolean supports(CredentialItem... items) {
// Set this according to your requirement
return true;
}
@Override
public boolean get(URIish uri, CredentialItem... items)
throws UnsupportedCredentialItem {
for (CredentialItem item : items) {
if (item instanceof CredentialItem.InformationalMessage) {
continue;
}
if (item instanceof CredentialItem.YesNoType) {
// Set this according to your requirement
((CredentialItem.YesNoType) item).setValue(true);
} else if (item instanceof CredentialItem.CharArrayType) {
if (passphrase != null) {
((CredentialItem.CharArrayType) item)
.setValue(passphrase.toCharArray());
} else {
return false;
}
} else if (item instanceof CredentialItem.StringType) {
if (passphrase != null) {
((CredentialItem.StringType) item)
.setValue(passphrase);
} else {
return false;
}
} else {
return false;
}
}
return true;
}
}
在这里,需要注意的重要事情是
通过CredentialsProvider
SshSessionFactory
https://stackoverflow.com/questions/67767455
复制相似问题