The solution isn't, in my opinion, mature enough to be used in enterprise / production environments but it is VERY promising and i can't wait for the next release to come out.
Yesterday, i started playing around with the
RHEV-M API and found a basic "security flaw" in it.
In fact, it is so basic that i'm even somewhat ashamed to point this out as a security flaw (hence why i referred to it in quotes) as it is more of a security problem caused by a miss-configuration.
First, let me start by giving you all a little background on how the solution works.
Oddly enough, the RHEV solution works by running a RHEV Manager service under Windows 2008 R2. Yeaps, you read it right, it ONLY works under Windows 2008 R2.
Nevertheless, and without getting into much detail, there is a reason for that: the main service uses legacy code that was developed specifically for Windows 2008 R2. But fear not, RHEV v 3.0 will work, entirely, on Linux systems!
So we start by adding the IIS role and enabling .NET 3.5 under Windows 2008 R2.
Then we install the actual RHEV Manager service (whose role is somewhat similar to VMware vCenter), deploy a new SQL Server Express instance (or use an existing one) and decide if you want to use local or AD level authentication.
Because i'm only evaluating the solution, i've actually deployed with local authentication.
After the service is up and running, we can manage it using some powershell extensions or using a web interface (though, be advised, it only runs on Internet Explorer browsers).
Finally, we deploy each of the hypervisors and then set them up in the manager by creating data and ISO storage domains, associating them with a datacenter, adding one or more clusters to that datacenter and adding the hypervisors to one of those clusters.
The web interface itself is pretty slick and that's the part that impressed me the most!
Now, the nice folks at RH and Fedora created an API for people to be able to programatically manage the RHEV Manager, the
RHEV-M API.
The interesting thing about this API is that it works by serving a
REST web service (
as described here) of a servlet container (such as
Tomcat or
JBoss) and that web service essentially works as a wrapper for the aforementioned powershell extensions.
I deployed the necessary .war files and configured an Apache Tomcat web server, as described in
the documentation that ships with the API, but did not know exactly how to authenticate against it when the browser asked for my user credentials.
I now know the username format is "user@domain" but my first try was to specify "Administrator" as the username and "mypassword" as the password.
This did not work and just made the browser hang (just loading the web service indefinitely) so i decided to take a look at Tomcat's logs and found this:
563003 [http-8443-6] INFO com.redhat.rhevm.api.powershell.util.PowerShellCmd - Running'get-version 'Login-User : login-user : Cannot Login. The Domain provided is not configured, please contact your administrator.
At line:1 char:24
+ logout-user; login-user <<<< -username "Administrator" -password "mypassword";
At line:1 char:24
+ logout-user; login-user <<<< -username "Administrator" -password "mypassword";
+ CategoryInfo : InvalidOperation: (:) [Login-User], RuntimeException
+ FullyQualifiedErrorId : RunActionFailed,RhevmCmd.PSCmdlet_Login_User
Well, after seeing the username and password i had passed to the web service and references to one of the powershell cmdlets ("login-user") that ships with the RHEV Manager, i immediately thought: command injection!
So i decided to pass an escape char to it for my username (i.e. '\' )and, surprise surprise, this actually did not cause the API to inject a command (as i had expected - because they apparently do some filtering) but it accepted my credentials and gave me access to the full web service API!
I looked at the logs and found this:
0281268 [http-8443-4] WARN com.redhat.rhevm.api.powershell.util.PowerShellCmd - Login-User :
Cannot validate argument on parameter 'Domain'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At line:1 char:32
+ logout-user; login-user -domain <<<< "" -username "" -password "random";
+ CategoryInfo : InvalidData: (:) [Login-User], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,RhevmCmd.PSCmdlet_Login_User
281270 [http-8443-4] INFO com.redhat.rhevm.api.powershell.util.PowerShellCmd - Parsing powershell output
...
[WEB_SERVICE_XML_DATA]
...
This means that, although the "login-user" cmdlet did NOT accept my credentials, it threw an unexpected exception the API did not catch so it assumed the authentication had worked.
After looking at the log i obviously noticed that passing an empty string as the username and password would also work which is why i feel bad for even calling this a security flaw.
I submitted this bug to the rhev-m api's mailing list and talked with some really nice fellows at RH that told me they had never bumped into this problem under their environment and that this was caused by my type of environment / configuration.
Well, it is always good practice to run the web service as an unprivileged user (doh... ;o)) so their advice was that i would run it under different user credentials because, since the Administrator is already an administrator (hmm, really?!), the powershell cmdlet's security context is already privileged, hence, why the failed login-user cmdlet did not stop me from getting total access to the API.
As they say at the
API's official website, "the
API definition is in its early stages. It may yet change substantially before being becoming the the official
API" and "the PowerShell wrapper is for experimentation only and not a supported Red Hat solution" so, no real harm done with this.
I just wanted to write about it because i thought it was a funny situation (and to share what i've been working on lately).
The API ships with a python client api but i couldn't get it to work (it has some problems right now), plus, i need Perl code to consume it so i started creating my own Perl REST client API.
It has been very fun to code so far (it's the first time i've consumed a REST web service from Perl, let alone using SSL and http authentication or
XML::LibXML).
I'm using Perl's REST::Client and that posed a challenge as i got to this module's documentation at cpan.org via google and was reading the docs for a very old version of it...
So getting SSL to work and authentication was a nightmare until i talked with a friend at work about it and he opened the module's latest documentation (by searching it directly using search.cpan.org).
I went back to my computer and FORTUNATELY noticed the page he found had more info, telling us we can access the
LWP::UserAgent object that
REST::Client uses to make requests!
With this info, i quickly managed to authenticate to the web service and started using it ;o)
I'm also very excited about XML::LibXML's
XPath support! With it, it has been extremely easy to parse the web service's XML data.
I'll share my Perl client API as soon as i'm done with it :o).