xcat2 / xcat-core

Code repo for xCAT core packages
Eclipse Public License 1.0
362 stars 171 forks source link

Allow specifying path to omshell and OMAPI algoritum. #7181

Open bviviano opened 2 years ago

bviviano commented 2 years ago

I am providing a patch against xCAT 2.16.3's dhcp.pm that will allow you to specify the path to omshell and the key algorithm used by OMAPI by setting values in the site table accordingly:

chdef -t site omshell="/opt/dhcp/bin/omshell"
chdef -t site omapi-algorithm="HMAC-SHA512"

If the site table entries do not exist, then the service will default to /usr/bin/omshell and HMAC-MD5, to maintain backwards compatibility.

This change is needed to support FIPS with xCAT when doing makedhcp -a.

Per this solutions article from Red Hat, the dhcp-server RPM in RHEL8 does not support FIPS. However, the most recent stock ISC DHCPd does support FIPS with levels up to SHA512.

With this patch, you can install the DHCPd from isc.org into an alternate location, like /opt and tell xCAT where to find omshell and what key algorithm to use when talking to omshell, so that makedhcp -a will work on a MN with FIPS enabled.

--- dhcp.pm-orig        2022-05-19 07:15:28.887655630 -0400
+++ dhcp.pm     2022-05-23 07:59:59.612842185 -0400
@@ -186,10 +186,24 @@
         }
     }

+    # Get path for omshell from site table, if set
+    my $omshellbin="/usr/bin/omshell";
+    my @oms=xCAT::TableUtils->get_site_attribute("omshell");
+    if ($oms[0]){
+        $omshellbin=$oms[0];
+    }
+    # Get HMAC algorithum from site table, if set
+    my $omapialgorithm = "HMAC-MD5";
+    my @omapia=xCAT::TableUtils->get_site_attribute("omapi-algorithm");
+    if ($omapia[0]){
+        $omapialgorithm=$omapia[0];
+    }
+
     # open ipv4 omshell file handles - $OMOUT will contain the response
-    open2($OMOUT, $OMIN, "/usr/bin/omshell ");
+    open2($OMOUT, $OMIN, "$omshellbin ");

     # setup omapi for the connection and check for the node requested
+    print $OMIN "key-algorithm $omapialgorithm\n";
     print $OMIN "key "
       . $omapiuser . " \""
       . $omapikey . "\"\n";
@@ -252,9 +266,10 @@

     # if using IPv6 addresses check using omshell IPv6 port
     if ($usingipv6) {
-        open2($OMOUT6, $OMIN6, "/usr/bin/omshell ");
+        open2($OMOUT6, $OMIN6, "$omshellbin ");
         print $OMOUT6 "port 7912\n";
         print $OMOUT6 "connect\n";
+       print $OMOUT6 "key-algorithm $omapialgorithm\n";
         print $OMIN6 "key "
           . $omapiuser . " \""
           . $omapikey . "\"\n";
@@ -2029,9 +2044,23 @@
                 return;
             }    # TODO sane err

+            # Get path for omshell from site table, if set
+            my $omshellbin="/usr/bin/omshell";
+            my @oms=xCAT::TableUtils->get_site_attribute("omshell");
+            if ($oms[0]){
+                $omshellbin=$oms[0];
+            }
+            # Get HMAC algorithum from site table, if set
+            my $omapialgorithm = "HMAC-MD5";
+            my @omapia=xCAT::TableUtils->get_site_attribute("omapi-algorithm");
+            if ($omapia[0]){
+                $omapialgorithm=$omapia[0];
+            }
+
             #Have nodes to update
             #open2($omshellout,$omshell,"/usr/bin/omshell");
-            open($omshell, "|/usr/bin/omshell > /dev/null");
+            open($omshell, "|$omshellbin > /dev/null");
+            print $omshell "key-algorithm $omapialgorithm\n";
             print $omshell "key "
               . $ent->{username} . " \""
               . $ent->{password} . "\"\n";
