1 """
2 @copyright: 2011 Mark LaPerriere
3
4 @license:
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 U{http://www.apache.org/licenses/LICENSE-2.0}
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 @summary:
18 A network auditing plugin that should work with most Redhat-like distros
19
20 @author: Mark LaPerriere
21 @contact: pyhai@mindmind.com
22 @organization: Mind Squared Design / www.mindmind.com
23 @version: 0.1.3
24 @date: Jan 19, 2012
25 """
26 from pyhai.plugins import AuditorPlugin
27 from subprocess import Popen, PIPE
28 import os
29 import shlex
30 import platform
31 import logging
32
33
34 _logger = logging.getLogger(__name__)
35 _logger.addHandler(logging.NullHandler())
36
37
39
40 - def run(self, *args, **kwargs):
41 network_info = {}
42
43 ifconfig_cmd = '/bin/env ifconfig -a'
44 ifconfig_out = Popen(shlex.split(ifconfig_cmd), stdout=PIPE).stdout.read().splitlines()
45 _logger.debug('ifconfig command results [%s]: %s', ifconfig_cmd, ifconfig_out)
46
47 line_no = 0
48 found_break = False
49 nic = None
50 for line in ifconfig_out:
51
52 stripped_row = line.strip()
53 if stripped_row == '':
54 found_break = True
55 continue
56
57 row = stripped_row.split()
58
59 if line_no == 0 or found_break:
60 if found_break: found_break = False
61
62 nic = row[0]
63
64 if nic == 'lo':
65 nic = None
66 continue
67
68 if nic not in network_info:
69 network_info[nic] = {}
70
71 network_info[nic]['name'] = nic
72 network_info[nic]['label'] = nic
73 network_info[nic]['device_id'] = nic
74 network_info[nic]['mac_address'] = row[4]
75
76 if nic is not None:
77 if row[0] == 'inet' and row[1].startswith('addr:'):
78 network_info[nic]['ip_address'] = row[1].split(':', 1)[1]
79 network_info[nic]['subnet_mask'] = row[3].split(':', 1)[1]
80
81 line_no += 1
82
83
84 try:
85 distribution = platform.linux_distribution()[0]
86 except:
87 _logger.exception('Could not determine distribution.')
88 return network_info
89
90 dns_servers = []
91 redhat_servers = ('CentOS Linux', 'Red Hat Enterprise Linux Server')
92 if distribution in redhat_servers:
93 dns_servers = self._redhat_dns_servers()
94
95 for nic in network_info.keys():
96
97 if distribution in redhat_servers:
98 dhcp_enabled, dhcp_server = self._redhat_dhcp(nic)
99 network_info[nic]['dhcp_enabled'] = dhcp_enabled
100 network_info[nic]['dhcp_server'] = dhcp_server
101
102 network_info[nic]['default_gateway'] = self._redhat_default_gateway()
103 network_info[nic]['dns_servers'] = dns_servers
104 network_info[nic]['speed'] = self._redhat_speed(nic)
105 network_info[nic]['name'] = self._redhat_nic_name(nic)
106
107 return network_info
108
110 dhcp_enabled = False
111 dhcp_servers = []
112 dhcp_lease_report = '/var/lib/dhclient/dhclient-%s.leases' % nic
113 if os.path.exists(dhcp_lease_report):
114 with open(dhcp_lease_report) as fp:
115 for line in fp.read().splitlines():
116 row = line.strip().split()
117 if len(row) >= 3:
118 if row[1] == 'dhcp-server-identifier' and row[2] not in dhcp_servers:
119 dhcp_servers.append(row[2])
120
121 if dhcp_servers >= 1:
122 dhcp_enabled = True
123 return (dhcp_enabled, dhcp_servers)
124
126 route_cmd = 'route -n'
127 route_out = Popen(shlex.split(route_cmd), stdout=PIPE).stdout.read().splitlines()
128 _logger.debug('route comand output [%s]: %s', route_cmd, route_out)
129
130 for line in route_out:
131 row = line.strip().split()
132 if row[3] in ('UG', 'G'):
133 return [row[1], ]
134
135 return []
136
137
139 dns_servers = []
140 with open('/etc/resolv.conf') as fp:
141 for line in fp.read().splitlines():
142 row = line.strip().split()
143 if row[0] == 'nameserver':
144 if row[1] not in dns_servers:
145 dns_servers.append(row[1])
146 return dns_servers
147
149 with open('/var/log/dmesg') as fp:
150 for line in fp.read().splitlines():
151 row = map(lambda s: s.strip(':'), line.strip().split())
152 if len(row) <= 1:
153 continue
154 if row[0] == nic or row[0] == nic:
155 return row[1]
156 elif row[1] == nic or row[1] == nic:
157 return row[2]
158 return None
159
161 ethtool_cmd = 'ethtool %s' % nic
162 ethtool_out = Popen(shlex.split(ethtool_cmd), stdout=PIPE).stdout.read().splitlines()
163 _logger.debug('ethtool command output [%s]: %s', ethtool_cmd, ethtool_out)
164
165 for line in ethtool_out:
166 row = map(lambda s: s.strip(':'), line.strip().split())
167 if len(row) >= 2:
168 if row[0] == 'Speed':
169 if row[1].endswith('Mb/s'):
170
171 return str(int(row[1].replace('Mb/s', '')) * 1000 * 1000)
172 else:
173 return row[1]
174 return None
175