- Obtain the process's parent hierarchy.
- Display the hierarchy on the pop-ups and the process dialog.
- [pop-ups] Added a Detailed view with all the metadata of the
process.
- [cache-events] Improved the cache of processes.
- [ruleseditor] Fixed enabling md5 checksum widget.
Related: #413, #406
Now you can create rules to filter processes by checksum. Only md5 is
available at the moment.
There's a global configuration option that you can use to enable or
disable this feature, from the config file or from the Preferences
dialog.
As part of this feature there have been more changes:
- New proc monitor method (PROCESS CONNECTOR) that listens for
exec/exit events from the kernel.
This feature depends on CONFIG_PROC_EVENTS kernel option.
- Only one cache of active processes for ebpf and proc monitor
methods.
More info and details: #413.
For the eBPF monitoring method, we listed and stored local addresses
every second, so that we could later check if the source IP of an
outbound connection was local or not, because sometimes we received
outbound connections like:
443:1.1.1.1 -> 192.168.1.123:12345
This could have been alread solved on this change e090833, so maybe
we no longer need this code.
- Now we subscribe to local addresses events, to receive add/remove
events asynchronously, without having to list local addrs
every second, alliviating CPU usage.
- Fixed creating context object to cancel subroutines. It was not
working properly when switching between proc monitor methods.
When using proc monitor method + interceptUnknown, allow to ask the user
about connections not associated with a process. Usually they're safe to
discard, but on some special cases it helps not disrupt some services.
Block of code to find connections via netstat moved to procmon/
- Fixed firewall dialog label alignment.
- Fixed potential race condition when stopping the daemon, and there're
connections being enqueued.
- Added "clear" button to GUI's filter line (#786)
- Create ebpf cache object only if the modules have been loaded.
- Set default stats workers to the sme amount defined in configuration.
Closes#785
Under certain situations, like when using systemd-resolved as DNS
resolver, we receive outbound connections with the fields swapped:
Instead of: local-port:local-ip -> public-ip:public-port
we receive: public-port:public-ip -> local-ip:local-port
Sometimes this behaviour causes network slowdowns, or no network at all.
If we swap the fields of these connections, then we're able to get the
process and keep functioning as usual. But what causes this behaviour is
yet unknown, and needs further analysis.
See these issues for more information: #779 , #711
In order to detect short-lived processes we intercept new processes
executions as they happen, and cache them for later use.
When a new connection is established, then we check if the PID of the
connection is cached, and use the details of the process to ask the user
to allow or deny it.
However, there're some situations where the path or cmdline of a PID,
doesn't correspond with the one that's establishing the connection.
Given the same PID:
- Sometimes we receive from the tracepoint a wrong/non-existent path.
- Other times we receive a "helper" which is the one executing the
real binary that opens the connection.
For these reasons now when a new connection is established, we read the
path to the binary from proc. If the PID is cached and the cached path
differs, then we'll use the path from proc.
We lose a bit of performance, but hopefully we'll be more consistent
with what the user expect, while at the same time keeping intercepting
short-lived processes.
Downsides: for execveat() executions we won't display the original binary.
Closes#771
Whenever a process exits, we delete the corresponding entry from
cache.
But when a process executes a new process (sh -c ls), we receive an
exit event for the parent, while the child continues working with *the
same PID*. Sometimes we don't receive exit events for the child, so the
entry was never removed from cache.
We should properly detect the exits, but forthe time being, delete
expired processes from cache every minute.
Up until now we loaded the eBPF modules from /etc/opensnitchd.
However there has been some problems upgrading the modules to newer
versions with the deb packages, because every file under /etc/ is
treated as a conffile, and whenever a conffile changes it prompt you to
update it or not. Some users decided to no upgrade it, ending up with
eBPF modules incompatible with the new daemon.
https://www.debian.org/doc/manuals/maint-guide/dother.en.html#conffiles
On the other hand, the FHS dictates that /etc/ is for configuration
files, and /usr/lib for object files:
"/usr/lib includes object files and libraries. [21] On some systems,
it may also include internal binaries that are not intended to be
executed directly by users or shell scripts."
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s06.html
So now, we look for the eBPF modules under /usr/local/lib/opensnitchd/ebpf/
or /usr/lib/opensnitchd/ebpf/, and as a last resort under
/etc/opensnitchd/
Up until now some error and warning messages were only logged out to the
system, not allowing the user know what was happening under the hood.
Now the following events are notified:
- eBPF related errors.
- netfilter queue errors.
- configuration errors.
WIP, we'll keep improving it and build new features on top of this one.
- Get cmdline arguments from kernel along with the absolute path to the
binary.
If the cmdline has more than 20 arguments, or one of the arguments is
longer than 256 bytes, get it from ProcFS.
- Improved stopping ebpf monitor method.
Improved process detections by monitoring new processes execution.
It allow us to know the path of a process before a socket is opened.
Closes#617
Other improvements:
- If we fail to retrieve the path of a process, then we'll use the comm
name of the connection/process.
- Better kernel connections detection.
- If debugfs is not loaded, we'll try to mount it, to allow to use
eBPF monitor method.
Future work (help wanted):
- Extract command line arguments from the kernel (sys_execve, or mm
struct).
- Monitor other functions (execveat, clone*, fork, etc).
- Send these events to the server (GUI), and display all the commands
an application has executed.
The eBPF cache is meant mainly for certain applications that
establish 2-4 new connections in under 1-2 seconds. Thus, a cache of 1
minute per item was too much, 10-20 seconds is enough.
Also, check old items every minute to keep the number of items low.
* 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
https://github.com/evilsocket/opensnitch/pull/513#issuecomment-924400824
More information regarding this change: #493
- Fixed reloading process monitor method if the configuration changes on
disk. This can occur in two situations: 1) if it's changed from the
UI, 2) if the user changes it manually.
- Ensure that we don't crash if there's an error changing the
method and ebpf is active.
- When changing monitor method to ebpf and it fails to start, stop it
anyway. It helps cleaning up kprobes and avoiding the error
"cannot write...: file exists".
- Fixed multiple race conditions when using the cache of PIDs.
- Improved the chances to hit the cache of inodes, which helps to keep
down the times to get the PID of a connection to <= 30us.
These caches are mainly used when not using "ebpf" proc monitor method.
When enabling the eBPF monitor method we dump the active connections,
but in some cases there're no active connections, and because of this
we're failing enabling this monitor method.
If there're no connections established, netlink returns 0 entries. It's
not clear if it's an indication of error in some cases or the expected
result.
Either way:
- fail only if we're unable to load the eBPF module.
- dump TCP IPv6 connections only if IPv6 is enabled in the syste,-
It'd probably be a good idea to write a module and encapsulate all the
functionality of the fields in funcs(), to lock them properly
(get/set maps, etc).
TODO: replace monitorLocalAddress() by
netlink.AddrSubscribeWithoptions(), to receive addresses' events
asynchronously.
Sometimes when a new connection is about to be established, we don't get
the PID of the process using the eBPF proc monitor method. But in some
rare situations, the kernel still holds information about the connection
(sock_diag struct basically). We assume that these connections are
initiated from kernel space.
Per some debugging, this doesn't seem to be always the root cause, so
these connections will only be shown if InterceptUnknown config field is
set to true.
On systems that have been running for a long time (for example 552
days) we were failing parsing the starttime field:
```
Could not find or convert Starttime. This should never happen.
Please report this incident to the Opensnitch developers:
strconv.Atoi: parsing "4242026842": value out of range
```
- extra: fixed tests.
* Use ebpf program to find PID of new connections.
before running the branch you have to compile ebpf_prog/opensnitch.c
opensnitch.c is an eBPF program. Compilation requires getting kernel source.
cd opensnitch
wget https://github.com/torvalds/linux/archive/v5.8.tar.gz
tar -xf v5.8.tar.gz
patch linux-5.8/tools/lib/bpf/bpf_helpers.h < ebpf_prog/file.patch
cp ebpf_prog/opensnitch.c ebpf_prog/Makefile linux-5.8/samples/bpf
cd linux-5.8 && yes "" | make oldconfig && make prepare && make headers_install # (1 min)
cd samples/bpf && make
objdump -h opensnitch.o #you should see many section, number 1 should be called kprobe/tcp_v4_connect
llvm-strip -g opensnitch.o #remove debug info
sudo cp opensnitch.o /etc/opensnitchd
cd ../../../daemon
--opensnitchd expects to find opensnitch.o in /etc/opensnitchd/
--start opensnitchd with:
opensnitchd -rules-path /etc/opensnitchd/rules -process-monitor-method ebpf
Co-authored-by: themighty1 <you@example.com>
Co-authored-by: Gustavo Iñiguez Goia <gooffy1@gmail.com>