如何通过 Spring Cloud Config 使用自定义 ssh 密钥位置
How to use a custom ssh key location with Spring Cloud Config
我正在尝试设置一个 Spring Cloud Config 服务器,该服务器使用 ssh 私钥的自定义位置。
我需要为密钥指定自定义位置的原因是因为用户 运行 应用程序没有主目录..所以我无法为我的密钥使用默认的 ~/.ssh
目录。
我知道可以选择创建只读帐户并在配置中提供 user/password 但 ssh 方式接缝更干净。
有没有办法设置它?
我遇到了类似的问题,因为我的默认 SSH 密钥是用密码加密的,因此没有 "just work",这是有道理的,因为这是无头设置。
我深入研究了 Spring Cloud Config,org.eclipse.jgit 并最终进入了 com.jcraft.jsch。简短的回答是 JGit 和 Spring Cloud 都没有公开一个明显的方法来做到这一点。
JSch 在 JSch() 实例中明确支持此功能,但您无法从 Spring 云级别获得它。至少我在一个小时左右的时间里找不到。
阅读更多代码后...我发现了一个相对简单的解决方法,允许您设置任何您想要的 SSH 密钥。
首先:创建一个class如下:
/**
* @file FixedSshSessionFactory.java
*
* @date Aug 23, 2016 2:16:11 PM
* @author jzampieron
*/
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.util.FS;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
/**
* Short Desc Here.
*
* @author jzampieron
*
*/
public class FixedSshSessionFactory extends JschConfigSessionFactory
{
protected String[] identityKeyPaths;
/**
* @param string
*/
public FixedSshSessionFactory( String... identityKeyPaths )
{
this.identityKeyPaths = identityKeyPaths;
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
*/
@Override
protected void configure( Host hc, Session session )
{
// nothing special needed here.
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
*/
@Override
protected JSch getJSch( Host hc, FS fs ) throws JSchException
{
JSch jsch = super.getJSch( hc, fs );
// Clean out anything 'default' - any encrypted keys
// that are loaded by default before this will break.
jsch.removeAllIdentity();
for( final String identKeyPath : identityKeyPaths )
{
jsch.addIdentity( identKeyPath );
}
return jsch;
}
}
然后用jgit注册:
...
import org.eclipse.jgit.transport.SshSessionFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigserverApplication
{
public static void main(String[] args) {
URL res = ConfigserverApplication.class.getClassLoader().getResource( "keys/id_rsa" );
String path = res.getPath();
SshSessionFactory.setInstance( new FixedSshSessionFactory( path ) );
SpringApplication.run(ConfigserverApplication.class, args);
}
}
对于此示例,我将密钥存储在 src/main/resources/keys 文件夹中,并且
我正在使用 class 加载程序来获取它们。
removeAllIdentities 很重要 b/c JSch 在我指定的密钥之前加载我的默认 ssh 密钥,然后 Spring Cloud 崩溃了 b/c 它的加密。
这使我能够成功地使用 bitbucket 进行身份验证。
@Jeffrey Zampieron 的 FixedSshSessionFactory
解决方案很好。但是,如果将 spring 启动应用程序打包为 fat jar,它将不起作用。
为了与 fat jar 一起工作,稍微润色一下,
/**
* @file FixedSshSessionFactory.java
* @date Aug 23, 2016 2:16:11 PM
* @author jzampieron
*/
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.util.FS;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* Short Desc Here.
*
* @author jzampieron
*/
@Slf4j
public class FixedSshSessionFactory extends JschConfigSessionFactory {
protected URL[] identityKeyURLs;
/**
* @param url
*/
public FixedSshSessionFactory(URL... identityKeyURLs) {
this.identityKeyURLs = identityKeyURLs;
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
*/
@Override
protected void configure(Host hc, Session session) {
// nothing special needed here.
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
*/
@Override
protected JSch getJSch(Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
// Clean out anything 'default' - any encrypted keys
// that are loaded by default before this will break.
jsch.removeAllIdentity();
int count = 0;
for (final URL identityKey : identityKeyURLs) {
try (InputStream stream = identityKey.openStream()) {
jsch.addIdentity("key" + ++count, StreamUtils.copyToByteArray(stream), null, null);
} catch (IOException e) {
logger.error("Failed to load identity " + identityKey.getPath());
}
}
return jsch;
}
}
我正在尝试设置一个 Spring Cloud Config 服务器,该服务器使用 ssh 私钥的自定义位置。
我需要为密钥指定自定义位置的原因是因为用户 运行 应用程序没有主目录..所以我无法为我的密钥使用默认的 ~/.ssh
目录。
我知道可以选择创建只读帐户并在配置中提供 user/password 但 ssh 方式接缝更干净。
有没有办法设置它?
我遇到了类似的问题,因为我的默认 SSH 密钥是用密码加密的,因此没有 "just work",这是有道理的,因为这是无头设置。
我深入研究了 Spring Cloud Config,org.eclipse.jgit 并最终进入了 com.jcraft.jsch。简短的回答是 JGit 和 Spring Cloud 都没有公开一个明显的方法来做到这一点。
JSch 在 JSch() 实例中明确支持此功能,但您无法从 Spring 云级别获得它。至少我在一个小时左右的时间里找不到。
阅读更多代码后...我发现了一个相对简单的解决方法,允许您设置任何您想要的 SSH 密钥。
首先:创建一个class如下:
/**
* @file FixedSshSessionFactory.java
*
* @date Aug 23, 2016 2:16:11 PM
* @author jzampieron
*/
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.util.FS;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
/**
* Short Desc Here.
*
* @author jzampieron
*
*/
public class FixedSshSessionFactory extends JschConfigSessionFactory
{
protected String[] identityKeyPaths;
/**
* @param string
*/
public FixedSshSessionFactory( String... identityKeyPaths )
{
this.identityKeyPaths = identityKeyPaths;
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
*/
@Override
protected void configure( Host hc, Session session )
{
// nothing special needed here.
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
*/
@Override
protected JSch getJSch( Host hc, FS fs ) throws JSchException
{
JSch jsch = super.getJSch( hc, fs );
// Clean out anything 'default' - any encrypted keys
// that are loaded by default before this will break.
jsch.removeAllIdentity();
for( final String identKeyPath : identityKeyPaths )
{
jsch.addIdentity( identKeyPath );
}
return jsch;
}
}
然后用jgit注册:
...
import org.eclipse.jgit.transport.SshSessionFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigserverApplication
{
public static void main(String[] args) {
URL res = ConfigserverApplication.class.getClassLoader().getResource( "keys/id_rsa" );
String path = res.getPath();
SshSessionFactory.setInstance( new FixedSshSessionFactory( path ) );
SpringApplication.run(ConfigserverApplication.class, args);
}
}
对于此示例,我将密钥存储在 src/main/resources/keys 文件夹中,并且 我正在使用 class 加载程序来获取它们。
removeAllIdentities 很重要 b/c JSch 在我指定的密钥之前加载我的默认 ssh 密钥,然后 Spring Cloud 崩溃了 b/c 它的加密。
这使我能够成功地使用 bitbucket 进行身份验证。
@Jeffrey Zampieron 的 FixedSshSessionFactory
解决方案很好。但是,如果将 spring 启动应用程序打包为 fat jar,它将不起作用。
为了与 fat jar 一起工作,稍微润色一下,
/**
* @file FixedSshSessionFactory.java
* @date Aug 23, 2016 2:16:11 PM
* @author jzampieron
*/
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.util.FS;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* Short Desc Here.
*
* @author jzampieron
*/
@Slf4j
public class FixedSshSessionFactory extends JschConfigSessionFactory {
protected URL[] identityKeyURLs;
/**
* @param url
*/
public FixedSshSessionFactory(URL... identityKeyURLs) {
this.identityKeyURLs = identityKeyURLs;
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
*/
@Override
protected void configure(Host hc, Session session) {
// nothing special needed here.
}
/* (non-Javadoc)
* @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
*/
@Override
protected JSch getJSch(Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
// Clean out anything 'default' - any encrypted keys
// that are loaded by default before this will break.
jsch.removeAllIdentity();
int count = 0;
for (final URL identityKey : identityKeyURLs) {
try (InputStream stream = identityKey.openStream()) {
jsch.addIdentity("key" + ++count, StreamUtils.copyToByteArray(stream), null, null);
} catch (IOException e) {
logger.error("Failed to load identity " + identityKey.getPath());
}
}
return jsch;
}
}