DSfW: Post Configuration of DNS on an Additional Domain Controller in OES2SP3

0 Likes
During DSfW configuration, you are provided with an option to select the installation of DNS. For the first domain controller (DC) of the forest root domain, this is done by default. For all the additional domain controllers (ADC), the DNS configuration in OES2SP3 is optional. However, after DSfW configuration on the ADC, if you need to configure DNS on the ADC, it cannot be done using YaST. The script provided here enables you to configure DNS on the ADC in a post-configuration manner.

This script can be run on an ADC in scenarios like:


  1. The ADC in OES2SP2 upgraded to OES2SP3, and DNS server is to be configured

  • The ADC already in OES2SP3 code level and it is not already configured as a DNS server.

    The script does the following operations:


    1. Configure DNS by running "dns-inst". This installs DNS on the ADC.

  • Add the ADC's DNS server object to the forward zone and reverse zone objects in the dNIPZoneServers attribute.

  • Add the forward and reverse zone object to the dNIPZoneList attribute of the ADC's DNS server.

  • Add the NS record for the ADC's DNS server to the forward zone.

  • Update the "xad.ini" configuration file for "DNSSERVER" and "DNS Master" entries, as it changes after the DNS configuration on the ADC.

  • Update /etc/resolv.conf with "nameserver" referring the local server IP.

  • Restart the novell-named. Re-start is attempted twice. Even then if it still doesn't come up, restart it after the script execution is complete.

  • All the DNS related contexts and administrator FQDNs are read from the install registry (xad.ini and XAD::registry perl module).

    The passwords are read from the environment variables. More information is provided below.

  • The execution logs appear on console as well as goes to /var/opt/novell/xad/log/dns_config.log.





The script need be executed by exporting the following environment variables or can be given inline during the execution of the script ;

The example of command line execution of the script is:

# NDSEXISTINGADMINPASSWD=<tree-admin-password> DOMAINADMINPASSWD=<domain-admin-password> perl ./configure_dns_adc.pl 


The script accepts two environment variables:

NDSEXISTINGADMINPASSWD - Tree Administrator password




  1. In case of name-mapped (NM), it is the tree administrator password.

  • In case of non-name-mapped (NNM), it is the Forest Root Domain (FRD) administrator password.



DOMAINADMINPASSWD - Domain Administrator Password.



The DNS configuration on a ADC provides the mechanism for load balancing between domain controllers. Also this helps in the scenario when the PDC role transfer/seizure need to be done. With DNS server also present on the ADC, the new PDC will be completely functional as a primary domain controller.

Labels:

