Problem This recipe demonstrates how to harvest security relevant ndd information (Solaris 5.[6-9]), compare it to a set of reference values, and generate a delimited report that is suitable for automated processing and analysis. Motivation Checking ndd settings regularly promotes awareness and better security practices. Having a centrally managed repository of ndd snapshots may help resolve network anomalies more quickly because any changes that have occurred over time have potentially been recorded. Requirements Cooking with this recipe requires an operational WebJob server. If you do not have one of those, refer to the instructions provided in the README.INSTALL file that comes with the source distribution. The latest source distribution is available here: http://sourceforge.net/project/showfiles.php?group_id=40788 Each client system must be running Solaris 5.[6-9] and have at least the following utilities: awk, basename, egrep, ndd, sed, sh, test, tr, and webjob. The commands presented throughout this recipe were designed to be executed within a Bourne shell (i.e. sh or bash). Solution The solution is to harvest and check ndd information using webjob and check_ndd on the client. The uploaded output can then be processed and analyzed on the server using a number of different techniques. The following steps describe how to implement this solution. 1. Set WEBJOB_CLIENT and WEBJOB_COMMANDS as appropriate for your server. Next, extract check_ndd from this recipe, and move it to the appropriate commands directory. If you want check_ndd to be bound to a particular client, set WEBJOB_CLIENT as appropriate before running the following commands. Once the file is in place, set its ownership and permissions to 0:0 and mode 644, respectively. $ export WEBJOB_CLIENT=common $ export WEBJOB_COMMANDS=/integrity/profiles/${WEBJOB_CLIENT}/commands $ sed -e '1,/^--- check_ndd ---$/d; /^--- check_ndd ---$/,$d' webjob-check-ndd.txt > check_ndd $ mv check_ndd ${WEBJOB_COMMANDS} $ chown 0:0 ${WEBJOB_COMMANDS}/check_ndd $ chmod 644 ${WEBJOB_COMMANDS}/check_ndd 2. Create a crontab entry on each client that periodically executes check_ndd. Be sure to substitute the correct path for WEBJOB_HOME prior to committing the new crontab. For example, the following entry would execute check_ndd hourly: 0 * * * * ${WEBJOB_HOME=/usr/local/integrity}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg check_ndd all 3. The output produced by check_ndd should be similar to that shown below. The status field is 'pass' or 'fail' when the specified parameter exists and its actual value does or does not match the corresponding target value. The status field is 'indeterminate' when the specified parameter could not be tested -- either because it was invalid or it did not exist on the target OS. Details on the various ndd parameters and how they relate to security can be found in "Solaris Operating Environment Network Settings for Security", which is part of the Sun BluePrints Series and is available online here: http://www.sun.com/solutions/blueprints/1200/network-updt1.pdf --- sample-output-for-solaris-5.7 --- status,driver,parameter,actual_value,target_value fail,/dev/ip,ip_forward_directed_broadcasts,1,0 fail,/dev/ip,ip_forward_src_routed,1,0 pass,/dev/ip,ip_forwarding,0,0 fail,/dev/ip,ip_ignore_redirect,0,1 pass,/dev/ip,ip_respond_to_address_mask_broadcast,0,0 fail,/dev/ip,ip_respond_to_echo_broadcast,1,0 fail,/dev/ip,ip_respond_to_timestamp,1,0 fail,/dev/ip,ip_respond_to_timestamp_broadcast,1,0 fail,/dev/ip,ip_send_redirects,1,0 fail,/dev/ip,ip_strict_dst_multihoming,0,1 indeterminate,/dev/ip,ip6_forward_src_routed,,0 indeterminate,/dev/ip,ip6_forwarding,,0 indeterminate,/dev/ip,ip6_ignore_redirect,,1 indeterminate,/dev/ip,ip6_respond_to_echo_multicast,,0 indeterminate,/dev/ip,ip6_send_redirects,,0 indeterminate,/dev/ip,ip6_strict_dst_multihoming,,1 fail,/dev/tcp,tcp_conn_req_max_q,128,1024 fail,/dev/tcp,tcp_conn_req_max_q0,1024,4096 fail,/dev/tcp,tcp_ip_abort_cinterval,180000,60000 indeterminate,/dev/tcp,tcp_rev_src_routes,,0 fail,/dev/tcp,tcp_strong_iss,1,2 --- sample-output-for-solaris-5.7 --- --- sample-output-for-solaris-5.8 --- status,driver,parameter,actual_value,target_value pass,/dev/ip,ip_forward_directed_broadcasts,0,0 pass,/dev/ip,ip_forward_src_routed,0,0 pass,/dev/ip,ip_forwarding,0,0 pass,/dev/ip,ip_ignore_redirect,1,1 pass,/dev/ip,ip_respond_to_address_mask_broadcast,0,0 pass,/dev/ip,ip_respond_to_echo_broadcast,0,0 pass,/dev/ip,ip_respond_to_timestamp,0,0 pass,/dev/ip,ip_respond_to_timestamp_broadcast,0,0 pass,/dev/ip,ip_send_redirects,0,0 pass,/dev/ip,ip_strict_dst_multihoming,1,1 fail,/dev/ip,ip6_forward_src_routed,1,0 pass,/dev/ip,ip6_forwarding,0,0 fail,/dev/ip,ip6_ignore_redirect,0,1 fail,/dev/ip,ip6_respond_to_echo_multicast,1,0 pass,/dev/ip,ip6_send_redirects,0,0 fail,/dev/ip,ip6_strict_dst_multihoming,0,1 fail,/dev/tcp,tcp_conn_req_max_q,256,1024 pass,/dev/tcp,tcp_conn_req_max_q0,4096,4096 fail,/dev/tcp,tcp_ip_abort_cinterval,30000,60000 pass,/dev/tcp,tcp_rev_src_routes,0,0 pass,/dev/tcp,tcp_strong_iss,2,2 --- sample-output-for-solaris-5.8 --- --- sample-output-for-solaris-5.9 --- status,driver,parameter,actual_value,target_value pass,/dev/ip,ip_forward_directed_broadcasts,0,0 pass,/dev/ip,ip_forward_src_routed,0,0 pass,/dev/ip,ip_forwarding,0,0 pass,/dev/ip,ip_ignore_redirect,1,1 pass,/dev/ip,ip_respond_to_address_mask_broadcast,0,0 pass,/dev/ip,ip_respond_to_echo_broadcast,0,0 fail,/dev/ip,ip_respond_to_timestamp,1,0 pass,/dev/ip,ip_respond_to_timestamp_broadcast,0,0 pass,/dev/ip,ip_send_redirects,0,0 fail,/dev/ip,ip_strict_dst_multihoming,0,1 pass,/dev/ip,ip6_forward_src_routed,0,0 pass,/dev/ip,ip6_forwarding,0,0 pass,/dev/ip,ip6_ignore_redirect,1,1 fail,/dev/ip,ip6_respond_to_echo_multicast,1,0 pass,/dev/ip,ip6_send_redirects,0,0 fail,/dev/ip,ip6_strict_dst_multihoming,0,1 fail,/dev/tcp,tcp_conn_req_max_q,128,1024 fail,/dev/tcp,tcp_conn_req_max_q0,1024,4096 fail,/dev/tcp,tcp_ip_abort_cinterval,180000,60000 pass,/dev/tcp,tcp_rev_src_routes,0,0 pass,/dev/tcp,tcp_strong_iss,2,2 --- sample-output-for-solaris-5.9 --- Closing Remarks The reference settings used in check_ndd are derived from information presented in the referenced BluePrints document and the author's personal preferences. Credits This recipe was brought to you by Klayton Monroe. Appendix 1 --- check_ndd --- #!/bin/sh ###################################################################### # # Copyright 2003-2003 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Harvest and check security relevant ndd information. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin PROGRAM=`basename $0` NDDCheckSecurityParameters() { NDD=${1-/usr/sbin/ndd} PROTOCOL=$2 case "${PROTOCOL}" in ip) DRIVER=/dev/ip ip_forward_directed_broadcasts=0 ip_forward_src_routed=0 ip_forwarding=0 ip_ignore_redirect=1 ip_respond_to_address_mask_broadcast=0 ip_respond_to_echo_broadcast=0 ip_respond_to_timestamp=0 ip_respond_to_timestamp_broadcast=0 ip_send_redirects=0 ip_strict_dst_multihoming=1 TARGET_PARAMETERS=" ip_forward_directed_broadcasts ip_forward_src_routed ip_forwarding ip_ignore_redirect ip_respond_to_address_mask_broadcast ip_respond_to_echo_broadcast ip_respond_to_timestamp ip_respond_to_timestamp_broadcast ip_send_redirects ip_strict_dst_multihoming " ;; ip6) DRIVER=/dev/ip ip6_forward_src_routed=0 ip6_forwarding=0 ip6_ignore_redirect=1 ip6_respond_to_echo_multicast=0 ip6_send_redirects=0 ip6_strict_dst_multihoming=1 TARGET_PARAMETERS=" ip6_forward_src_routed ip6_forwarding ip6_ignore_redirect ip6_respond_to_echo_multicast ip6_send_redirects ip6_strict_dst_multihoming " ;; tcp) DRIVER=/dev/tcp tcp_conn_req_max_q=1024 tcp_conn_req_max_q0=4096 tcp_ip_abort_cinterval=60000 tcp_rev_src_routes=0 tcp_strong_iss=2 TARGET_PARAMETERS=" tcp_conn_req_max_q tcp_conn_req_max_q0 tcp_ip_abort_cinterval tcp_rev_src_routes tcp_strong_iss " ;; *) echo "${PROGRAM}: Protocol='${PROTOCOL}' Error='Unsupported protocol.'" 1>&2 ;; esac ACTUAL_PARAMETERS=`${NDD} ${DRIVER} \? | sed 's/(.*)//' | awk '{print $1}' | egrep "^${PROTOCOL}_"` for TARGET_PARAMETER in ${TARGET_PARAMETERS} ; do eval TARGET_VALUE=\$${TARGET_PARAMETER} ; STATUS=indeterminate ; ACTUAL_VALUE="" for ACTUAL_PARAMETER in ${ACTUAL_PARAMETERS} ; do if [ "${ACTUAL_PARAMETER}" = "${TARGET_PARAMETER}" ] ; then ACTUAL_VALUE=`${NDD} ${DRIVER} ${TARGET_PARAMETER} | tr -d "\n"` if [ "${ACTUAL_VALUE}" = "${TARGET_VALUE}" ] ; then STATUS=pass else STATUS=fail fi break fi done echo "${STATUS},${DRIVER},${TARGET_PARAMETER},${ACTUAL_VALUE},${TARGET_VALUE}" done } NDDUsage() { echo 1>&2 echo "Usage: ${PROGRAM} {all|ip4|ip6|tcp}" 1>&2 echo 1>&2 exit 1 } NDDMain() { ARGUMENT=`echo $1 | tr "[A-Z]" "[a-z]"` case "${ARGUMENT}" in all) PROTOCOLS="ip ip6 tcp" ;; ip4) PROTOCOLS="ip" ;; ip6) PROTOCOLS="ip6" ;; tcp) PROTOCOLS="tcp" ;; *) NDDUsage ;; esac if [ ! -x ${NDD=/usr/sbin/ndd} ] ; then echo "${PROGRAM}: Command='${NDD}' Error='Command does not exist or is not executable.'" 1>&2 exit 2 fi HEADER="status,driver,parameter,actual_value,target_value" ; echo ${HEADER} for PROTOCOL in ${PROTOCOLS} ; do NDDCheckSecurityParameters "${NDD}" "${PROTOCOL}" done } NDDMain $* ; exit 0 --- check_ndd ---