Domain Controller

This document describes how to configure a computer running FreeBSD to serve as an Active Directory domain controller.

Base UNIX Domain Controller

First, setup the server:

  1. Install FreeBSD and configure networking. Be sure to set the server’s hostname such as with hostname="dc.example.com" in /etc/rc.conf
  2. Configure the Samba 4 port by entering /usr/ports/net/samba43/ and running make config. (The version 4.4 of the Samba port is presently broken.)
  3. For a minimal install, select neither mDNSresponder nor avahi while configuring the build.
  4. Build and install Samba 4 by running make install clean.
  5. Activate filesystem ACLs in /etc/fstab, e.g., /dev/ada0p2 / ufs rw,acls 1 1.
  6. Configure Samba by running samba-tool domain provision --use-rfc2307 --interactive.
  7. Use samba-tool user add to add users to Samba’s authentication database.
  8. Activate Samba by adding samba_server_enable="YES" to /etc/rc.conf.

Next, add a Windows client to the domain:

  1. Set the Windows host’s DNS resolver to point to the Samba server’s IP address.
  2. Right click on the computer icon; select properties; select change settings near the text computer name; and press the button to change the computer’s domain.
  3. Select the domain radio button and type in Samba 4’s full domain.
  4. Click ok and provide the administrative password for the Samba 4 domain.
  5. Restart the client computer.

As an aside, Red Hat-derived Linux distributions such as RHEL, CentOS, and Fedora make it difficult to configure Samba 4 as an Active Directory domain controller. This is primarily because these distributions use MIT Kerberos, while many of the Active Directory-related features in Samba 4 require Heimdal Kerberos. Information about the coming solution to this problem can be found on the Internet, including as documented by the Samba project.

Adding Host Records to Samba’s DNS implementation

Each domain host will likely require a DNS record in Samba’s DNS service. You can use the following command to add an A record to the domain controller at dc.example.com for the host which is named host.example.com and bears the IP address 10.0.0.64: samba-tool dns add dc.example.com example.com host A 10.0.0.64.

Remote Management from a Windows Computer

Windows provides facilities for remotely managing domain-connected computers. In order to activate one such facility on a user computer, run the following on that user computer:

Enable-PSremoting

Once the user computer is set to accept remote-management requests, you can run the following command as the domain administrator from an administrative computer to test remote management (replace TARGET with the computer you intent to manage):

Invoke-Command -Computer TARGET -ScriptBlock { "C:\Program files" |  Get-ChildItem }

Smart-Card Authentication

Certificate Production

Establish a Certificate Authority

Smart-card-based authentication requires a number of certificates: CA "root-of-trust" certificate, a certificate for the domain controller, and certificates for each user.

  1. Create a basic CA directory structure from within the root of where you intend to store your certificates and other materials: mkdir certs crl private newcerts.
  2. Create a blank file named index.txt.
  3. Create files named serial and crlnumber containing 00.
  4. Add the following to /etc/openssl.cnf:
