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.
Added config option to set how often the garbage collector runs.
For example:
"Internal": {
"GCPercent": 75
},
If this option is not specified in the config file, or the value
is 0, then the GC percentage is not configured.
More info:
https://pkg.go.dev/runtime/debug#SetGCPercent
Now it's possible to configure eBPF modules path from the
default-config.json file:
"Ebpf": {
"ModulesPath": "..."
}
If the option is not provided, or if it's empty, we'll keep loading from
the default directories:
- /usr/local/lib/opensnitchd/ebpf
- /usr/lib/opensnitchd/ebpf
- /etc/opensnitchd/ebpf (deprecated, will be removed in the future).
Closes#928
- Allow to configure system firewall configuration file path:
* via cli (-fw-config-file).
* via global configuration file.
- Allow to configure fw rules check interval.
The system fw config file contains regular iptables/nftables rules.
Previously it was hardcoded to /etc/opensnitchd/system-fw.json
The interval to check if the interception rules were added was also
hardcoded to 10 seconds. Now it's possible to configure it.
A value of "0s" disables the interval, while "" defaults to 10 seconds.
- Added cli option -config-file to specify an alternate path to the
config file.
- Allow to configure rules path from the configuration file (cli option
takes precedence).
- Default options are now /etc/opensnitchd/rules and
/etc/opensnitchd/default-config.json. Previously the default rules
directory was "rules" (relative path).
Closes#449
- Fixed several leaks.
- Cache of events reorganized and improved.
* items are added faster.
* proc details are rebuilt if needed (checksums, proc tree, etc)
* proc's tree is reused if we've got the parent in cache.
rel: #413
- 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.
- Allow to use SSL certificates to secure unix sockets communications.
- Allow to use abstract users sockets for server and nodes.
Go gRPC doesn't seem to understand unix sockets addresses that start
with "unix-abstract:", and python gRPC doesn't seem to understand
"unix:@" addresses.
Therefore, on the server (python gRPC) we use the format "unix:@" to
specify the address where the server will listen on, and rewrite it to
"unix-abstract:" before starting the server.
Note about certs and abstract unix sockets:
When creating the SSL certificates, you'll have to specify the
address of the unix socket as the Common Name of the certificates:
Address: "unix:@my-abstract-socket"
Common Name: @my-abstract-socket
- Send errors to the server (GUI) if there's any error when reloading
the system fw rules (far from being perfect/optimal, needs a
rewrite).
- Don't load the configuration after saving it, let the watcher reload
it on write change to avoid double reload/duplicated errors.
- Test that the default config is loaded properly.
- Test that changes to the config are saved to disk.
- Test that changes to the config file on disk are reloaded properly.
Allow to cypher channel communications with certificates.
There are 3 authentication types: simple, tls-simple and tls-mutual.
- 'simple' wont't cypher communications.
- 'tls-simple' uses a server key and certificate for the server, and a
common CA certificate or the server certificate to authenticate all
nodes.
- 'tls-mutual' uses a server key and certificate for the server, and a
client key and certificate per node.
There are 2 options to verify how gRPC validates credentials:
- SkipVerify: https://pkg.go.dev/crypto/tls#Config
- ClientAuthType: https://pkg.go.dev/crypto/tls#ClientAuthType
Example configuration:
"Server": {
"Address": "127.0.0.1:12345",
"Authentication": {
"Type": "tls-simple",
"TLSOptions": {
"CACert": "/etc/opensnitchd/auth/ca-cert.pem",
"ServerCert": "/etc/opensnitchd/auth/server-cert.pem",
"ClientCert": "/etc/opensnitchd/auth/client-cert.pem",
"ClientKey": "/etc/opensnitchd/auth/client-key.pem",
"SkipVerify": false,
"ClientAuthType": "req-and-verify-cert"
}
}
}
More info: https://github.com/evilsocket/opensnitch/wiki/Nodes
- fsnotify notifies 2 WRITE events sometimes (known bug), which leads to
read 0 bytes one of the times.
As now we send these errors to the GUI, on some systems we were
displaying an error reading the config, which was not really the case.
- Only parse the config before writing it to disk, instead of call the
load() method.
- Configuration of system firewall rules from the GUI is not supported for
iptables. Up until now only a warning was displayed, encouring to change
fw type manually.
Now if configured fw type is iptables (default-config.json, Firewall:),
and the user opens the fw dialog, we'll ask the user to change it from
the GUI.
- Add fw rules before connecting to the GUI. Otherwise we send to the
GUI an invalid fw state.
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.
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.
Now you can send events to syslog, local or remote.
This feature was requested here #638
This feature allows you to integrate opensnitch with your SIEM. Take a
look at the above discussion to see examples with
syslog-ng+promtail+loki+grafana.
There's only one logger implemented (syslog), but it should be easily
expandable to add more type of loggers (elastic, etc).
The event format can be CSV or RFC5424. It sould also be easy to add
more formats.
- Allow to configure stats workers. They were hardcoded to 4.
- Added ability to add a description to the rules.
- Display the description field on the Rules view, and remove the internal
fields (operator, operator_data, etc).
- Added DB migrations.
- Improved rules' executable path field tooltip (#661).
Closes#652#466
* Allow to configure firewall rules from the GUI (WIP)
New features:
- Configure and list system firewall rules from the GUI (nftables).
- Configure chains' policies.
- Add simple rules to allow incoming ports.
- Add simple rules to exclude apps (ports) from being intercepted.
This feature is only available for nftables. iptables is still supported,
you can add rules to the configuration file and they'll be loaded, but
you can't configure them from the GUI.
More information: #592
There are two issues when connecting to the GUI via TCP on localhost:
- Sometimes when the daemon is launched with the GUI already running, the
notifications channel is not established.
* Give 10 seconds to connect, if it timeouts, disconnect everything
and try to reconnect again.
- After some time the notifications channel is closed from the server
side (i.e., the GUI), and it is not restablished.
* Forcefully disconnect everything, and let it reconnect again.
Both issues should be investigated further to find the root problem.
- 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".
When the daemon connects to the GUI, use the default action
configured on the GUI to apply a verdict on new connections.
We were using daemon's default action, so if it was Allow but the user
had configured Deny on the GUI it was allowing connections, causing some
confusion (#489)
TODO: apply this action not only on connecting to the GUI, but also when
saving the configuration from the GUI.
- The firewall rules defined in /etc/opensnitchd/system-fw.json take
precedence over the interception rules, but we were inserting the
interception rules before the system's ones. With this change #455
should be fixed.
- On the other hand, the DefaultAction was not being applied correctly
in all cases. As of today the DefaultAction is applied in 2 scenarios:
* When the daemon is connected to the GUI and the user doesn't answer
a pop-up.
* When the daemon is not connected to the GUI.
However as we don't parse all network protocols, even if the GUI is
connected we may end up parsing a connection and don't know what to do
with it. In this case the DefaultAction was always Deny.
Now in the above scenario, i.e.: when the GUI is connected but we
can't parse a connection, we'll apply the DefaultAction configured by
the user.
Previous behaviour:
1) Before version 1.0.0b the daemon kept a list of processes that had
established connections. The list was displayed on the GUI as is, so
the maximum number of connections displayed were 100 (hardcoded).
2) When the intercepted connections reached 100, the last entry of the
list was removed, and a new one was inserted on the top.
After v1.0.0 we started saving connections to a DB on the GUI side, to
get rid of the hardcoded connections limit. However, the point 2) was
still present that caused some problems:
- When the backlog was full we kept inserting and deleting connections
from it continuously, one by one.
- If there was a connections burst we could end up missing some
connections.
New behaviour:
- The statisics are deleted from the daemon everytime we send them to
the GUI, because we don't need them on the daemon anymore.
- If the GUI is not connected, the connections will be added to the
backlog as in the point 2).
- When the backlog reaches the limit, it'll keep deleting the last
one in order to insert a new one.
- The number of connections to keep on the backlog is configurable.
- If the statistics configuration is missing, default values will be
150 (maxEvents) and 25 (maxStats).
Notes:
If the GUI is saving the data to memory (default), there won't be
any noticeable side effect.
If the GUI is configured to save the connections to a DB on disk, and
the daemon sends all the backlog at once, the GUI may experience a
delay and a high CPU spike. This can occur on connecting to the daemon
(because the backlog will be full), or when an app sends too many
connections per second (like nmap).
Before this change, we tried to determine what firewall to use based on
the version of iptables (if -V legacy -> nftables, otherwise iptables).
This caused problems (#455), and as there's no support yet for nftables
system firewall rules, it can't be configured to workaround these
errors.
Now the default firewall to use will be iptables.
If it's not available (installed), can't be used or the configuration
option is empty/missing, we'll use nftables.
Prior to v1.4.x versions, when a pop-up asked the user to allow or deny
a connection, the rest of the network traffic was dropped until an
action was taken.
We fixed it, but when a pop-up was asking to allow or deny a new connection,
we let it passing by if the daemon's DefaultAction option was set to
allow, even if the user hadn't taken an action on it yet.
It also caused some confusion if the users had configured the pop-up's
DefaultAction to deny, they were expecting to not allow the connection
until they had decided what to do.
Now the previous behaviour has been restored, having these usage
scenarios:
- If the GUI is connected + daemon DefaultAction set to allow or deny.
Result:
1. Prompt the user to allow or deny the new connection.
2. Deny the new connection until the user takes an action on it.
3. Allow the rest of traffic, allowing known connections, and
denying new ones until the active pop-up is closed and we can
prompt the user again.
- GUI disconnected.
Result:
1. Apply daemon's DefaultAction from the configuration file
default-config.json.
closes: #392
Added basic nftables support, which adds the needed rules to intercept
outgoing network traffic and DNS responses. System rules will be added
soon.
What netfilter subsystem to use is determined based on the following:
- nftables: if the _iptables_ binary is not present in the system, or
if the iptables version (iptables -V) is
"iptables vX.Y.Z (nf_tables)".
- iptables: in the rest of the cases.
problem:
- after losing network connectivity node<->server, the node didn't restore
the connection. In reality, the connection with the server was not
closed, but the notifications channel was closed due to inactivity
after 20s.
set inactivity timeouts to 20s on both node and server. Previous
timeouts were 2h for the main connection and 20s for the streaming
channels (notifications).
- get rid of the logic to determine if the server is alive or not based
on sending pings.
Instead, use the connection events when a node connects/disconnects
(Subscribe).
The Ping call is still used to send the statistics.
other:
- fixed exception when updating the status of a node.
If we change the monitor method from the GUI, and it fails to start
(eBPF, audit or ftrace), use the old configured method and don't save
the configuration to disk, to avoid configuring a monitor method that
doesn't work.
* 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>