authorizePublicKey with AMI

156 views
Skip to first unread message

Dex

unread,
Aug 5, 2011, 5:46:33 PM8/5/11
to jclouds
Hi all:

I have a private AMI image (CentOS), which does not allow root login
with password. I.e., it allows only ssh/certs based remote login.

I was using Jclouds to create EC2 instance (using Template) similar to
the ec2-compterservice-spot sample does.

It's not clear what "authorizePublicKey()" does. I passed my ssh
public key to the method, but, the EC2 instance created using Jclous
does not have my public key installed.

I thought the "authorizePublicKey()" will install my ssh key. Do I
misunderstand the method's usage?

Or what is the right way or requirements to install the SSH key when
an EC2 instance is created?

Thanks,
dex

Andrew Phillips

unread,
Aug 5, 2011, 8:02:36 PM8/5/11
to jcl...@googlegroups.com
> It's not clear what "authorizePublicKey()" does. I passed my ssh
> public key to the method, but, the EC2 instance created using Jclous
> does not have my public key installed.
>
> I thought the "authorizePublicKey()" will install my ssh key. Do I
> misunderstand the method's usage?

Have you had an opportunity to look at

http://code.google.com/p/jclouds/wiki/ComputeGuide#Authorizing_your_RSA_SSH_Public_Key

If that looks like what you're doing and it's not working, please post
a code sample. Thanks!

ap

Adrian Cole

unread,
Aug 6, 2011, 9:35:15 AM8/6/11
to jcl...@googlegroups.com
Hi, guys.

Unless you really only desire to authorize your public key, I'd recommend using AdminAccess.standard().  AdminAccess will install a new user on the newly created node, by default using the same username as the one you are running jclouds with.  Here's an example:


Cheers,
-Adrian


--
You received this message because you are subscribed to the Google Groups "jclouds" group.
To post to this group, send email to jcl...@googlegroups.com.
To unsubscribe from this group, send email to jclouds+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jclouds?hl=en.


Dex

unread,
Aug 8, 2011, 11:19:17 AM8/8/11
to jclouds
I really want to authorize a user only through public key. My AMI has
the private key.

Here is the code for that part:
...
Template template =
cloudComputeService.templateBuilder().hardwareId(InstanceType.M1_LARGE)
.imageId("us-east-1/" + imageId).build();

template.getOptions().as(AWSEC2TemplateOptions.class)
// authorize my ssh key
.authorizePublicKey(
Files.toString(new
File(System.getProperty("user.home") + "/.ssh/id_rsa.pub"),
Charsets.UTF_8))
/*.keyPair(keyPair)

.securityGroups(group)*/;

// run only a single node
NodeMetadata node =
Iterables.getOnlyElement(cloudComputeService.createNodesInGroup(group,
1, template));

