The action of joining a computer to a domain is not a well-defined operation, and so the exact mechanics of how you utilize the domain joining functionality and how its outputs are integrated with the rest of your system will vary depending on your use case.
This will try to cover some common examples.
The default behavior requires only the domain name and the credentials of a user with sufficient administrative rights to create computers within the domain. :
from ms_active_directory import join_ad_domain
comp = join_ad_domain('example.com', 'Administrator@example.com', 'example-password')
The join_ad_domain
function returns a ManagedADComputer
object with many helpful functions describing properties of the created computer.
This will use the local hostname of the machine running this code as the computer name. It will create the computer in AD's default Computers
container.
It enables AES256-SHA1
as an encryption type for both receiving and initiating kerberos contexts, and it configures <local hostname>.<domain dns name>
as the hostname of the computer in AD and registers the default HOST
service.
It then writes kerberos keys for the new computer account to /etc/krb5.keytab
, which is the default location for kerberos keytabs.
This all enables the account to be used for authenticating with other domain resources as a client over protocols like SMB and LDAP using kerberos, as well as receiving incoming kerberos authentication as a server for things like SSH. This is because the HOST
service encapsulates many standard services in the domain.
However, it is still up to the caller to do things like configure sshd to utilize the keytab.
A number of customizations exist for security reasons.
You can change things like the encryption types enabled on the account to support older clients. You can also change location where the account is created when joining a domain in order to use a less privileged user for the act of joining. Locations can be LDAP distinguished names or windows path style canonical names.
You can also set the computer name if you have a desired naming scheme. This will impact the hostnames configured in the domain for the computer. :
from ms_active_directory import join_ad_domain, ADEncryptionType
domain = 'example.com'
less_privileged_user = 'ops-manager@example.com'
password = 'password2'
# ldap-style relative distinguished name of a location
less_privileged_loc = 'OU=service-machines,OU=ops'
computer_name = 'workstation10'
legacy_enc_type = ADEncryptionType.RC4_HMAC
new_enc_type = ADEncryptionType.AES256_CTS_HMAC_SHA1_96
comp = join_ad_domain(domain, less_privileged_user, password, computer_name=computer_name,
computer_location=less_privileged_loc, computer_encryption_types=[legacy_enc_type, new_enc_type])
alt_format_loc = '/ops/service-machines'
comp = join_ad_domain(domain, less_privileged_user, password, computer_name=computer_name,
computer_location=alt_format_loc, computer_encryption_types=[legacy_enc_type, new_enc_type])
You can also manually set the computer password. The default is to generate a random 120 character password, but if you want to share this computer across services, and some cannot interact with the generated kerberos keys, then you may wish to set a password manually.
You can also change where the kerberos keys are written to. :
from ms_active_directory import join_ad_domain
domain = 'example.com'
user = 'ops-manager@example.com'
password = 'password2'
kerberos_key_location = '/usr/shared/keys/workstation-key.keytab'
computer_name = 'workstation10'
computer_password = 'workstation-shared-pw'
comp = join_ad_domain(domain, user, password, computer_key_file_path=kerberos_key_location,
computer_name=computer_name, computer_password=computer_password)
You can configure different hostnames for your computer when joining the domain. This is useful when you have multiple different hostnames for a single device, or want to use a computer name that doesn't match your network name.
You can also configure services in order to restrict or broaden what is supported by the computer when acting as a server (e.g. you can add nfs if the machine will be an nfs server).
Joining will fail if another computer in the domain is using the services you specify on any of the hostnames you specify in order to avoid conflicts that cause undefined behavior. :
from ms_active_directory import join_ad_domain
domain = 'example.com'
user = 'ops-manager@example.com'
password = 'password2'
services = ['HOST', 'nfs', 'cifs', 'HTTP']
computer_name = 'workstation10'
computer_host1 = 'central-mount-point.example.com'
computer_host2 = 'example-web-server.example.com'
comp = join_ad_domain(domain, user, password, computer_name=computer_name,
computer_hostnames=[computer_host1, computer_host2],
computer_services=services)
You can use an ADDomain
object to join the domain as well, using a join
function. This allows you to combine all of the functionality mentioned earlier around site-awareness, server preferences, TLS settings, and network multi-tenancy with the domain joining functionality mentioned in this section.
The parameters are all the same, except the domain need not be provided when using an ADDomain
object, so it just adds more functionality in exchange for a slightly less simple workflow.
from ms_active_directory import ADDomain
domain = ADDomain('example.com', site='us-eastern-dc',
source_ip='10.25.21.30', dns_nameservers=['10.25.21.20'])
user = 'ops-manager@example.com'
password = 'password2'
less_privileged_loc = 'OU=service-machines,OU=ops'
services = ['HOST', 'nfs', 'cifs', 'HTTP']
computer_name = 'workstation10'
comp = domain.join(user, password, computer_hostnames=[computer_host1, computer_host2],
computer_services=services, computer_location=less_privileged_loc)
For some setups, accounts may be pre-created and then taken over by the computers that will use them.
This can be done in order to greatly restrict the permissions of the user that is used for joining, as they only need RESET PASSWORD
permissions on the computer account, or CHANGE PASSWORD
if the current computer password is provided. :
from ms_active_directory import ADDomain, join_ad_domain_by_taking_over_existing_computer
domain_dns_name = 'example.com'
site = 'us-eastern-dc'
existing_computer_name = 'precreated-comp'
user = 'single-account-admin@example.com'
password = 'password2'
computer_obj = join_ad_domain_by_taking_over_existing_computer(domain_dns_name, user, password,
ad_site=site, computer_name=existing_computer_name)
# or use a domain object to use various power-user domain features
domain = ADDomain(domain_dns_name, site=site,
source_ip='10.25.21.30', dns_nameservers=['10.25.21.20'])
domain.join_by_taking_over_existing_computer(user, password, computer_name=existing_computer_name)