AdwaitPatankar
Contributor
Contributor

Getting VM console (HTML5 web) using pre-authenticated URL

We are trying to use HTML5 web console from vCenter 6.0 web client. We are doing this using vsphere APIs and launching

browser with console URL that has preauthenticated token (session clone ticket).

However, when we fire the preauthenticated URL (/vsphereclient/webconsole.html with necessary parameters), we are always routed to the SSO login page the first time around and after passing the authentication phase, then redirected to the VM console. This happens only for the first request. Any further ‘get vm console’ requests using the pre-authenticated URL work just fine and directly render the VM console. The moment we switch to a new browser window (or the incognito mode), it again asks for an explicit login on the SSO page.

What I would like to know is if

  1. What is the validity in terms of time for the session clone ticket? Is there a way to configure this setting?
  2. Is there a way to get around the JSESSIONID cookie? Is there any other step that is needed to be able to get the console without vCenter login screen because we have already authenticated and obtained the token.
Tags (1)
22 Replies
jwswizzle
Enthusiast
Enthusiast

Hello,

We are currently looking at using the HTML Console SDK to connect to vm's. I have been looking at their online documentation ( https://www.vmware.com/support/developer/html-console/html-console-sdk-100-programmer-guide.pdf ) that gives a very brief connection example. I was wondering if this is the same HTML Console that you are using? If so, could you inform what the connection string to the virtual machine looks like? And possibly how you were able to obtain it? In their example on page 5, you can see they are just using wss:/127.0.0.1:8080. And they say in step 6 to "connect with the appropriate destination url" but no other information about how to obtain that.

0 Kudos
heapmaster
Contributor
Contributor

We are having the same issue and are being redirected to the SSO login page, this just started occurring in VMware 6, all other previous versions of 5 it worked without issue (besides slight modification to the URL with port/params). Any idea on how to fix this issue?

Solar Powered Data Center & Web Hosting: http://www.aiso.net
0 Kudos
allstuffinbox
Contributor
Contributor

In case if someone read this post.

Look at virtuallyghetto.com "how to generate a pre-authenticated HTML5 VM console link...".

There are also useful comments and link to the perl script, which generate required link.

Unfortunately it is not working for vsphere 6.0 if you not logged in to vsphere web interface.

0 Kudos
allstuffinbox
Contributor
Contributor

The same issue for us.

If someone knows the workaround, please reply.

I don't understand vmware actions like these.

You have customers which are interested in HTML5 console to forward it to their clients, it is an actual standard for such things, you provide API for it and It's worked well for several releases.

And now it is not. Good marketing strategy.


Also I noticed that if you even change the sessionTicket= in link (generated from vsphere web interface) to the fake one, this link still works well, so ticket not required.

Don't know if it is a security issue or not, but it's funny.


0 Kudos
allstuffinbox
Contributor
Contributor

I used the following workaround for vCenter  6.0:


1) Login to vCenter web interface using curl, wget, perl LWP::UserAgent etc to get required cookie:


GET https://@VCHOST@/vsphere-client/logon

  with HTTP headers

    Referer: https://@VCHOST@/vsphere-client/?csp)

GET @LOCATION@&passwordSupplied=1

  with HTTP headers

    Cookie: @COOKIE@

    Authorization: Basic @AUTH@

    CastleAuthorization: Basic @AUTH@

    Referer: @LOCATION@&passwordEntry=1


Where

@VCHOST@ - vCenter hostname

@LOCATION@ - URL taken from the Location header of the previous HTTP reply

@AUTH@ - login+password of vCenter user encoded in standard basic HTTP header format

@COOKIE@ - a set of cookies taken from the Set-Cookie headers of the previous HTTP replies


From the second request you will receive required cookies.

The CastleSessionvsphere.test.local cookie (from header Set-Cookie:  CastleSessionvsphere.local=_abcdef012345678; Path=/; Secure; HttpOnly) is enough in my case to get the console below.


2) Prepare web console link:

https://@VCHOST@:9443/vsphere-client/webconsole.html?vmId=@VMID@&vmName=@VMNAME@&serverGuid=@GUID@&h...


Where

@VCHOST@ - vCenter hostname

@VMID@ - VM identifier ($vm_view->{mo_ref}->value using Vsphere Perl API)

@VMNAME@ - VM name ($vm_view->name)

@GUID@ - some guid ($sc = $vim->get_service_content(); $sc->about->instanceUuid)

