WilliamLam.com

  • About
    • About
    • Privacy
  • VMware Cloud Foundation
  • VKS
  • Homelab
    • Hardware Options
    • Hardware Reviews
    • Lab Deployment Scripts
    • Nested Virtualization
    • Homelab Podcasts
  • VMware Nostalgia
  • Apple

Automating Active Directory User Management in ESXi Kickstart

02.24.2011 by William Lam // 2 Comments

In the previous post we looked at Automating Active Directory Domain Join in ESXi Kickstart. We are now going to look at adding domain users without having to manually go through vSphere Client or external scripts after an ESXi host has been provisioned. We are going to be leveraging vim-cmd to accomplish this during the kickstart installation. Before doing so, you will need to know the the available roles on a default ESXi host and the syntax for a given permission.

To see the available roles, you can run the following command on an already provisioned ESXi host:

vim-cmd vimsvc/auth/roles | less

The default roles on an ESXi host are:

  • NoAccess
  • ReadOnly
  • Admin

To see the existing permissions, you can run the following command on an already provisioned ESXi host:

vim-cmd vimsvc/auth/permissions

These entries will match what you see in the vSphere Client and dictate who has login access to the ESXi host.

To add a new permission, we will be using the "vim-cmd vimsvc/auth/entity_permission_add" and it requires five parameters.

  • First - Entity (This can be found by looking at the output from permissions)
  • Second - Username
  • Third - Boolean on whether this is a group or not (should be false)
  • Fourth - The role to be applied to the user
  • Fifth - Boolean on whether to propagate this permission

If you manually add a domain user, you can easily verify the user can login by running the "id" command which will perform a look up on the user. If it is successful, it should return an entry corresponding to something like this:

Note: We need to use the double slash "\" to escape the initial slash when running the query. Also make note of the domain name as it may or may not match your full domain name.

We are now ready to craft a simple script that will add domain users as part of the ESXi kickstart process. The following snippet should be placed in the %firstboot section of your kickstart and after your Active Directory domain join code. Make sure you replace the DOMAIN_NAME variable along with the usernames. In the example I have two separate for loops to handle ReadOnly and Admin users, you do not need both if you are only adding one type of users.

The script basically performs a simple 60sec sleep to ensure the domain join process has completed before continuing. If you do not place a sleep, the subsequent code will fail to execute. The next step is to validate the user by doing a simple lookup using "id" command and upon successful look up of the user, we add the appropriate permissions.

Note: We only have two add these two entities: "vim.Folder:ha-folder-root" and "vim.ComputeResource:ha-compute-res" to properly add a permission.

If everything was successful, after your ESXi installation you now should have your host joined to your Active Directory and a list of domain users who now have permission to login to the ESXi host. You can verify by using the vSphere Client and taking a look at the Permissions tab.

If you would like to create custom roles on your ESXi host, you can use the following command:

vim-cmd vimsvc/auth/role_add

Note: The syntax for the privileges parameter lists only five, but it actually accepts as many as you need with the custom role

Categories // Uncategorized Tags // active directory, ESXi 4.1, kickstart, mob, vimsh

Automating Active Directory Domain Join in ESX(i) Kickstart

02.23.2011 by William Lam // 10 Comments

I recently received an email asking if it was possible to automate the joining of an ESXi 4.1 host to Active Directory within a kickstart installation. The simple answer is yes; you can easily do so using the same trick found in tip #7 in Automating ESXi 4.1 Kickstart Tips & Tricks post which connects locally to the vSphere MOB using python.

Having said that, there is a small caveat to this solution in which the credentials used to join the ESX(i) host must be exposed in clear-text, this may or may not be acceptable. A potential way of getting this to work is to create a dedicated windows service account with limited privileges to add only ESXi hosts to your domain.

The reason for the use of clear-text password is the vSphere API method that is used to join an ESX(i) host to AD domain, joinDomain(), only supports plain text.

Ideally, the password parameter should accept either an encrypted hash or some type of certificate which can be validated by Active Directory server. The actual solution is pretty straight forward, by crafting the appropriate call to vSphere MOB, we are able to generate a python script during the %firstboot section of ESX(i) kickstart installation which will execute upon the initial boot up of the host.

Update (03/26/11):  Thanks to VMTN user klich who has found a solution to embed the password of the Active Directory user in a base64 encoding so that it is not visible in plain text for anyone who has access to the kickstart configuration file. To create the encoded hash, you will need access to either a ESX(i) or UNIX/Linux system which has python interpreter installed.

You will need to run the following command and substitute the password you wish to encode.

python -c "import base64;
print base64.b64encode('MySuperSecurePasswordYo')"

The output will be your encoded hash:

