Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: evilsocket/opensnitch
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.4.0
Choose a base ref
...
head repository: evilsocket/opensnitch
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.5.0-rc.1
Choose a head ref

Commits on Sep 10, 2021

  1. Copy the full SHA
    9ccb649 View commit details

Commits on Sep 12, 2021

  1. added action reject

    When blocking a connection via libnetfilter-queue using NF_DROP the
    connection is discarded. If the blocked connection is a DNS query, the app
    that initiated it will wait until it times out, which is ~30s.
    
    This behaviour can for example cause slowdowns loading web pages: #481
    
    This change adds the option to reject connections by killing the socket
    that initiated them.
    
    Denying:
        $ time telnet 1.1.1.1 22
        Trying 1.1.1.1...
        telnet: Unable to connect to remote host: Connection timed out
    
        real	2m10,039s
    
    Rejecting:
        $ time telnet 1.1.1.1 22
        Trying 1.1.1.1...
        telnet: Unable to connect to remote host: Software caused connection abort
    
        real	0m0,005s
    gustavo-iniguez-goya committed Sep 12, 2021
    Copy the full SHA
    8d3540f View commit details

Commits on Sep 13, 2021

  1. Copy the full SHA
    c66d5d6 View commit details

Commits on Sep 15, 2021

  1. Copy the full SHA
    0776c1b View commit details
  2. 1
    Copy the full SHA
    35975bc View commit details
  3. Merge pull request #505 from themighty1/patch-1

    github.com/golang/protobuf deprecated
    gustavo-iniguez-goya authored Sep 15, 2021
    Copy the full SHA
    408ce3f View commit details
  4. Merge pull request #506 from themighty1/patch-2

    need to generate go.sum otherwise we get errors
    gustavo-iniguez-goya authored Sep 15, 2021
    Copy the full SHA
    2d26865 View commit details
  5. Copy the full SHA
    500b7c7 View commit details

Commits on Sep 17, 2021

  1. rules: added more lists types to block/allow

    - Added lists of IPs and network ranges. One per line. Blank lines or
      lines that start with # are ignored.
    - Added lists of domains with regular expressions. One per line.
      Blank lines or lines that start with # are ignored.
    
    Until now you could use regular expressions with the fields
    "To this host" or "To this IP", to match multiple domains or IPs.
    But if you wanted to use more than 2-3 domains or IPs it was not really
    user friendly.
    
    Hopefully we'll be a little more versatile to cover use cases like #461
    and #485.
    gustavo-iniguez-goya committed Sep 17, 2021
    Copy the full SHA
    3b6c041 View commit details

Commits on Sep 19, 2021

  1. don't overwrite rules if they already exist.

    Don't overwrite rules when adding or editing rules, to avoid losing
    already added rules.
    
    closes #512
    gustavo-iniguez-goya committed Sep 19, 2021
    Copy the full SHA
    c97a01d View commit details
  2. don't overwrite rules if they already exist (2/2)

    Don't overwrite rules when adding or editing rules, to avoid losing
    already added rules.
    
    - When adding a rule, check if there's already a rule with the same
      name.
    - After adding a new rule, enter into EDIT mode, to allow changes to the
      rule without closing the dialog.
    - If the user changes the name after adding a rule, check if there's a
      rule with the same name.
    - When editing a rule and the user changes the name, check if there's a
      rule with the same name.
    
    issue #512
    gustavo-iniguez-goya committed Sep 19, 2021
    Copy the full SHA
    2c1acdb View commit details