Collateral
How To-Best Practice
Comment List
  • The minor change in the script which is a ldif operation. The changed script is as follows :



    #!/usr/bin/perl -I. -I.. -I/opt/novell/xad/lib64/perl -I/opt/novell/xad/lib/perl
    use strict ;
    use warnings;
    use File::Temp;

    use Logger;
    use XAD::registry;
    use Install::adc_install;
    use XAD::dnsrecords;

    my $inst = "";
    my $LDAP_ERR_DUPLICATE = 20;

    sub install_dns() {
    my $dns_locator_context = registry::getReg("DNS_LOCATOR_OBJECT");
    my $dns_group_context = registry::getReg ("DNSDHCP_GROUP");
    my $dns_server_context = registry::getReg("DNSSERVER_CONTEXT");
    my $dns_ncp_server_context = registry::getReg("DNS_NCPServer");
    my $ldapadmin = registry::getReg ("NDSEXISTINGADMINNAME");
    my $dns_server_ip = registry::getReg("DNS_SERVER_IP");
    my $domain = registry::getReg("Root Domain");

    my $dns_inst_cmd = "/opt/novell/named/bin/dns-inst";
    my $hostname = `/bin/hostname`;
    my ($puser_name, $puser_passwd) = ("", "");
    chomp($hostname);

    $ldapadmin =~ s/\.([a-z,A-Z,0-9]*)=/,$1=/g;
    $dns_locator_context =~ s/cn=DNS\-DHCP,//;
    $dns_group_context =~ s/cn=DNSDHCP\-GROUP,//;
    $dns_ncp_server_context =~ s/cn=.+?,//;

    eval {
    `/opt/novell/proxymgmt/bin/cp_retrieve_proxy_cred username > x`;
    if ($? == 0) {
    $puser_name = `cat x`;
    chomp($puser_name);
    `/opt/novell/proxymgmt/bin/cp_retrieve_proxy_cred password > x`;
    if ($? == 0) {
    $puser_passwd = `cat x`;
    chomp($puser_passwd);
    } else { unlink ("x"); die ("Failed to retrieve proxy user password"); }

    unlink ("x");

    $dns_inst_cmd .= " $dns_server_ip 1636 '$ldapadmin'";

    if (not defined $ENV{NDSEXISTINGADMINPASSWD}) {
    die ("Admin password is not exported in NDSEXISTINGADMINPASSWD environment variable for ldap admin [$ldapadmin]");
    }

    $dns_inst_cmd .= " '$ENV{NDSEXISTINGADMINPASSWD}'";

    $dns_inst_cmd .= " '$puser_name' '$puser_passwd' 1";

    $dns_inst_cmd .= " '$dns_locator_context' '$dns_group_context' '$dns_server_context'";

    $dns_inst_cmd .= " '$dns_ncp_server_context' 1 $hostname $domain 1";

    # Execute it now
    my @output = `$dns_inst_cmd`;
    chomp(@output);
    if ($?) {
    die ("The execution of dns_inst failed: @output");
    }
    } else { unlink ("x"); die ("Failed to retrieve DNS proxy user name");}

    };

    if ($@) { Log(ERR, "DNS installation failed : $@") };
    }


    sub update_zoneservers_and_zonelist($) {

    my $dnsserver = shift;
    my $tempfile = mktemp("/tmp/tmp.XXXXXXX");
    my $fwd_zone = registry::getReg("DNS_ZONE");
    my $rev_zone = registry::getReg("IP_ADDRESS_UNDERSCORE_FORM");
    my $fwdzone_context = registry::getReg("FWDZONE_CONTEXT");
    my $revzone_context = registry::getReg("REVZONE_CONTEXT");

    eval {
    open FILE,">$tempfile" or die ("Failed to open the temporary file");
    print FILE "dn: cn=$fwd_zone,$fwdzone_context\n";
    print FILE "changetype: modify\n";
    print FILE "add: dNIPZoneServers\n";
    print FILE "dNIPZoneServers: $dnsserver\n";
    close (FILE);

    # Execute the ldap command
    my $output = `LDAPCONF=/etc/opt/novell/xad/openldap/ldap.conf /usr/bin/ldapmodify -Y EXTERNAL -f $tempfile -Q -c`;
    my $error = $? >> 8;
    if ($? != 0 and $error != $LDAP_ERR_DUPLICATE) {
    unlink($tempfile);
    die ("Failed to udpate the zone server [$dnsserver] on fwd zone [$fwd_zone,$fwdzone_context]");
    }
    unlink($tempfile);
    Log ("Successfully updated the zone server [$dnsserver] on zone [$fwd_zone]");

    open FILE,">$tempfile" or die ("Failed to open the temporary file");
    print FILE "dn: cn=$rev_zone,$revzone_context\n";
    print FILE "changetype: modify\n";
    print FILE "add: dNIPZoneServers\n";
    print FILE "dNIPZoneServers: $dnsserver\n";
    close (FILE);

    # Execute the ldap command
    $output = `LDAPCONF=/etc/opt/novell/xad/openldap/ldap.conf /usr/bin/ldapmodify -Y EXTERNAL -f $tempfile -Q -c`;
    $error = $? >> 8;
    if ($? != 0 and $error != $LDAP_ERR_DUPLICATE) {
    unlink($tempfile);
    die ("Failed to udpate the zone server [$dnsserver] on reverse zone [$rev_zone,$revzone_context]");
    }
    unlink($tempfile);

    Log ("Successfully updated the zone server [$dnsserver] on zone [$rev_zone]");
    };

    if ($@) { Log (ERR, "Failed to update the zone servers : $@"); }

    eval {
    open FILE,">$tempfile" or die ("Failed to open the temporary file");
    print FILE "dn: $dnsserver\n";
    print FILE "changetype: modify\n";
    print FILE "add: dNIPZoneList\n";
    print FILE "dNIPZoneList: cn=$fwd_zone,$fwdzone_context\n";
    print FILE "dNIPZoneList: cn=$rev_zone,$revzone_context\n";
    close (FILE);

    # Execute the ldap command
    my $output = `LDAPCONF=/etc/opt/novell/xad/openldap/ldap.conf /usr/bin/ldapmodify -Y EXTERNAL -f $tempfile -Q -c`;
    my $error = $? >> 8;
    if ($? != 0 and $error != $LDAP_ERR_DUPLICATE) {
    unlink($tempfile);
    die ("Failed to udpate the zone list [$dnsserver] on fwd zone [$fwd_zone,$fwdzone_context]");
    }
    unlink($tempfile);
    Log ("Successfully updated the zone list on [$dnsserver]");
    };
    if ($@) { Log (ERR, "Failed to update the zone lists : $@"); }
    }


    sub update_NS_record() {
    my $live_dsstatedir = registry::getReg("LIVE_DSSTATEDIR");
    my $dnsroot = registry::getReg("DNSROOT");
    my $fwdzone_context = registry::getReg("FWDZONE_CONTEXT");
    my $dnshostname = registry::getReg("DNS Host Name");
    my $installMachineName = registry::getReg("InstallMachineName");

    dns::Process_RR("IN NS $dnshostname", 0, $fwdzone_context, "TRUE", "add");

    eval {
    my $zone_name = substr ($dnshostname, (length($installMachineName) +1), length($dnshostname));
    my $ldif_to_upload = "$live_dsstatedir/dns/RR/\@_NS_update_"."$zone_name".".ldif";
    my $output = `LDAPCONF=/etc/opt/novell/xad/openldap/ldap.conf /usr/bin/ldapmodify -Y EXTERNAL -f '$ldif_to_upload' -Q -c 2>&1 >/dev/null`;
    my $error = $? >> 8;
    if ($? != 0 and $error != $LDAP_ERR_DUPLICATE) {
    die ("Failed to udpate the zone [$zone_name] NS record.");
    }
    };

    if ($@) { Log (ERR, "Failed to update the NS record for the forward zone: $@"); }

    Log ("Successfully updated the NS record ");
    }

    sub create_records() {
    # Here we create the two ldif files for NS records :
    # Also adding the local dns_server object into zone servers

    my $localhostname = `/bin/hostname`;
    chop($localhostname);
    my $dnsserver_context = registry::getReg("DNSSERVER_CONTEXT");
    my $dnsserver = "cn=DNS_$localhostname,$dnsserver_context";


    $inst->decide_domain_zones();

    update_zoneservers_and_zonelist($dnsserver);

    update_NS_record();
    }

    sub main () {
    my $XAD_INI = "/etc/opt/novell/xad/xad.ini";
    my $localhostname = `/bin/hostname`;
    chop($localhostname);
    my $dnsserver_context = registry::getReg("DNSSERVER_CONTEXT");
    my $dnsserver = "cn=DNS_$localhostname,$dnsserver_context";

    $ENV{ADM_PASSWD} = $ENV{DOMAINADMINPASSWD};
    $inst = adc_install->new();

    Logger::set_filename ("/var/opt/novell/xad/log/dns_config.log");

    if (registry::getReg("PROVISIONED") ne "YES") {
    Log ("The server is not provisioned yet. This script is meant to be run in a post-install fashion.");
    exit (0);
    }

    if (registry::getReg("IS_REPLICA") ne "TRUE") {
    Log ("The script is meant to be run only on the ADC.");
    exit (0);
    }

    if (registry::getReg("DNSMASTER") eq "TRUE") {
    Log ("DNS is already configured on this server.");
    exit (0);
    }

    # Commenting the ones which are completed.
    install_dns();
    create_records();

    # Update some xad.ini variables as the server is now acting as DNS server
    util::replace_line_in_file("DNSSERVER = ", "DNSSERVER = $dnsserver", $XAD_INI);
    util::replace_line_in_file("DNS Master = ", "DNS Master= TRUE", $XAD_INI);


    # Update the resolv_conf and restart novell-named;
    registry::setReg("DNS Master", "TRUE");
    util::update_resolv_conf();

    util::novell_named_restart();
    `rcnovell-named status`;
    if ($?) {
    sleep 5;
    `rcnovell-named start`;
    `rcnovell-named status`;
    if ($?) {
    Log ("novell-named is not coming up properly");
    }
    }
    }

    main;
Related
Recommended