CRLURL      = [URL of CRL server, e.g., https://crl.example.com/example.com.crl]
BASEDIR     = [Base of certificate store; where signed certificates go]
COUNTRY     = [Two-letter country code]
STATE       = [State of province (not abbreviated)]
LOCALITY    = [City, town, etc.]
ORG         = [Name of organization]
OU          = [Organizational unit]
DOMAIN      = [Domain, e.g., example.com]
EMAIL       = [Email address]@$DOMAIN
DC          = [Hostname of domain controller]

# Using "ADSI Edit" on Windows:
#   1. Connect to domain controller
#   2. Default naming context
#   3. DC=...
#   4. OU=Domain Controllers
#   5. Right click on CN=... and select Properties
#   6. View objectGUID in hexadecimal
DCGUID      = [Domain controller's GUID in HEX, eg, FEEDDEADBEEF...]

# Using "ADSI Edit" on Windows:
#   1. Connect to domain controller
#   2. Default naming context
#   3. DC=...
#   4. CN=Users
#   5. Right click on CN=... and select Properties
#   6. View usePrincipalName
UPN         = [UPN of user]

oid_section = new_oids

[ new_oids ]
scardLogin = 1.3.6.1.4.1.311.20.2.2
msUPN      = 1.3.6.1.4.1.311.20.2.3
msKDC      = 1.3.6.1.5.2.3.5
msADGUID   = 1.3.6.1.4.1.311.25.1

[ ca ]
default_ca  = CA_default                  # The default ca section

[ CA_default ]
dir              = $BASEDIR               # Where everything is kept
certs            = $dir/certs             # Where the issued certs are kept
crl_dir          = $dir/crl               # Where the issued crl are kept
database         = $dir/index.txt         # database index file.
unique_subject   = yes                    # Set to 'no' to allow creation of
new_certs_dir    = $dir/newcerts          # default place for new certs.
certificate      = $dir/cacert.pem        # The CA certificate
serial           = $dir/serial            # The current serial number
crlnumber        = $dir/crlnumber         # the current crl number
crl              = $dir/ca-crl.pem        # The current CRL
private_key      = $dir/private/cakey.pem # The private key
RANDFILE         = $dir/private/.rand     # private random number file
# x509_extensions =               # Extensions to add to certificate
name_opt         = ca_default             # Subject Name options
cert_opt         = ca_default             # Certificate field options
crl_extensions   = crl_ext
default_days     = 730                    # how long to certify for
default_crl_days = 30                     # how long before next CRL
default_md       = sha256                 # use public key default MD
preserve         = no                     # keep passed DN ordering
policy           = policy_match

[ policy_match ]
countryName            = match
stateOrProvinceName    = match
organizationName       = match
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional

[ policy_anything ]
countryName            = match
stateOrProvinceName    = match
localityName           = match
organizationName       = match
organizationalUnitName = match
commonName             = supplied
emailAddress           = supplied

[ req ]
default_bits           = 4096
default_keyfile        = privkey.pem
distinguished_name     = req_distinguished_name
x509_extensions        = v3_ca            # The extensions to add to the self signed cert
string_mask            = utf8only
attributes             = req_attributes

[ req_attributes ]
challengePassword     = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName      = An optional company name

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)
countryName_default            = $COUNTRY
countryName_min                = 2
countryName_max                = 2
stateOrProvinceName            = State or Province Name (full name)
stateOrProvinceName_default    = $STATE
localityName                   = Locality Name (eg, city)
localityName_default           = $LOCALITY
organizationName               = Organization Name (eg, company)
organizationName_default       = $ORG
organizationalUnitName         = Organizational Unit Name (eg, section)
organizationalUnitName_default = $OU
emailAddress                   = Email Address
emailAddress_default           = $EMAIL
emailAddress_max               = 64
commonName                     = Common Name (eg, YOUR name)
commonName_default             = hostname.$DOMAIN
commonName_max                 = 64

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage         = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints       = CA:true
keyUsage               = cRLSign, keyCertSign
crlDistributionPoints  = URI:$CRLURL
nsCertType             = sslCA, emailCA
subjectAltName         = email:copy
issuerAltName          = issuer:copy

[ crl_ext ]
issuerAltName          = issuer:copy
authorityKeyIdentifier = keyid:always

# Extensions for domain-controller certificates:

[ usr_cert_mskdc ]
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end-user certificate as a CA.
basicConstraints       = CA:FALSE
crlDistributionPoints  = URI:$CRLURL
nsCertType             = server
keyUsage               = nonRepudiation, digitalSignature, keyEncipherment
nsComment              = "Domain Controller Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName         = @dc_subjalt
issuerAltName          = issuer:copy
nsCaRevocationUrl      = $CRLURL
extendedKeyUsage       = clientAuth,serverAuth,msKDC

[dc_subjalt]
DNS                    = $DC
otherName              = msADGUID;FORMAT:HEX,OCTETSTRING:$DCGUID

# Extensions for smart-card user certificates:

[ usr_cert_scarduser ]

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end-user certificate as a CA.
basicConstraints       = CA:FALSE
crlDistributionPoints  = URI:$CRLURL
nsCertType             = client, email
keyUsage               = nonRepudiation, digitalSignature, keyEncipherment
nsComment              = Smart Card Login Certificate
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName         = email:copy,otherName:msUPN;UTF8:$UPN
issuerAltName          = issuer:copy
nsCaRevocationUrl      = $CRLURL
extendedKeyUsage       = clientAuth,scardLogin

Generate a CA Root Certificate

  1. Properly define the variables at the top of openssl.cnf.
  2. See notes on the use of certificates. You will want to use the -config openssl.cnf option to use the above configuration.

Generate a Certificate for Samba

  1. Under the CA_default section of openssl.cnf, set x509_extensions = usr_cert_mskdc and ensure the line is not commented out.
  2. Generate the certificate using openssl req -new -newkey rsa:4096 -keyout private/dc-key.pem -out dc-req.pem -config openssl.cnf -nodes.
  3. Sign the Samba certificate using the CA certificate openssl ca -config openssl.cnf -in dc-req.pem -out dc-cert.pem.

Generate a Smart-Card User Certificate

  1. Under the CA_default section of openssl.cnf, set x509_extensions = usr_cert_scarduser and ensure the line is not commented out.
  2. Generate the certificate using openssl req -new -newkey rsa:2048 -keyout private/user-key.pem -out user-req.pem -config openssl.cnf -nodes. Note that you might have limited key types/sizes to choose from, depending on the type of smartcard you plan to use.
  3. Sign the user certificate using the CA certificate openssl ca -config openssl.cnf -in user-req.pem -out user-cert.pem.
  4. Install the certificate and private key onto a smartcard.

Certificate-Revocation-List Server

  1. Configure, build, and install the apache24 port.
  2. Generate and install a certificate and private key for Apache at /usr/local/etc/apache24/.
  3. Configure Apache, including the following in /usr/local/etc/apache24/httpd.conf:
  • LoadModule ssl_module modules/mod_ssl.so
  • ServerName crl.example.com:443
  • Listen 443
  • SSLEngine on
  • SSLCertificateFile /usr/local/etc/apache24/crl.example.com.pem
  • SSLCertificateKeyFile /usr/local/etc/apache24/crl.example.com.key
  1. Generate the CRL with openssl ca -config openssl.cnf -gencrl -out example.com.crl and install the result in Apache’s document directory.

Configure Samba to support certificate-based login

  1. Copy the necessary certificates and the CRL onto the Samba host (see the next step for what Samba will require).
  2. Generate Diffie-Hellman parameters: openssl dhparam 4096 -out dc-dhparams.pem.
  3. Add to smb4.conf:
tls enabled       = yes
tls certfile      = /usr/local/samba/private/tls/dc-cert.pem
tls keyfile       = /usr/local/samba/private/tls/secure/dc-privkey.pem
tls cafile        = /usr/local/samba/private/tls/cacert.pem
tls crlfile       = /usr/local/samba/private/tls/ca.crl
tls dhparams file = /usr/local/samba/private/tls/dc-dhparams.pem

Configure Windows to support certificate-based login

  1. Convert your PEM-format CA certificate to DER: openssl x509 -in cacert.pem -out cacert.cer -outform DER.
  2. Convert your user certificate to DER: openssl x509 -in Administrator-cert.pem -out Administrator-cert.cer -outform DER.
Assistant Professor

My research interests include free and open source software, system security, and network security.