Commits on Sep 22, 2021

  1. Allow to intercept more kernel connections (#513)

    * Allow to intercept some kernel connections
    
    Some connections are initiated from kernel space, like WireGuard
    VPNs (#454), NFS or SMB connections (#502) and ip tunnels (#500).
    
    Note: This feature is complete for x86_64, WIP for aarch64, and not supported for armhf and i386
    #513 (comment)
    
    More information regarding this change: #493
    gustavo-iniguez-goya authored Sep 22, 2021
    Copy the full SHA
    0526b84 View commit details

Commits on Sep 25, 2021

  1. ui: allow to filter connections by PID

    This change allows to filter connections by PID.
    
    Others have referred to this feature as "filter connections for this
    instance/session" or similar, so maybe a better wording is needed.
    Open a new discussion or send a PR if you have a better sentence that
    describe this option please.
    gustavo-iniguez-goya committed Sep 25, 2021
    Copy the full SHA
    4ea0904 View commit details

Commits on Oct 5, 2021

  1. ui, tests: added rules editor tests

    to run them:
    pytest tests/
    
    They dould be integrated with a github action.
    gustavo-iniguez-goya committed Oct 5, 2021
    Copy the full SHA
    ff99b39 View commit details

Commits on Oct 6, 2021

  1. Copy the full SHA
    655f1eb View commit details
  2. Update go.yml

    gustavo-iniguez-goya authored Oct 6, 2021
    Copy the full SHA
    67afb5b View commit details
  3. Copy the full SHA
    eb51840 View commit details
  4. Copy the full SHA
    3af6a11 View commit details
  5. Copy the full SHA
    fd40feb View commit details

Commits on Oct 8, 2021

  1. ui: fixed crash when displaying the GUI

    On Fedora 34, without the appindicator extension installed, when the GUI
    was displayed it crashed with the following error:
    
    TypeError: index 0 has type 'float' but 'int' is expected.
    
    related: #526
    gustavo-iniguez-goya committed Oct 8, 2021
    Copy the full SHA
    9ef64da View commit details

Commits on Oct 19, 2021

  1. Copy the full SHA
    e8dd174 View commit details

Commits on Oct 25, 2021

  1. ui, tests: added Preferences dialog tests

    TODO: test db configuration changes. There're problems clicking on the
    QMessageBox.
    gustavo-iniguez-goya committed Oct 25, 2021
    Copy the full SHA
    c609b09 View commit details

Commits on Oct 28, 2021

  1. ui: fixed GUI loading when DE autologin is on

    Fixed GUI loading behaviour when DE's autologin is on.
    
    Background:
     Sometimes the system tray is not available, so our app's icon
     does not show up. In this case we show the GUI to allow the user
     manage the rules and view connections.
    
    If the user activated the autologin option, on KDE (and probably others)
    our service was launched before the panel was ready, so the system tray was
    not available yet and we were showing the Events window.
    
    Changes:
    - Delay 10s the check to see if the system tray is available, to give it
      time to load.
    - Add X-KDE-Autostart-after=panel to kcm_opensnitch.desktop, to launch
      the GUI only after the panel is loaded.
    - Misc: removed OpenSnitch entry from System Settings on KDE, and update
      the categories where the app is shown in the menus.
    
    Closes #535
    gustavo-iniguez-goya committed Oct 28, 2021
    Copy the full SHA
    9d0c5a1 View commit details

Commits on Nov 4, 2021

  1. set prompt width and height after initial display; set prompt minimum…

    … and maximum size using initial width and height values
    ryanolton committed Nov 4, 2021
    Copy the full SHA
    c3039dd View commit details
  2. Merge pull request #540 from ryanolton/master

    Prompt UI height and width fixes
    gustavo-iniguez-goya authored Nov 4, 2021
    Copy the full SHA
    689c83f View commit details

Commits on Nov 12, 2021

  1. rules: don't load rules that fail to compile

    Be sure that we don't load invalid regexp rules.
    
    related: #536
    gustavo-iniguez-goya committed Nov 12, 2021
    Copy the full SHA
    743ef71 View commit details

Commits on Nov 15, 2021

  1. improved connections parsing

    Under certain conditions, when we dumped inodes via netlink, we were
    linking network connections to wrong applications.
    
    - To improve this situation:
    
    1) Use netfilter's UID by default:
       Sometimes the UID reported via netlink was different than the one
       reported by libnetfilter. libnetfilter UID is always correct.
       If you had a rule that filtered by UID, this problem could cause to
       prompt you again to allow the connection.
    
    2) Use the netlink entry that matches exactly the properties of an
       outgoing connection:
       There're some in-kernel sockets that doesn't match 1:1 outgoing
       connections (daemon/netlink/socket.go#L22).
       In order to identify the applications that initiate these network
       connections we use a workaround. But under certain conditions
       (source port reuse), we were associating connections to wrong
       applications.
       So in order to avoid this problem, if there's a 1:1 match use that
       netlink entry. If not, fallback to the workaround.
    
    - misc: added more logs to better debug these issues.
    gustavo-iniguez-goya committed Nov 15, 2021
    Copy the full SHA
    479b8de View commit details
Showing with 2,060 additions and 598 deletions.
  1. +14 −11 .github/ISSUE_TEMPLATE/bug_report.md
  2. +4 −0 .github/ISSUE_TEMPLATE/config.yml
  3. +15 −0 .github/ISSUE_TEMPLATE/feature-request.md
  4. +2 −0 .github/workflows/go.yml
  5. +1 −0 daemon/Makefile
  6. +5 −5 daemon/conman/connection.go
  7. +1 −1 daemon/core/version.go
  8. +6 −8 daemon/go.mod
  9. +9 −5 daemon/main.go
  10. +32 −5 daemon/netlink/socket.go
  11. +19 −0 daemon/netlink/socket_linux.go
  12. +1 −1 daemon/opensnitch.spec
  13. +12 −0 daemon/procmon/details.go
  14. +24 −16 daemon/procmon/parse.go
  15. +1 −0 daemon/procmon/process.go
  16. +5 −1 daemon/rule/loader.go
  17. +34 −0 daemon/rule/loader_test.go
  18. +93 −16 daemon/rule/operator.go
  19. +96 −14 daemon/rule/operator_lists.go
  20. +17 −0 daemon/rule/operator_test.go
  21. +3 −2 daemon/rule/rule.go
  22. +31 −0 daemon/rule/testdata/invalid-regexp-list.json
  23. +16 −0 daemon/rule/testdata/invalid-regexp.json
  24. +6 −0 debian/changelog
  25. +3 −0 debian/rules
  26. +1 −1 ebpf_prog/README
  27. +63 −1 ebpf_prog/opensnitch.c
  28. +1 −1 proto/Makefile
  29. +6 −0 ui/debian/changelog
  30. 0 ui/i18n/locales/{fr-FR → fr_FR}/opensnitch-fr_FR.ts
  31. +1 −1 ui/i18n/opensnitch_i18n.pro
  32. +2 −2 ui/opensnitch-ui.spec
  33. +1 −0 ui/opensnitch/config.py
  34. +45 −25 ui/opensnitch/database.py
  35. +24 −8 ui/opensnitch/dialogs/prompt.py
  36. +199 −20 ui/opensnitch/dialogs/ruleseditor.py
  37. +11 −5 ui/opensnitch/dialogs/stats.py
  38. +4 −1 ui/opensnitch/nodes.py
  39. +5 −0 ui/opensnitch/res/preferences.ui
  40. +5 −0 ui/opensnitch/res/prompt.ui
  41. +681 −435 ui/opensnitch/res/ruleseditor.ui
  42. +17 −5 ui/opensnitch/res/stats.ui
  43. +12 −2 ui/opensnitch/service.py
  44. +1 −1 ui/opensnitch/version.py
  45. +1 −4 ui/resources/kcm_opensnitch.desktop
  46. +1 −1 ui/resources/opensnitch_ui.desktop
  47. +5 −0 ui/tests/dialogs/__init__.py
  48. +141 −0 ui/tests/dialogs/test_preferences.py
  49. +383 −0 ui/tests/dialogs/test_ruleseditor.py
25 changes: 14 additions & 11 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
---
name: Bug report
name: 🐞 Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

Present yourself (or at least say "Hello" or "Hi") and be kind && respectful.
Please, check the FAQ and Known Problems pages before creating the bug report:
https://github.com/evilsocket/opensnitch/wiki/FAQs
https://github.com/evilsocket/opensnitch/wiki/Known-problems

**Describe the bug**
A clear and concise description of what the bug is.

Include the following information:
- OpenSnitch version.
- OS: [e.g. Debian GNU/Linux, ArchLinux, Slackware, ...]
- Version [e.g. Buster, 10.3, 20.04]
- Window Manager: [e.g. GNOME Shell, KDE, enlightenment, i3wm, ...]
- Kernel version: echo $(uname -a)

**To Reproduce**
Describe in detail as much as you can what happened.

@@ -28,22 +37,16 @@ If it's a crash of the GUI:

If the daemon doesn't start:
- Post last 15 lines of the log file `/var/log/opensnitchd.log`
- Or launch it from a terminal (`/usr/bin/opensnitchd -rules-path /etc/opensnitchd/rules`) and post the errors logged to the terminal.
- Or launch it from a terminal as root (`# /usr/bin/opensnitchd -rules-path /etc/opensnitchd/rules`) and post the errors logged to the terminal.

If the deb or rpm packages fail to install:
- Install them from a terminal (`dpkg -i opensnitch*` / `yum install opensnitch*`), and post the errors logged to stdout.
- Install them from a terminal (`$ sudo dpkg -i opensnitch*` / `$ sudo yum install opensnitch*`), and post the errors logged to stdout.

**Expected behavior (optional)**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**OS (please complete the following information):**
- OS: [e.g. Debian GNU/Linux, ArchLinux, Slackware, ...]
- Window Manager: [e.g. GNOME shell, KDE, enlightenment, ...]
- Kernel version: echo $(uname -a)
- Version [e.g. Buster, 10.3, 20.04]
If applicable, add screenshots to help explain your problem. It may help to understand the issue much better.

**Additional context**
Add any other context about the problem here.
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
contact_links:
- name: 🙋 Question
url: https://github.com/evilsocket/opensnitch/discussions/new
about: Ask your question here
15 changes: 15 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: 💡 Feature request
about: Suggest an idea
title: '[Feature Request] <title>'
labels: feature
assignees: ''

---

<!--
Note: Please, use the search box to see if this feature has already been requested.
-->

### Summary:
<!-- A concise description of the new feature. -->
2 changes: 2 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -22,6 +22,8 @@ jobs:
export GOPATH=~/go
export PATH=$PATH:$GOPATH/bin
go get github.com/golang/protobuf/protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
cd proto
make ../daemon/ui/protocol/ui.pb.go
go get -v -t -d ./...
1 change: 1 addition & 0 deletions daemon/Makefile
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ install:
@systemctl daemon-reload

opensnitchd: $(SRC)
@go get
@go build -o opensnitchd .

clean:
10 changes: 5 additions & 5 deletions daemon/conman/connection.go
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
}

