Skip to content

Commit

Permalink
Merge pull request #1 from evilsocket/master
Browse files Browse the repository at this point in the history
pull request
  • Loading branch information
Shiva authored May 3, 2017
2 parents 748da47 + 9b5d29c commit 9ad6845
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 12 deletions.
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

OpenSnitch is a GNU/Linux port of the Little Snitch application firewall.

<p align="center">
<img src="https://raw.githubusercontent.com/evilsocket/opensnitch/master/screenshot.png" alt="OpenSnitch"/>
</p>

**Warning: This is still alpha quality software, don't rely on it (yet) for your computer security.**

<center>
<img src="https://raw.githubusercontent.com/evilsocket/opensnitch/master/screenshot.png" alt="OpenSnitch"/>
</center>
## Requirements

You'll need a GNU/Linux distribution with `iptables`, `NFQUEUE` and `ftrace` kernel support.

## Install

Expand All @@ -18,6 +22,33 @@ OpenSnitch is a GNU/Linux port of the Little Snitch application firewall.

sudo opensnitch

## Known Issues / Future Improvements

Before opening an issue, keep in mind that the current implementation is just an experiment to see the doability of the project, future improvements of OpenSnitch will include:

Split the project into `opensnitchd`, `opensnitch-ui` and `opensnitch-ruleman`:

* `opensnitchd` will be a C++ daemon, running as root with the main logic. It'll fix [this](https://github.com/evilsocket/opensnitch/issues/28).
* `opensnitch-ui` python (?) UI running as normal user, getting the daemon messages. Will fix [this](https://github.com/evilsocket/opensnitch/issues/20).
* `opensnitch-ruleman` python (?) UI for rule editing.

## How Does It Work

OpenSnitch is an application level firewall, meaning then while running, it will detect and alert the user for every outgoing connection applications he's running are creating. This can be extremely **effective to detect and block unwanted connections** on your system that might be caused by a security breach, **causing data exfiltration to be much harder for an attacker**.
In order to do that, OpenSnitch relies on `NFQUEUE`, an `iptables` target/extension which allows an userland software to intercept IP packets and either `ALLOW` or `DROP` them, once started it'll install the following iptables rules:

OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass

This will use `conntrack` iptables extension to pass all newly created connection packets to NFQUEUE number 0 (the one OpenSnitch is listening on), and then:

INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass

This will also redirect DNS queries to OpenSnitch, allowing the software to perform and IP -> hostname resolution without performing active DNS queries itself.

Once a new connection is detected, the software relies on the `ftrace` kernel extension in order to track which PID (therefore which process) is creating the connection.

If `ftrace` is not available for your kernel, OpenSnitch will fallback using the `/proc` filesystem, even if this method will also work, it's vulnerable to application path manipulation as [described in this issue](https://github.com/evilsocket/opensnitch/issues/12), therefore **it's highly suggested to run OpenSnitch on a ftrace enabled kernel**.

## TODOs

grep -r TODO opensnitch | cut -d '#' -f 2 | sort -u
Expand Down
4 changes: 1 addition & 3 deletions bin/opensnitch
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python2
# This file is part of OpenSnitch.
#
# Copyright(c) 2017 Simone Margaritelli
Expand Down Expand Up @@ -61,5 +61,3 @@ def main():
snitch.stop()

main()


9 changes: 5 additions & 4 deletions opensnitch/procmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ def is_ftrace_available():
return False

def get_app_name( self, pid ):
pid = int(pid)
with self.lock:
if pid in self.pids and 'filename' in self.pids[pid]:
return self.pids[pid]['filename']
if pid is not None:
pid = int(pid)
with self.lock:
if pid in self.pids and 'filename' in self.pids[pid]:
return self.pids[pid]['filename']

return None

Expand Down
4 changes: 2 additions & 2 deletions opensnitch/snitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Snitch:
# 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 1 -j REJECT" )
"OUTPUT --protocol tcp -m mark --mark 101285 -j REJECT" )

# TODO: Support IPv6!
def __init__( self ):
Expand Down Expand Up @@ -87,7 +87,7 @@ def pkt_callback(self,pkt):
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(1)
pkt.set_mark(101285)
pkt.drop()
else:
pkt.accept()
Expand Down
Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9ad6845

Please sign in to comment.