Note: Make sure your ESX(i) hostname is configured with a FQDN (Fully Qualified Domain Name), else you will get an error when trying to join to AD domain.

The following snippet should be added to your %firstboot section of your kickstart. Remember to replace the variables: domainname, ad_username and encodedpassword with your configurations and make sure to leave the password variable blank.

ESX(i) 4.1
cat > /tmp/joinActiveDirectory.py << __JOIN_AD__

import sys,re,os,urllib,urllib2

# MOB url
url = "https://localhost/mob/?moid=ha-ad-auth&method=joinDomain"

# mob login credentials -- use password = "" for build scripting
username = "root"
password = ""

# which domain to join, and associated OU
# e.g.
#       "primp-industries.com"
#       "primp-industries.com/VMware Server OU"
domainname = "primp-industries.com"

# active directory credentials using encoded base64 password
ad_username = "*protected email*"
encodedpassword = "TXlTdXBlclNlY3VyZVBhc3N3b3JkWW8"
ad_password = base64.b64decode(encodedpassword)

#auth
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,username,password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

#execute method
params = {'domainName':domainname,'userName':ad_username,'password':ad_password}
e_params = urllib.urlencode(params)
req = urllib2.Request(url,e_params)
page = urllib2.urlopen(req).read()
__JOIN_AD__

#execute python script to Join AD
python /tmp/joinActiveDirectory.py

If you are using ESX(i) 4.1 Update 1 or if you run into the "urllib2.HTTPError: HTTP Error 403: Forbidden: Possible Cross-Site Request Forgery" you will need to use the following snippet below which includes the session cookie as part of the request to the vSphere MOB due to a recent CSRF patch from VMware identified by VMTN user klitch.

ESX(i) 4.1 Update 1

cat > /tmp/joinActiveDirectory.py << __JOIN_AD__

import sys,re,os,urllib,urllib2,base64

# mob url
url = "https://localhost/mob/?moid=ha-ad-auth&method=joinDomain"

# mob login credentials -- use password = "" for build scripting
username = "root"
password = ""

# which domain to join, and associated OU
# e.g.
#       "primp-industries.com"
#       "primp-industries.com/VMware Server OU"
domainname = "primp-industries.com"

# active directory credentials using encoded base64 password
ad_username = "*protected email*"
encodedpassword = "TXlTdXBlclNlY3VyZVBhc3N3b3JkWW8"
ad_password = base64.b64decode(encodedpassword)

# Create global variables
global passman,authhandler,opener,req,page,page_content,nonce,headers,cookie,params,e_params

# Code to build opener with HTTP Basic Authentication
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,username,password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

### Code to capture required page data and cookie required for post back to meet CSRF requirements  ###
req = urllib2.Request(url)
page = urllib2.urlopen(req)
page_content= page.read()

# regex to get the vmware-session-nonce value from the hidden form entry
reg = re.compile('name="vmware-session-nonce" type="hidden" value="?([^\s^"]+)"')
nonce = reg.search(page_content).group(1)

# get the page headers to capture the cookie
headers = page.info()
cookie = headers.get("Set-Cookie")

# Code to join the domain
params = {'vmware-session-nonce':nonce,'domainName':domainname,'userName':ad_username,'password':ad_password}
e_params = urllib.urlencode(params)
req = urllib2.Request(url, e_params, headers={"Cookie":cookie})
page = urllib2.urlopen(req).read()

__JOIN_AD__

#execute python script to Join AD
python /tmp/joinActiveDirectory.py
After your ESXi host has completed installation, you can login to the ESX(i) host using the vSphere Client and you should see a recent successful task on the domain join process.

You can also verify by clicking on Configurations->Authentication Services and verify that your ESX(i) host is now part of the Active Directory domain.

In the next post, I will go over the details of adding domain users within the ESX(i) kickstart.

As a side note, it is quite unfortunate that ESXi only supports Microsoft Active Directory and does not integrate with other well known directory services such as NIS/NIS+, Kerberos, OpenLDAP, eDirectory, etc; this was actually possible with classic ESX. VMware has continued to focus on Windows-centric solutions and neglect the UNIX/Linux community by not supporting OS agnostic management tools that integrate with their vSphere platform. I hope this will change in the future for true interoperability.

Categories // Uncategorized Tags // active directory, ESXi 4.1, kickstart, mob

How to compile a statically linked rsync binary for ESXi

02.21.2011 by William Lam // 36 Comments

Running rsync on ESXi is not a new topic, there are a number of users in the community who have made this work. One well-known user, Dave Mishchenko, who runs vm-help and recently authored VMware ESXi: Planning, Implementation, and Security, provides an rsync binary that can be downloaded to run on ESXi. Not that I did not trust Dave and the source of his rsync binary, but I wanted to compile my own and understand the process Dave took to get to a compatible rsync for ESXi. In talking to Dave, I found out the binary was actually provided by a VMTN user, named glim who had noted some of the details in this VMTN thread.

