Merge pull request #1 from evilsocket/master

pull request
This commit is contained in:
Shiva 2017-05-03 15:59:16 +02:00 committed by GitHub
commit 9ad684580c
5 changed files with 42 additions and 12 deletions

View file

@ -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
@ -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

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python2
# This file is part of OpenSnitch.
#
# Copyright(c) 2017 Simone Margaritelli
@ -61,5 +61,3 @@ def main():
snitch.stop()
main()

View file

@ -81,10 +81,11 @@ class ProcMon(threading.Thread):
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

View file

@ -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 ):
@ -87,7 +87,7 @@ class Snitch:
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()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 26 KiB