[Openstack] [Nova] What is the correct way to provide Windows instance password for user?
Juerg Haefliger
juergh at gmail.com
Thu Jan 23 13:28:13 UTC 2014
Here it is. I'm not a PowerShell expert so go easy on me :-)
...Juerg
#
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# Author: Juerg Haefliger <juerg.haefliger at hp.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
# 02110-1301 USA
#
# Simple powershell script that runs at startup and provides the following
# functionality.
# 1) Generate a random password
# 2) Set the Administrator password
# 3) Pull the public SSH key from the Nova metadata server
# 4) Encrypt the random password with the public SSH key
# 5) Write the encrypted password to the serial port (console log)
#
$metadata_url = "http://169.254.169.254/2009-04-04/meta-data"
$id_rsa_dir = "C:\Users\Administrator\.ssh"
$id_rsa_pub = $id_rsa_dir + "\id_rsa.pub"
$id_rsa_pub8 = $id_rsa_dir + "\id_rsa.pub8"
Function Log([string] $text)
{
$now = Get-Date -format "MMM dd HH:mm:ss"
$console.WriteLine($now + " " + $env:Computername + ": [cloud-init] " +
$text)
}
Function CloudInit()
{
$script:console = New-Object System.IO.Ports.SerialPort `
COM1,115200,None,8,One
$console.Open()
Log("Starting")
}
Function CloudExit()
{
Log("Done")
$console.Close()
exit
}
Function Out([string] $text)
{
$console.WriteLine($text)
}
Function WaitForMetadataService()
{
log("Connect to metadata service")
$client = New-Object Net.WebClient
for ($i = 1; $i -le 10; $i++) {
if ($i -gt 1) {
Start-Sleep -s ($i * 2)
log("Connect to metadata service (" + $i + ". try)")
}
$tmp = $client.DownloadString($metadata_url)
if ($?) {
return
}
}
log("Giving up")
CloudExit
}
Function GetLocalHostname()
{
log("Get local hostname")
$client = New-Object Net.WebClient
$val = $client.DownloadString($metadata_url + "/local-hostname")
return $val
}
Function GetPublicSshKey()
{
log("Get public SSH key")
if (!(Test-Path $id_rsa_dir)) {
New-Item -type directory -path $id_rsa_dir
}
$client = New-Object Net.WebClient
$val = $client.DownloadString($metadata_url +
"/public-keys/0/openssh-key")
$val | Out-File -encoding ascii -filePath $id_rsa_pub
ssh-keygen -e -P "dummy" -m pkcs8 -f $id_rsa_pub | Out-File `
-encoding ascii -filePath $id_rsa_pub8
}
Function GenerateRandomPassword([int] $length)
{
log("Generate random password")
Add-Type -AssemblyName System.Web
$val = [System.Web.Security.Membership]::GeneratePassword($length, 4)
return $val
}
Function EncryptPassword([string] $secret)
{
log("Encrypt random password")
$temp_file = [System.IO.Path]::GetTempFileName()
$secret | openssl rsautl -encrypt -inkey $id_rsa_pub8 -pubin `
-out $temp_file
$val = openssl enc -base64 -in $temp_file
Remove-Item $temp_file
return $val
}
Function SetAdministratorPassword([string] $secret)
{
log("Set Administrator password")
[adsi] $admin = "WinNT://" + $env:Computername + "/Administrator"
$admin.SetPassword($secret)
}
Function PrintEncryptedPassword([string[]] $secret)
{
Out("-----BEGIN BASE64-ENCODED ENCRYPTED PASSWORD-----")
foreach ($line in $secret) {
Out($line)
}
Out("-----END BASE64-ENCODED ENCRYPTED PASSWORD-----")
}
CloudInit
if (Test-Path $id_rsa_pub) {
Log("Nothing to do")
CloudExit
}
$plain_pw = GenerateRandomPassword(12)
SetAdministratorPassword($plain_pw)
WaitForMetadataService
GetPublicSshKey
$encrypted_pw = EncryptPassword($plain_pw)
PrintEncryptedPassword($encrypted_pw)
CloudExit
On Thu, Jan 23, 2014 at 9:52 AM, Clark, Robert Graham
<robert.clark at hp.com>wrote:
> On Thu Jan 23 07:54:23 2014, Juerg Haefliger wrote:
> > On Tue, Jan 21, 2014 at 8:22 AM, Joe Topjian <joe at topjian.net
> > <mailto:joe at topjian.net>> wrote:
> > >
> > > Hi Juerg,
> > >
> > > That's a really creative way of setting the password. Are you able
> > to share your powershell script?
> >
> > Sorry, missed this request earlier. Need to check with legal (sigh).
> >
> > ..Juerg
> >
> >
> > > Thanks,
> > > Joe
> > >
> > >
> > > On Tue, Jan 21, 2014 at 8:15 AM, Juerg Haefliger <juergh at gmail.com
> > <mailto:juergh at gmail.com>> wrote:
> > >>
> > >>
> > >> On Tue, Jan 21, 2014 at 3:15 AM, jeffty <wantwatering at gmail.com
> > <mailto:wantwatering at gmail.com>> wrote:
> > >> >
> > >> > Thanks Joe, It really helps.
> > >> >
> > >> > Will check them to find the proper way.
> > >> >
> > >> > Thanks.
> > >> >
> > >> > On 1/19/2014 3:32 PM, Joe Topjian wrote:
> > >> > > Hello,
> > >> > >
> > >> > > We've used this in the past:
> > >> > >
> > >> > > https://github.com/jordanrinke/openstack
> > >> > >
> > >> > > It allows a user to type in an Administrator password in the
> > Post Config
> > >> > > text box when launching an instance in Horizon. The password is
> > then
> > >> > > retrieved when Windows first boots via the metadata service.
> > >> > >
> > >> > > We stopped using it for two reasons, though:
> > >> > >
> > >> > > 1. The password was permanently stored in the metadata server
> > >> > > 2. There was no (default) way to let the user know that the
> > password
> > >> > > they chose was not a strong enough password
> > >> > >
> > >> > > We now just have users connect to the VNC console and set the
> > password
> > >> > > upon first boot.
> > >> > >
> > >> > > There have been a few discussions over the past year on the
> > >> > > openstack-operators list about the cloudbase Windows cloud-init
> > service.
> > >> > > I think one or two people have been able to get the password
> > injection
> > >> > > portion working. It might be worth a shot to search the archives:
> > >> > >
> > >> > > http://www.gossamer-threads.com/lists/openstack/operators/
> > >> > >
> > >> > > Joe
> > >> > >
> > >> > >
> > >> > > On Sun, Jan 19, 2014 at 4:21 AM, jeffty <wantwatering at gmail.com
> > <mailto:wantwatering at gmail.com>
> > >> > > <mailto:wantwatering at gmail.com
> > <mailto:wantwatering at gmail.com>>> wrote:
> > >> > >
> > >> > > Thanks Jacob.
> > >> > >
> > >> > > Is there any openstack API guide for send instance password
> > while
> > >> > > launch it?
> > >> > >
> > >> > > Thanks.
> > >> > >
> > >> > > On 1/19/2014 11:08 AM, Jacob Godin wrote:
> > >> > > > Yes, they must input a password every time. It's within
> > Windows, they
> > >> > > > must use the console.
> > >> > > >
> > >> > > > Sent from my mobile device
> > >> > > >
> > >> > > > On Jan 18, 2014 10:51 PM, "jeffty"
> > <wantwatering at gmail.com <mailto:wantwatering at gmail.com>
> > >> > > <mailto:wantwatering at gmail.com <mailto:wantwatering at gmail.com
> >>
> > >> > > > <mailto:wantwatering at gmail.com
> > <mailto:wantwatering at gmail.com> <mailto:wantwatering at gmail.com
> > <mailto:wantwatering at gmail.com>>>>
> > >> > > wrote:
> > >> > > >
> > >> > > > Thanks Jacob.
> > >> > > >
> > >> > > > Then the user must input a password for every windows
> > instance he
> > >> > > > launched?
> > >> > > >
> > >> > > > In other word different instance owns different
> > password even
> > >> > > they are
> > >> > > > launched at the same time? e.g. Input 3 while launching
> > >> > > instance in
> > >> > > > Horizon portal for this windows image.
> > >> > > >
> > >> > > > If yes, how to send this password to the instance in
> > portal?
> > >> > > That should
> > >> > > > be implemented by meta service.
> > >> > > >
> > >> > > > If no, all of the instances have the same default
> > password, right?
> > >> > > >
> > >> > > >
> > >> > > > On 1/19/2014 10:02 AM, Jacob Godin wrote:
> > >> > > > > We've used sysprep to have the administrator
> > provide a password
> > >> > > > when the
> > >> > > > > instance is first booted.
> > >> > > >
> > >>
> > >> We use a simple powershell script that generates a random
> > Administrator password on first boot, pulls the SSH key from the
> > metadata server, encrypts the password with the key and writes the
> > encrypted password to the serial port.
> > >>
> > >> The user retrieves the encrypted password through the nova
> > console-log and decrypts it with his private key. The image is setup
> > such that the user is prompted to change the (random) password the
> > first time he logs into the instance.
> > >>
> > >> ...Juerg
> > >>
> > >>
> > >>
> > >> > >
> > >> > > _______________________________________________
> > >> > > Mailing list:
> > >> > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
> > >> > > Post to : openstack at lists.openstack.org
> > <mailto:openstack at lists.openstack.org>
> > >> > > <mailto:openstack at lists.openstack.org
> > <mailto:openstack at lists.openstack.org>>
> > >> > > Unsubscribe :
> > >> > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
> > >> > >
> > >> > >
> > >> >
> > >> >
> > >> > _______________________________________________
> > >> > Mailing list:
> > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
> > >> > Post to : openstack at lists.openstack.org
> > <mailto:openstack at lists.openstack.org>
> > >> > Unsubscribe :
> > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
> > >
> > >
>
> If it's not possible to release the script it shouldn't be to hard to
> re-create. Juerg has already described the tricky bit, which is the
> crypto stuff, the only piece missing is putting the password into
> Windows :)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack/attachments/20140123/29937e47/attachment.html>
More information about the Openstack
mailing list