The user basically created a statically linked versus a dynamically linked version of rsync which runs without relying on libraries that may or may not be present on ESXi. My initial attempts failed using both a 32/64bit CentOS 5.5 and latest version of rsync 3.0.7 and 3.0.3. The compilation of rsync was successful, but upon executing on ESXi, it immediately had a segmentation fault. I started to think there might be some dependencies in libraries that were used to compile rsync that I was missing. I was also in conversation with Alain Spineux, creator of MKSBackup regarding this same topic and he had found a way to compile rsync based on the article Hacking ESXi by Stjepan Groš.

Stejepan found that using CentOS 3.9, one could compile both statically and dynamically linked binaries without any modifications to ESXi. Though Stejepan did not provide the steps to compile rsync, it is relatively simple to do so. I also found that you do not need to use older 3.0.3 release of rsync, you can use the latest version which is 3.0.7 as of writing this article.

Before we get started, let me remind you of the disclaimer:
*** THIS IS PROBABLY NOT SUPPORTED BY VMWARE, USE AT YOUR OWN RISK ***

Step 1

Download and install CentOS 3.9 i386 - You can find a list of download sites here

Step 2

With a default installation of CentOS 3.9, you just need to get GCC installed

yum -y install gcc

Step 3

Next you will need to download the latest version of rsync which is 3.0.7 here and SCP it to your CentOS system

Step 4

Next you will now extract the contents of the rsync-3.0.7.tar.gz

tar -zxvf rsync-3.0.7.tar.gz

Step 5

Now you will change into the rsync-3.0.7 directory and run the configure command

./configure

Step 6

Now you will run the make command which will compile rsync, but you will also be passing in additional flags to create a statically linked binary

make CFLAGS="-static" EXEEXT="-static"

Step 7

Finally, you will need to run the strip utility which discards all symbols from object files

strip rsync-static

You now have a self-contain rsync binary labeled rsync-static found in the current working directory

Next up, you will SCP the rsync-static binary to your ESX(i) host and set the appropriate permissions to execute. I decided to temporarily store it in /tmp, but if you want the binary to persist through a reboot, you may want to store it in either a local or remote VMFS/NFS volume.

I quickly verified that rsync was in functional, by rsyncing /etc directory in ESXi over to another host. I use the following command:

/tmp/rsync-static --compress --progress --stats -e dbclient -Rr /etc build-centos:/upload

Once the file transfer has completed, you should see the /etc directory replicated on the destination host.

You may have noticed in the command line we are specifying "dbclient", by default rsync will go over SSH but ESXi does not actually have the traditional ssh client that we are all used to. It actually uses dropbear which is tiny SSH server and client which is frequently used in embedded systems such as Busybox.

Since /bin/ssh path does not exists, rsync will fail unless you specify the dbclient to the -e parameter.

Alain also found that retrieving peer name may fail and the rsync code currently does not properly handle this failure and just exits. By looking at the clientname.c source code which is part of rsync, Alain noted that even the developers left a comment that states the error could probably be handled without exiting. The fix is to just comment out the rsynerr line which does not force the program to exit when hitting this problem and this can be found on line 171.

Once you have made the changes, you just need to follow the instructions above to compile your static rsync binary. This is not necessary required, but if you run into this issue, this is a quick hack that can help.

I would like to thank Alain for sharing this tidbit of information

Categories // Uncategorized Tags // ESXi 4.1, rsync

  • « Previous Page
  • 1
  • …
  • 533
  • 534
  • 535
  • 536
  • 537
  • …
  • 565
  • Next Page »

Search

Thank Author

Author

William is Distinguished Platform Engineering Architect in the VMware Cloud Foundation (VCF) Division at Broadcom. His primary focus is helping customers and partners build, run and operate a modern Private Cloud using the VMware Cloud Foundation (VCF) platform.

Connect

  • Bluesky
  • Email
  • GitHub
  • LinkedIn
  • Mastodon
  • Reddit
  • RSS
  • Twitter
  • Vimeo

Recent

  • PowerCLI remediation script for running NSX Edge on AMD Ryzen for VCF 9.0 06/20/2025
  • Failed to locate kickstart on Nested ESXi VM CD-ROM in VCF 9.0 06/20/2025
  • NVMe Tiering with Nested Virtualization in VCF 9.0 06/20/2025
  • VCF 9.0 Installer workaround for ESXi hosts with different vendor 06/19/2025
  • NVMe Tiering with AMD Ryzen CPU workaround for VCF 9.0 06/19/2025

Advertisment

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy

Copyright WilliamLam.com © 2025