@@ -2040,11 +2069,12 @@
             }
             print $omshell "connect\n";
             if ($usingipv6) {
-                open($omshell6, "|/usr/bin/omshell > /dev/null");
+                open($omshell6, "|$omshellbin > /dev/null");
                 if ($::XCATSITEVALS{externaldhcpservers}) {
                     print $omshell "server $::XCATSITEVALS{externaldhcpservers}\n";
                 }
                 print $omshell6 "port 7912\n";
+                print $omshell6 "key-algorithm $omapialgorithm\n";
                 print $omshell6 "key "
                   . $ent->{username} . " \""
                   . $ent->{password} . "\"\n";
@@ -2953,6 +2983,13 @@
 sub newconfig6 {
     if ($::XCATSITEVALS{externaldhcpservers}) { return; }

+    # Get HMAC algorithum from site table, if set
+    my $omapialgorithm = "HMAC-MD5";
+    my @omapia=xCAT::TableUtils->get_site_attribute("omapi-algorithm");
+    if ($omapia[0]){
+        $omapialgorithm=$omapia[0];
+    }
+
     #phase 1, basic working
     #phase 2, ddns too, evaluate other stuff from dhcpv4 as applicable
     push @dhcp6conf, "#xCAT generated dhcp configuration\n";
@@ -2963,7 +3000,7 @@
     #    push @dhcp6conf, "update-static-leases on;\n";
     push @dhcp6conf, "omapi-port 7912;\n";        #Enable omapi...
     push @dhcp6conf, "key xcat_key {\n";
-    push @dhcp6conf, "  algorithm hmac-md5;\n";
+    push @dhcp6conf, "  algorithm $omapialgorithm;\n";
     my $passtab = xCAT::Table->new('passwd', -create => 1);
     (my $passent) =
       $passtab->getAttribs({ key => 'omapi', username => 'xcat_key' }, 'password');
@@ -2994,6 +3031,13 @@
     if ($::XCATSITEVALS{externaldhcpservers}) { return; }
     return newconfig_aix() if ($^O eq 'aix');

+    # Get HMAC algorithum from site table, if set
+    my $omapialgorithm = "HMAC-MD5";
+    my @omapia=xCAT::TableUtils->get_site_attribute("omapi-algorithm");
+    if ($omapia[0]){
+        $omapialgorithm=$omapia[0];
+    }
+
     # This function puts a standard header in and enough to make omapi work.
     my $passtab = xCAT::Table->new('passwd', -create => 1);
     push @dhcpconf, "#xCAT generated dhcp configuration\n";
@@ -3026,7 +3070,7 @@
     push @dhcpconf, "\n";
     push @dhcpconf, "omapi-port 7911;\n";            #Enable omapi...
     push @dhcpconf, "key xcat_key {\n";
-    push @dhcpconf, "  algorithm hmac-md5;\n";
+    push @dhcpconf, "  algorithm $omapialgorithm;\n";
     (my $passent) =
       $passtab->getAttribs({ key => 'omapi', username => 'xcat_key' }, 'password');
     my $secret = encode_base64(genpassword(32));     #Random from set of  62^32
bviviano commented 2 years ago

For completeness, here is the procedure I used to install ISC DHCPd onto my RHEL8 FIPS enabled system in /opt and use it with xCAT:

At this point, systemd and xCAT will start/stop/restart the dhcpd service using the ISC install dhcpd daemon in /opt/dhcp/sbin.

You can confirm operations by

  1. systemctl stop dhcpd
  2. echo > /var/lib/dhcpd/dhcpd.leases
  3. systemctl start dhcpd
  4. makedhcp -a
  5. ls -l /var/lib/dhcpd/dhcpd.leases
[root@smtools ~]# systemctl stop dhcpd
[root@smtools ~]# echo > /var/lib/dhcpd/dhcpd.leases
[root@smtools ~]# ls -l /var/lib/dhcpd/dhcpd.leases
-rw-r--r-- 1 root root 1 May 23 08:31 /var/lib/dhcpd/dhcpd.leases
[root@smtools ~]# systemctl start dhcpd
[root@smtools ~]# makedhcp -a
[root@smtools ~]# ls -l /var/lib/dhcpd/dhcpd.leases
-rw-r--r-- 1 root root 12463 May 23 08:31 /var/lib/dhcpd/dhcpd.leases
[root@smtools ~]#