class Snitch: # TODO: Support IPv6! def __init__(self, database): self.lock = Lock() self.rules = Rules(database) self.dns = DNSCollector() self.q = NetfilterQueueWrapper(self) self.procmon = ProcMon() self.iptcrules = None self.dbus_service = OpensnitchService(self.q.handlers, self.rules) def start(self): if ProcMon.is_ftrace_available(): self.procmon.enable() self.procmon.start() self.iptcrules = IPTCRules() self.dbus_service.run() def stop(self): self.procmon.disable() self.q.stop() if self.iptcrules is not None: self.iptcrules.remove()
class Snitch: # TODO: Support IPv6! def __init__(self, database): self.lock = Lock() self.rules = Rules(database) self.dns = DNSCollector() self.q = NetfilterQueueWrapper(self) self.procmon = ProcMon() self.qt_app = QtApp(self.q.connection_futures, self.rules) def start(self): if ProcMon.is_ftrace_available(): self.procmon.enable() self.procmon.start() self.qt_app.run() def stop(self): self.procmon.disable()
class Snitch: IPTABLES_RULES = ( # Get DNS responses "INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass", # Get connection packets "OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass", # Reject packets marked by OpenSnitch "OUTPUT --protocol tcp -m mark --mark 101285 -j REJECT") # TODO: Support IPv6! def __init__(self): self.lock = Lock() self.rules = Rules() self.dns = DNSCollector() self.q = NetfilterQueue() self.procmon = ProcMon() self.qt_app = QtApp() self.desktop_parser = LinuxDesktopParser() self.q.bind(0, self.pkt_callback, 1024 * 2) def get_verdict(self, c): verdict = self.rules.get_verdict(c) if verdict is None: with self.lock: c.hostname = self.dns.get_hostname(c.dst_addr) (save_option, verdict, apply_for_all) = self.qt_app.prompt_user(c) if save_option != Rule.ONCE: self.rules.add_rule(c, verdict, apply_for_all, save_option) return verdict def pkt_callback(self, pkt): verd = Rule.ACCEPT try: data = pkt.get_payload() packet = IP(data) if self.dns.is_dns_response(packet): self.dns.add_response(packet) else: conn = Connection(self.procmon, self.desktop_parser, data) if conn.proto is None: logging.debug("Could not detect protocol for packet.") elif conn.pid is None: logging.debug("Could not detect process for connection.") else: verd = self.get_verdict(conn) except Exception as e: logging.exception("Exception on packet callback:") if verd == Rule.DROP: logging.info("Dropping %s from %s" % (conn, conn.get_app_name())) # mark this packet so iptables will drop it pkt.set_mark(101285) pkt.drop() else: pkt.accept() def start(self): for r in Snitch.IPTABLES_RULES: logging.debug("Applying iptables rule '%s'" % r) os.system("iptables -I %s" % r) if ProcMon.is_ftrace_available(): self.procmon.enable() self.procmon.start() self.qt_app.run() self.q.run() def stop(self): for r in Snitch.IPTABLES_RULES: logging.debug("Deleting iptables rule '%s'" % r) os.system("iptables -D %s" % r) self.procmon.disable() self.q.unbind()