@HOST@ - value taken from settings array ($sc = $vim->get_service_content(); $settingmgr = $vim->get_view(mo_ref => $sc->setting); $settings = $settingmgr->setting;) by VirtualCenter.FQDN key

@TICKET@ - ticket ($sessionmgr = $vim->get_view(mo_ref => $sc->sessionManager); $sessionmgr->AcquireCloneTicket())

@TP@ - ssl thumbprint ($ticket = $vm_view->AcquireTicket(ticketType => 'webmks'); $ticket->sslThumbprint)


So you will get link like this:

https://dc01-vc-qqq.test.local:9443/vsphere-client/webconsole.html?vmId=vm-56&vmName=test&serverGuid...


3) Set the cookies from step 1 for your browser, then open the generated link from step 2. Done!

0 Kudos
vittoriop77
Contributor
Contributor

Hello,

I'm trying to use your solution in a powershell script but I didn't understand what is CastleAuthorization: Basic @AUTH@.

Is it a specific cookie with the same credentials of Authorization: Basic @AUTH@ ?

Thanks

Vittorio

0 Kudos
allstuffinbox
Contributor
Contributor

Hi, no, that is a HTTP header (note indentation below "with HTTP headers"), but I don't know if it required or not.

Steps listed here generated from the HTTP traffic dump which happens when you login to vCenter web interface.

0 Kudos
vittoriop77
Contributor
Contributor

Thank you for the answer !!

I'm now able to get CastleSessionvsphere.local cookie with the following powershell code.

If I set the cookie from my web site, the domain is different so the cookie could not be used...

Were you able to use it for a redirected console session ?

############  REMOVE CERTIFICATE WARNING ###############

add-type @"

    using System.Net;

    using System.Security.Cryptography.X509Certificates;

    public class TrustAllCertsPolicy : ICertificatePolicy {

        public bool CheckValidationResult(

            ServicePoint srvPoint, X509Certificate certificate,

            WebRequest request, int certificateProblem) {

            return true;

        }

    }

"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

#########################################################################

$source = "https://vcenter.vc.local/vsphere-client/logon"

$request = [System.Net.WebRequest]::Create($source)

$request.Referer = "https://vcenter.vc.local/vsphere-client/?csp"

$request.AllowAutoRedirect=$false

$response = $request.GetResponse()

If ($response.StatusCode -eq "Found")

    {

        $Destination = $response.GetResponseHeader("Location")

        $cookie = $response.GetResponseHeader("Set-Cookie")

    }

$response

$source2 = $Destination+"&passwordSupplied=1"

$request2 = [System.Net.WebRequest]::Create($source2)

$request2.Headers.add("Set-Cookie",$cookie)

$request2.Headers.add("Authorization","Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==")  #BASE64 credentials

$request2.Headers.add("CastleAuthorization","Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==")  #BASE64 credentials

$request2.Referer = $Destination+"&passwordEntry=1"

$cookiejar = New-Object System.Net.CookieContainer

$request2.CookieContainer = $cookiejar

$request2.GetResponse()

$cookies = $cookiejar.GetCookies("https://vcenter.vc.local")

$cookies

0 Kudos
allstuffinbox
Contributor
Contributor

Yes, it is possible using some sort of websocket proxy, so this proxy placed between vSphere and client browser and manages all that cookie stuff if needed.

I don't know details since this proxy implemented/configured by other persons.

Actually, there are two possibilities to use that proxy:

- with the above method and connecting to vSphere;

- using novnc and connecting to ESXi host directly (only $vm_view->AcquireTicket(ticketType => 'webmks') needed and no cookie, see GitHub - rgerganov/mks: Client for VMware consoles).

Both methods have some (solvable) problems when establishing outside console connections (I heard something like vmware slightly changed protocol), and with both of them we experience periodic disconnects, unfortunately...

We still working on resolving these issues.

0 Kudos
vittoriop77
Contributor
Contributor

Thank you again for your answer,

I've a question regarding noVNC: do this feature require to configure each VM setting RemoteDisplay.vnc.enabled in order to enable VNC server ?

0 Kudos
allstuffinbox
Contributor
Contributor

Don't know where to find that setting in vSphere web interface, but VMs created by default in web interface or by perl api (vnc not mentioned) are accessible with both methods.

0 Kudos
jpsider
Expert
Expert

For powershell I use this snippet.  I then write that to my SQL server table. This will work with 5 or 6.

#=======================================================================================

