aboutsummaryrefslogtreecommitdiffstats
path: root/src/msec/plugins/network.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/msec/plugins/network.py')
-rw-r--r--src/msec/plugins/network.py198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/msec/plugins/network.py b/src/msec/plugins/network.py
new file mode 100644
index 0000000..8721027
--- /dev/null
+++ b/src/msec/plugins/network.py
@@ -0,0 +1,198 @@
+#!/usr/bin/plugin
+"""Msec plugin for enforcing network security settings"""
+
+# main plugin class name
+PLUGIN = "network"
+
+# configuration
+
+import os
+import re
+import string
+import stat
+import sys
+
+import config
+
+import gettext
+# localization
+try:
+ gettext.install('msec')
+except IOError:
+ _ = str
+
+# list of config files
+
+ATALLOW = '/etc/at.allow'
+AUTOLOGIN = '/etc/sysconfig/autologin'
+BASTILLENOLOGIN = '/etc/bastille-no-login'
+CRON = '/etc/cron.d/msec'
+CRONALLOW = '/etc/cron.allow'
+FSTAB = '/etc/fstab'
+GDM = '/etc/pam.d/gdm'
+GDMCONF = '/etc/X11/gdm/custom.conf'
+HALT = '/usr/bin/halt'
+HOSTCONF = '/etc/host.conf'
+HOSTSDENY = '/etc/hosts.deny'
+INITTAB = '/etc/inittab'
+ISSUE = '/etc/issue'
+ISSUENET = '/etc/issue.net'
+KDE = '/etc/pam.d/kde'
+KDMRC = '/usr/share/config/kdm/kdmrc'
+LILOCONF = '/etc/lilo.conf'
+LOGINDEFS = '/etc/login.defs'
+MENULST = '/boot/grub/menu.lst'
+SHELLCONF = '/etc/security/shell'
+MSECBIN = '/usr/sbin/msec'
+MSECCRON = '/etc/cron.hourly/msec'
+MSEC_XINIT = '/etc/X11/xinit.d/msec'
+OPASSWD = '/etc/security/opasswd'
+PASSWD = '/etc/pam.d/passwd'
+POWEROFF = '/usr/bin/poweroff'
+REBOOT = '/usr/bin/reboot'
+SECURITYSH = '/usr/share/msec/security.sh'
+SERVER = '/etc/security/msec/server'
+SHADOW = '/etc/shadow'
+SHUTDOWN = '/usr/bin/shutdown'
+SHUTDOWNALLOW = '/etc/shutdown.allow'
+SSHDCONFIG = '/etc/ssh/sshd_config'
+STARTX = '/usr/bin/startx'
+SYSCTLCONF = '/etc/sysctl.conf'
+SYSLOGCONF = '/etc/syslog.conf'
+XDM = '/etc/pam.d/xdm'
+XSERVERS = '/etc/X11/xdm/Xservers'
+EXPORT = '/root/.xauth/export'
+
+# regexps
+# X server
+SECURETTY = '/etc/securetty'
+STARTX_REGEXP = '(\s*serverargs=".*) -nolisten tcp(.*")'
+XSERVERS_REGEXP = '(\s*[^#]+/usr/bin/X .*) -nolisten tcp(.*)'
+GDMCONF_REGEXP = '(\s*command=.*/X.*?) -nolisten tcp(.*)$'
+KDMRC_REGEXP = re.compile('(.*?)-nolisten tcp(.*)$')
+# ctrl-alt-del
+CTRALTDEL_REGEXP = '^ca::ctrlaltdel:/sbin/shutdown.*'
+# consolehelper
+CONSOLE_HELPER = 'consolehelper'
+# ssh PermitRootLogin
+PERMIT_ROOT_LOGIN_REGEXP = '^\s*PermitRootLogin\s+(no|yes|without-password|forced-commands-only)'
+# tcp_wrappers
+ALL_REGEXP = '^ALL:ALL:DENY'
+ALL_LOCAL_REGEXP = '^ALL:ALL EXCEPT 127\.0\.0\.1:DENY'
+# sulogin
+SULOGIN_REGEXP = '~~:S:wait:/sbin/sulogin'
+
+def invert(param):
+ """Returns inverse value for param. E.g., yes becomes no, and no becomes yes."""
+ if param == "yes":
+ return "no"
+ else:
+ return "yes"
+class network:
+ def __init__(self, log=None, configfiles=None, root=None):
+ """This plugin is responsible for enforcing network security settings on the machine."""
+ self.log = log
+ self.configfiles = configfiles
+ self.root = root
+
+ # associate helper commands with files
+ self.configfiles.add_config_assoc(INITTAB, '/sbin/telinit q')
+ self.configfiles.add_config_assoc('/etc(?:/rc.d)?/init.d/(.+)', '[ -f /var/lock/subsys/@1 ] && @0 reload')
+ self.configfiles.add_config_assoc(SYSCTLCONF, '/sbin/sysctl -e -p /etc/sysctl.conf')
+ self.configfiles.add_config_assoc(SSHDCONFIG, '[ -f /var/lock/subsys/sshd ] && /etc/rc.d/init.d/sshd restart')
+ self.configfiles.add_config_assoc(LILOCONF, '[ `/usr/sbin/detectloader` = LILO ] && /sbin/lilo')
+ self.configfiles.add_config_assoc(SYSLOGCONF, '[ -f /var/lock/subsys/syslog ] && service syslog reload')
+ self.configfiles.add_config_assoc('^/etc/issue$', '/usr/bin/killall mingetty')
+
+ # security options
+ config.SETTINGS['ACCEPT_BOGUS_ERROR_RESPONSES'] = ("network.accept_bogus_error_responses", ['yes', 'no'])
+ config.SETTINGS['ACCEPT_BROADCASTED_ICMP_ECHO'] = ("network.accept_broadcasted_icmp_echo", ['yes', 'no'])
+ config.SETTINGS['ACCEPT_ICMP_ECHO'] = ("network.accept_icmp_echo", ['yes', 'no'])
+ config.SETTINGS['ALLOW_REMOTE_ROOT_LOGIN'] = ("network.allow_remote_root_login", ['yes', 'no', 'without-password'])
+ config.SETTINGS['ENABLE_DNS_SPOOFING_PROTECTION'] = ("network.enable_dns_spoofing_protection", ['yes', 'no'])
+ config.SETTINGS['ENABLE_IP_SPOOFING_PROTECTION'] = ("network.enable_ip_spoofing_protection", ['yes', 'no'])
+ config.SETTINGS['ENABLE_LOG_STRANGE_PACKETS'] = ("network.enable_log_strange_packets", ['yes', 'no'])
+
+ # network settings
+ for check in ["ACCEPT_BOGUS_ERROR_RESPONSES", "ACCEPT_BROADCASTED_ICMP_ECHO", "ACCEPT_ICMP_ECHO",
+ "ALLOW_REMOTE_ROOT_LOGIN", "ALLOW_X_CONNECTIONS", "ALLOW_XSERVER_TO_LISTEN",
+ "AUTHORIZE_SERVICES", "ENABLE_DNS_SPOOFING_PROTECTION", "ENABLE_IP_SPOOFING_PROTECTION",
+ "ENABLE_LOG_STRANGE_PACKETS"]:
+ config.SETTINGS_NETWORK.append(check)
+
+ def allow_remote_root_login(self, arg):
+ ''' Allow remote root login via sshd. If yes, login is allowed. If without-password, only public-key authentication logins are allowed. See sshd_config(5) man page for more information.'''
+ sshd_config = self.configfiles.get_config_file(SSHDCONFIG)
+
+ if not sshd_config.exists():
+ return
+
+ val = sshd_config.get_match(PERMIT_ROOT_LOGIN_REGEXP, '@1')
+
+ if val != arg:
+ if arg == "yes":
+ self.log.info(_('Allowing remote root login'))
+ sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
+ 'PermitRootLogin yes', 1)
+ elif arg == "no":
+ self.log.info(_('Forbidding remote root login'))
+ sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
+ 'PermitRootLogin no', 1)
+ elif arg == "without-password":
+ self.log.info(_('Allowing remote root login only by passphrase'))
+ sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
+ 'PermitRootLogin without-password', 1)
+
+ def set_zero_one_variable(self, file, variable, value, one_msg, zero_msg):
+ ''' Helper function for enable_ip_spoofing_protection, accept_icmp_echo, accept_broadcasted_icmp_echo,
+ # accept_bogus_error_responses and enable_log_strange_packets.'''
+ f = self.configfiles.get_config_file(file)
+ curvalue = f.get_shell_variable(variable)
+ if value == "yes":
+ value = "1"
+ else:
+ value = "0"
+ if value != curvalue:
+ if value == "1":
+ self.log.info(one_msg)
+ f.set_shell_variable(variable, 1)
+ else:
+ self.log.info(zero_msg)
+ f.set_shell_variable(variable, 0)
+
+ def enable_ip_spoofing_protection(self, arg, alert=1):
+ ''' Enable IP spoofing protection.'''
+ self.set_zero_one_variable(SYSCTLCONF, 'net.ipv4.conf.all.rp_filter', arg, 'Enabling ip spoofing protection', 'Disabling ip spoofing protection')
+
+ def enable_dns_spoofing_protection(self, arg, alert=1):
+ ''' Enable name resolution spoofing protection.'''
+ hostconf = self.configfiles.get_config_file(HOSTCONF)
+
+ val = hostconf.get_match('nospoof\s+on')
+
+ if arg:
+ if not val:
+ self.log.info(_('Enabling name resolution spoofing protection'))
+ hostconf.replace_line_matching('nospoof', 'nospoof on', 1)
+ hostconf.replace_line_matching('spoofalert', 'spoofalert on', (alert != 0))
+ else:
+ if val:
+ self.log.info(_('Disabling name resolution spoofing protection'))
+ hostconf.remove_line_matching('nospoof')
+ hostconf.remove_line_matching('spoofalert')
+
+ def accept_icmp_echo(self, arg):
+ ''' Accept ICMP echo.'''
+ self.set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_echo_ignore_all', invert(arg), 'Ignoring icmp echo', 'Accepting icmp echo')
+
+ def accept_broadcasted_icmp_echo(self, arg):
+ ''' Accept broadcasted ICMP echo.'''
+ self.set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_echo_ignore_broadcasts', invert(arg), 'Ignoring broadcasted icmp echo', 'Accepting broadcasted icmp echo')
+
+ def accept_bogus_error_responses(self, arg):
+ ''' Accept bogus IPv4 error messages.'''
+ self.set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_ignore_bogus_error_responses', invert(arg), 'Ignoring bogus icmp error responses', 'Accepting bogus icmp error responses')
+
+ def enable_log_strange_packets(self, arg):
+ ''' Enable logging of strange network packets.'''
+ self.set_zero_one_variable(SYSCTLCONF, 'net.ipv4.conf.all.log_martians', arg, 'Enabling logging of strange packets', 'Disabling logging of strange packets')