From 22f6198f60f388fde32625c7abbccf2af43b58c5 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jan 2020 14:35:58 -0500 Subject: [PATCH 01/11] Fix nodebmcreset on bad noderange This prevents confusing python stack when a bad noderange is specified. --- confluent_client/bin/nodebmcreset | 2 ++ 1 file changed, 2 insertions(+) diff --git a/confluent_client/bin/nodebmcreset b/confluent_client/bin/nodebmcreset index ae253e77..09a6221b 100755 --- a/confluent_client/bin/nodebmcreset +++ b/confluent_client/bin/nodebmcreset @@ -47,6 +47,8 @@ exitcode = 0 errorNodes = set([]) session.stop_if_noderange_over(noderange, options.maxnodes) success = session.simple_noderange_command(noderange, 'configuration/management_controller/reset', 'reset', key='state', errnodes=errorNodes) # = 0 if successful +if success != 0: + sys.exit(success) # Determine which nodes were successful and print them From c666b111383dc37b45107ae51c6afc4e321c3551 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 08:10:01 -0500 Subject: [PATCH 02/11] Add ability to foreground exec confluent This allows easier debug and option for unit file in systemd to run foreground if it makes sense. --- confluent_server/bin/confluent | 2 +- confluent_server/confluent/main.py | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/confluent_server/bin/confluent b/confluent_server/bin/confluent index 62d6ab3d..db66e587 100755 --- a/confluent_server/bin/confluent +++ b/confluent_server/bin/confluent @@ -32,7 +32,7 @@ import confluent.main import multiprocessing if __name__ == '__main__': multiprocessing.freeze_support() - confluent.main.run() + confluent.main.run(sys.argv) #except: # pass #p.disable() diff --git a/confluent_server/confluent/main.py b/confluent_server/confluent/main.py index 50978a95..c009198e 100644 --- a/confluent_server/confluent/main.py +++ b/confluent_server/confluent/main.py @@ -77,13 +77,16 @@ def _daemonize(): print('confluent server starting as pid {0}'.format(thispid)) os._exit(0) os.closerange(0, 2) - os.umask(63) os.open(os.devnull, os.O_RDWR) os.dup2(0, 1) os.dup2(0, 2) + log.daemonized = True + + +def _redirectoutput(): + os.umask(63) sys.stdout = log.Logger('stdout', buffered=False) sys.stderr = log.Logger('stderr', buffered=False) - log.daemonized = True def _updatepidfile(): @@ -206,7 +209,7 @@ def setlimits(): pass -def run(): +def run(args): setlimits() try: signal.signal(signal.SIGUSR1, dumptrace) @@ -232,7 +235,10 @@ def run(): except (OSError, IOError) as e: print(repr(e)) sys.exit(1) - _daemonize() + if '-f' not in args: + _daemonize() + if '-o' not in args: + _redirectoutput() if havefcntl: _updatepidfile() signal.signal(signal.SIGINT, terminate) From a24866c2df2046ba29933af94f60e7c49e6e96d7 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 08:22:20 -0500 Subject: [PATCH 03/11] Fix exitcode for confetty noderange commands The exitcode was not being set for noderange commands where each node may independently raise errors. Correct the oversight by catching each subelements errors. --- confluent_client/bin/confetty | 3 +++ 1 file changed, 3 insertions(+) diff --git a/confluent_client/bin/confetty b/confluent_client/bin/confetty index 3844f6b8..e4e30e6d 100755 --- a/confluent_client/bin/confetty +++ b/confluent_client/bin/confetty @@ -299,8 +299,11 @@ currchildren = None def print_result(res): + global exitcode if 'errorcode' in res or 'error' in res: print(res['error']) + if 'errorcode' in res: + exitcode |= res['errorcode'] return if 'databynode' in res: print_result(res['databynode']) From 7a63ca8759e99d4d2b523b68dd0f4126e36bc046 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 08:53:42 -0500 Subject: [PATCH 04/11] Fix python3 problem with confetty Under python3, there is no unicode. --- confluent_client/bin/confetty | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/confluent_client/bin/confetty b/confluent_client/bin/confetty index e4e30e6d..043881a4 100755 --- a/confluent_client/bin/confetty +++ b/confluent_client/bin/confetty @@ -76,6 +76,11 @@ import confluent.termhandler as termhandler import confluent.tlvdata as tlvdata import confluent.client as client +try: + unicode +except NameError: + unicode = str + conserversequence = '\x05c' # ctrl-e, c clearpowermessage = False From 968efe719a3e94f74b783190b36189f8e0a64676 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 09:34:13 -0500 Subject: [PATCH 05/11] Add CAP_NET_BIND_SERVICE to unit file This is preparing for running as non-root. We need this capability to snoop SLP and PXE --- confluent_server/systemd/confluent.service | 1 + 1 file changed, 1 insertion(+) diff --git a/confluent_server/systemd/confluent.service b/confluent_server/systemd/confluent.service index 7a6f8fea..57476a17 100644 --- a/confluent_server/systemd/confluent.service +++ b/confluent_server/systemd/confluent.service @@ -8,6 +8,7 @@ Type=forking ExecStart=/opt/confluent/bin/confluent ExecStop=/opt/confluent/bin/confetty shutdown / Restart=on-failure +AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target From 0d5fa7a98a9133cca2a74d8ac76694c23abca267 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 09:52:52 -0500 Subject: [PATCH 06/11] Change confluent to run as non-root and harden systemd This mitigates a great deal of risk compared to prior behavior. --- confluent_server/confluent_server.spec.tmpl | 9 +++++++++ confluent_server/systemd/confluent.service | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index e86313a4..125104fb 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -52,6 +52,15 @@ cat INSTALLED_FILES if [ -x /usr/bin/systemctl ]; then /usr/bin/systemctl try-restart confluent >& /dev/null; fi true +%pre +getent group confluent > /dev/null || /usr/sbin/groupadd -r confluent +getent passwd confluent > /dev/null || /usr/sbin/useradd -r -g confluent -d /var/lib/confluent -s /sbin/nologin confluent +mkdir -p /etc/confluent +mkdir -p /var/lib/confluent +mkdir -p /var/run/confluent +mkdir -p /var/log/confluent +chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent + %post sysctl -p /usr/lib/sysctl.d/confluent.conf >& /dev/null if [ -x /usr/bin/systemctl ]; then /usr/bin/systemctl try-restart confluent >& /dev/null; fi diff --git a/confluent_server/systemd/confluent.service b/confluent_server/systemd/confluent.service index 57476a17..8ead8827 100644 --- a/confluent_server/systemd/confluent.service +++ b/confluent_server/systemd/confluent.service @@ -1,6 +1,7 @@ # IBM(c) 2015 Apache 2.0 +# Lenovo(c) 2020 Apache 2.0 [Unit] -Description=Confluent hardware manager +Description=Confluent hardware manager [Service] Type=forking @@ -9,6 +10,13 @@ ExecStart=/opt/confluent/bin/confluent ExecStop=/opt/confluent/bin/confetty shutdown / Restart=on-failure AmbientCapabilities=CAP_NET_BIND_SERVICE +User=confluent +Group=confluent +DevicePolicy=closed +CapabilityBoundingSet=CAP_NET_BIND_SERVICE +PrivateDevices=true +ProtectControlGroups=true +ProtectSystem=true [Install] WantedBy=multi-user.target From c1b82d8163b8fc2e877be6cc62beedc9d7e331c1 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 10:00:35 -0500 Subject: [PATCH 07/11] Protect confluent private data This blocks use of private confluent data in commands like nodelicense, nodefirmware, and nodemedia. --- confluent_server/confluent/messages.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index cf3d4707..3fc63b8e 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -545,9 +545,21 @@ class InputFirmwareUpdate(ConfluentMessage): raise Exception('User requested substitutions, but code is ' 'written against old api, code must be fixed or ' 'skip {} expansion') + if self.filebynode[node].startswith('/etc/confluent'): + raise Exception( + 'File transfer with /etc/confluent is not supported') + if self.filebynode[node].startswith('/var/log/confluent'): + raise Exception( + 'File transfer with /var/log/confluent is not supported') return self._filename def nodefile(self, node): + if self.filebynode[node].startswith('/etc/confluent'): + raise Exception( + 'File transfer with /etc/confluent is not supported') + if self.filebynode[node].startswith('/var/log/confluent'): + raise Exception( + 'File transfer with /var/log/confluent is not supported') return self.filebynode[node] class InputMedia(InputFirmwareUpdate): From c02064f0a5654362041f838e8faca2466e79880f Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 10:02:38 -0500 Subject: [PATCH 08/11] Add missing msgpack dependencies --- confluent_server/confluent_server.spec.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index 125104fb..9a631b96 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -13,9 +13,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot Prefix: %{_prefix} BuildArch: noarch %if "%{dist}" == ".el8" -Requires: python3-pyghmi >= 1.0.34, python3-eventlet, python3-greenlet, python3-pycryptodomex >= 3.4.7, confluent_client, python3-pyparsing, python3-paramiko, python3-dns, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-pyte, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-enum34, python3-asn1crypto, python3-cffi, python3-pyOpenSSL, python3-monotonic, python3-websocket-client +Requires: python3-pyghmi >= 1.0.34, python3-eventlet, python3-greenlet, python3-pycryptodomex >= 3.4.7, confluent_client, python3-pyparsing, python3-paramiko, python3-dns, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-pyte, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-enum34, python3-asn1crypto, python3-cffi, python3-pyOpenSSL, python3-monotonic, python3-websocket-client python3-msgpack %else -Requires: python-pyghmi >= 1.0.34, python-eventlet, python-greenlet, python-pycryptodomex >= 3.4.7, confluent_client, python-pyparsing, python-paramiko, python-dns, python-netifaces, python2-pyasn1 >= 0.2.3, python-pysnmp >= 4.3.4, python-pyte, python-lxml, python-eficompressor, python-setuptools, python-dateutil, python2-websocket-client +Requires: python-pyghmi >= 1.0.34, python-eventlet, python-greenlet, python-pycryptodomex >= 3.4.7, confluent_client, python-pyparsing, python-paramiko, python-dns, python-netifaces, python2-pyasn1 >= 0.2.3, python-pysnmp >= 4.3.4, python-pyte, python-lxml, python-eficompressor, python-setuptools, python-dateutil, python2-websocket-client python2-msgpack %endif Vendor: Jarrod Johnson Url: http://xcat.sf.net/ From 0badd9e5b40f53c6cad1694d06e36d9c571b62d0 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 10:16:33 -0500 Subject: [PATCH 09/11] Migrate confluent installs to non-root This will check for and repair uid 0 owned confluent directories. --- confluent_server/confluent_server.spec.tmpl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index 9a631b96..a8fb01b4 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -48,7 +48,7 @@ rmdir $RPM_BUILD_ROOT/etc/init.d rmdir $RPM_BUILD_ROOT/etc cat INSTALLED_FILES -%triggerin -- python-pyghmi +%triggerin -- python-pyghmi, python3-pyghmi, python2-pyghmi if [ -x /usr/bin/systemctl ]; then /usr/bin/systemctl try-restart confluent >& /dev/null; fi true @@ -63,7 +63,19 @@ chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluen %post sysctl -p /usr/lib/sysctl.d/confluent.conf >& /dev/null -if [ -x /usr/bin/systemctl ]; then /usr/bin/systemctl try-restart confluent >& /dev/null; fi +NEEDCHOWN=0 +NEEDSTART=0 +find /etc/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 +find /var/log/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 +find /var/run/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 +if [ $NEEDCHOWN = 1 ]; then + if systemctl is-active confluent > /dev/null; + NEEDSTART=1 + systemctl stop confluent + fi + chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent +fi +if systemctl is-active confluent > /dev/null || [ $NEEDSTART = 1 ]; then /usr/bin/systemctl restart confluent >& /dev/null; fi if [ ! -e /etc/pam.d/confluent ]; then ln -s /etc/pam.d/sshd /etc/pam.d/confluent fi From ff0b1bba7fb9e6c90f17ecc92e6302d1ff273d0b Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 10:37:49 -0500 Subject: [PATCH 10/11] Fix rpm spec file There was an ommision and a mistake. --- confluent_server/confluent_server.spec.tmpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index a8fb01b4..a4e20933 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -69,12 +69,13 @@ find /etc/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 find /var/log/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 find /var/run/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 if [ $NEEDCHOWN = 1 ]; then - if systemctl is-active confluent > /dev/null; + if systemctl is-active confluent > /dev/null; then NEEDSTART=1 systemctl stop confluent fi chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent fi +systemctl daemon-reload if systemctl is-active confluent > /dev/null || [ $NEEDSTART = 1 ]; then /usr/bin/systemctl restart confluent >& /dev/null; fi if [ ! -e /etc/pam.d/confluent ]; then ln -s /etc/pam.d/sshd /etc/pam.d/confluent From 0b577af1cad62011627c400305a679b27210b385 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 31 Jan 2020 11:48:34 -0500 Subject: [PATCH 11/11] Fix ownership of confluent cache It needs to be owned by the confluent user. --- confluent_server/confluent_server.spec.tmpl | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index a4e20933..e65cfe5b 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -55,25 +55,23 @@ true %pre getent group confluent > /dev/null || /usr/sbin/groupadd -r confluent getent passwd confluent > /dev/null || /usr/sbin/useradd -r -g confluent -d /var/lib/confluent -s /sbin/nologin confluent -mkdir -p /etc/confluent -mkdir -p /var/lib/confluent -mkdir -p /var/run/confluent -mkdir -p /var/log/confluent -chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent +mkdir -p /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent /var/cache/confluent +chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent /var/cache/confluent %post sysctl -p /usr/lib/sysctl.d/confluent.conf >& /dev/null NEEDCHOWN=0 NEEDSTART=0 -find /etc/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 -find /var/log/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 -find /var/run/confluent -uid 0 | egrep '.*' && NEEDCHOWN=1 +find /etc/confluent -uid 0 | egrep '.*' > /dev/null && NEEDCHOWN=1 +find /var/log/confluent -uid 0 | egrep '.*' > /dev/null && NEEDCHOWN=1 +find /var/run/confluent -uid 0 | egrep '.*' > /dev/null && NEEDCHOWN=1 +find /var/cache/confluent -uid 0 | egrep '.*' > /dev/null && NEEDCHOWN=1 if [ $NEEDCHOWN = 1 ]; then if systemctl is-active confluent > /dev/null; then NEEDSTART=1 systemctl stop confluent fi - chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent + chown -R confluent:confluent /etc/confluent /var/lib/confluent /var/run/confluent /var/log/confluent /var/cache/confluent fi systemctl daemon-reload if systemctl is-active confluent > /dev/null || [ $NEEDSTART = 1 ]; then /usr/bin/systemctl restart confluent >& /dev/null; fi