Skip to content

Commit

Permalink
iptables simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkst-az committed Oct 17, 2024
1 parent 4e22bb5 commit c9f38fb
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 46 deletions.
4 changes: 1 addition & 3 deletions bin/opencanary.tac
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import sys
from twisted.application import service
from pkg_resources import iter_entry_points

from opencanary.config import config, is_docker, detectIPTables
from opencanary.config import config, is_docker
from opencanary.logger import getLogger
from opencanary.modules.http import CanaryHTTP
from opencanary.modules.https import CanaryHTTPS
Expand Down Expand Up @@ -84,8 +84,6 @@ if sys.platform.startswith("linux"):
if config.moduleEnabled("portscan") and is_docker():
# Remove portscan if running in DOCKER (specified in Dockerfile)
print("Can't use portscan in Docker. Portscan module disabled.")
elif config.moduleEnabled("portscan") and not detectIPTables():
print("Can't use portscan without iptables. Please install iptables.")
else:
from opencanary.modules.portscan import CanaryPortscan

Expand Down
1 change: 0 additions & 1 deletion docs/starting/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ For this configuration, you will need to set up your own Windows File Share. Ple

`portscan` - a log watcher that works with iptables to monitor when your Opencanary is being scanned.
At this stage, the portscan module supports the detection of Nmap OS, Nmap FIN, Nmap OS, Nmap NULL, and normal port scans.
`portscan.iptables_path` is available for you to specify the path to your `iptables` binary.

Logger Configuration
--------------------
Expand Down
16 changes: 0 additions & 16 deletions opencanary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
import os
import shutil
import subprocess

__version__ = "0.9.5"

STDPATH = os.pathsep.join(["/usr/bin", "/bin", "/usr/sbin", "/sbin"])


def safe_exec(binary_name: str, args: list) -> bytes:
"""
Executes the given binary with the given arguments as a subprocess. What makes this safe is that the binary name
is not executed as an alias, and only binaries that live in trusted system locations are executed. This means that
only system-wide binaries are executable.
"""
exec_path = shutil.which(binary_name, path=STDPATH)
if exec_path is None:
raise Exception(f"Could not find executable ${binary_name} in ${STDPATH}")

args.insert(0, exec_path)
return subprocess.check_output(args)
9 changes: 0 additions & 9 deletions opencanary/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from os.path import expanduser
from pkg_resources import resource_filename
from pathlib import Path
from . import safe_exec

SAMPLE_SETTINGS = resource_filename(__name__, "data/settings.json")
SETTINGS = "opencanary.conf"
Expand Down Expand Up @@ -36,13 +35,6 @@ def is_docker():
)


def detectIPTables():
if shutil.which("iptables"):
return True
else:
return False


SERVICE_REGEXES = {
"ssh.version": r"(SSH-(2.0|1.5|1.99|1.0)-([!-,\-./0-~]+(:?$|\s))(?:[ -~]*)){1,253}$",
}
Expand Down Expand Up @@ -77,7 +69,6 @@ def __init__(self, configfile=SETTINGS):
print("[-] Failed to open %s for reading (%s)" % (fname, e))
except ValueError as e:
print("[-] Failed to decode json from %s (%s)" % (fname, e))
safe_exec("cp", ["-r", fname, "/var/tmp/config-err-$(date +%%s)"])
except Exception as e:
print("[-] An error occurred loading %s (%s)" % (fname, e))
if self.__config is None:
Expand Down
27 changes: 10 additions & 17 deletions opencanary/modules/portscan.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from opencanary.modules import CanaryService
from opencanary.modules import FileSystemWatcher
from opencanary import safe_exec
from opencanary import STDPATH
import os
import subprocess
import shutil


Expand Down Expand Up @@ -66,11 +67,6 @@ def handleLines(self, lines=None): # noqa: C901

self.logger.log(data)


def detectNFTables():
return b"nf_tables" in safe_exec("iptables", ["--version"])


class CanaryPortscan(CanaryService):
NAME = "portscan"

Expand All @@ -85,18 +81,8 @@ def __init__(self, config=None, logger=None):
"portscan.ignore_localhost", default=False
)
self.ignore_ports = config.getVal("portscan.ignore_ports", default=[])
self.iptables_path = self.config.getVal("portscan.iptables_path", False)
self.config = config

def getIptablesPath(self):
if self.iptables_path:
return self.iptables_path

if detectNFTables():
return shutil.which("iptables-legacy")

return shutil.which("iptables") or "/sbin/iptables"

def startYourEngines(self, reactor=None):
# Logging rules for loopback interface.
# This is separate from the canaryfw rule as the canary watchdog was
Expand All @@ -117,7 +103,14 @@ def configUpdated(
pass

def set_iptables_rules(self):
iptables_path = self.getIptablesPath()
iptables_path = shutil.which("iptables-legacy", STDPATH) or shutil.which("iptables", STDPATH)

if not iptables_path:
raise Exception("Portscan module failed to start as iptables cannot be found. Please install iptables.")

if b"nf_tables" in subprocess.check_output([iptables_path, "--version"]):
raise Exception("Portscan module failed to start as iptables-legacy cannot be found. Please install iptables-legacy")

os.system(
'sudo {0} -t mangle -D PREROUTING -p tcp -i lo -j LOG --log-level=warning --log-prefix="canaryfw: " -m limit --limit="{1}/hour"'.format(
iptables_path, self.lorate
Expand Down

0 comments on commit c9f38fb

Please sign in to comment.