The EC2 instance was created sucessfully, but the following socket
test failed :
RetryablePredicate<IPSocket> socketTester = new
RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 300,
1, 1, TimeUnit.SECONDS);
IPSocket socket = new
IPSocket(Iterables.get(node.getPublicAddresses(), 0),
node.getLoginPort());
if (socketTester.apply(socket)) {
System.out.printf("<< socket ready [%s] node(%s)
%n", socket, node.getId());
System.out.printf("ssh to node with the following
command:%n ssh %s@%s%n",
node.getCredentials().identity,
socket.getAddress());

} else {
System.out.printf("<< socket not ready [%s]
node(%s)%n", socket, node.getId());
}

In addition, I noticed that I have to pass the location in
"imageId()". Should it take a "default" location if it is not
provided?

I'll try the AdminAccess.standar() late.

Thanks,

dex

On Aug 6, 7:35 am, Adrian Cole <adrian.f.c...@gmail.com> wrote:
> Hi, guys.
>
> Unless you really only desire to authorize your public key, I'd recommend
> using AdminAccess.standard().  AdminAccess will install a new user on the
> newly created node, by default using the same username as the one you are
> running jclouds with.  Here's an example:
>
> https://github.com/jclouds/jclouds-examples/blob/master/compute-basic...
>
> Cheers,
> -Adrian
>
> On Sat, Aug 6, 2011 at 12:02 AM, Andrew Phillips <aphill...@qrmedia.com>wrote:
>
> > It's not clear what "authorizePublicKey()" does.  I passed my ssh
> >> public key to the method, but, the EC2 instance created using Jclous
> >> does not have my public key installed.
>
> >> I thought the "authorizePublicKey()" will install my ssh key. Do I
> >> misunderstand the method's usage?
>
> > Have you had an opportunity to look at
>
> >http://code.google.com/p/**jclouds/wiki/ComputeGuide#**
> > Authorizing_your_RSA_SSH_**Public_Key<http://code.google.com/p/jclouds/wiki/ComputeGuide#Authorizing_your_R...>
>
> > If that looks like what you're doing and it's not working, please post a
> > code sample. Thanks!
>
> > ap
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "jclouds" group.
> > To post to this group, send email to jcl...@googlegroups.com.
> > To unsubscribe from this group, send email to jclouds+unsubscribe@**
> > googlegroups.com <jclouds%2Bunsu...@googlegroups.com>.
> > For more options, visit this group athttp://groups.google.com/**
> > group/jclouds?hl=en <http://groups.google.com/group/jclouds?hl=en>.

Dex

unread,
Aug 8, 2011, 11:25:57 AM8/8/11
to jclouds
Correction to my previous post which did not show the login port/22:

The Socket Tester code should be:
..
IPSocket socket = new
IPSocket(Iterables.get(node.getPublicAddresses(), 0),
node.getLoginPort());
if (socketTester.apply(socket)) {
System.out.printf("<< socket ready [%s] node(%s)%n",
socket, node.getId());
System.out.printf("ssh to node with the following
command:%n ssh %s@%s%n",
node.getCredentials().identity,
socket.getAddress());
System.exit(0);
} else {
System.out.printf("<< socket not ready [%s] node(%s)
%n", socket, node.getId());
}

I never got the socket is ready for ssh in my testing. But, I was able
to login to the IDR outside the java code.
Dex

Adrian Cole

unread,
Aug 8, 2011, 6:41:35 PM8/8/11
to jcl...@googlegroups.com
Hi, Dex.

Odd that your socket doesn't connect, as this should certainly "just work"

Just to remove variables, do you mind running the compute-basics demo?  This is something we test on each release, and maybe work your way up from there?


I hope this helps.
-Adrian

To unsubscribe from this group, send email to jclouds+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jclouds?hl=en.


Dex

unread,
Aug 8, 2011, 7:09:50 PM8/8/11
to jclouds
Adrian:

Your sample works!

It works if I use your samples with "normal" AMIs.

I'll dig into it. It may be just my AMI thing, and give you a update
on it late.

Thanks for the help.

dex

Adrian Cole

unread,
Aug 8, 2011, 7:15:57 PM8/8/11
to jcl...@googlegroups.com
Hi, Dex.

Glad you made progress!

I'm guessing we don't know what the login user is of your private image.

If this is the case, either
    set TemplateOption.overrideLoginUserWith("my_user")
or
   setup jclouds to parse your private image:
http://code.google.com/p/jclouds/wiki/EC2#Parsing_private_images


You might also want to disable parsing of other images, if you only
use yours.  This will really help performance.

      properties.setProperty(PROPERTY_EC2_AMI_QUERY,

               "owner-id=YOUR_ID_HERE;state=available;image-type=machine");

...createContext(access, secret, modules,  properties);

-A

Dex

unread,
Aug 9, 2011, 11:30:05 AM8/9/11
to jclouds

Hi, Adrian:

I did use parsing private image in my code, thanks.
BTW, the 'root' is the login user.

I went back to my code, and found out that the following code (keyPair
option) causes errors.
Template template =
cloudComputeService.templateBuilder().hardwareId(InstanceType.M1_LARGE)
.imageId("us-east-1/" + imageId).build();

template.getOptions().as(AWSEC2TemplateOptions.class)

// authorize my ssh key
.authorizePublicKey(
Files.toString(new
File(System.getProperty("user.home") + "/.ssh/id_rsa.pub"),
Charsets.UTF_8))
.keyPair(keyPair);


I used keyPair to specify an existing KeyPair. With the above code I
got the following nullpoint exception:
....
09:18:12.750 [user thread 0] DEBUG jclouds.compute - << options
applied node(us-east-1/i-1b3a4b7a)
org.jclouds.compute.RunNodesException: error running 1 node
tag(Appliance) location(us-east-1) image(ami-965aa9ff) size(m1.large)
options([groupIds=[], keyPair=TestKP, noKeyPair=false,
monitoringEnabled=false, placementGroup=null, noPlacementGroup=false,
subnetId=null, userData=null, blockDeviceMappings=[], spotPrice=null,
spotOptions=[formParameters={}]])
Execution failures:

0 error[s]
Node failures:

1) NullPointerException on node us-east-1/i-1b3a4b7a:
java.lang.NullPointerException: no credential found for root on node
us-east-1/i-1b3a4b7a
at
com.google.common.base.Preconditions.checkNotNull(Preconditions.java:
231)
at
org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode.apply(CreateSshClientOncePortIsListeningOnNode.java:
56)
at
org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode.apply(CreateSshClientOncePortIsListeningOnNode.java:
40)
at
org.jclouds.compute.callables.RunScriptOnNodeAsInitScriptUsingSsh.init(RunScriptOnNodeAsInitScriptUsingSsh.java:
117)
at
org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap.call(InitializeRunScriptOnNodeOrPlaceInBadMap.java:
67)
at
org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap.call(InitializeRunScriptOnNodeOrPlaceInBadMap.java:
40)
at
org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.call(CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java:
148)
at
org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.call(CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java:
57)

Without using keyPair(), the same code works (i.e., did not get the
exception).

BTW, the EC2 instance was created correctly with the given KeyPair.

In addition, the security group name showed in AWS is pre-appended
"jcloud#" and appended with the region as below:
clouds#Appliance#us-east-1

The group I given is "Appliance" in this case. Why is that?

How do I tell jclouds to use an existing KeyPair in this case?

I'll try your other suggestion late. Thanks for the help.

dex

Adrian Cole

unread,
Aug 9, 2011, 11:59:36 AM8/9/11
to jcl...@googlegroups.com
Hi, Dex.

Amazon does not store the private key of your keypair, so you need to
supply it, if you want to ssh in and do anything on the machine (such
as authorize another key)

There's 2 ways you can do this. as a templateOption,
overrideLoginCredentialWith(your_id_rsa_string) or
overrideCredentialsWith(new Credentials("root", your_id_rsa_string))

Keep in mind that authorizePublicKey() is redundant, if it is the same
as what corresponds to the keyPair() option.

WRT the security group, jclouds creates a security group for you, with
rules corresponding to the inboundPorts() option (defaults to open
poer 22), unless you use the option
EC2TemplateOptions.securityGroups().

Note, the more you use features like security groups and keypairs, the
less portable your code will be across clouds.

-A

Dex

unread,
Aug 9, 2011, 3:56:58 PM8/9/11
to jclouds
Adrian:

Thank for clarifying the usage of authorizePublicKey() here. It makes
lot sense now.

I originally thought this option will install the public key on the EC
instance like appending the public key to .ssh/know_hosts in this
case.

BTW, jclouds sitll creates a jcloud security group even I specify the
securityGroup() option.

Thanks again.

dex
> ...
>
> read more »

stephane

unread,
Aug 13, 2011, 10:41:23 AM8/13/11
to jclouds
hi All, Adrian,

Just stumbled on this thread while googling on what looks like the
same problem described up here.

Mainly, while trying to create a node with the following code (using
clojure/org.jclouds.compute2):

(def my-template (build-template compute {
:key-pair "my.keypair"
:security-groups [ "default" ]
:run-script (AdminAccess/standard)
:user-data (. "userdata" getBytes)
}))

(create-node compute "web" my-template)

it breaks on node creation with:

... java.lang.NullPointerException: no credential found for ec2-
user on node ...

just like mentioned previously in the thread.

Now, trying to solve this, I did try to use the
"overrideCredentialsWith" to update the template:

(def credentials (Credentials. "ec2-user" "-----BEGIN RSA PRIVATE
KEY----- my rsa priv key*******")
(.overrideCredentialsWith (.getOptions my-template) credentials)

and recreated the node

(create-node compute "web" my-template)

but this breaks as well with the same error message.

Would you have any suggestions? What is wrong in the above code? :)
Best thanks
Stéphane

On Aug 9, 5:59 pm, Adrian Cole <adrian.f.c...@gmail.com> wrote:
> Hi, Dex.
>
> ...
>
> read more »

Dex

unread,
Aug 15, 2011, 11:39:03 AM8/15/11
to jclouds
As Adrian pointed out in earlier post that keyPair() is redundant to
overrideCondentialsWith(). You just need one of them, not both.

Dex
> ...
>
> read more »

stephane

unread,
Aug 16, 2011, 12:36:55 PM8/16/11
to jclouds
hi Dex,

Thanks for the update. Ok I had read it as keyPair() being redundant
to authorizePublicKey().

But still I can't get this to work.. so tried to narrow it to
something that does work, and work
up from there. For example, creating a node with this template:

(def my-template (build-template compute {
:key-pair "a.keypair"
}))

works perfectly.

If we add to this the run-script option (so that the current user is
set as admin, instead of
the likes of "ec2-user" or "root"):

(def my-template (build-template compute {
:key-pair "a.keypair"
:run-script (AdminAccess/standard)
}))

then it breaks .. but why?

Note, what am trying to achieve here is have jclouds not create a key
pair each time
a new node is created (else the AWS console ends up showing e.g.. 40
different
key pairs, when only one would be enough) - and have jclouds set up my
user
(the user am running jclouds with) as an admin user on the given node.
Best thanks
Stéphane
> ...
>
> read more »

Adrian Cole

unread,
Aug 16, 2011, 4:29:49 PM8/16/11
to jcl...@googlegroups.com
Hi, all.

I can see this needs to be clarified. Bear with me a bit and I'll
send over an example that does exactly what you are looking for.

Cheers,
-Adrian

stephane

unread,
Aug 16, 2011, 5:43:05 PM8/16/11
to jclouds
great! looking forward to it
Best thanks
Stéphane
> ...
>
> read more »

Vijay Kiran

unread,
Sep 6, 2011, 6:50:01 AM9/6/11
to jcl...@googlegroups.com
Hi All,

I added an FAQ on how to use your key pair with EC2 here: http://www.jclouds.org/documentation/faqs/ec2-faq - Please take a look and let me know if it makes things clear enough.

I'm working on a clojure example for the same and will push it the jclouds-examples [https://github.com/jclouds/jclouds-examples/].

./Vijay

Adrian Cole

unread,
Sep 6, 2011, 9:03:54 AM9/6/11
to jcl...@googlegroups.com
Thanks, Vijay. I appreciate you handling this.

-Adrian

> --
> You received this message because you are subscribed to the Google Groups
> "jclouds" group.

> To view this discussion on the web visit
> https://groups.google.com/d/msg/jclouds/-/neyHzGdp0QcJ.

Reply all
Reply to author
Forward
0 new messages