pid := -1
var uid int
uid := -1
if procmon.MethodIsEbpf() {
pid, uid, err = ebpf.GetPid(c.Protocol, c.SrcPort, c.SrcIP, c.DstIP, c.DstPort)
if err != nil {
@@ -118,17 +118,17 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
for n, inode := range inodeList {
pid = procmon.GetPIDFromINode(inode, fmt.Sprint(inode, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort))
if pid != -1 {
log.Debug("[%d] PID found %d", n, pid)
log.Debug("[%d] PID found %d [%d]", n, pid, inode)
c.Entry.INode = inode
break
}
}
}

if uid != -1 {
c.Entry.UserId = uid
} else if c.Entry.UserId == -1 && nfp.UID != 0xffffffff {
if nfp.UID != 0xffffffff {
c.Entry.UserId = int(nfp.UID)
} else {
c.Entry.UserId = uid
}

if pid == os.Getpid() {
2 changes: 1 addition & 1 deletion daemon/core/version.go
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package core
// version related consts
const (
Name = "opensnitch-daemon"
Version = "1.4.0"
Version = "1.5.0rc1"
Author = "Simone 'evilsocket' Margaritelli"
Website = "https://github.com/evilsocket/opensnitch"
)
14 changes: 6 additions & 8 deletions daemon/go.mod
Original file line number Diff line number Diff line change
@@ -5,17 +5,15 @@ go 1.14
require (
github.com/evilsocket/ftrace v1.2.0
github.com/fsnotify/fsnotify v1.4.7
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v1.5.0
github.com/google/gopacket v1.1.14
github.com/google/nftables v0.0.0-20210514154851-a285acebcad3
github.com/iovisor/gobpf v0.2.0
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
golang.org/x/net v0.0.0-20190311183353-d8887717615a
github.com/vishvananda/netlink v0.0.0-20210811191823-e1a867c6b452
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 // indirect
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444 // indirect
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1
golang.org/x/text v0.3.0 // indirect
google.golang.org/grpc v1.27.0
google.golang.org/protobuf v1.26.0
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.26.0 // indirect
)
14 changes: 9 additions & 5 deletions daemon/main.go
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ import (
"github.com/evilsocket/opensnitch/daemon/firewall"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/evilsocket/opensnitch/daemon/netfilter"
"github.com/evilsocket/opensnitch/daemon/netlink"
"github.com/evilsocket/opensnitch/daemon/procmon/monitor"
"github.com/evilsocket/opensnitch/daemon/rule"
"github.com/evilsocket/opensnitch/daemon/statistics"
@@ -295,25 +296,28 @@ func acceptOrDeny(packet *netfilter.Packet, con *conman.Connection) *rule.Rule {
}

}
if packet == nil {
log.Debug("Packet nil after processing rules")
return r
}

if r.Enabled == false {
applyDefaultAction(packet)
ruleName := log.Green(r.Name)
log.Info("DISABLED (%s) %s %s -> %s:%d (%s)", uiClient.DefaultAction(), log.Bold(log.Green("✔")), log.Bold(con.Process.Path), log.Bold(con.To()), con.DstPort, ruleName)

} else if r.Action == rule.Allow {
if packet != nil {
packet.SetVerdictAndMark(netfilter.NF_ACCEPT, packet.Mark)
}
packet.SetVerdictAndMark(netfilter.NF_ACCEPT, packet.Mark)
ruleName := log.Green(r.Name)
if r.Operator.Operand == rule.OpTrue {
ruleName = log.Dim(r.Name)
}
log.Debug("%s %s -> %s:%d (%s)", log.Bold(log.Green("✔")), log.Bold(con.Process.Path), log.Bold(con.To()), con.DstPort, ruleName)
} else {
if packet != nil {
packet.SetVerdict(netfilter.NF_DROP)
if r.Action == rule.Reject {
netlink.KillSocket(con.Protocol, con.SrcIP, con.SrcPort, con.DstIP, con.DstPort)
}
packet.SetVerdict(netfilter.NF_DROP)

log.Debug("%s %s -> %s:%d (%s)", log.Bold(log.Red("✘")), log.Bold(con.Process.Path), log.Bold(con.To()), con.DstPort, log.Red(r.Name))
}
37 changes: 32 additions & 5 deletions daemon/netlink/socket.go
Original file line number Diff line number Diff line change
@@ -44,8 +44,9 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
if sock.UID != 0xffffffff {
uid = int(sock.UID)
}
log.Debug("[%d/%d] outgoing connection: %d:%v -> %v:%d || netlink response: %d:%v -> %v:%d inode: %d - loopback: %v multicast: %v unspecified: %v linklocalunicast: %v ifaceLocalMulticast: %v GlobalUni: %v ",
log.Debug("[%d/%d] outgoing connection uid: %d, %d:%v -> %v:%d || netlink response: %d:%v -> %v:%d inode: %d - loopback: %v multicast: %v unspecified: %v linklocalunicast: %v ifaceLocalMulticast: %v GlobalUni: %v ",
n, len(sockList),
int(sock.UID),
srcPort, srcIP, dstIP, dstPort,
sock.ID.SourcePort, sock.ID.Source,
sock.ID.Destination, sock.ID.DestinationPort, sock.INode,
@@ -62,14 +63,11 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
((sock.ID.Destination.IsGlobalUnicast() || sock.ID.Destination.IsLoopback()) && sock.ID.Destination.Equal(dstIP)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
} else if sock.ID.SourcePort == uint16(srcPort) && sock.ID.Source.Equal(srcIP) &&
(sock.ID.DestinationPort == uint16(dstPort)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
}
log.Debug("GetSocketInfo() invalid: %d:%v -> %v:%d", sock.ID.SourcePort, sock.ID.Source, sock.ID.Destination, sock.ID.DestinationPort)
}

// handle special cases (see function description): ntp queries (123), broadcasts, incomming connections.
if len(inodes) == 0 && len(sockList) > 0 {
for n, sock := range sockList {
if sockList[n].ID.Destination.Equal(net.IPv4zero) || sockList[n].ID.Destination.Equal(net.IPv6zero) {
@@ -79,6 +77,10 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
sockList[n].ID.SourcePort, sockList[n].ID.Source,
sockList[n].ID.Destination, sockList[n].ID.DestinationPort,
sockList[n].INode, TCPStatesMap[sock.State])
} else if sock.ID.SourcePort == uint16(srcPort) && sock.ID.Source.Equal(srcIP) &&
(sock.ID.DestinationPort == uint16(dstPort)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
} else {
log.Debug("netlink socket not found, EXCLUDING entry: %d:%v -> %v:%d || %d:%v -> %v:%d inode: %d state: %s",
srcPort, srcIP, dstIP, dstPort,
@@ -124,3 +126,28 @@ func GetSocketInfoByInode(inodeStr string) (*Socket, error) {
}
return nil, fmt.Errorf("Inode not found")
}

// KillSocket kills a socket given the properties of a connection.
func KillSocket(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPort uint) {
family := uint8(syscall.AF_INET)
ipproto := uint8(syscall.IPPROTO_TCP)
protoLen := len(proto)
if proto[protoLen-1:protoLen] == "6" {
family = syscall.AF_INET6
}

if proto[:3] == "udp" {
ipproto = syscall.IPPROTO_UDP
if protoLen >= 7 && proto[:7] == "udplite" {
ipproto = syscall.IPPROTO_UDPLITE
}
}

if sockList, err := SocketGet(family, ipproto, uint16(srcPort), uint16(dstPort), srcIP, dstIP); err == nil {
for _, s := range sockList {
if err := socketKill(family, ipproto, s.ID); err != nil {
log.Debug("Unable to kill socket:", srcPort, dstPort, err)
}
}
}
}
19 changes: 19 additions & 0 deletions daemon/netlink/socket_linux.go
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ import (
// which adds support for query UDP, UDPLITE and IPv6 sockets to SocketGet()

const (
SOCK_DESTROY = 21
sizeofSocketID = 0x30
sizeofSocketRequest = sizeofSocketID + 0x8
sizeofSocket = sizeofSocketID + 0x18
@@ -186,6 +187,24 @@ func (s *Socket) deserialize(b []byte) error {
return nil
}

// SocketKill kills a connection
func socketKill(family, proto uint8, sockID SocketID) error {

sockReq := &SocketRequest{
Family: family,
Protocol: proto,
ID: sockID,
}

req := nl.NewNetlinkRequest(SOCK_DESTROY, syscall.NLM_F_REQUEST|syscall.NLM_F_ACK)
req.AddData(sockReq)
_, err := req.Execute(syscall.NETLINK_INET_DIAG, 0)
if err != nil {
return err
}
return nil
}

// SocketGet returns the list of active connections in the kernel
// filtered by several fields. Currently it returns connections
// filtered by source port and protocol.
2 changes: 1 addition & 1 deletion daemon/opensnitch.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: opensnitch
Version: 1.4.0
Version: 1.5.0rc1
Release: 1%{?dist}
Summary: OpenSnitch is a GNU/Linux application firewall

12 changes: 12 additions & 0 deletions daemon/procmon/details.go
Original file line number Diff line number Diff line change
@@ -36,6 +36,15 @@ func (p *Process) setCwd(cwd string) {
p.CWD = cwd
}

func (p *Process) readComm() error {
data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/comm", p.ID))
if err != nil {
return err
}
p.Comm = core.Trim(string(data))
return nil
}

func (p *Process) readCwd() error {
link, err := os.Readlink(fmt.Sprintf("/proc/%d/cwd", p.ID))
if err != nil {
@@ -74,6 +83,9 @@ func (p *Process) readPath() error {

func (p *Process) readCmdline() {
if data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", p.ID)); err == nil {
if len(data) == 0 {
return
}
for i, b := range data {
if b == 0x00 {
data[i] = byte(' ')
40 changes: 24 additions & 16 deletions daemon/procmon/parse.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import (
"os"
"time"

"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/evilsocket/opensnitch/daemon/procmon/audit"
)
@@ -86,9 +87,6 @@ func GetPIDFromINode(inode int, inodeKey string) int {
// If it exists in /proc, a new Process{} object is returned with the details
// to identify a process (cmdline, name, environment variables, etc).
func FindProcess(pid int, interceptUnknown bool) *Process {
if interceptUnknown && pid == -100 {
return NewProcess(-100, "Linux kernel")
}
if interceptUnknown && pid < 0 {
return NewProcess(0, "")
}
@@ -115,22 +113,32 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
return proc
}
}

linkName := fmt.Sprint("/proc/", pid, "/exe")
if _, err := os.Lstat(linkName); err != nil {
// if the PID dir doesn't exist, the process may have exited or be a kernel connection
// XXX: can a kernel connection exist without an entry in ProcFS?
if core.Exists(fmt.Sprint("/proc/", pid)) == false {
log.Debug("PID can't be read /proc/", pid)
return nil
}

if link, err := os.Readlink(linkName); err == nil {
proc := NewProcess(pid, link)

proc.readCmdline()
proc.readCwd()
proc.readEnv()
proc.cleanPath()
linkName := fmt.Sprint("/proc/", pid, "/exe")
link, err := os.Readlink(linkName)
proc := NewProcess(pid, link)
proc.readCmdline()
proc.readCwd()
proc.readEnv()
proc.cleanPath()

if len(proc.Args) == 0 {
proc.readComm()
proc.Args = make([]string, 0)
proc.Args = append(proc.Args, proc.Comm)
}

addToActivePidsCache(uint64(pid), proc)
return proc
// If the link to the binary can't be read, the PID may be of a kernel task
if err != nil || proc.Path == "" {
proc.Path = "Kernel connection"
}
return nil

addToActivePidsCache(uint64(pid), proc)
return proc
}
Loading