Nfqueue bypass option skips the enqueue of packets to userspace
if no application is listening to the queue.
https://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace
If this flag is not specified, and for example the daemon dies
unexpectedly, all the outbound traffic will be blocked.
Up until now we've been using this flag by default not to block network
traffic if the daemon dies or is killed for some reason. But some users
want to use precisely this behaviour (#884, #1183, #1201).
Now you can configure it, to block connections if the daemon
unexpectedly dies.
The option is on by default in the configuration (QueueBypass: true).
If this item is not present in the daemon config file, then it'll be
false.
- Calculate the ram usage of a process in the daemon, using the page
size of the system.
- Added new functions to read some details of a process, so we can use
them in other parts of the code.
Added new task to monitor the resources of remote nodes, like
ram, swap, number of processes or load average of the system.
The task is initiated when the user selects a node, and the data
received from the node is added to the right panel of the Nodes tab.
The task is stopped when changing to another tab, or when deselecting a
node.
Particularly useful for monitoring remote nodes.
daemon tasks are actions that are executed in background by the daemon.
They're started from the GUI (server) via a Notification (protobuf),
with the type TASK_START (protobuf).
Once received in the daemon, the TaskManager starts the task in
background.
Tasks may run at interval times (every 5s, 2days, etc), until they
finish an operation, until a timeout, etc.
Each task has each own configuration options, which will customize the
behaviour of its operations.
In this version, if the GUI is closed, the daemon will stop all the
running tasks.
Each Task has a flag to ignore this behaviour, for example if they need
to run until they finish and only send a notification to the GUI,
instead of streaming data continuously to the GUI (server).
- Up until now we only had one task that could be initiated from the GUI:
the process monitor dialog. It has been migrated to a Task{}.
- go.mod bumped to v1.20, to use unsafe string functions.
- go.sum updated accordingly.
When exporting rules from the GUI, the Created field was exported as
timestamp. Importing rules worked fine, because json.Marshall() accepts
the timestamp format.
However, when the daemon was loading a rule with the Created field as
timestamp, since the field was defined as time.Time, it expected a RFC3339
string (https://pkg.go.dev/time#Time.UnmarshalJSON)
so it failed to parse the timestamp and the rule was not loaded.
Now the field is defined as string, it's always saved as RFC3339, and if
we fail to parse these fields we'll use a temporary date instead of
failing loading the rule.
More info:
https://github.com/evilsocket/opensnitch/issues/1140#issuecomment-2140904847Closes#1140
Start monitoring the config file every time we read the file, to survive:
- malformed json file
- intermediate file removal (when writing we receive 2 write events,
one of0 bytes)
"A watch will be automatically removed if the watched path is deleted or
renamed"
"A path can only be watched once; watching it more than once is a no-op and
will not return an error"
https://pkg.go.dev/github.com/fsnotify/fsnotify#Watcher.Add
- When reloading rules from a path:
stop existing (domains,ips,regexp) lists monitors, stop rules
watcher and start watching the new dir for changes, delete existing
rules from memory, etc.
- Previously, cli parameters (queue number, log file, etc) were taking
into account before loading the configuration.
Now the configuration file is loaded first (default-config.json), and
if any of the cli parameter has been specified, it'll overwrite the
loaded configuration from file.
This means for example that if you use "-process-monitor-method proc",
and "ebpf" is configured in default-config.json, firstly "ebpf" will
be configured, and later "proc".
(-queue-num option for now requires to match config option
cfg.FwOptions.QueueNumber)
Allow to customize:
- EventsWorkers: number of goroutines to handle kernel events.
Default 8.
- QueueEventsSize: max number of events in the queue.
By default 0, meaning that it'll relay on the available goroutines to
process the events. If it's > 0, and the daemon can't process the
events fast enough, they'll be queued. Once the queue is full, it'll
behave as it was of size 0.
If there're lost events, a message will be logged: "Lost ebpf events..."
- Added new configuration field to allow configure fw interception
number queue (default to 0):
"FwOptions": {
"QueueNum": 0
}
(we still need to reconfigure nfqueue queues in order for this to
take effect).
- If the fw configuration path is not supplied, default to
/etc/opensnitchd/system-fw.json
- The loggers were not being properly initialized.
- The fw was only being load on reload, instead of on startup
and reload.
Kudos to @1fishe2fishe for reporting this problem and proposing a
fix in #1130!
By default when adding the interception rules, we were killing all
existing connections, to force them go to the netfilter queue.
However in some environments this is not acceptable, so now it's configurable.
Besides, we were doing this only for nftables, so now it also works for
iptables.
When disabling the interception from the server (GUI), the network
interception was stopped, but the procs monitor kept running.
Now the procs monitor in use is also stopped, not to interfere with
the rest of the system (except 'proc').
improvements to the loggers modules:
- allow to specify a connection timeout (there was only a write
timeout).
- performance improvements when building the messages to be
written/sent.
- allow to restart the connection with remote servers if we fill up the
messages queue.
This can occur for example if we connect to a remote server, start
sending messages, but we haven't allowed other connections yet.
In this case the connections never recovered from this state, and we
weren't prompted to allow the needed connections.
(more work nd testing needed)
continuation of previous commit bde5d34deb
- Allow to reconfigure stats limits (how many events we keep on the
daemon, number of workers, ...)
- Allow to reconfigure loggers.
We only offered two options for the DefaultAction option: allow/deny.
Since a long time ago we support "reject"ing connections, but it was not
configurable as the DefaultAction.
Closes: #1108
We build the parent process tree of a process when it's executed
for the first time.
Now we also build the tree when an already running process opens a new
outbound connection by the first time.
if an invalid opensnitch-procs.o module was loaded, we were flooding
the log with errors.
In these cases stop processing events after 20 errors (random, we should
have no errors).
This may occur if the module is malformed (valid .o ebpf module but
different structs, etc), or when loading modules from other versions.
Closes: #1099#1082
We were not reacting to common exit signals, only to kill/interrupt
signals, so the DNS uprobes were never properly removed. Each uprobe
has the PID of the daemon in the identifier, so in theory, there
shouldn't be conflicts, but better clean our probes on exit.
previous to this commit with the daemon running
(and lot of starts/stops):
~ # cat /sys/kernel/debug/tracing/uprobe_events |wc -l
367
after stopping the daemon:
~ # cat /sys/kernel/debug/tracing/uprobe_events |wc -l
364
~ # > /sys/kernel/debug/tracing/uprobe_events
~ # cat /sys/kernel/debug/tracing/uprobe_events |wc -l
0
~ # cp opensnitchd-new /usr/bin/opensnitchd ; service opensnitchd start
~ # cat /sys/kernel/debug/tracing/uprobe_events |wc -l
3
~ # service opensnitchd stop
~ # cat /sys/kernel/debug/tracing/uprobe_events |wc -l
0
Added the path to the libc as well as the calculated offset for the
uprobe.
Don't return on the first error found loading a uprobe, instead try all
the uprobes and return if the loaded uprobes are 0.
There's a long running task that monitors established connections every
~2s.
When a connection is not found via ebpf or proc, sometimes it's found
there so we can use the inode to search for the process.
However on some systems the netlink call to dump the sockets may fail
continuously, wasting resources. It'll also fail if you block connections
to port 0 (common case for ICMP packets).
So if there're too many errors dumpng the sockets, stop this task for
these cases.
- When discovering the hierarchy of a process, reuse components of
the tree if they're already on cache, to improve speed and reduce
mem allocs.
- When building the tree of a proces, rebuild the tree if the first
component doesn't have pid 1. Otherwise reuse the tree.
Simplify the cache of connections by storing only the PID of a process,
instead of the Process object.
We can obtain the Process object from the cache of processes by PID.