Soup To Nuts Sun DSEE
From Brandonhutchinson.com
m (→Upgrading to DS 6.2) |
|||
| Line 800: | Line 800: | ||
# '''/opt/SUNWdsee/ds6/bin/dsadm start /var/ds''' | # '''/opt/SUNWdsee/ds6/bin/dsadm start /var/ds''' | ||
(hostname2) # '''dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname1:636''' | (hostname2) # '''dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname1:636''' | ||
| + | |||
| + | == Installing Directory Service Control Center (DSCC) == | ||
| + | |||
| + | The DSEE ZIP distribution provides everything needed for DSCC except for Sun Web Console. Unfortunately, Sun Web Console is only available within [http://www.sun.com/software/javaenterprisesystem/index.jsp Sun Java Enterprise System]. | ||
| + | |||
| + | In this example, Sun Web Console is installed from packages within the Sun Java ES Update 1 distribution. | ||
| + | |||
| + | $ '''unzip -q java_es-5u1-identsuite-ga-solaris-sparc.zip''' | ||
| + | $ '''cd java_es-5u1-identsuite/Solaris_sparc/Product/sunwebconsole''' | ||
| + | # '''for PKG in `ls -d SUNW*` ; do yes | pkgadd -d . $PKG ; done''' | ||
| + | # '''cd SunOS-5.10-sparc''' | ||
| + | # '''for PKG in `ls -d SUNW*` ; do yes | pkgadd -d . $PKG ; done''' | ||
| + | |||
| + | Next, clear any previous DSCC configuration and initialize DSCC. | ||
| + | # '''/opt/SUNWdsee/dscc6/bin/dsccsetup dismantle''' | ||
| + | # '''/opt/SUNWdsee/dscc6/bin/dsccsetup initialize''' | ||
| + | |||
== Troubleshooting == | == Troubleshooting == | ||
Revision as of 18:59, 28 November 2007
In the following instructions, Sun Directory Server Enterprise Edition (DSEE) 6.1 is installed on two Solaris 10 Sparc servers. The LDAP servers are configured for multi-master replication over SSL. The LDAP passwd and group databases are populated from an existing NIS environment, and Solaris 8 Sparc LDAP clients are bound to the LDAP servers.
Download DSEE
From the DSEE download page, select the following options:
- Under Step 1: Select Component, select Directory Server Enterprise Edition 6.x
- Under Step 2: Select Version, select 6.1
- Under Step 3: Select Delivery Type, select Compressed Archive (ZIP)
- Under Step 4: Select Platform, select Solaris 10 SPARC
Install DSEE
Perform the following steps on both LDAP servers.
- Extract the DSEE tarball.
$ gzip -cd DSEE.6.1.Solaris-Sparc-full.tar.gz | tar xvf -
- Install DSEE. In this example, DSEE is installed in /opt/SUNWdsee.
$ cd DSEE_ZIP_Distribution # ./dsee_deploy install --no-inter --install-path /opt/SUNWdsee
Directory Server instance creation
Perform the following steps on both LDAP servers.
- Create a Directory Server instance. In this example, the Directory Instance is created in /var/ds. When prompted to choose the Directory Manager password, use the same Directory Manager password on both LDAP servers.
# dsadm create /var/ds Choose the Directory Manager password: Confirm the Directory Manager password: Use 'dsadm start /var/ds' to start the instance
- Start the Directory Server instance.
# dsadm start /var/ds
Directory Information Tree (DIT) creation
Perform the following steps on both LDAP servers.
- Create the root suffix of the Directory Information Tree (DIT). In this example, the root suffix is dc=example,dc=com. Accept the self-signed certificate that was automatically created during #Directory Server instance creation.
# dsconf create-suffix dc=example,dc=com
- Create the sub-suffix. In this example, the sub-suffix is dc=subdomain,dc=example,dc=com.
# dsconf create-suffix dc=subdomain,dc=example,dc=com
- Attach the sub-suffix to the root suffix.
# dsconf set-suffix-prop dc=subdomain,dc=example,dc=com parent-suffix-dn:dc=example,dc=com
Configure SSL
Please see the excellent instructions at Native Solaris LDAP client over SSL from which much of this information was obtained.
Create the Certificate Authority (CA)
The following instructions assume OpenSSL is installed in /usr/local on hostname1, and that hostname1 will be the CA. These steps only need to be performed on hostname1.
- Create the CA directory.
# mkdir /CA # cd /CA
- Create the CA private key.
# /usr/local/ssl/bin/openssl genrsa -out ca.key 1024 Generating RSA private key, 1024 bit long modulus ....++++++ ..++++++ e is 65537 (0x10001)
- Create a self-signed x509 CA certificate. The CA certificate will be valid for 20 years (-days 7300).
# /usr/local/ssl/bin/openssl req -out ca.cert -key ca.key -new -x509 -days 7300 -subj "/CN=Example Certificate Authority"
- Create a configuration file for the CA (e.g., /CA/ca.conf). CA-signed certificates will be valid for 5 years (default_days = 1825).
[ ca ] default_ca = ExampleCA # Default CA [ ExampleCA ] private_key = ca.key # CA key certificate = ca.cert # CA certificate database = ca.db # Keep track of certs issued serial = ca.serial # Serial number for next cert default_days = 1825 # Validity for certs issued default_md = md5 # Default message digest policy = policy_cn # What should be in subject new_certs_dir = . # Dir for newly created certs [ policy_cn ] commonName = supplied # CN must be supplied
- Create a database to track certificates.
# touch ca.db
- Create a file containing the serial number for the next signed certificate.
# echo 01 > ca.serial
Create Certificate Signing Requests (CSRs)
Make sure to use the fully-qualified domain name of the LDAP server in the CSR subject (i.e., --name ...).
(hostname1) # dsadm request-cert --name hostname1.example.com --org organization --city city --state state --country country \ -o /CA/hostname1.cert.req -F ascii /var/ds (hostname2) # dsadm request-cert --name hostname2.example.com --org organization --city city --state state --country country \ -o /tmp/hostname2.cert.req -F ascii /var/ds
Sign the CSRs
- Copy hostname2:/tmp/hostname2.cert.req to hostname1:/CA.
- Sign the CSRs on the CA server hostname1.
# cd /CA # /usr/local/ssl/bin/openssl ca -config ca.conf -in hostname1.cert.req -out hostname1.cert # /usr/local/ssl/bin/openssl ca -config ca.conf -in hostname2.cert.req -out hostname2.cert
Add signed server certificate and CA certificate to database
- Copy hostname1:/CA/hostname2.cert and hostname1:/CA/ca.cert to hostname2:/tmp
- Add the CA-signed server certificate.
(hostname1) # dsadm add-cert --ca /var/ds hostname1 /CA/hostname1.cert (hostname2) # dsadm add-cert --ca /var/ds hostname2 /tmp/hostname2.cert
- Add the CA certificate.
(hostname1) # dsadm add-cert --ca -C /var/ds ExampleCA /CA/ca.cert (hostname2) # dsadm add-cert --ca -C /var/ds ExampleCA /tmp/ca.cert
Modify dse.ldif
dse.ldif on each LDAP server must be changed to use the new server certificates instead of the defaultCert self-signed certificate for secure LDAP. Although dsconf set-server-prop ssl-rsa-cert-name should be used to make this change, I was unable to get it to work.
- On hostname1, change nsSSLPersonalitySSL: defaultCert to nsSSLPersonalitySSL: hostname1 in /var/ds/config/dse.ldif.
- On hostname2, change nsSSLPersonalitySSL: defaultCert to nsSSLPersonalitySSL: hostname2 in /var/ds/config/dse.ldif.
Restart Directory Server on both LDAP servers to begin using the new server certificates for secure LDAP.
# dsadm restart /var/ds
Create the LDAP client certificate database files (if applicable)
The following steps are only required when using TLS:Simple authentication. In this example, only "simple" authentication is used, because TLS:Simple authentication is impossible with Solaris 8 and Solaris 9 LDAP clients and the DSEE 6.1 LDAP server (see #Solaris 8 and Solaris 9 instructions).
The LDAP client database files are needed to "trust" the CA, and therefore trust all server certificates signed by the CA.
Solaris 10 instructions
- On the CA (hostname1), create a new certificate and key database in /var/ldap. Do not enter a password when prompted.
# mkdir /var/ldap # /usr/sfw/bin/certutil -N -d /var/ldap Enter a password which will be used to encrypt your keys. The password should be at least 8 characters long, and should contain at least one non-alphabetic character. Enter new password: Re-enter password:
- Create the client database files.
# /usr/sfw/bin/certutil -A -d /var/ldap -n ExampleCA -t C,, -i /CA/ca.cert
- Copy the following client databases files to /var/ldap on all Solaris 10 LDAP clients.
- /var/ldap/cert8.db
- /var/ldap/key3.db
- /var/ldap/secmod.db
- Change the permissions of these files to 444 on all Solaris 10 LDAP clients.
Solaris 8 and Solaris 9 instructions
The NSS security libraries in Solaris 8 and Solaris 9 only support cert7 server certificates. DSEE 5.2P4 and later create certificates in cert8 format. As far as I know, it is impossible to use TLS:Simple authentication on a Solaris 8 or Solaris 9 LDAP client with a DSEE 5.2P4 or later Directory Server. More information is available here and here.
The following notes show how to create LDAP client databases in cert7.db format. Using these instructions, I am able to get a Solaris 8 client to bind to a DSEE 6.1 server using TLS:Simple authentication. However, I receive the following error when trying to authenticate with a user in the LDAP passwd database:
[17/Sep/2007:14:17:30 -0500] conn=204 op=0 msgId=-1 - closing from Solaris_8_LDAP_client:38839 - B4 - Server failed to flush BER data back to client -
In this example, hostname3 is a Solaris 8 LDAP client.
To create the LDAP client databases in cert7.db format:
- Copy hostname1:/CA/ca.cert to hostname3:/tmp.
- Download NSS 3.3.2 binary distribution to hostname3:/tmp.
- Download SunOS 5.8 optimize Platform - Sun ONE Directory SDK for C 5.08 to hostname3:/tmp. certutil provided with NSS 3.3.2 requires shared libraries that are provided with Sun ONE Directory SDK for C 5.08.
Perform the following steps on hostname3:
- Extract NSS 3.3.2.
# gzip -cd nss-3.3.2.tar.gz | tar xvf -
- Extract Sun ONE Directory SDK for C 5.08.
# gzip -cd ldapcsdk5.08-SunOS5.8_OPT.OBJ.tar.gz
- Copy the missing shared libraries to nss-3.3.2/lib.
# cp lib/libplc4.so lib/libplds4.so lib/libnspr4.so nss-3.3.2/lib
- Create a new certificate and key database in /var/ldap. Do not enter a password when prompted.
# mkdir /var/ldap # cd nss-3.3.2/bin # LD_LIBRARY_PATH=../lib ./certutil -N -d /var/ldap Enter a password which will be used to encrypt your keys. The password should be at least 8 characters long, and should contain at least one non-alphabetic character. Enter new password: Re-enter password:
- Create the client database files.
# LD_LIBRARY_PATH=../lib ./certutil -A -d /var/ldap -n ExampleCA -t C,, -i /tmp/ca.cert
- Copy the following client databases files to /var/ldap on all Solaris 8 and Solaris 9 LDAP clients.
- /var/ldap/cert7.db
- /var/ldap/key3.db
- /var/ldap/secmod.db
- Change the permissions of these files to 444 on all Solaris 8 and Solaris 9 LDAP clients.
Create the schema and LDAP client profile
If you are using Solaris 10 Update 3 or earlier, the /usr/lib/ldap/idsconfig script will have to be modified to work with DSEE 6.x. A list of needed modifications is provided here.
Run the idsconfig script to prepare the schema and create an LDAP client profile. In this example, the proxy credential level is used with "simple" authentication. Since we are using multimaster replication, both LDAP servers--hostname1 with IP address 192.168.1.100 and hostname2 with IP address 192.168.1.101--are specified in the Default server list.
# /usr/lib/ldap/idsconfig
It is strongly recommended that you BACKUP the directory server
before running idsconfig.
Hit Ctrl-C at any time before the final confirmation to exit.
Do you wish to continue with server setup (y/n/h)? [n] y
Enter the iPlanet Directory Server's (iDS) hostname to setup: hostname1
Enter the port number for iDS (h=help): [389]
ERROR: idsconfig only works with iDS version 5.x, not 6.1.
Enter the directory manager DN: [cn=Directory Manager]
Enter passwd for cn=Directory Manager :
Enter the domainname to be served (h=help): [example.com] subdomain.example.com
Enter LDAP Base DN (h=help): [dc=subdomain,dc=example,dc=com]
Checking LDAP Base DN ...
Validating LDAP Base DN and Suffix ...
Enter the profile name (h=help): [default] simple
Default server list (h=help): [192.168.1.100] 192.168.1.100 192.168.1.101
Preferred server list (h=help):
Choose desired search scope (one, sub, h=help): [one]
The following are the supported credential levels:
1 anonymous
2 proxy
3 proxy anonymous
Choose Credential level [h=help]: [1] 2
The following are the supported Authentication Methods:
1 none
2 simple
3 sasl/DIGEST-MD5
4 tls:simple
5 tls:sasl/DIGEST-MD5
Choose Authentication Method (h=help): [1] 2
Current authenticationMethod: simple
Do you want to add another Authentication Method? n
Do you want the clients to follow referrals (y/n/h)? [n]
Do you want to modify the server timelimit value (y/n/h)? [n]
Do you want to modify the server sizelimit value (y/n/h)? [n]
Do you want to store passwords in "crypt" format (y/n/h)? [n]
Do you want to setup a Service Authentication Methods (y/n/h)? [n] y
The following are the supported Authentication Methods:
1 simple
2 sasl/DIGEST-MD5
3 tls:simple
4 tls:sasl/DIGEST-MD5
Choose Service Authentication Method: [1]
Current authenticationMethod: pam_ldap:simple
Do you want to add another Authentication Method? n
Do you want to setup a Service Auth. Method for "keyserv" (y/n/h)? [n]
Do you want to setup a Service Auth. Method for "passwd-cmd" (y/n/h)? [n] y
The following are the supported Authentication Methods:
1 simple
2 sasl/DIGEST-MD5
3 tls:simple
4 tls:sasl/DIGEST-MD5
Choose Service Authentication Method: [1]
Current authenticationMethod: passwd-cmd:simple
Do you want to add another Authentication Method? n
Client search time limit in seconds (h=help): [30]
Profile Time To Live in seconds (h=help): [43200]
Bind time limit in seconds (h=help): [10]
Do you wish to setup Service Search Descriptors (y/n/h)? [n]
Summary of Configuration
1 Domain to serve : subdomain.example.com
2 Base DN to setup : dc=subdomain,dc=example,dc=com
3 Profile name to create : simple
4 Default Server List : 192.168.1.100
5 Preferred Server List :
6 Default Search Scope : one
7 Credential Level : proxy
8 Authentication Method : simple
9 Enable Follow Referrals : FALSE
10 iDS Time Limit :
11 iDS Size Limit :
12 Enable crypt password storage : FALSE
13 Service Auth Method pam_ldap : pam_ldap:simple
14 Service Auth Method keyserv :
15 Service Auth Method passwd-cmd: passwd-cmd:simple
16 Search Time Limit : 30
17 Profile Time to Live : 43200
18 Bind Limit : 10
19 Service Search Descriptors Menu
Enter config value to change: (1-19 0=commit changes) [0]
Enter DN for proxy agent: [cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com]
Enter passwd for proxyagent:
Re-enter passwd:
WARNING: About to start committing changes. (y=continue, n=EXIT) y
1. Schema attributes have been updated.
2. Schema objectclass definitions have been added.
3. NisDomainObject added to dc=subdomain,dc=example,dc=com.
4. Top level "ou" containers complete.
5. automount maps: auto_home auto_direct auto_master auto_shared processed.
6. ACI for dc=subdomain,dc=example,dc=com modified to disable self modify.
7. Add of VLV Access Control Information (ACI).
8. Proxy Agent cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com added.
9. Give cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com read permission for password.
10. Generated client profile and loaded on server.
11. Processing eq,pres indexes:
uidNumber (eq,pres) Finished indexing.
ipNetworkNumber (eq,pres) Finished indexing.
gidnumber (eq,pres) Finished indexing.
oncrpcnumber (eq,pres) Finished indexing.
automountKey (eq,pres) Finished indexing.
12. Processing eq,pres,sub indexes:
ipHostNumber (eq,pres,sub) Finished indexing.
membernisnetgroup (eq,pres,sub) Finished indexing.
nisnetgrouptriple (eq,pres,sub) Finished indexing.
13. Processing VLV indexes:
subdomain.example.com.getgrent vlv_index Entry created
subdomain.example.com.gethostent vlv_index Entry created
subdomain.example.com.getnetent vlv_index Entry created
subdomain.example.com.getpwent vlv_index Entry created
subdomain.example.com.getrpcent vlv_index Entry created
subdomain.example.com.getspent vlv_index Entry created
subdomain.example.com.getauhoent vlv_index Entry created
subdomain.example.com.getsoluent vlv_index Entry created
subdomain.example.com.getauduent vlv_index Entry created
subdomain.example.com.getauthent vlv_index Entry created
subdomain.example.com.getexecent vlv_index Entry created
subdomain.example.com.getprofent vlv_index Entry created
subdomain.example.com.getmailent vlv_index Entry created
subdomain.example.com.getbootent vlv_index Entry created
subdomain.example.com.getethent vlv_index Entry created
subdomain.example.com.getngrpent vlv_index Entry created
subdomain.example.com.getipnent vlv_index Entry created
subdomain.example.com.getmaskent vlv_index Entry created
subdomain.example.com.getprent vlv_index Entry created
subdomain.example.com.getip4ent vlv_index Entry created
subdomain.example.com.getip6ent vlv_index Entry created
idsconfig: Setup of iDS server hostname1 is complete.
Note: idsconfig has created entries for VLV indexes. Use the
directoryserver(1m) script on hostname1 to stop
the server and then enter the following vlvindex
sub-commands to create the actual VLV indexes:
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getgrent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.gethostent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getnetent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getpwent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getrpcent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getspent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getauhoent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getsoluent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getauduent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getauthent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getexecent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getprofent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getmailent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getbootent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getethent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getngrpent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getipnent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getmaskent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getprent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getip4ent
directoryserver -s <server-instance> vlvindex -n dev -T subdomain.example.com.getip6ent
Modify Directory Access Control Instructions (ACIs)
- Create an LDIF file with the following contents (e.g., /tmp/aci.ldif):
dn: dc=subdomain,dc=example,dc=com changetype: modify add: aci aci: (target ="ldap:///dc=subdomain,dc=example,dc=com")(targetattr !="userPassword")(version 3.0;acl "Anonymous read-search access";allow (read , search, compare)(userdn = "ldap:///anyone");) aci: (target="ldap:///dc=subdomain,dc=example,dc=com") (targetattr = "*")(version 3.0; acl "allow all Admin group"; allow(all) groupdn = "ldap: ///cn=Directory Administrators,ou=Groups,dc=subdomain,dc=example,dc=com";) - delete: aci aci: aci: (target="ldap:///dc=subdomain,dc=example,dc=com")(targetattr="userPassword")(version 3.0; acl LDAP_Naming_Services_proxy_password_read; allow (compare,read,search) userdn = "ldap:///cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com";)
- Apply the LDIF file.
# ldapmodify -D "cn=Directory Manager" -f /tmp/aci.ldif Enter bind password: modifying entry dc=subdomain,dc=example,dc=com
Explanation of ACI LDIF
When creating the schema using Directory Service Control Center (DSCC) and "Create Top Entry for the Suffix," the schema has the following ACIs:
aci: (target ="ldap:///dc=subdomain,dc=example,dc=com")(targetattr !="userPassword")(version 3.0;acl "Anonymous read-search access";allow (read , search, compare)(userdn = "ldap:///anyone");) aci: (target="ldap:///dc=subdomain,dc=example,dc=com") (targetattr = "*")(version 3.0; acl "allow all Admin group"; allow(all) groupdn = "ldap: ///cn=Directory Administrators,ou=Groups,dc=subdomain,dc=example,dc=com";) aci: (targetattr = "cn||uid||uidNumber||gidNumber||homeDirectory||shadowLastCh ange||shadowMin||shadowMax||shadowWarning||shadowInactive||shadowExpire||sha dowFlag||memberUid")(version 3.0; acl LDAP_Naming_Services_deny_write_access ; deny (write) userdn = "ldap:///self";)
A schema created using dsconf has only the following ACI:
aci: (targetattr = "cn||uid||uidNumber||gidNumber||homeDirectory||shadowLastCh ange||shadowMin||shadowMax||shadowWarning||shadowInactive||shadowExpire||sha dowFlag||memberUid")(version 3.0; acl LDAP_Naming_Services_deny_write_access ; deny (write) userdn = "ldap:///self";)
If the above ACI in bold is not present in the schema, you may receive errors
- when binding to the client:
Failed to find defaultSearchBase for domain subdomain.example.com
- during subsequent runs of idsconfig:
2. Schema objectclass definitions have been added. ERROR: update of NisDomainObject in dc=subdomain,dc=example,dc=com failed.
- or when running ldaplist on an already-bound client:
ldaplist: Object not found ldaplist: Object not found (Session error no available conn. )
When creating an LDAP client profile using idsconfig with the proxy credential level, an ACI is added to allow the proxyagent user to read the userPassword attribute. This means that ldaplist -l passwd on an LDAP client will display the encrypted password hash of all LDAP users, something we definitely do not want. Since we are using pam_ldap for authentication, the proxyagent user does not need read access to the userPassword attribute, so we delete this ACI.
Directory Server password policy
Organizational requirements
Our organization requires adherence to the following password policy:
- Maximum password age is 90 days.
- Passwords must consist of both numeric and alphabetic characters.
- New passwords cannot be the same as the 3 previously used passwords.
- Accounts must be locked out after 4 invalid logon attempts.
- Once locked out, user accounts remain locked until the System Administrator unlocks the account.
List the default password policy
The following is the default Directory Server password policy. Defaults that will have to be changed to meet our organization's password policy requirements are listed in bold.
# dsconf get-server-prop | grep ^pwd- pwd-accept-hashed-pwd-enabled : N/A pwd-check-enabled : off pwd-compat-mode : DS5-compatible-mode pwd-expire-no-warning-enabled : on pwd-expire-warning-delay : 1d pwd-failure-count-interval : 10m pwd-grace-login-limit : disabled pwd-keep-last-auth-time-enabled : off pwd-lockout-duration : 1h pwd-lockout-enabled : off pwd-lockout-repl-priority-enabled : on pwd-max-age : disabled pwd-max-failure-count : 3 pwd-max-history-count : disabled pwd-min-age : disabled pwd-min-length : 6 pwd-mod-gen-length : 6 pwd-must-change-enabled : off pwd-root-dn-bypass-enabled : off pwd-safe-modify-enabled : off pwd-storage-scheme : SSHA pwd-strong-check-dictionary-path : /opt/SUNWdsee/ds6/plugins/words-english-bi g.txt pwd-strong-check-enabled : off pwd-strong-check-require-charset : lower pwd-strong-check-require-charset : upper pwd-strong-check-require-charset : digit pwd-strong-check-require-charset : special pwd-supported-storage-scheme : CRYPT pwd-supported-storage-scheme : SHA pwd-supported-storage-scheme : SSHA pwd-supported-storage-scheme : NS-MTA-MD5 pwd-supported-storage-scheme : CLEAR pwd-user-change-enabled : on
Modify the password policy
Perform the following steps on both LDAP servers.
- Expire passwords after 90 days.
# dsconf set-server-prop pwd-max-age:90d
- Require passwords to contain at least 1 of each pwd-strong-check-require-charset (by default, at least one uppercase, lowercase, number, and special character) and that passwords do not contain strings from pwd-strong-check-dictionary-path.
# dsconf set-server-prop pwd-check-enabled:on Enabling "pwd-check-enabled" property automatically sets the value of "pwd-accept-hashed-pwd-enabled" property to "off". # dsconf set-server-prop pwd-strong-check-enabled:on Directory Server must be restarted for changes to take effect.
- Require passwords to contain any 3 (instead of all 4) of a (1) uppercase character, (2) lowercase character, (3) number, or (4) special character.
# dsconf set-server-prop pwd-strong-check-require-charset:any-three Directory Server must be restarted for changes to take effect.
- Prevent users from reusing their last 3 passwords.
# dsconf set-server-prop pwd-max-history-count:3
- Lock user accounts indefinitely after 4 consecutive password failures.
# dsconf set-server-prop pwd-lockout-enabled:on # dsconf set-server-prop pwd-max-failure-count:4
(The latter can be set while the former is "off" by default, although no account lockout would occur)
# dsconf set-server-prop pwd-lockout-duration:disabled
I make two other changes to the default password policy that are not part of our organization's password policy, but are listed in the Center for Information Security's Solaris Benchmark.
- Warn users 4 weeks prior to password expiration.
# dsconf set-server-prop pwd-expire-warning-delay:28d
- Require users to keep their passwords at least 7 days.
# dsconf set-server-prop pwd-min-age:7d
Finally, I configure the Directory Server to record the last authentication time for each user. This requires us to change pwd-compat-mode from DS5-compatible-mode to DS6-migration-mode or DS6-mode[1].
# dsconf set-server-prop pwd-keep-last-auth-time-enabled:on
Directory Server "localhost:389" raised an unexpected error:
"[LDAP: error code 53 - (Password Policy: modify policy entry) "pwdKeepLastAuthTime: true" is not supported in server mode DS5-compatible-mode ("cn=config" pwdCompat: 0).]".
See the errors log for details.
The "set-server-prop" operation failed on "localhost:389".
# dsconf pwd-compat to-DS6-migration-mode
## Beginning password policy compatibility changes.
## Password policy compatibility changes finished.
Task completed (slapd exit code: 0).
# dsconf pwd-compat to-DS6-mode
## Beginning password policy compatibility changes.
## Password policy compatibility changes finished.
Task completed (slapd exit code: 0).
# dsconf set-server-prop pwd-keep-last-auth-time-enabled:on
Restart Directory Server
Restart the Directory Server for the password policy changes to take effect.
# dsadm restart /var/ds Server stopped Server started: pid=26834
Add LDAP entries
Bind an LDAP client
In order to use ldapaddent to populate the passwd and group databases below, you must first bind an LDAP client to an LDAP server. In this example, hostname3--a Solaris 8 Sparc LDAP client--should be bound to hostname1.
- Solaris 8 instructions:
# ldapclient -w proxyagent_password -P simple -d subdomain.example.com \ -D cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com hostname1
- Solaris 10 instructions:
# ldapclient init -a profileName=simple -a domainName=subdomain.example.com \ -a proxyDN=cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com -a proxyPassword=proxyagent_password hostname1
I recommend completing the remaining steps before binding the rest of the LDAP clients.
Populate the passwd database
We were asked to add all users with GID 2050 from an existing NIS environment into the LDAP passwd database. Instead of using the UIDs in the NIS passwd map, we want to reorder them, starting with UID 1000.
$ ypcat passwd | awk -F: '$4 == 2050 { print }' > nis_passwd_map
e.g., reorder_nis_passwd_map.sh
#!/bin/sh UID=1000 while read LINE ; do IFS=: set $LINE echo "$1:$2:$UID:$4:$5:$6:$7" UID=`expr $UID + 1` done < nis_passwd_map > nis_passwd_map.new mv nis_passwd_map.new nis_passwd_map
On an LDAP client, run ldapaddent command to populate the passwd database. Since the NIS passwd map contains the password hashes, use the -p flag with ldapaddent to process the password field. Note that the password you are prompted for is the cn=Directory Manager password.
Note: Since some of the imported passwords did not adhere to the Directory Server's password policy, pwd-check-enabled had to be temporarily disabled on the Directory Server.
(hostname3) # ldapaddent -a simple -p -D "cn=Directory Manager" -f nis_passwd_map passwd Enter password: 19: Constraint violation Error while adding line: ... (hostname1) # dsconf set-server-prop pwd-check-enabled:off Disabling "pwd-check-enabled" property automatically sets the value of "pwd-accept-hashed-pwd-enabled" property to "N/A". (hostname3) # ldapaddent -a simple -p -D "cn=Directory Manager" -f nis_passwd_map passwd Enter password: 682 entries added (hostname1) # dsconf set-server-prop pwd-check-enabled:on Enabling "pwd-check-enabled" property automatically sets the value of "pwd-accept-hashed-pwd-enabled" property to "off".
Populate the group database
The only group from the NIS group map that we want migrated to LDAP is the group with GID 2050.
$ ypcat group | awk -F: '$3 == 2050 { print }' > nis_group_map
Run the following command on an LDAP client to populate the group database.
# ldapaddent -a simple -D "cn=Directory Manager" -f nis_group_map group Enter password: 19: Constraint violation Error while adding line: ... 0 entries added
I'm not sure why, but I had to temporarily disable pwd-check-enabled on the Directory Server in order to populate the groups database with nis_group_map.
(hostname1) # dsconf set-server-prop pwd-check-enabled:off Disabling "pwd-check-enabled" property automatically sets the value of "pwd-accept-hashed-pwd-enabled" property to "N/A". (hostname3) # ldapaddent -a simple -D "cn=Directory Manager" -f nis_group_map group Enter password: 1 entries added (hostname1) # dsconf set-server-prop pwd-check-enabled:on Enabling "pwd-check-enabled" property automatically sets the value of "pwd-accept-hashed-pwd-enabled" property to "off".
Populate the auto_home database
In our environment, user home directories are stored on a NetApp FAS system acting as an NFS server. The location of users' home directories is netapp_fas:/vol/home/user_id. To configure the /home AutoFS file system for this directory path, import the following LDIF file (e.g., /tmp/auto_home.ldif):
dn: automountKey=*,automountMapName=auto_home,dc=subdomain,dc=example,dc=com automountInformation: -vers=3 netapp_fas:/vol/home/& objectClass: automount objectClass: top automountKey: *
# ldapmodify -a -D "cn=Directory Manager" -f /tmp/auto_home.ldif Enter bind password: adding new entry automountKey=*,automountMapName=auto_home,dc=subdomain,dc=example,dc=com
Configure replication
The suffix dc=subdomain,dc=example,dc=com will be replicated over SSL in a multi-master configuration on LDAP servers hostname1 and hostname2.
- Enable the master replicated suffix on both LDAP servers. The replication ID for all master replicas of the suffix must be unique; it will be "1" on hostname1 and "2" on hostname2.
(hostname1) # dsconf enable-repl -d 1 master dc=subdomain,dc=example,dc=com Enter "cn=Directory Manager" password: Use "dsconf create-repl-agmt" to create replication agreements on "dc=subdomain,dc=example,dc=com". (hostname2) # dsconf enable-repl -d 2 master dc=subdomain,dc=example,dc=com Enter "cn=Directory Manager" password: Use "dsconf create-repl-agmt" to create replication agreements on "dc=subdomain,dc=example,dc=com".
- Set the multi-master password file on both servers. Although this password can be different on each server, I use the same password on both servers.
(hostname1) # echo multimaster_password_file > /var/ds/db/subdomain/multimaster_password_file (hostname2) # echo multimaster_password_file > /var/ds/db/subdomain/multimaster_password_file
- Create replication agreements and setup authentication between the two servers. In this multi-master replication configuration, hostname1 is the supplier for consumer hostname2, and hostname2 is the supplier for consumer hostname1.
(hostname1) # dsconf create-repl-agmt --auth-protocol "ssl-simple" dc=subdomain,dc=example,dc=com hostname2:636 (hostname2) # dsconf create-repl-agmt --auth-protocol "ssl-simple" dc=subdomain,dc=example,dc=com hostname1:636
- Configure the replication agreement authentication password file to be the multi-master password file.
# dsconf set-repl-agmt-prop -h hostname1 -p 389 dc=subdomain,dc=example,dc=com \ hostname2:636 auth-pwd-file:/var/ds/db/subdomain/multimaster_password_file # dsconf set-repl-agmt-prop -h hostname2 -p 389 dc=subdomain,dc=example,dc=com \ hostname1:636 auth-pwd-file:/var/ds/db/subdomain/multimaster_password_file
- Restart the Directory Server on both LDAP servers for the configuration changes to take effect.
(hostname1) # dsadm restart /var/ds (hostname2) # dsadm restart /var/ds
- Initialize the replica by copying the contents of dc=subdomain,dc=example,dc=com from hostname1 to hostname2.
(hostname1) # dsconf init-repl-dest dc=subdomain,dc=example,dc=com hostname2:636
Confirm replication is working
On hostname1:
# dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname2:636 Enter "cn=Directory Manager" password: Configuration Status : OK Authentication Status : OK Initialization Status : OK Status : Enabled Last Update Date : Sep 11, 2007 3:08:12 PM
On hostname2:
# dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname1:636 Enter "cn=Directory Manager" password: Configuration Status : OK Authentication Status : OK Initialization Status : OK Status : Enabled Last Update Date : Sep 11, 2007 3:13:54 PM
Final Steps
Prevent the proxyagent user's password from expiring
If you are using the proxy credential level on LDAP clients, the proxyagent user's password should never expire. If it does, LDAP clients will not be able to retrieve name service information from the LDAP server(s).
To prevent the proxyagent user's password from expiring:
$ /usr/bin/printf "dn: cn=proxyagent,ou=profile,dc=subdomain,dc=example,dc=com\nchangetype: \ modify\nreplace: PasswordExpirationTime\nPasswordExpirationTime: 20380119031407Z\n" | \ ldapmodify -h hostname1 -D "cn=Directory Manager"
Create user home directories
In our environment, the LDAP servers hostname1 and hostname2 have root-level access on the NetApp FAS system used for user home directories. On one of these systems, create user home directories using the above nis_passwd_map and the following script:
#!/bin/sh [ ! -d /tmp/mnt ] && mkdir /tmp/mnt mount netapp_fas:/vol/home /tmp/mnt OLDIFS=$IFS while read LINE ; do IFS=: set $LINE USER=$1 UID=$3 GID=$4 mkdir /tmp/mnt/$USER IFS=$OLDIFS chown $UID:$GID /tmp/mnt/$USER done < nis_passwd_map
Bind the remaining LDAP clients
Use the steps listed in #Bind an LDAP client to bind the remaining LDAP clients to the LDAP servers.
Configure the name service switch on LDAP clients
When running ldapclient to initialize the LDAP clients, /etc/nsswitch.conf is overwritten with /etc/nsswitch.ldap. It is likely that /etc/nsswitch.conf will have to be modified, as it does not use DNS when looking up hostnames, and generally only references local files when LDAP is not available.
Configure LDAP clients to use pam_ldap authentication
The default /etc/pam.conf file uses pam_unix authentication. pam_unix authentication has two drawbacks:
- The user password must be stored in "crypt" format.
- The userPassword attribute must be readable by the name service.
The latter drawback means that an ldaplist -l passwd command will reveal each user's password hash.
pam_ldap authentication does not have these drawbacks. With pam_ldap, users attempts to bind to the Directory Server using their identity and password. If the bind is successful, the user is authenticated. The userPassword attribute is not used by pam_ldap.
/etc/pam.conf must be modified to use pam_ldap. The following pam.conf files may be used for pam_ldap authentication:
- An example pam.conf file for pam_ldap (Solaris 8 and 9)
- An example pam.conf file for pam_ldap (Solaris 10)
Configure OpenSSH to use PAM for authentication
If you are using an OpenSSH server, you may have to configure it to use PAM for authentication. To enable PAM with OpenSSH, change UsePAM no to UsePAM yes in sshd_config. Solaris 8 and 9 users will likely have to perform this step.
The SSH server provided with Solaris 10 uses PAM for authentication by default via the PAMAuthenticationViaKBDInt yes configuration directive.
Upgrading to DS 6.2
I used this basic procedure to upgrade from DS 6.1 to DS 6.2 on our two LDAP servers.
- Stop the Directory Server instance on hostname2.
- Uncompress and install Directory Server 6.2, overwriting the previous installation.
- Start the Directory Server on hostname2.
- Confirm that any pending replication changes from hostname1 have transferred.
- Repeat the process on hostname1.
On hostname2:
# /opt/SUNWdsee/ds6/bin/dsadm stop /var/ds $ gzip -cd DSEE.6.2.Solaris-Sparc-full.tar.gz | tar xf - $ cd DSEE_ZIP_Distribution # ./dsee_deploy install --no-inter --install-path /opt/SUNWdsee # /opt/SUNWdsee/ds6/bin/dsadm start /var/ds (hostname1) # dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname2:636
On hostname1:
# /opt/SUNWdsee/ds6/bin/dsadm stop /var/ds $ gzip -cd DSEE.6.2.Solaris-Sparc-full.tar.gz | tar xf - $ cd DSEE_ZIP_Distribution # ./dsee_deploy install --no-inter --install-path /opt/SUNWdsee # /opt/SUNWdsee/ds6/bin/dsadm start /var/ds (hostname2) # dsconf show-repl-agmt-status dc=subdomain,dc=example,dc=com hostname1:636
Installing Directory Service Control Center (DSCC)
The DSEE ZIP distribution provides everything needed for DSCC except for Sun Web Console. Unfortunately, Sun Web Console is only available within Sun Java Enterprise System.
In this example, Sun Web Console is installed from packages within the Sun Java ES Update 1 distribution.
$ unzip -q java_es-5u1-identsuite-ga-solaris-sparc.zip $ cd java_es-5u1-identsuite/Solaris_sparc/Product/sunwebconsole # for PKG in `ls -d SUNW*` ; do yes | pkgadd -d . $PKG ; done # cd SunOS-5.10-sparc # for PKG in `ls -d SUNW*` ; do yes | pkgadd -d . $PKG ; done
Next, clear any previous DSCC configuration and initialize DSCC.
# /opt/SUNWdsee/dscc6/bin/dsccsetup dismantle # /opt/SUNWdsee/dscc6/bin/dsccsetup initialize
Troubleshooting
ldaplist: Object not found (LDAP ERROR (1): Operations error.)
(LDAP_client) $ ldaplist -l passwd ldaplist: Object not found (LDAP ERROR (1): Operations error.)
(LDAP_server) $ cat /var/ds/logs/errors [11/Sep/2007:16:48:28 -0500] - ERROR<20753> - Backend Database - conn=-1 op=-1 msgId=-1 - vlv_build_idl: can't follow db cursor (err -30989)
According to the DSEE Troubleshooting Guide, this error means the database is incoherent, and should be rebuilt using db2ldif, then ldif2db. However, these utilities are not provided with DSEE 6.1. I was able to restore normal functionality by restarting the directory server instance.
(LDAP_server) # dsadm restart
