How to use a custom ssh key location with Spring Cloud Config

自古美人都是妖i 提交于 2019-12-21 04:07:06

问题


I am trying to setup a Spring Cloud Config server that uses a custom location for the ssh private key. The reason i need to specify a custom location for the key is because the user running the application has no home directory ..so there is not way for me to use the default ~/.ssh directory for my key. I know that there is the option of creating a read-only account and provide the user/password in the configuration but the ssh way seams more clean.
Is there a way I can setup this?


回答1:


After reading a lot more code... I found a relatively simple work around to allow you to set whatever SSH keys you want.

First: Create a class as follows:

/**
 * @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;
   }


}

Then register it with 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);
    }

}

For this example I'm storing the keys in the src/main/resources/keys folder and I'm using the class loader to get at them.

The removeAllIdentities is important b/c JSch was loading my default ssh key before the one I specified and then Spring Cloud was crashing out b/c its encrypted.

This allowed me to successfully authenticate with bitbucket.




回答2:


The FixedSshSessionFactory solution of @Jeffrey Zampieron is good. However it won't work if packaging the spring boot app as a fat jar.

Polish it a bit for working with 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;
    }


}



回答3:


I am having a similar problem because my default SSH key is encrypted with a password and therefore doesn't "just work", which makes sense because this is a head-less setup.

I went source-diving into Spring Cloud Config, org.eclipse.jgit and eventually ended up in com.jcraft.jsch. The short answer is that neither JGit nor Spring Cloud expose an obvious way to do this.

JSch clearly supports this feature within a JSch() instance, but you can't get at it from the Spring Cloud level. At least not that I could find in a hour or so of looking.



来源:https://stackoverflow.com/questions/33798013/how-to-use-a-custom-ssh-key-location-with-spring-cloud-config

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!