Listing 4. check_listening_ports.cf

body common control

{
bundlesequence  => { "check_listening_ports"  };
inputs  => { "Cfengine_stdlib.cf"  };
}

bundle agent check_listening_ports
{
vars:
"listening_ports_and_processes_ideal_scene"
string =>
"22 sshd 80 httpd 443 httpd 5308 cf-server";
# this is our expected configuration

vars:
"listening_ports_and_processes" string =>
execresult("/usr/sbin/lsof -i -n -P | \
/bin/grep LISTEN | \
/bin/sed -e 's#*:##' | \
/bin/grep -v 127.0.0.1 | \
/bin/grep -v ::1 | \
/bin/awk '{print $8,$1}' | \
/bin/sort | \
/usr/bin/uniq | \
/bin/sort -n | \
/usr/bin/xargs echo", "useshell"); # actual config.
# tell Cfengine to use a shell with "useshell"
# to do a command pipeline.

classes:
"reality_does_not_match_ideal_scene" not =>
  regcmp (
      "$(listening_ports_and_processes)",
      "$(listening_ports_and_processes_ideal_scene)"
  );  # check whether expected config matches actual

reports:
  reality_does_not_match_ideal_scene::
"
DANGER!
DANGER! Expected open ports and processes:
DANGER! $(listening_ports_and_processes_ideal_scene)
DANGER!
DANGER! Actual open ports and processes:
DANGER! $(listening_ports_and_processes)
DANGER!
";  # and yell loudly if it does not match.
    # Note:  A "commands" promise could be used in
    # addition to "reports" to send a text message
    # to a sysadmin cell phone or to feed
    # CRITICAL status to a monitoring system.
}