function GetConsoleUrl($vmName, $hypVersion, $maxWaitTimeInSecs=$MAXWAITSECS) {

  if ($hypVersion -eq 6){

  $ConsolePort = 9443

  $myVM = Get-VM $vmName

  $VMMoRef = $myVM.ExtensionData.MoRef.Value

  #Get Vcenter from advanced settings

  $UUID = ((Connect-VIServer $Vcenter -user $VCenterUN -Password $VCenterPW -ErrorAction SilentlyContinue).InstanceUUID)

  $SettingsMgr = Get-View $global:DefaultVIServer.ExtensionData.Client.ServiceContent.Setting

  $Settings = $SettingsMgr.Setting.GetEnumerator()

  $AdvancedSettingsFQDN = ($Settings | Where {$_.Key -eq "VirtualCenter.FQDN" }).Value

  #Get vCenter ticket

  $SessionMgr = Get-View $global:DefaultVIServer.ExtensionData.Client.ServiceContent.SessionManager

  $Session = $SessionMgr.AcquireCloneTicket()

  #Create URL and place it in the Database

  $ConsoleLink = "https://$($Vcenter):$($ConsolePort)/vsphere-client/webconsole.html?vmId=$($VMMoRef)&vmName=$($myVM.N...{UUID}&host=$($AdvancedSettingsFQDN)&sessionTicket=$($Session)&thumbprint=5A:AB:D4:75:29:E8:D5:94:09:8F:D2:91:CF:DC:AB:C0:69:03:37:42"

  $query = "update sut_information set SUT_RemoteConsoleLink='$ConsoleLink',SUT_Console_Active='TRUE' where SUT_Name = '$SUTname'"

  RunSQLCommand $query

  return $True

  }

  Else {

  #Create URL and place it in the Database

  $myVM = Get-VM $vmName

  $UUID = ((Connect-VIServer $Vcenter -user $VCenterUN -Password $VCenterPW -ErrorAction SilentlyContinue).InstanceUUID).ToUpper()

  $MoRef = $myVM.ExtensionData.MoRef.Value

  $ConsoleLink = "https://${Vcenter}:9443/vsphere-client/vmrc/vmrc.jsp?vm=urn:vmomi:VirtualMachine:${MoRef}:${UUID}"

  $query = "update sut_information set SUT_RemoteConsoleLink='$ConsoleLink',SUT_Console_Active='TRUE' where SUT_Name = '$SUTname'"

  RunSQLCommand $query

  return $True

  }

  return $True

}

0 Kudos
vittoriop77
Contributor
Contributor

Hello jpsider,

your script works fine but the problem is related to pre-authentication.  When you connect to vSphere 6 you'll be prompted for vCenter Credentials.

The solution provided by allstuffinbox manage the vCenter authentication behind the scene but the authentication cookie (CastleSessionvsphere.local) is associated to the vcenter domain and I cannot use in my Web Site.

Using a websocket proxy we should be able to add the authentication cookie to the connection.

Vittorio

0 Kudos
jpsider
Expert
Expert

Gotcha,

I think that if you are looking to get around the idea of authentication, that using VNC will be your best solution, Open up the esx firewall, and use a tool like Guacamole to manage your vnc connections.  You can authenticate at the Guac layer, and allow free access to running vm's that Guac can view via VNC.

0 Kudos
vittoriop77
Contributor
Contributor

In order to enable VNC, I need to configure each virtual machine VMX file and set with different port, I've about 1000 virtual machines and I've a change ratio of 10 VM per day (created/deleted).

This is the solution suggested by Openstack but I think it doesn't scale out with my change ratio.

What do you think ?

0 Kudos
jpsider
Expert
Expert

I think it can scale, if you manage the system properly. There is a lot of work ahead of you, specifically if you want to restrict access from/to certain vms.  With a DB you can manage the VNC ports that are available for each vm to each host. If HA/DRS is enabled, this does get slightly more complex to keep the DB updated with the correct host/port, but nothing that is not overcome-able. This is just software. 🙂 lol. Trust me when I say your change ratio is minor compared to some larger applications that exist out there.

vittoriop77
Contributor
Contributor

OK thanks, I'll try !

Do you know if it's possible to script the VMX change in order to add the VNC port using PowerCLI  ?

0 Kudos
jpsider
Expert
Expert

Hmm, I Might be mistaken, but that is a port change on the esx host, not the .vmx file of the VM.  But with Powercli you can make policy changes to the esx host. 

0 Kudos
vittoriop77
Contributor
Contributor

jpsider, are you saying that I need to connect to a VNC port for ESX and then it will redirect me to the VM I need with the webmks ticket ?

What is this port ?   The 5900 port is not listening on my ESX host...

0 Kudos