nfsinkhole¶
nfsinkhole is a Python package for setting up a Unix server as a sinkhole (all protocols/ports to a secondary interface).
nfsinkhole¶
Warning
This version is considered experimental. Do not attempt to use this library in production until tests via travis and docker are setup, stable, and sufficiently covered.
Attention
You are responsible for rotating log files (/var/log/nfsinkhole*), and syslog forwarding must be configured manually (automation pending).
nfsinkhole is a Python library and scripts for setting up a Unix server as a sinkhole (monitor, log/capture, and drop all traffic to a secondary interface).
The default setup arguments monitor/capture all traffic. Setup arguments are provided to configure protocols, ports, rate limiting, logging, source IP/CIDR exclusions from logging, and optional packet capture.
All sinkhole events are written to /var/log/nfsinkhole-events.log. Optionally, you can enable tcpdump to output packet capture text to /var/log/nfsinkhole-pcap.log if your version of tcpdump supports packet printing; otherwise reverts to /var/log/nfsinkhole.pcap.
Features¶
- Simple install script
- Installs as a init.d/systemctl service
- Service modifies iptables on start/stop, no need to persist iptables
- rsyslog and syslog-ng (pending) supported
- RedHat/CentOS 6/7 tested
- Python 2.6+ and 3.0+ supported
- Built-in support for dealing with SELinux/AppArmor
- Packet capture of sinkhole traffic (printed output to log for tcpdump v4.5+)
- Useful set of utilities
- Detailed logging to /var/log/nfsinkhole-*
- Syslog forwarding configuration (pending)
- BSD license
Planned Improvements¶
- API/class documentation
- syslog-ng support (currently partially built; unused)
- Tests via travis-ci/docker
- Coverage via coverage.io
- Exception handling overhaul
- Set logging level (currently debug)
- BIND/Microsoft/etc DNS server configuration documentation/examples
- Monitoring use case examples
- Automatic configuration for syslog forwarding
- SIEM parsers/apps/plugins
- Official support/testing for more OS environments
- Support handling exceptions for HIPS and other endpoint security products
- Intelligent handling/handshakes (inspired by iptrap - https://github.com/jedisct1/iptrap)
Dependencies¶
OS:
iptables (likely already included in base OS)
tcpdump (optional - likely already included in base OS)
Python 2.6:
argparse
Python 2.7, 3.0+:
None!
Installing¶
Attention
The nfsinkhole service, iptables rules, and tcpdump must run as root. You can still use user/virtualenv Python environments, for the library, but ultimately, the core sinkhole will be run as root.
Note
Replace any below occurence of <INTERFACE> with the name of your sinkhole network interface name.
Base OS (pip) – RECOMMENDED¶
If pip is not installed, you will first need to add the EPEL repo and install:
sudo yum install epel-release
sudo yum install python-pip
RHEL/CentOS 6/7¶
Basic:
pip install --user --upgrade nfsinkhole
python ~/.local/bin/nfsinkhole-setup.py --interface <INTERFACE> --install --pcap
virtualenv:
pip install virtualenv
virtualenv nfsinkhole
source nfsinkhole/bin/activate
nfsinkhole/bin/pip install nfsinkhole
nfsinkhole/bin/python nfsinkhole/bin/nfsinkhole-setup.py --interface <INTERFACE> --install --pcap
Base OS (no pip)¶
RHEL/CentOS 6¶
GitHub - Stable:
wget -O argparse.tar.gz https://github.com/ThomasWaldmann/argparse/tarball/master
tar -C argparse -zxvf argparse.tar.gz
cd argparse
python setup.py install --user prefix=
cd ..
rm -Rf argparse
wget -O nfsinkhole.tar.gz https://github.com/secynic/nfsinkhole/tarball/master
tar -C nfsinkhole -zxvf nfsinkhole.tar.gz
cd nfsinkhole
python setup.py install --user prefix=
cd ..
rm -Rf nfsinkhole
python ~/.local/bin/nfsinkhole-setup.py --interface <INTERFACE> --install --pcap
RHEL/CentOS 7¶
GitHub - Stable:
wget -O nfsinkhole.tar.gz https://github.com/secynic/nfsinkhole/tarball/master
tar -C nfsinkhole -zxvf nfsinkhole.tar.gz
cd nfsinkhole
python setup.py install --user prefix=
cd ..
rm -Rf nfsinkhole
python ~/.local/bin/nfsinkhole-setup.py --interface <INTERFACE> --install --pcap
Service¶
Once installed you need to start the nfsinkhole service.
RHEL/CentOS 6¶
sudo service nfsinkhole start
RHEL/CentOS 7¶
sudo systemctl start nfsinkhole.service
Contributing¶
Issue submission¶
Follow the guidelines detailed in the appropriate section below. As a general rule of thumb, provide as much information as possible when submitting issues.
Bug reports¶
Title should be a short, descriptive summary of the bug
Include the OS, Python, and nfsinkhole versions affected
Provide a context (with code example) in the description of your issue. What are you attempting to do?
Include the full obfuscated output. Make sure to set DEBUG logging:
import logging LOG_FORMAT = ('[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)s] ' '[%(funcName)s()] %(message)s') logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
Include sources of information with links or screenshots
Do you have a suggestion on how to fix the bug?
Feature Requests¶
- Title should be a short, descriptive summary of the feature requested
- Provide use case examples
- Include sources of information with links or screenshots
- Do you have a suggestion on how to implement the feature?
Testing¶
Testing code and infrastructure is in progress.
Questions¶
I am happy to answer any questions and provide assistance where possible. Please be clear and concise. Provide examples when possible. Check the nfsinkhole documentation and the issue tracker before asking a question.
Pull Requests¶
What to include¶
Aside from the core code changes, it is helpful to provide the following (where applicable):
- Unit tests
- Examples
- Sphinx configuration changes in /docs
- Requirements (python2.6.txt, etc)
Guidelines¶
- Title should be a short, descriptive summary of the changes
- Follow PEP 8 where possible.
- Follow the Google docstring style guide for comments
- Must be compatible with Python 2.6, 2.7, and 3+
- Must not break OS compatibility for RHEL 6/7, CentOS 6/7
- Break out reusable code to functions
- Make your code easy to read and comment where necessary
- Reference the GitHub issue number in the description (e.g., Issue #01)
- When running nosetests, make sure to follow Testing
License¶
Copyright (c) 2016 Philip Hane All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
apparmor¶
TODO
iptables¶
TODO
rsyslog¶
TODO
selinux¶
TODO
service¶
TODO
syslog-ng¶
TODO
tcpdump¶
TODO
utils¶
TODO
Library Structure¶
-
class
nfsinkhole.apparmor.
AppArmor
[source]¶ The class for managing apparmor policy enforcement, if it is installed.
-
exception
nfsinkhole.exceptions.
BinaryNotFound
[source]¶ An Exception for when a binary is not detected.
-
exception
nfsinkhole.exceptions.
IPTablesError
[source]¶ An Exception for when a iptables process generates stderr output.
-
exception
nfsinkhole.exceptions.
IPTablesExists
[source]¶ An Exception for when iptables rules, related to nfsinkhole, exist.
-
exception
nfsinkhole.exceptions.
IPTablesNotExists
[source]¶ An Exception for when iptables rules, related to nfsinkhole, don’t exist.
-
exception
nfsinkhole.exceptions.
SubprocessError
[source]¶ An Exception for when a generic subprocess generates stderr output.
-
class
nfsinkhole.iptables.
IPTablesSinkhole
(interface=None, interface_addr=None, log_prefix='"[nfsinkhole] "', protocol='all', dport='0:65535', hashlimit='1/h', hashlimitmode='srcip, dstip, dstport', hashlimitburst='1', hashlimitexpire='3600000', srcexclude='127.0.0.1')[source]¶ The class for managing sinkhole configuration within iptables.
Parameters: - interface – The secondary network interface dedicated to sinkhole traffic. Warning: Do not accidentally set this to your primary interface. It will drop all traffic, and kill your remote access.
- interface_addr – The IP address assigned to interface.
- log_prefix – Prefix for syslog messages.
- protocol – The protocol(s) to log (all traffic will still be dropped). Accepts a comma separated string of protocols (tcp,udp,udplite,icmp,esp,ah,sctp) or all.
- dport – The destination port(s) to log (for applicable protocols). Range should be in the format startport:endport or 0,1,2,3,n..
- hashlimit – Set the hashlimit rate. Hashlimit is used to tune the amount of events logged. See the iptables-extensions docs: http://ipset.netfilter.org/iptables-extensions.man.html
- hashlimitmode – Set the hashlimit mode, a comma separated string of options (srcip,srcport,dstip,dstport). More options here results in more logs generated.
- hashlimitburst – Maximum initial number of packets to match.
- hashlimitexpire – Number of milliseconds to keep entries in the hash table.
- srcexclude – Exclude a comma separated string of source IPs/CIDRs from logging.
-
list_existing_rules
(filter_io_drop=False)[source]¶ The function for retrieving current iptables rules related to nfsinkhole.
Parameters: filter_io_drop – Boolean for only showing the DROP rules for INPUT and OUTPUT. These are not shown by default. This exists to avoid allowing packets on the interface if the service is down. If installed, the interface always drops all traffic regardless of the service state. Returns: Matching sinkhole lines returned by iptables -S. Return type: List Raises: IPTablesError
– A Unix process had an error (stderr).
-
class
nfsinkhole.rsyslog.
RSyslog
(is_systemd=False)[source]¶ The class for managing rsyslog checks and configuration.
Parameters: is_systemd – True if systemd is in use, False if not (use init.d). -
create_config
(prefix='[nfsinkhole] ')[source]¶ The function for creating the rsyslog config.
Parameters: prefix – The log prefix set in iptables.
-
-
class
nfsinkhole.service.
SystemService
(interface=None, interface_addr=None, log_prefix='"[nfsinkhole] "', protocol='all', dport='0:65535', hashlimit='1/h', hashlimitmode='srcip, dstip, dstport', hashlimitburst='1', hashlimitexpire='3600000', srcexclude='127.0.0.1', pcap=True)[source]¶ The class for managing the nfsinkhole init.d/systemd service.
Parameters: - interface – The secondary network interface dedicated to sinkhole traffic. Warning: Do not accidentally set this to your primary interface. It will drop all traffic, and kill your remote access.
- interface_addr – The IP address assigned to interface.
- log_prefix – Prefix for syslog messages.
- protocol – The protocol(s) to log (all traffic will still be dropped). Accepts a comma separated string of protocols (tcp,udp,udplite,icmp,esp,ah,sctp) or all.
- dport – The destination port(s) to log (for applicable protocols). Range should be in the format startport:endport or 0,1,2,3,n..
- hashlimit – Set the hashlimit rate. Hashlimit is used to tune the amount of events logged. See the iptables-extensions docs: http://ipset.netfilter.org/iptables-extensions.man.html
- hashlimitmode – Set the hashlimit mode, a comma separated string of options (srcip,srcport,dstip,dstport). More options here results in more logs generated.
- hashlimitburst – Maximum initial number of packets to match.
- hashlimitexpire – Number of milliseconds to keep entries in the hash table.
- srcexclude – Exclude a comma separated string of source IPs/CIDRs from logging.
- pcap – Enable packet capture text or raw depending on tcpdump version.’
-
class
nfsinkhole.syslog_ng.
SyslogNG
(is_systemd=False)[source]¶ The class for managing syslog-ng checks and configuration.
Parameters: is_systemd – True if systemd is in use, False if not (init.d). -
create_config
(prefix='[nfsinkhole] ')[source]¶ The function for creating the syslog-ng config. (incomplete/unused)
Parameters: prefix – The log prefix set in iptables.
-
-
class
nfsinkhole.tcpdump.
TCPDump
(sbin='/usr/sbin/tcpdump')[source]¶ The class for managing tcpdump checks.
Parameters: sbin – Path to tcpdump binary
-
nfsinkhole.utils.
get_default_interface
()[source]¶ The function for getting the default Unix network interface address.
Returns: The network interface name, or None. Return type: String
-
nfsinkhole.utils.
get_interface_addr
(interface=None)[source]¶ The function for automatically determining a Unix network interface address.
Parameters: interface – The network interface name. Returns: The IP address for the interface, or None. Return type: String
-
nfsinkhole.utils.
popen_wrapper
(cmd_arr=None, raise_err=False, log_stdout_line=True)[source]¶ The function for subprocess with custom logging output.
Parameters: - cmd_arr – Array of command strings to pass to subprocess.Popen().
- raise_err – If stderr is encountered, raise SubprocessError.
- log_stdout_line – If True, logs each stdout line as a separate log entry. If False, logs all of stdout in a single log entry.
Returns: stdout, stderr of the completed subprocess.
Return type: Tuple
Raises: ValueError
– cmd_arr argument is not provided or is None.TypeError
– cmd_arr argument is not a list.SubprocessError
– The subprocess encountered an error (stderr). raise_err must be True for this.
-
nfsinkhole.utils.
set_system_timezone
(timezone='UTC')[source]¶ The function for setting the system timezone.
Parameters: timezone – The timezone to set, see /usr/share/zoneinfo/* for options. Raises: SubprocessError
– One of the processes associated with manual timezone configuration encountered an error.