def setup(self): self.add_copy_spec([ "/etc/firewalld/firewalld.conf", "/etc/firewalld/*.xml", "/etc/firewalld/icmptypes/*.xml", "/etc/firewalld/services/*.xml", "/etc/firewalld/zones/*.xml", "/etc/sysconfig/firewalld", "/var/log/firewalld", ]) # collect nftables ruleset nft_pred = SoSPredicate(self, kmods=['nf_tables', 'nfnetlink'], required={'kmods': 'all'}) self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True) # use a 10s timeout to workaround dbus problems in # docker containers. self.add_cmd_output([ "firewall-cmd --list-all-zones", "firewall-cmd --direct --get-all-chains", "firewall-cmd --direct --get-all-rules", "firewall-cmd --direct --get-all-passthroughs", "firewall-cmd --permanent --list-all-zones", "firewall-cmd --permanent --direct --get-all-chains", "firewall-cmd --permanent --direct --get-all-rules", "firewall-cmd --permanent --direct --get-all-passthroughs", "firewall-cmd --state", "firewall-cmd --get-log-denied" ], timeout=10)
def setup(self): self.add_cmd_output([ "ipvsadm -Ln", "ipvsadm -Ln --connection", "ipvsadm -Ln --persistent-conn", "ipvsadm -Ln --rate", "ipvsadm -Ln --stats", "ipvsadm -Ln --thresholds", "ipvsadm -Ln --timeout" ], pred=SoSPredicate(self, kmods=['ip_vs']))
def setup(self): self.add_copy_spec( ["/etc/docker/daemon.json", "/var/lib/docker/repositories-*"]) self.add_journal(units="docker") self.add_cmd_output("ls -alhR /etc/docker") self.set_cmd_predicate(SoSPredicate(self, services=["docker"])) subcmds = [ 'events --since 24h --until 1s', 'info', 'images', 'network ls', 'ps', 'ps -a', 'stats --no-stream', 'version', 'volume ls' ] for subcmd in subcmds: self.add_cmd_output("docker %s" % subcmd) # separately grab these separately as they can take a *very* long time if self.get_option('size'): self.add_cmd_output('docker ps -as') self.add_cmd_output('docker system df') nets = self.get_command_output('docker network ls') if nets['status'] == 0: n = [n.split()[1] for n in nets['output'].splitlines()[1:]] for net in n: self.add_cmd_output("docker network inspect %s" % net) ps_cmd = 'docker ps -q' if self.get_option('all'): ps_cmd = "%s -a" % ps_cmd fmt = '{{lower .Repository}}:{{lower .Tag}} {{lower .ID}}' img_cmd = "docker images --format='%s'" % fmt vol_cmd = 'docker volume ls -q' containers = self._get_docker_list(ps_cmd) images = self._get_docker_list(img_cmd) volumes = self._get_docker_list(vol_cmd) for container in containers: self.add_cmd_output("docker inspect %s" % container, subdir='containers') if self.get_option('logs'): self.add_cmd_output("docker logs -t %s" % container, subdir='containers') for img in images: name, img_id = img.strip().split() insp = name if 'none' not in name else img_id self.add_cmd_output("docker inspect %s" % insp, subdir='images') for vol in volumes: self.add_cmd_output("docker volume inspect %s" % vol, subdir='volumes')
def collect_iptable(self, tablename): """ When running the iptables command, it unfortunately auto-loads the modules before trying to get output. Some people explicitly don't want this, so check if the modules are loaded before running the command. If they aren't loaded, there can't possibly be any relevant rules in that table """ modname = "iptable_" + tablename cmd = "iptables -t " + tablename + " -nvL" self.add_cmd_output(cmd, pred=SoSPredicate(self, kmods=[modname]))
def setup(self): self.add_copy_spec([ "/etc/containers", "/etc/crictl.yaml", "/etc/crio/crio.conf", "/etc/crio/seccomp.json", "/etc/systemd/system/cri-o.service", "/etc/sysconfig/crio-*" ]) self.add_env_var( ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY']) self.add_journal(units="crio") self.add_cmd_output("ls -alhR /etc/cni") # base cri-o installation does not require cri-tools, which is what # supplies the crictl utility self.set_cmd_predicate(SoSPredicate(self, packages=['cri-tools'])) subcmds = [ 'info', 'images', 'pods', 'ps', 'ps -a', 'ps -v', 'stats', 'version', ] self.add_cmd_output(["crictl %s" % s for s in subcmds]) ps_cmd = 'crictl ps --quiet' if self.get_option('all'): ps_cmd = "%s -a" % ps_cmd img_cmd = 'crictl images --quiet' pod_cmd = 'crictl pods --quiet' containers = self._get_crio_list(ps_cmd) images = self._get_crio_list(img_cmd) pods = self._get_crio_list(pod_cmd) for container in containers: self.add_cmd_output("crictl inspect %s" % container) if self.get_option('logs'): self.add_cmd_output("crictl logs -t %s" % container, subdir="containers") for image in images: self.add_cmd_output("crictl inspecti %s" % image, subdir="images") for pod in pods: self.add_cmd_output("crictl inspectp %s" % pod, subdir="pods")
def setup(self): self.add_copy_spec([ "/etc/sssd/sssd.conf", "/var/log/sssd/*", "/var/lib/sss/pubconf/krb5.include.d/*", # SSSD 1.14 "/etc/sssd/conf.d/*.conf" ]) # call sssctl commands only when sssd service is running, # otherwise the command timeouts sssd_pred = SoSPredicate(self, services=["sssd"]) self.add_cmd_output("sssctl config-check", pred=sssd_pred) # if predicate fails, domain["status"] = None and thus we skip parsing # missing output domain = self.collect_cmd_output("sssctl domain-list", pred=sssd_pred) if domain['status'] == 0: for domain_name in domain['output'].splitlines(): self.add_cmd_output("sssctl domain-status -o " + domain_name)
def setup(self): self.add_copy_spec([ "/boot/efi/EFI/*/grub.cfg", "/boot/grub2/grub.cfg", "/boot/grub2/grubenv", "/boot/grub/grub.cfg", "/boot/loader/entries", "/etc/default/grub", "/etc/grub2.cfg", "/etc/grub.d" ]) self.add_cmd_output("ls -lanR /boot") # call grub2-mkconfig with GRUB_DISABLE_OS_PROBER=true to prevent # possible unwanted loading of some kernel modules # further, check if the command supports --no-grubenv-update option # to prevent removing of extra args in $kernel_opts, and (only) if so, # call the command with this argument env = {} env['GRUB_DISABLE_OS_PROBER'] = 'true' grub_cmd = 'grub2-mkconfig' co = {'cmd': 'grub2-mkconfig --help', 'output': '--no-grubenv-update'} if self.test_predicate(self, pred=SoSPredicate(self, cmd_outputs=co)): grub_cmd += ' --no-grubenv-update' self.add_cmd_output(grub_cmd, env=env)
def setup(self): self.pki_tomcat_dir_v4 = "/var/lib/pki/pki-tomcat" self.pki_tomcat_dir_v3 = "/var/lib/pki-ca" self.pki_tomcat_conf_dir_v4 = "/etc/pki/pki-tomcat/ca" self.pki_tomcat_conf_dir_v3 = "/etc/pki-ca" # Returns "v3", "v4", or None ipa_version = self.check_ipa_server_version() if self.ipa_server_installed(): self._log_debug("IPA server install detected") self._log_debug("IPA version is [%s]" % ipa_version) self.add_copy_spec([ "/var/log/ipaserver-install.log", "/var/log/ipaserver-kra-install.log", "/var/log/ipareplica-install.log", "/var/log/ipareplica-ca-install.log", "/var/log/ipa-custodia.audit.log" ]) if self.ca_installed(): self._log_debug("CA is installed: retrieving PKI logs") self.retrieve_pki_logs(ipa_version) self.add_copy_spec([ "/var/log/ipaclient-install.log", "/var/log/ipaupgrade.log", "/var/log/krb5kdc.log", "/var/log/dirsrv/slapd-*/logs/access", "/var/log/dirsrv/slapd-*/logs/errors", "/etc/dirsrv/slapd-*/dse.ldif", "/etc/dirsrv/slapd-*/schema/99user.ldif", "/etc/hosts", "/etc/httpd/alias/*", "/etc/named.*", "/etc/ipa/ca.crt", "/etc/ipa/default.conf", "/etc/ipa/kdcproxy/kdcproxy.conf", "/etc/ipa/kdcproxy/ipa-kdc-proxy.conf", "/etc/ipa/kdcproxy.conf", "/root/.ipa/log/cli.log", "/var/lib/certmonger/requests/[0-9]*", "/var/lib/certmonger/cas/[0-9]*", "/var/lib/ipa/ra-agent.pem", "/var/lib/ipa/certs/httpd.crt", "/var/kerberos/krb5kdc/kdc.crt", "/var/lib/ipa/sysrestore/sysrestore.state", "/var/log/ipa/healthcheck/healthcheck.log*" ]) # Make sure to use the right PKI config and NSS DB folders if ipa_version == "v4": self.pki_tomcat_dir = self.pki_tomcat_dir_v4 self.pki_tomcat_conf_dir = self.pki_tomcat_conf_dir_v4 else: self.pki_tomcat_dir = self.pki_tomcat_dir_v3 self.pki_tomcat_conf_dir = self.pki_tomcat_conf_dir_v3 self.add_cmd_output("certutil -L -d %s/alias" % self.pki_tomcat_dir) self.add_copy_spec("%s/CS.cfg" % self.pki_tomcat_conf_dir) self.add_forbidden_path([ "/etc/pki/nssdb/key*", "/etc/dirsrv/slapd-*/key*", "/etc/dirsrv/slapd-*/pin.txt", "/etc/dirsrv/slapd-*/pwdfile.txt", "/etc/httpd/alias/ipasession.key", "/etc/httpd/alias/key*", "/etc/httpd/alias/pin.txt", "/etc/httpd/alias/pwdfile.txt", "/etc/named.keytab", "%s/alias/key*" % self.pki_tomcat_dir, "%s/flatfile.txt" % self.pki_tomcat_conf_dir, "%s/password.conf" % self.pki_tomcat_conf_dir, ]) self.add_cmd_output([ "ls -la /etc/dirsrv/slapd-*/schema/", "certutil -L -d /etc/httpd/alias/", "pki-server cert-find --show-all", "pki-server subsystem-cert-validate ca", "klist -ket /etc/dirsrv/ds.keytab", "klist -ket /etc/httpd/conf/ipa.keytab", "klist -ket /var/lib/ipa/gssproxy/http.keytab" ]) getcert_pred = SoSPredicate(self, services=['certmonger']) self.add_cmd_output("getcert list", pred=getcert_pred) for certdb_directory in glob("/etc/dirsrv/slapd-*/"): self.add_cmd_output("certutil -L -d %s" % certdb_directory) return
def setup(self): super(Networking, self).setup() self.add_copy_spec([ "/proc/net/", "/etc/nsswitch.conf", "/etc/yp.conf", "/etc/inetd.conf", "/etc/xinetd.conf", "/etc/xinetd.d", "/etc/host*", "/etc/resolv.conf", "/etc/network*", "/etc/nftables", "/etc/sysconfig/nftables.conf", "/etc/nftables.conf", "/etc/dnsmasq*", "/sys/class/net/*/device/numa_node", "/sys/class/net/*/flags", "/sys/class/net/*/statistics/", "/etc/iproute2" ]) self.add_forbidden_path([ "/proc/net/rpc/use-gss-proxy", "/proc/net/rpc/*/channel", "/proc/net/rpc/*/flush", # Cisco CDP "/proc/net/cdp", "/sys/net/cdp", # Dialogic Diva "/proc/net/eicon" ]) self.add_cmd_output("ip -o addr", root_symlink="ip_addr") self.add_cmd_output("route -n", root_symlink="route") self.add_cmd_output("plotnetcfg") # collect iptables -t for any existing table, if we can't read the # tables, collect 3 default ones (nat, mangle, filter) try: ip_tables_names = open("/proc/net/ip_tables_names").read() except IOError: ip_tables_names = "nat\nmangle\nfilter\n" for table in ip_tables_names.splitlines(): self.collect_iptable(table) # collect the same for ip6tables try: ip_tables_names = open("/proc/net/ip6_tables_names").read() except IOError: ip_tables_names = "nat\nmangle\nfilter\n" for table in ip_tables_names.splitlines(): self.collect_ip6table(table) self.collect_nftables() self.add_cmd_output("netstat %s -neopa" % self.ns_wide, root_symlink="netstat") self.add_cmd_output([ "netstat -s", "netstat %s -agn" % self.ns_wide, "ip route show table all", "ip -6 route show table all", "ip -4 rule", "ip -6 rule", "ip -s -d link", "ip -d address", "ifenslave -a", "ip mroute show", "ip maddr show", "ip -s -s neigh show", "ip neigh show nud noarp", "biosdevname -d", "tc -s qdisc show", ]) # below commands require some kernel module(s) to be loaded # run them only if the modules are loaded, or if explicitly requested # via --allow-system-changes option ip_macsec_show_cmd = "ip -s macsec show" macsec_pred = SoSPredicate(self, kmods=['macsec']) self.add_cmd_output(ip_macsec_show_cmd, pred=macsec_pred, changes=True) ss_cmd = "ss -peaonmi" ss_pred = SoSPredicate(self, kmods=[ 'tcp_diag', 'udp_diag', 'inet_diag', 'unix_diag', 'netlink_diag', 'af_packet_diag' ], required={'kmods': 'all'}) self.add_cmd_output(ss_cmd, pred=ss_pred, changes=True) # When iptables is called it will load the modules # iptables and iptables_filter if they are not loaded. # The same goes for ipv6. self.add_cmd_output("iptables -vnxL", pred=SoSPredicate(self, kmods=['iptable_filter'])) self.add_cmd_output("ip6tables -vnxL", pred=SoSPredicate(self, kmods=['ip6table_filter'])) # Get ethtool output for every device that does not exist in a # namespace. for eth in listdir("/sys/class/net/"): # skip 'bonding_masters' file created when loading the bonding # module but the file does not correspond to a device if eth == "bonding_masters": continue self.add_cmd_output([ "ethtool " + eth, "ethtool -d " + eth, "ethtool -i " + eth, "ethtool -k " + eth, "ethtool -S " + eth, "ethtool -T " + eth, "ethtool -a " + eth, "ethtool -c " + eth, "ethtool -g " + eth, "ethtool -e " + eth, "ethtool -P " + eth, "ethtool -l " + eth, "ethtool --phy-statistics " + eth, "ethtool --show-priv-flags " + eth, "ethtool --show-eee " + eth ]) # Collect information about bridges (some data already collected via # "ip .." commands) self.add_cmd_output([ "bridge -s -s -d link show", "bridge -s -s -d -t fdb show", "bridge -s -s -d -t mdb show", "bridge -d vlan show" ]) if self.get_option("traceroute"): self.add_cmd_output("/bin/traceroute -n %s" % self.trace_host) # Capture additional data from namespaces; each command is run # per-namespace. ip_netns = self.collect_cmd_output("ip netns") cmd_prefix = "ip netns exec " if ip_netns['status'] == 0: out_ns = [] # Regex initialization outside of for loop if self.get_option("namespace_pattern"): pattern = '(?:%s$)' % '$|'.join( self.get_option("namespace_pattern").split()).replace( '*', '.*') for line in ip_netns['output'].splitlines(): # If there's no namespaces, no need to continue if line.startswith("Object \"netns\" is unknown") \ or line.isspace() \ or line[:1].isspace(): continue # if namespace_pattern defined, append only namespaces # matching with pattern if self.get_option("namespace_pattern"): if bool(match(pattern, line)): out_ns.append(line.partition(' ')[0]) # if namespaces is defined and namespace_pattern is not defined # remove from out_ns namespaces with higher index than defined elif self.get_option("namespaces") != 0: out_ns.append(line.partition(' ')[0]) if len(out_ns) == self.get_option("namespaces"): self._log_warn("Limiting namespace iteration " + "to first %s namespaces found" % self.get_option("namespaces")) break else: out_ns.append(line.partition(' ')[0]) for namespace in out_ns: ns_cmd_prefix = cmd_prefix + namespace + " " self.add_cmd_output([ ns_cmd_prefix + "ip address show", ns_cmd_prefix + "ip route show table all", ns_cmd_prefix + "iptables-save", ns_cmd_prefix + "netstat %s -neopa" % self.ns_wide, ns_cmd_prefix + "netstat -s", ns_cmd_prefix + "netstat %s -agn" % self.ns_wide, ]) ss_cmd = ns_cmd_prefix + "ss -peaonmi" # --allow-system-changes is handled directly in predicate # evaluation, so plugin code does not need to separately # check for it self.add_cmd_output(ss_cmd, pred=ss_pred) # Collect ethtool commands only when ethtool_namespaces # is set to true. if self.get_option("ethtool_namespaces"): # Devices that exist in a namespace use less ethtool # parameters. Run this per namespace. for namespace in out_ns: ns_cmd_prefix = cmd_prefix + namespace + " " netns_netdev_list = self.exec_cmd(ns_cmd_prefix + "ls -1 /sys/class/net/") for eth in netns_netdev_list['output'].splitlines(): # skip 'bonding_masters' file created when loading the # bonding module but the file does not correspond to # a device if eth == "bonding_masters": continue self.add_cmd_output([ ns_cmd_prefix + "ethtool " + eth, ns_cmd_prefix + "ethtool -i " + eth, ns_cmd_prefix + "ethtool -k " + eth, ns_cmd_prefix + "ethtool -S " + eth ]) return
def collect_nftables(self): """ Collects nftables rulesets with 'nft' commands if the modules are present """ self.add_cmd_output("nft list ruleset", pred=SoSPredicate(self, kmods=['nf_tables']))
def collect_ip6table(self, tablename): """ Same as function above, but for ipv6 """ modname = "ip6table_" + tablename cmd = "ip6tables -t " + tablename + " -nvL" self.add_cmd_output(cmd, pred=SoSPredicate(self, kmods=[modname]))
def setup(self): super(Networking, self).setup() self.add_copy_spec([ "/proc/net/", "/etc/nsswitch.conf", "/etc/yp.conf", "/etc/inetd.conf", "/etc/xinetd.conf", "/etc/xinetd.d", "/etc/host*", "/etc/resolv.conf", "/etc/network*", "/etc/nftables", "/etc/sysconfig/nftables.conf", "/etc/nftables.conf", "/etc/dnsmasq*", "/sys/class/net/*/device/numa_node", "/sys/class/net/*/flags", "/sys/class/net/*/statistics/", "/etc/iproute2" ]) self.add_forbidden_path([ "/proc/net/rpc/use-gss-proxy", "/proc/net/rpc/*/channel", "/proc/net/rpc/*/flush", # Cisco CDP "/proc/net/cdp", "/sys/net/cdp", # Dialogic Diva "/proc/net/eicon" ]) self.add_cmd_output("ip -o addr", root_symlink="ip_addr") self.add_cmd_output("route -n", root_symlink="route") self.add_cmd_output("plotnetcfg") # collect iptables -t for any existing table, if we can't read the # tables, collect 3 default ones (nat, mangle, filter) try: ip_tables_names = open("/proc/net/ip_tables_names").read() except IOError: ip_tables_names = "nat\nmangle\nfilter\n" for table in ip_tables_names.splitlines(): self.collect_iptable(table) # collect the same for ip6tables try: ip_tables_names = open("/proc/net/ip6_tables_names").read() except IOError: ip_tables_names = "nat\nmangle\nfilter\n" for table in ip_tables_names.splitlines(): self.collect_ip6table(table) self.collect_nftables() self.add_cmd_output("netstat %s -neopa" % self.ns_wide, root_symlink="netstat") self.add_cmd_output([ "netstat -s", "netstat %s -agn" % self.ns_wide, "ip route show table all", "ip -6 route show table all", "ip -4 rule", "ip -6 rule", "ip -s -d link", "ip -d address", "ifenslave -a", "ip mroute show", "ip maddr show", "ip -s -s neigh show", "ip neigh show nud noarp", "biosdevname -d", "tc -s qdisc show", ]) # below commands require some kernel module(s) to be loaded # run them only if the modules are loaded, or if explicitly requested # via --allow-system-changes option ip_macsec_show_cmd = "ip -s macsec show" macsec_pred = SoSPredicate(self, kmods=['macsec']) self.add_cmd_output(ip_macsec_show_cmd, pred=macsec_pred, changes=True) ss_cmd = "ss -peaonmi" ss_pred = SoSPredicate(self, kmods=[ 'tcp_diag', 'udp_diag', 'inet_diag', 'unix_diag', 'netlink_diag', 'af_packet_diag' ], required={'kmods': 'all'}) self.add_cmd_output(ss_cmd, pred=ss_pred, changes=True) # When iptables is called it will load the modules # iptables and iptables_filter if they are not loaded. # The same goes for ipv6. if self.check_ext_prog("grep -q iptable_filter /proc/modules"): self.add_cmd_output("iptables -vnxL") if self.check_ext_prog("grep -q ip6table_filter /proc/modules"): self.add_cmd_output("ip6tables -vnxL") # Get ethtool output for every device that does not exist in a # namespace. for eth in listdir("/sys/class/net/"): # skip 'bonding_masters' file created when loading the bonding # module but the file does not correspond to a device if eth == "bonding_masters": continue self.add_cmd_output([ "ethtool " + eth, "ethtool -d " + eth, "ethtool -i " + eth, "ethtool -k " + eth, "ethtool -S " + eth, "ethtool -T " + eth, "ethtool -a " + eth, "ethtool -c " + eth, "ethtool -g " + eth, "ethtool -e " + eth, "ethtool -P " + eth, "ethtool -l " + eth, "ethtool --phy-statistics " + eth, "ethtool --show-priv-flags " + eth, "ethtool --show-eee " + eth ]) # Collect information about bridges (some data already collected via # "ip .." commands) self.add_cmd_output([ "bridge -s -s -d link show", "bridge -s -s -d -t fdb show", "bridge -s -s -d -t mdb show", "bridge -d vlan show" ]) if self.get_option("traceroute"): self.add_cmd_output("/bin/traceroute -n %s" % self.trace_host) # Capture additional data from namespaces; each command is run # per-namespace. ip_netns_file = self.get_cmd_output_now("ip netns") cmd_prefix = "ip netns exec " if ip_netns_file: for namespace in self.get_ip_netns(ip_netns_file): ns_cmd_prefix = cmd_prefix + namespace + " " self.add_cmd_output([ ns_cmd_prefix + "ip address show", ns_cmd_prefix + "ip route show table all", ns_cmd_prefix + "iptables-save", ns_cmd_prefix + "netstat %s -neopa" % self.ns_wide, ns_cmd_prefix + "netstat -s", ns_cmd_prefix + "netstat %s -agn" % self.ns_wide ]) ss_cmd = ns_cmd_prefix + "ss -peaonmi" # --allow-system-changes is handled directly in predicate # evaluation, so plugin code does not need to separately # check for it self.add_cmd_output(ss_cmd, pred=ss_pred) # Devices that exist in a namespace use less ethtool # parameters. Run this per namespace. for namespace in self.get_ip_netns(ip_netns_file): ns_cmd_prefix = cmd_prefix + namespace + " " netns_netdev_list = self.call_ext_prog(ns_cmd_prefix + "ls -1 /sys/class/net/") for eth in netns_netdev_list['output'].splitlines(): # skip 'bonding_masters' file created when loading the # bonding module but the file does not correspond to # a device if eth == "bonding_masters": continue self.add_cmd_output([ ns_cmd_prefix + "ethtool " + eth, ns_cmd_prefix + "ethtool -i " + eth, ns_cmd_prefix + "ethtool -k " + eth, ns_cmd_prefix + "ethtool -S " + eth ]) return