Showing preview only (7,356K chars total). Download the full file or copy to clipboard to get everything.
Repository: evilsocket/opensnitch
Branch: master
Commit: f2ce07409651
Files: 441
Total size: 6.9 MB
Directory structure:
gitextract_fp8zrzif/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── config.yml
│ │ └── feature-request.md
│ └── workflows/
│ ├── build_ebpf_modules.yml
│ ├── generic_validations.yml
│ └── go.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── daemon/
│ ├── .gitignore
│ ├── Gopkg.toml
│ ├── Makefile
│ ├── conman/
│ │ ├── connection.go
│ │ └── connection_test.go
│ ├── core/
│ │ ├── core.go
│ │ ├── ebpf.go
│ │ ├── gzip.go
│ │ ├── system.go
│ │ └── version.go
│ ├── data/
│ │ ├── default-config.json
│ │ ├── init/
│ │ │ ├── opensnitchd-dinit
│ │ │ ├── opensnitchd-openrc
│ │ │ └── opensnitchd.service
│ │ ├── network_aliases.json
│ │ ├── rules/
│ │ │ ├── 000-allow-localhost.json
│ │ │ └── 000-allow-localhost6.json
│ │ ├── system-fw.json
│ │ └── tasks/
│ │ └── tasks.json
│ ├── dns/
│ │ ├── ebpfhook.go
│ │ ├── parse.go
│ │ ├── systemd/
│ │ │ └── monitor.go
│ │ └── track.go
│ ├── firewall/
│ │ ├── common/
│ │ │ └── common.go
│ │ ├── config/
│ │ │ ├── config.go
│ │ │ └── config_test.go
│ │ ├── iptables/
│ │ │ ├── iptables.go
│ │ │ ├── monitor.go
│ │ │ ├── rules.go
│ │ │ └── system.go
│ │ ├── nftables/
│ │ │ ├── chains.go
│ │ │ ├── chains_test.go
│ │ │ ├── exprs/
│ │ │ │ ├── counter.go
│ │ │ │ ├── counter_test.go
│ │ │ │ ├── ct.go
│ │ │ │ ├── ct_test.go
│ │ │ │ ├── enums.go
│ │ │ │ ├── ether.go
│ │ │ │ ├── ether_test.go
│ │ │ │ ├── iface.go
│ │ │ │ ├── iface_test.go
│ │ │ │ ├── ip.go
│ │ │ │ ├── ip_test.go
│ │ │ │ ├── limit.go
│ │ │ │ ├── log.go
│ │ │ │ ├── log_test.go
│ │ │ │ ├── meta.go
│ │ │ │ ├── meta_test.go
│ │ │ │ ├── nat.go
│ │ │ │ ├── nat_test.go
│ │ │ │ ├── notrack.go
│ │ │ │ ├── operator.go
│ │ │ │ ├── port.go
│ │ │ │ ├── port_test.go
│ │ │ │ ├── protocol.go
│ │ │ │ ├── protocol_test.go
│ │ │ │ ├── quota.go
│ │ │ │ ├── quota_test.go
│ │ │ │ ├── utils.go
│ │ │ │ ├── verdict.go
│ │ │ │ └── verdict_test.go
│ │ │ ├── monitor.go
│ │ │ ├── monitor_test.go
│ │ │ ├── nftables.go
│ │ │ ├── nftest/
│ │ │ │ ├── nftest.go
│ │ │ │ ├── test_utils.go
│ │ │ │ └── utils.go
│ │ │ ├── parser.go
│ │ │ ├── rule_helpers.go
│ │ │ ├── rules.go
│ │ │ ├── rules_test.go
│ │ │ ├── system.go
│ │ │ ├── system_test.go
│ │ │ ├── tables.go
│ │ │ ├── tables_test.go
│ │ │ ├── testdata/
│ │ │ │ └── test-sysfw-conf.json
│ │ │ ├── utils.go
│ │ │ └── utils_test.go
│ │ └── rules.go
│ ├── go.mod
│ ├── go.sum
│ ├── internal/
│ │ └── testutil/
│ │ └── network.go
│ ├── log/
│ │ ├── formats/
│ │ │ ├── csv.go
│ │ │ ├── formats.go
│ │ │ ├── json.go
│ │ │ ├── rfc3164.go
│ │ │ └── rfc5424.go
│ │ ├── log.go
│ │ └── loggers/
│ │ ├── logger.go
│ │ ├── remote.go
│ │ ├── remote_syslog.go
│ │ └── syslog.go
│ ├── main.go
│ ├── netfilter/
│ │ ├── netfilter_test.go
│ │ ├── packet.go
│ │ ├── queue.c
│ │ ├── queue.go
│ │ └── queue.h
│ ├── netlink/
│ │ ├── ifaces.go
│ │ ├── procmon/
│ │ │ └── procmon.go
│ │ ├── socket.go
│ │ ├── socket_linux.go
│ │ ├── socket_packet.go
│ │ ├── socket_test.go
│ │ └── socket_xdp.go
│ ├── netstat/
│ │ ├── entry.go
│ │ ├── find.go
│ │ ├── parse.go
│ │ └── parse_packet.go
│ ├── procmon/
│ │ ├── activepids.go
│ │ ├── audit/
│ │ │ ├── client.go
│ │ │ ├── config.go
│ │ │ └── parse.go
│ │ ├── cache.go
│ │ ├── cache_events.go
│ │ ├── cache_events_test.go
│ │ ├── cache_test.go
│ │ ├── details.go
│ │ ├── ebpf/
│ │ │ ├── cache.go
│ │ │ ├── config.go
│ │ │ ├── debug.go
│ │ │ ├── ebpf.go
│ │ │ ├── ebpf_test.go
│ │ │ ├── events.go
│ │ │ ├── find.go
│ │ │ ├── monitor.go
│ │ │ └── utils.go
│ │ ├── find.go
│ │ ├── find_test.go
│ │ ├── monitor/
│ │ │ └── init.go
│ │ ├── parse.go
│ │ ├── process.go
│ │ ├── process_test.go
│ │ └── testdata/
│ │ └── proc-environ
│ ├── rule/
│ │ ├── loader.go
│ │ ├── loader_test.go
│ │ ├── operator.go
│ │ ├── operator_aliases.go
│ │ ├── operator_lists.go
│ │ ├── operator_test.go
│ │ ├── rule.go
│ │ ├── rule_test.go
│ │ └── testdata/
│ │ ├── 000-allow-chrome.json
│ │ ├── 001-deny-chrome.json
│ │ ├── invalid-regexp-list.json
│ │ ├── invalid-regexp.json
│ │ ├── lists/
│ │ │ ├── domains/
│ │ │ │ └── domainlists.txt
│ │ │ ├── ips/
│ │ │ │ └── ips.txt
│ │ │ ├── nets/
│ │ │ │ └── nets.txt
│ │ │ └── regexp/
│ │ │ └── domainsregexp.txt
│ │ ├── live_reload/
│ │ │ ├── test-live-reload-delete.json
│ │ │ └── test-live-reload-remove.json
│ │ ├── rule-disabled-operator-list-expanded.json
│ │ ├── rule-disabled-operator-list.json
│ │ ├── rule-operator-list-data-empty.json
│ │ └── rule-operator-list.json
│ ├── statistics/
│ │ ├── event.go
│ │ └── stats.go
│ ├── tasks/
│ │ ├── base/
│ │ │ └── main.go
│ │ ├── config/
│ │ │ ├── main.go
│ │ │ ├── monitor.go
│ │ │ └── utils.go
│ │ ├── doc.go
│ │ ├── downloader/
│ │ │ ├── README.md
│ │ │ ├── config.go
│ │ │ ├── downloader.go
│ │ │ ├── main.go
│ │ │ └── utils.go
│ │ ├── iocscanner/
│ │ │ ├── README.md
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── main.go
│ │ │ ├── run_tools.go
│ │ │ └── tools/
│ │ │ ├── base/
│ │ │ │ └── base.go
│ │ │ ├── dpkg/
│ │ │ │ └── dpkg.go
│ │ │ ├── executer/
│ │ │ │ └── executer.go
│ │ │ ├── generic/
│ │ │ │ └── generic.go
│ │ │ └── yara/
│ │ │ └── yara.go
│ │ ├── load.go
│ │ ├── looptask/
│ │ │ └── main.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── nodemonitor/
│ │ │ ├── main.go
│ │ │ └── main_test.go
│ │ ├── pidmonitor/
│ │ │ ├── main.go
│ │ │ └── main_test.go
│ │ ├── scheduler/
│ │ │ ├── daily.go
│ │ │ └── scheduler.go
│ │ └── socketsmonitor/
│ │ ├── dump.go
│ │ ├── main.go
│ │ └── options.go
│ └── ui/
│ ├── alerts.go
│ ├── auth/
│ │ └── auth.go
│ ├── client.go
│ ├── client_test.go
│ ├── config/
│ │ └── config.go
│ ├── config_utils.go
│ ├── notifications.go
│ ├── notifications_tasks.go
│ ├── protocol/
│ │ └── .gitkeep
│ └── testdata/
│ ├── config-invalid-procmon.json
│ ├── default-config.json
│ └── default-config.json.orig
├── ebpf_prog/
│ ├── Makefile
│ ├── README
│ ├── arm-clang-asm-fix.patch
│ ├── bpf_headers/
│ │ ├── bpf_core_read.h
│ │ ├── bpf_helper_defs.h
│ │ ├── bpf_helpers.h
│ │ └── bpf_tracing.h
│ ├── common.h
│ ├── common_defs.h
│ ├── opensnitch-dns.c
│ ├── opensnitch-procs.c
│ └── opensnitch.c
├── proto/
│ ├── .gitignore
│ ├── Makefile
│ └── ui.proto
├── release.sh
├── ui/
│ ├── .gitignore
│ ├── LICENSE
│ ├── MANIFEST.in
│ ├── Makefile
│ ├── bin/
│ │ └── opensnitch-ui
│ ├── i18n/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── generate_i18n.sh
│ │ ├── locales/
│ │ │ ├── ar/
│ │ │ │ └── opensnitch-ar.ts
│ │ │ ├── cs_CZ/
│ │ │ │ └── opensnitch-cs_CZ.ts
│ │ │ ├── de_DE/
│ │ │ │ └── opensnitch-de_DE.ts
│ │ │ ├── es_ES/
│ │ │ │ └── opensnitch-es_ES.ts
│ │ │ ├── eu_ES/
│ │ │ │ └── opensnitch-eu_ES.ts
│ │ │ ├── fi_FI/
│ │ │ │ └── opensnitch-fi_FI.ts
│ │ │ ├── fr_FR/
│ │ │ │ └── opensnitch-fr_FR.ts
│ │ │ ├── he_IL/
│ │ │ │ └── opensnitch-he_IL.ts
│ │ │ ├── hi_IN/
│ │ │ │ └── opensnitch-hi_IN.ts
│ │ │ ├── hu_HU/
│ │ │ │ └── opensnitch-hu_HU.ts
│ │ │ ├── id_ID/
│ │ │ │ └── opensnitch-id_ID.ts
│ │ │ ├── it_IT/
│ │ │ │ └── opensnitch-it_IT.ts
│ │ │ ├── ja_JP/
│ │ │ │ └── opensnitch-ja_JP.ts
│ │ │ ├── lt_LT/
│ │ │ │ └── opensnitch-lt_LT.ts
│ │ │ ├── nb_NO/
│ │ │ │ └── opensnitch-nb_NO.ts
│ │ │ ├── nl_NL/
│ │ │ │ └── opensnitch-nl_NL.ts
│ │ │ ├── pt_BR/
│ │ │ │ └── opensnitch-pt_BR.ts
│ │ │ ├── ro_RO/
│ │ │ │ └── opensnitch-ro_RO.ts
│ │ │ ├── ru_RU/
│ │ │ │ └── opensnitch-ru_RU.ts
│ │ │ ├── sq_AL/
│ │ │ │ └── opensnitch-sq_AL.ts
│ │ │ ├── sv_SE/
│ │ │ │ └── opensnitch-sv_SE.ts
│ │ │ ├── tr_TR/
│ │ │ │ └── opensnitch-tr_TR.ts
│ │ │ ├── uk_UA/
│ │ │ │ └── opensnitch-uk_UA.ts
│ │ │ ├── zh_Hans/
│ │ │ │ └── opensnitch-zh_Hans.ts
│ │ │ └── zh_TW/
│ │ │ └── opensnitch-zh_TW.ts
│ │ └── opensnitch_i18n.pro
│ ├── opensnitch/
│ │ ├── __init__.py
│ │ ├── actions/
│ │ │ ├── __init__.py
│ │ │ ├── default_configs.py
│ │ │ ├── enums.py
│ │ │ └── utils.py
│ │ ├── auth/
│ │ │ └── __init__.py
│ │ ├── config.py
│ │ ├── customwidgets/
│ │ │ ├── __init__.py
│ │ │ ├── addresstablemodel.py
│ │ │ ├── colorizeddelegate.py
│ │ │ ├── completer.py
│ │ │ ├── firewalltableview.py
│ │ │ ├── generictableview.py
│ │ │ ├── itemwidgetcentered.py
│ │ │ ├── main.py
│ │ │ ├── netstattablemodel.py
│ │ │ └── updownbtndelegate.py
│ │ ├── database/
│ │ │ ├── __init__.py
│ │ │ ├── enums.py
│ │ │ └── migrations/
│ │ │ ├── upgrade_1.sql
│ │ │ ├── upgrade_2.sql
│ │ │ └── upgrade_3.sql
│ │ ├── desktop_parser.py
│ │ ├── dialogs/
│ │ │ ├── __init__.py
│ │ │ ├── conndetails.py
│ │ │ ├── events/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── config.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── menu_actions.py
│ │ │ │ ├── menus.py
│ │ │ │ ├── nodes.py
│ │ │ │ ├── queries.py
│ │ │ │ ├── tasks/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── netstat.py
│ │ │ │ │ └── nodemon.py
│ │ │ │ └── views.py
│ │ │ ├── firewall.py
│ │ │ ├── firewall_rule/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── notifications.py
│ │ │ │ ├── rules.py
│ │ │ │ ├── statements.py
│ │ │ │ └── utils.py
│ │ │ ├── preferences/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── sections/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── db.py
│ │ │ │ │ ├── nodes.py
│ │ │ │ │ └── ui.py
│ │ │ │ ├── settings.py
│ │ │ │ ├── signals.py
│ │ │ │ └── utils.py
│ │ │ ├── processdetails.py
│ │ │ ├── prompt/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── checksums.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── details.py
│ │ │ │ ├── dialog.py
│ │ │ │ └── utils.py
│ │ │ └── ruleseditor/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── dialog.py
│ │ │ ├── nodes.py
│ │ │ ├── rules.py
│ │ │ ├── signals.py
│ │ │ └── utils.py
│ │ ├── firewall/
│ │ │ ├── __init__.py
│ │ │ ├── chains.py
│ │ │ ├── enums.py
│ │ │ ├── exprs.py
│ │ │ ├── profiles.py
│ │ │ ├── rules.py
│ │ │ └── utils.py
│ │ ├── nodes.py
│ │ ├── notifications.py
│ │ ├── plugins/
│ │ │ ├── __init__.py
│ │ │ ├── downloader/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _gui.py
│ │ │ │ ├── downloader.py
│ │ │ │ └── example/
│ │ │ │ └── downloaders.json
│ │ │ ├── highlight/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── example/
│ │ │ │ │ ├── commonActionsDelegate.json
│ │ │ │ │ └── rulesActionsDelegate.json
│ │ │ │ └── highlight.py
│ │ │ ├── sample/
│ │ │ │ ├── __init__.py
│ │ │ │ └── sample.py
│ │ │ ├── versionchecker/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── versionchecker.json
│ │ │ │ └── versionchecker.py
│ │ │ └── virustotal/
│ │ │ ├── __init__.py
│ │ │ ├── _models.py
│ │ │ ├── _popups.py
│ │ │ ├── _procdialog.py
│ │ │ ├── _utils.py
│ │ │ ├── example/
│ │ │ │ └── virustotal.json
│ │ │ └── virustotal.py
│ │ ├── proto/
│ │ │ ├── __init__.py
│ │ │ ├── enums.py
│ │ │ ├── pre3200/
│ │ │ │ ├── ui_pb2.py
│ │ │ │ └── ui_pb2_grpc.py
│ │ │ ├── ui_pb2.py
│ │ │ └── ui_pb2_grpc.py
│ │ ├── res/
│ │ │ ├── __init__.py
│ │ │ ├── firewall.ui
│ │ │ ├── firewall_rule.ui
│ │ │ ├── preferences.ui
│ │ │ ├── process_details.ui
│ │ │ ├── prompt.ui
│ │ │ ├── resources.qrc
│ │ │ ├── ruleseditor.ui
│ │ │ ├── stats.ui
│ │ │ └── themes/
│ │ │ └── dark/
│ │ │ └── icons/
│ │ │ └── LICENSE
│ │ ├── rules.py
│ │ ├── service.py
│ │ ├── themes/
│ │ │ ├── README.md
│ │ │ └── dark_white.xml
│ │ ├── utils/
│ │ │ ├── __init__.py
│ │ │ ├── duration/
│ │ │ │ ├── __init__.py
│ │ │ │ └── duration.py
│ │ │ ├── infowindow.py
│ │ │ ├── languages.py
│ │ │ ├── logger/
│ │ │ │ ├── __init__.py
│ │ │ │ └── logger.py
│ │ │ ├── network_aliases/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── network_aliases.json
│ │ │ │ └── network_aliases.py
│ │ │ ├── qvalidator.py
│ │ │ ├── sockets.py
│ │ │ ├── themes/
│ │ │ │ ├── __init__.py
│ │ │ │ └── themes.py
│ │ │ └── xdg.py
│ │ └── version.py
│ ├── requirements.txt
│ ├── resources/
│ │ ├── io.github.evilsocket.opensnitch.appdata.xml
│ │ ├── kcm_opensnitch.desktop
│ │ └── opensnitch_ui.desktop
│ ├── setup.py
│ └── tests/
│ ├── README.md
│ ├── __init__.py
│ ├── conftest.py
│ ├── dialogs/
│ │ ├── __init__.py
│ │ ├── test_preferences.py
│ │ └── test_ruleseditor.py
│ └── test_nodes.py
└── utils/
├── legacy/
│ └── make_ads_rules.py
├── packaging/
│ ├── build_modules.sh
│ ├── daemon/
│ │ ├── deb/
│ │ │ └── debian/
│ │ │ ├── NEWS
│ │ │ ├── changelog
│ │ │ ├── control
│ │ │ ├── copyright
│ │ │ ├── gbp.conf
│ │ │ ├── gitlab-ci.yml
│ │ │ ├── opensnitch.init
│ │ │ ├── opensnitch.install
│ │ │ ├── opensnitch.logrotate
│ │ │ ├── opensnitch.service
│ │ │ ├── rules
│ │ │ ├── source/
│ │ │ │ └── format
│ │ │ └── watch
│ │ └── rpm/
│ │ └── opensnitch.spec
│ └── ui/
│ ├── deb/
│ │ └── debian/
│ │ ├── changelog
│ │ ├── compat
│ │ ├── control
│ │ ├── copyright
│ │ ├── postinst
│ │ ├── postrm
│ │ ├── rules
│ │ └── source/
│ │ ├── format
│ │ └── options
│ └── rpm/
│ └── opensnitch-ui.spec
└── scripts/
├── ads/
│ └── update_adlists.sh
├── debug-ebpf-maps.sh
├── ipasn_db_sync.sh
├── ipasn_db_update.sh
└── restart-opensnitch-onsleep.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: gustavo-iniguez-goya
patreon: # Replace with a single patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: 🐞 Bug report
about: Create a report to help us improve
title: '[Bug Report] <title>'
labels: 'bug'
assignees: ''
---
<!--
Please, check the FAQ and Known Problems pages before creating the bug report:
https://github.com/evilsocket/opensnitch/wiki/FAQs
GUI related issues:
https://github.com/evilsocket/opensnitch/wiki/GUI-known-problems
Daemon related issues:
- Run `opensnitchd -check-requirements` to see if your kernel is compatible.
- https://github.com/evilsocket/opensnitch/wiki/daemon-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, ...]
- OS version: [e.g. Buster, 10.3, 20.04]
- Window Manager: [e.g. GNOME Shell, KDE, enlightenment, i3wm, ...]
- Kernel version: [`uname -a`]
### To Reproduce:
<!-- Describe in detail as much as you can what happened. -->
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
### Post error logs:
<!--
If it's a crash of the GUI:
- Launch it from a terminal and reproduce the issue.
- Post the errors logged to the terminal.
If the daemon doesn't start or doesn't intercept connections:
- Run `opensnitchd -check-requirements` to see if your kernel is compatible.
- Post last 15 lines of the log file `/var/log/opensnitchd.log`
- 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 (`$ 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 or videos to help explain your problem. It may help to understand the issue much better. -->
### Additional context:
<!-- Add any other context about the problem here. -->
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:
- name: 🙋 Question
url: https://github.com/evilsocket/opensnitch/discussions/new
about: Ask your question here
================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.md
================================================
---
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. -->
================================================
FILE: .github/workflows/build_ebpf_modules.yml
================================================
# This is a basic workflow to help you get started with Actions
name: CI - build eBPF modules
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "master" branch
push:
paths:
- 'ebpf_prog/*'
- '.github/workflows/build_ebpf_modules.yml'
pull_request:
paths:
- 'ebpf_prog/*'
- '.github/workflows/build_ebpf_modules.yml'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
# The matrix configuration will execute the steps, once per dimension defined:
# kernel 5.8 + tag 1.5.0
# kernel 5.8 + tag master
# kernel 6.0 + tag 1.5.0, etc
build:
strategy:
matrix:
kernel: ["6.0"]
tag: ["1.5.0", "master"]
runs-on: ubuntu-22.04
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v3
with:
# ref: can be a branch name, tag, commit, etc
ref: ${{ matrix.tag }}
- name: Get dependencies
run: |
sudo apt-get install git dpkg-dev rpm flex bison ca-certificates wget python3 rsync bc libssl-dev clang llvm libelf-dev libzip-dev git libnetfilter-queue-dev libpcap-dev protobuf-compiler python3-pip dh-golang golang-any golang-golang-x-net-dev golang-google-grpc-dev golang-goprotobuf-dev libmnl-dev golang-github-vishvananda-netlink-dev golang-github-evilsocket-ftrace-dev golang-github-google-gopacket-dev golang-github-fsnotify-fsnotify-dev linux-headers-$(uname -r)
- name: Download kernel sources and compile eBPF modules
run: |
kernel_version="${{ matrix.kernel }}"
if [ ! -d utils/packaging/ ]; then
mkdir -p utils/packaging/
fi
wget https://raw.githubusercontent.com/evilsocket/opensnitch/master/utils/packaging/build_modules.sh -O utils/packaging/build_modules.sh
bash utils/packaging/build_modules.sh $kernel_version
sha1sum ebpf_prog/modules/opensnitch*o > ebpf_prog/modules/checksums.txt
- uses: actions/upload-artifact@v4
with:
name: opensnitch-ebpf-modules-${{ matrix.kernel }}-${{ matrix.tag }}
path: ebpf_prog/modules/*
================================================
FILE: .github/workflows/generic_validations.yml
================================================
name: Test resources validation
on:
# Trigger this workflow only when ebpf modules changes.
push:
paths:
- 'ui/resources/*'
- '.github/workflows/generic.yml'
pull_request:
paths:
- 'ui/resources/*'
- '.github/workflows/generic.yml'
# Allow to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
name: Install tools
runs-on: ubuntu-latest
steps:
- name: Check out git code
uses: actions/checkout@v2
- name: Get and prepare dependencies
run: |
set -e
set -x
sudo apt install desktop-file-utils appstream
- name: Validate resources
run: |
set -e
set -x
desktop-file-validate ui/resources/opensnitch_ui.desktop
appstreamcli validate ui/resources/io.github.evilsocket.opensnitch.appdata.xml
================================================
FILE: .github/workflows/go.yml
================================================
name: Build status
on:
push:
paths:
- 'daemon/**'
- '.github/workflows/go.yml'
pull_request:
paths:
- 'daemon/**'
- '.github/workflows/go.yml'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.23.0
uses: actions/setup-go@v3
with:
go-version: 1.23.0
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v3
- name: Get dependencies
run: |
sudo apt-get install git libnetfilter-queue-dev libmnl-dev libpcap-dev protobuf-compiler
export GOPATH=~/go
export PATH=$PATH:$GOPATH/bin
go install github.com/golang/protobuf/protoc-gen-go@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.1
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
cd proto
make ../daemon/ui/protocol/ui.pb.go
cd ../daemon
go mod tidy; go mod vendor
- name: Build
run: |
cd daemon
go build -v .
- name: Test
run: |
cd daemon
sudo PRIVILEGED_TESTS=1 NETLINK_TESTS=1 go test ./...
================================================
FILE: .gitignore
================================================
*.sock
*.pyc
*.profile
.vscode/
.idea/
.DS_Store
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: Makefile
================================================
all: protocol opensnitch_daemon gui
install:
@cd daemon && make install
@cd ui && make install
protocol:
@cd proto && make
opensnitch_daemon:
@cd daemon && make
gui:
@cd ui && make
clean:
@cd daemon && make clean
@cd proto && make clean
@cd ui && make clean
run:
cd ui && pip3 install --upgrade . && cd ..
opensnitch-ui --socket unix:///tmp/osui.sock &
./daemon/opensnitchd -rules-path /etc/opensnitchd/rules -ui-socket unix:///tmp/osui.sock -cpu-profile cpu.profile -mem-profile mem.profile
test:
clear
make clean
clear
mkdir -p rules
make
clear
make run
adblocker:
clear
make clean
clear
make
clear
python make_ads_rules.py
clear
cd ui && pip3 install --upgrade . && cd ..
opensnitch-ui --socket unix:///tmp/osui.sock &
./daemon/opensnitchd -rules-path /etc/opensnitchd/rules -ui-socket unix:///tmp/osui.sock
================================================
FILE: README.md
================================================
<p align="center">
<small>Join the project community on our server!</small>
<br/><br/>
<a href="https://discord.gg/btZpkp45gQ" target="_blank" title="Join our community!">
<img src="https://dcbadge.limes.pink/api/server/https://discord.gg/btZpkp45gQ"/>
</a>
</p>
<hr/>
<p align="center">
<img alt="opensnitch" src="https://raw.githubusercontent.com/evilsocket/opensnitch/master/ui/opensnitch/res/icon.png" height="160" />
<p align="center">
<img src="https://github.com/evilsocket/opensnitch/workflows/Build%20status/badge.svg" />
<a href="https://github.com/evilsocket/opensnitch/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/evilsocket/opensnitch.svg?style=flat-square"></a>
<a href="https://github.com/evilsocket/opensnitch/blob/master/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-GPL3-brightgreen.svg?style=flat-square"></a>
<a href="https://goreportcard.com/report/github.com/evilsocket/opensnitch/daemon"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/evilsocket/opensnitch/daemon?style=flat-square"></a>
<a href="https://repology.org/project/opensnitch/versions"><img src="https://repology.org/badge/tiny-repos/opensnitch.svg" alt="Packaging status"></a>
</p>
</p>
<p align="center"><strong>OpenSnitch</strong> is a GNU/Linux application firewall.</p>
<p align="center">•• <a href="#key-features">Key Features</a> • <a href="#download">Download</a> • <a href="#installation">Installation</a> • <a href="#opensnitch-in-action">Usage examples</a> • <a href="#in-the-press">In the press</a> ••</p>
<p align="center">
<img src="https://user-images.githubusercontent.com/2742953/85205382-6ba9cb00-b31b-11ea-8e9a-bd4b8b05a236.png" alt="OpenSnitch"/>
</p>
## Key features
* Interactive outbound connections filtering.
* [Block ads, trackers or malware domains](https://github.com/evilsocket/opensnitch/wiki/block-lists) system wide.
* Ability to [configure system firewall](https://github.com/evilsocket/opensnitch/wiki/System-rules) from the GUI (nftables).
- Configure input policy, allow inbound services, etc.
* Manage [multiple nodes](https://github.com/evilsocket/opensnitch/wiki/Nodes) from a centralized GUI.
* [SIEM integration](https://github.com/evilsocket/opensnitch/wiki/SIEM-integration)
## Download
Download deb/rpm packages for your system from https://github.com/evilsocket/opensnitch/releases
## Installation
#### deb
> $ sudo apt install ./opensnitch*.deb ./python3-opensnitch-ui*.deb
#### rpm
> $ sudo dnf install opensnitch*.rpm
Then run: `$ opensnitch-ui` or launch the GUI from the Applications menu.
Please, refer to [the documentation](https://github.com/evilsocket/opensnitch/wiki/Installation) for detailed information.
## OpenSnitch in action
Examples of OpenSnitch intercepting unexpected connections:
https://github.com/evilsocket/opensnitch/discussions/categories/show-and-tell
Have you seen a connection you didn't expect? [submit it!](https://github.com/evilsocket/opensnitch/discussions/new?category=show-and-tell)
## In the press
- 2017 [PenTest Magazine](https://twitter.com/pentestmag/status/857321886807605248)
- 11/2019 [It's Foss](https://itsfoss.com/opensnitch-firewall-linux/)
- 03/2020 [Linux Format #232](https://www.linux-magazine.com/Issues/2020/232/Firewalld-and-OpenSnitch)
- 08/2020 [Linux Magazine Polska #194](https://linux-magazine.pl/archiwum/wydanie/387)
- 08/2021 [Linux Format #280](https://github.com/evilsocket/opensnitch/discussions/631)
- 02/2022 [Linux User](https://www.linux-community.de/magazine/linuxuser/2022/03/)
- 06/2022 [Linux Magazine #259](https://www.linux-magazine.com/Issues/2022/259/OpenSnitch)
## Donations
If you find OpenSnitch useful and want to donate to the dedicated developers, you can do it from the **[Sponsor this project](https://github.com/sponsors/gustavo-iniguez-goya)** section on the right side of this repository.
You can see here who are the current maintainers of OpenSnitch:
https://github.com/evilsocket/opensnitch/commits/master
## Contributors
[See the list](https://github.com/evilsocket/opensnitch/graphs/contributors)
## Translating
<a href="https://hosted.weblate.org/engage/opensnitch/">
<img src="https://hosted.weblate.org/widget/opensnitch/multi-auto.svg" alt="Translation status" />
</a>
================================================
FILE: daemon/.gitignore
================================================
opensnitchd
vendor
================================================
FILE: daemon/Gopkg.toml
================================================
[[constraint]]
name = "github.com/fsnotify/fsnotify"
version = "1.4.7"
[[constraint]]
name = "github.com/google/gopacket"
version = "~1.1.14"
[[constraint]]
name = "google.golang.org/grpc"
version = "~1.11.2"
[[constraint]]
name = "github.com/evilsocket/ftrace"
version = "~1.2.0"
[prune]
go-tests = true
unused-packages = true
================================================
FILE: daemon/Makefile
================================================
#SRC contains all *.go *.c *.h files in daemon/ and its subfolders
SRC := $(shell find . -type f -name '*.go' -o -name '*.h' -o -name '*.c')
PREFIX?=/usr/local
all: opensnitchd
install:
@mkdir -p $(DESTDIR)/etc/opensnitchd/rules
@mkdir -p $(DESTDIR)/etc/opensnitchd/tasks
@install -Dm755 opensnitchd \
-t $(DESTDIR)$(PREFIX)/bin/
@install -Dm644 data/init/opensnitchd.service \
-t $(DESTDIR)/etc/systemd/system/
@install -Dm644 data/default-config.json \
-t $(DESTDIR)/etc/opensnitchd/
@install -Dm644 data/system-fw.json \
-t $(DESTDIR)/etc/opensnitchd/
@install -Dm644 data/network_aliases.json \
-t $(DESTDIR)/etc/opensnitchd/
@install -Dm600 data/rules/* $(DESTDIR)/etc/opensnitchd/rules/
@install -Dm600 data/tasks/tasks.json $(DESTDIR)/etc/opensnitchd/tasks/
@systemctl daemon-reload
opensnitchd: $(SRC)
@go get
@go build -o opensnitchd .
clean:
@rm -rf opensnitchd
================================================
FILE: daemon/conman/connection.go
================================================
package conman
import (
"errors"
"fmt"
"net"
"os"
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/dns"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/evilsocket/opensnitch/daemon/netfilter"
"github.com/evilsocket/opensnitch/daemon/netlink"
"github.com/evilsocket/opensnitch/daemon/netstat"
"github.com/evilsocket/opensnitch/daemon/procmon"
"github.com/evilsocket/opensnitch/daemon/procmon/audit"
"github.com/evilsocket/opensnitch/daemon/procmon/ebpf"
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
"github.com/google/gopacket/layers"
)
// Connection represents an outgoing connection.
type Connection struct {
Pkt *netfilter.Packet
Entry *netstat.Entry
Process *procmon.Process
Protocol string
DstHost string
SrcIP net.IP
DstIP net.IP
SrcPort uint
DstPort uint
}
var showUnknownCons = false
// Parse extracts the IP layers from a network packet to determine what
// process generated a connection.
func Parse(nfp netfilter.Packet, interceptUnknown bool) *Connection {
showUnknownCons = interceptUnknown
log.Trace("Connection.Parse(): %v", nfp)
if nfp.IsIPv4() {
con, err := NewConnection(&nfp)
if err != nil {
log.Debug("%s", err)
return nil
} else if con == nil {
return nil
}
return con
}
if core.IPv6Enabled == false {
return nil
}
con, err := NewConnection6(&nfp)
if err != nil {
log.Debug("%s", err)
return nil
} else if con == nil {
return nil
}
return con
}
func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (cr *Connection, err error) {
// no errors but not enough info neither
if c.parseDirection(protoType) == false {
log.Trace("discarding connection (proto %s): %+v", protoType, c)
return nil, nil
}
log.Debug("new connection %s => %d:%v -> %v (%s):%d uid: %d, mark: %x", c.Protocol, c.SrcPort, c.SrcIP, c.DstIP, c.DstHost, c.DstPort, nfp.UID, nfp.Mark)
c.Entry = &netstat.Entry{
Proto: c.Protocol,
SrcIP: c.SrcIP,
SrcPort: c.SrcPort,
DstIP: c.DstIP,
DstPort: c.DstPort,
UserId: -1,
INode: -1,
}
pid := -1
uid := -1
if procmon.MethodIsEbpf() {
swap := false
c.Process, swap, err = ebpf.GetPid(c.Protocol, c.SrcPort, c.SrcIP, c.DstIP, c.DstPort)
if swap {
c.swapFields()
}
if c.Process != nil {
c.Entry.UserId = c.Process.UID
return c, nil
}
if err != nil {
log.Debug("ebpf warning: %v", err)
}
log.Debug("[ebpf conn] PID not found via eBPF, falling back to proc")
} else if procmon.MethodIsAudit() {
if aevent := audit.GetEventByPid(pid); aevent != nil {
audit.Lock.RLock()
c.Process = procmon.NewProcessEmpty(pid, aevent.ProcName)
c.Process.Path = aevent.ProcPath
c.Process.ReadCmdline()
c.Process.CWD = aevent.ProcDir
audit.Lock.RUnlock()
// if the proc dir contains non alhpa-numeric chars the field is empty
if c.Process.CWD == "" {
c.Process.ReadCwd()
}
c.Process.ReadEnv()
c.Process.CleanPath()
procmon.EventsCache.Add(c.Process)
return c, nil
}
log.Debug("[auditd conn] PID not found via auditd, falling back to proc")
}
// Sometimes when using eBPF, the PID is not found by the connection's parameters,
// but falling back to legacy methods helps to find it and avoid "unknown/kernel pop-ups".
//
// One of the reasons is because after coming back from suspend state, for some reason (bug?),
// gobpf/libbpf is unable to delete ebpf map entries, so when they reach the maximum capacity no
// more entries are added, nor updated.
if pid < 0 {
// 0. lookup uid and inode via netlink. Can return several inodes.
// 1. lookup uid and inode using /proc/net/(udp|tcp|udplite)
// 2. lookup pid by inode
// 3. if this is coming from us, just accept
// 4. lookup process info by pid
var inodeList []int
uid, inodeList = netlink.GetSocketInfo(c.Protocol, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort)
if len(inodeList) == 0 {
procmon.GetInodeFromNetstat(c.Entry, &inodeList, c.Protocol, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort)
}
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 [%d]", n, pid, inode)
c.Entry.INode = inode
break
}
}
}
if pid == os.Getpid() {
// return a Process object with our PID, to be able to exclude our own connections
// (to the UI on a local socket for example)
c.Process = procmon.NewProcessEmpty(pid, "")
return c, nil
}
if nfp.UID != 0xffffffff {
uid = int(nfp.UID)
}
c.Entry.UserId = uid
if c.Process == nil {
if c.Process = procmon.FindProcess(pid, showUnknownCons); c.Process == nil {
return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
}
}
return c, nil
}
// NewConnection creates a new Connection object, and returns the details of it.
func NewConnection(nfp *netfilter.Packet) (c *Connection, err error) {
ipv4 := nfp.Packet.Layer(layers.LayerTypeIPv4)
if ipv4 == nil {
return nil, errors.New("Error getting IPv4 layer")
}
ip, ok := ipv4.(*layers.IPv4)
if !ok {
return nil, errors.New("Error getting IPv4 layer data")
}
c = &Connection{
SrcIP: ip.SrcIP,
DstIP: ip.DstIP,
DstHost: dns.HostOr(ip.DstIP, ""),
Pkt: nfp,
}
return newConnectionImpl(nfp, c, "")
}
// NewConnection6 creates a IPv6 new Connection object, and returns the details of it.
func NewConnection6(nfp *netfilter.Packet) (c *Connection, err error) {
ipv6 := nfp.Packet.Layer(layers.LayerTypeIPv6)
if ipv6 == nil {
return nil, errors.New("Error getting IPv6 layer")
}
ip, ok := ipv6.(*layers.IPv6)
if !ok {
return nil, errors.New("Error getting IPv6 layer data")
}
c = &Connection{
SrcIP: ip.SrcIP,
DstIP: ip.DstIP,
DstHost: dns.HostOr(ip.DstIP, ""),
Pkt: nfp,
}
return newConnectionImpl(nfp, c, "6")
}
func (c *Connection) parseDirection(protoType string) bool {
ret := false
if tcpLayer := c.Pkt.Packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
if tcp, ok := tcpLayer.(*layers.TCP); ok == true && tcp != nil {
c.Protocol = "tcp" + protoType
c.DstPort = uint(tcp.DstPort)
c.SrcPort = uint(tcp.SrcPort)
ret = true
if tcp.DstPort == 53 {
c.getDomains(c.Pkt, c)
}
}
} else if udpLayer := c.Pkt.Packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
if udp, ok := udpLayer.(*layers.UDP); ok == true && udp != nil {
c.Protocol = "udp" + protoType
c.DstPort = uint(udp.DstPort)
c.SrcPort = uint(udp.SrcPort)
ret = true
if udp.DstPort == 53 {
c.getDomains(c.Pkt, c)
}
}
} else if udpliteLayer := c.Pkt.Packet.Layer(layers.LayerTypeUDPLite); udpliteLayer != nil {
if udplite, ok := udpliteLayer.(*layers.UDPLite); ok == true && udplite != nil {
c.Protocol = "udplite" + protoType
c.DstPort = uint(udplite.DstPort)
c.SrcPort = uint(udplite.SrcPort)
ret = true
}
} else if sctpLayer := c.Pkt.Packet.Layer(layers.LayerTypeSCTP); sctpLayer != nil {
if sctp, ok := sctpLayer.(*layers.SCTP); ok == true && sctp != nil {
c.Protocol = "sctp" + protoType
c.DstPort = uint(sctp.DstPort)
c.SrcPort = uint(sctp.SrcPort)
ret = true
}
} else if icmpLayer := c.Pkt.Packet.Layer(layers.LayerTypeICMPv4); icmpLayer != nil {
if icmp, ok := icmpLayer.(*layers.ICMPv4); ok == true && icmp != nil {
c.Protocol = "icmp"
c.DstPort = 0
c.SrcPort = 0
ret = true
}
} else if icmp6Layer := c.Pkt.Packet.Layer(layers.LayerTypeICMPv6); icmp6Layer != nil {
if icmp6, ok := icmp6Layer.(*layers.ICMPv6); ok == true && icmp6 != nil {
c.Protocol = "icmp" + protoType
c.DstPort = 0
c.SrcPort = 0
ret = true
}
}
return ret
}
// swapFields swaps connection's fields.
// Used to workaround an issue where outbound connections
// have the fields swapped (procmon/ebpf/find.go).
func (c *Connection) swapFields() {
oEntry := c.Entry
c.Entry = &netstat.Entry{
Proto: c.Protocol,
SrcIP: oEntry.DstIP,
DstIP: oEntry.SrcIP,
SrcPort: oEntry.DstPort,
DstPort: oEntry.SrcPort,
UserId: oEntry.UserId,
INode: oEntry.INode,
}
c.SrcIP = oEntry.DstIP
c.DstIP = oEntry.SrcIP
c.DstPort = oEntry.SrcPort
c.SrcPort = oEntry.DstPort
}
func (c *Connection) getDomains(nfp *netfilter.Packet, con *Connection) {
domains := dns.GetQuestions(nfp)
if len(domains) < 1 {
return
}
for _, dns := range domains {
con.DstHost = dns
}
}
// To returns the destination host of a connection.
func (c *Connection) To() string {
if c.DstHost == "" {
return c.DstIP.String()
}
return fmt.Sprintf("%s (%s)", c.DstHost, c.DstIP)
}
func (c *Connection) String() string {
if c.Entry == nil {
return fmt.Sprintf("%d:%s ->(%s)-> %s:%d", c.SrcPort, c.SrcIP, c.Protocol, c.To(), c.DstPort)
}
if c.Process == nil {
return fmt.Sprintf("%d:%s (uid:%d) ->(%s)-> %s:%d", c.SrcPort, c.SrcIP, c.Entry.UserId, c.Protocol, c.To(), c.DstPort)
}
return fmt.Sprintf("%s (%d) -> %s:%d (proto:%s uid:%d)", c.Process.Path, c.Process.ID, c.To(), c.DstPort, c.Protocol, c.Entry.UserId)
}
// Serialize returns a connection serialized.
func (c *Connection) Serialize() *protocol.Connection {
c.Process.RLock()
defer c.Process.RUnlock()
return &protocol.Connection{
Protocol: c.Protocol,
SrcIp: c.SrcIP.String(),
SrcPort: uint32(c.SrcPort),
DstIp: c.DstIP.String(),
DstHost: c.DstHost,
DstPort: uint32(c.DstPort),
UserId: uint32(c.Entry.UserId),
ProcessId: uint32(c.Process.ID),
ProcessPath: c.Process.Path,
ProcessArgs: c.Process.Args,
ProcessEnv: c.Process.Env,
ProcessCwd: c.Process.CWD,
ProcessChecksums: c.Process.Checksums,
ProcessTree: c.Process.Tree,
}
}
================================================
FILE: daemon/conman/connection_test.go
================================================
package conman
import (
"fmt"
"net"
"testing"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/evilsocket/opensnitch/daemon/netfilter"
)
// Adding new packets:
// wireshark -> right click -> Copy as HexDump -> create []byte{}
func NewTCPPacket() gopacket.Packet {
// 47676:192.168.1.100 -> 1.1.1.1:23
testTCPPacket := []byte{0x4c, 0x6e, 0x6e, 0xd5, 0x79, 0xbf, 0x00, 0x28, 0x9d, 0x43, 0x7f, 0xd7, 0x08, 0x00, 0x45, 0x10,
0x00, 0x3c, 0x1d, 0x07, 0x40, 0x00, 0x40, 0x06, 0x59, 0x8e, 0xc0, 0xa8, 0x01, 0x6d, 0x01, 0x01,
0x01, 0x01, 0xba, 0x3c, 0x00, 0x17, 0x47, 0x7e, 0xf3, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
0xfa, 0xf0, 0x4c, 0x27, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x91, 0xfb,
0xb5, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0a}
return gopacket.NewPacket(testTCPPacket, layers.LinkTypeEthernet, gopacket.Default)
}
func NewUDPPacket() gopacket.Packet {
// 29517:192.168.1.109 -> 1.0.0.1:53
testUDPPacketDNS := []byte{
0x4c, 0x6e, 0x6e, 0xd5, 0x79, 0xbf, 0x00, 0x28, 0x9d, 0x43, 0x7f, 0xd7, 0x08, 0x00, 0x45, 0x00,
0x00, 0x40, 0x54, 0x1a, 0x40, 0x00, 0x3f, 0x11, 0x24, 0x7d, 0xc0, 0xa8, 0x01, 0x6d, 0x01, 0x00,
0x00, 0x01, 0x73, 0x4d, 0x00, 0x35, 0x00, 0x2c, 0xf1, 0x17, 0x05, 0x51, 0x00, 0x20, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x70, 0x69, 0x04, 0x68, 0x6f, 0x6c, 0x65, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
}
return gopacket.NewPacket(testUDPPacketDNS, layers.LinkTypeEthernet, gopacket.Default)
}
func EstablishConnection(proto, dst string) (net.Conn, error) {
c, err := net.Dial(proto, dst)
if err != nil {
fmt.Println(err)
return nil, err
}
return c, nil
}
func ListenOnPort(proto, port string) (net.Listener, error) {
l, err := net.Listen(proto, port)
if err != nil {
fmt.Println(err)
return nil, err
}
return l, nil
}
func NewPacket(pkt gopacket.Packet) *netfilter.Packet {
return &netfilter.Packet{
Packet: pkt,
UID: 666,
NetworkProtocol: netfilter.IPv4,
}
}
func NewDummyConnection(src, dst net.IP) *Connection {
return &Connection{
SrcIP: src,
DstIP: dst,
}
}
// Test TCP parseDirection()
func TestParseTCPDirection(t *testing.T) {
srcIP := net.IP{192, 168, 1, 100}
dstIP := net.IP{1, 1, 1, 1}
c := NewDummyConnection(srcIP, dstIP)
// 47676:192.168.1.100 -> 1.1.1.1:23
pkt := NewPacket(NewTCPPacket())
c.Pkt = pkt
// parseDirection extracts the src and dst port from a network packet.
if c.parseDirection("") == false {
t.Error("parseDirection() should not be false")
t.Fail()
}
if c.SrcPort != 47676 {
t.Error("parseDirection() SrcPort mismatch:", c)
t.Fail()
}
if c.DstPort != 23 {
t.Error("parseDirection() DstPort mismatch:", c)
t.Fail()
}
if c.Protocol != "tcp" {
t.Error("parseDirection() Protocol mismatch:", c)
t.Fail()
}
}
// Test UDP parseDirection()
func TestParseUDPDirection(t *testing.T) {
srcIP := net.IP{192, 168, 1, 100}
dstIP := net.IP{1, 0, 0, 1}
c := NewDummyConnection(srcIP, dstIP)
// 29517:192.168.1.109 -> 1.0.0.1:53
pkt := NewPacket(NewUDPPacket())
c.Pkt = pkt
// parseDirection extracts the src and dst port from a network packet.
if c.parseDirection("") == false {
t.Error("parseDirection() should not be false")
t.Fail()
}
if c.SrcPort != 29517 {
t.Error("parseDirection() SrcPort mismatch:", c)
t.Fail()
}
if c.DstPort != 53 {
t.Error("parseDirection() DstPort mismatch:", c)
t.Fail()
}
if c.Protocol != "udp" {
t.Error("parseDirection() Protocol mismatch:", c)
t.Fail()
}
}
================================================
FILE: daemon/core/core.go
================================================
package core
import (
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"strings"
"time"
)
const (
defaultTrimSet = "\r\n\t "
)
// Trim remove trailing spaces from a string.
func Trim(s string) string {
return strings.Trim(s, defaultTrimSet)
}
// Exec spawns a new process and reurns the output.
func Exec(executable string, args []string) (string, error) {
path, err := exec.LookPath(executable)
if err != nil {
return "", err
}
raw, err := exec.Command(path, args...).CombinedOutput()
if err != nil {
return "", err
}
return Trim(string(raw)), nil
}
// Exists checks if a path exists.
func Exists(path string) bool {
if _, err := os.Stat(path); os.IsNotExist(err) {
return false
}
return true
}
// ExpandPath replaces '~' shorthand with the user's home directory.
func ExpandPath(path string) (string, error) {
// Check if path is empty
if path != "" {
if strings.HasPrefix(path, "~") {
usr, err := user.Current()
if err != nil {
return "", err
}
// Replace only the first occurrence of ~
path = strings.Replace(path, "~", usr.HomeDir, 1)
}
return filepath.Abs(path)
}
return "", nil
}
// IsAbsPath verifies if a path is absolute or not
func IsAbsPath(path string) bool {
return path[0] == 47 // 47 == '/'
}
// GetFileModTime checks if a file has been modified.
func GetFileModTime(filepath string) (time.Time, error) {
fi, err := os.Stat(filepath)
if err != nil || fi.IsDir() {
return time.Now(), fmt.Errorf("GetFileModTime() Invalid file")
}
return fi.ModTime(), nil
}
// ConcatStrings joins the provided strings.
func ConcatStrings(args ...string) string {
return strings.Join(args, "")
}
================================================
FILE: daemon/core/ebpf.go
================================================
package core
import (
"fmt"
"github.com/cilium/ebpf"
"github.com/evilsocket/opensnitch/daemon/log"
)
// LoadEbpfModule loads the given eBPF module, from the given path if specified.
// Otherwise t'll try to load the module from several default paths.
func LoadEbpfModule(module, path string) (m *ebpf.Collection, err error) {
var (
modulesDir = "/opensnitchd/ebpf"
paths = []string{
fmt.Sprint("/usr/local/lib", modulesDir),
fmt.Sprint("/usr/lib", modulesDir),
fmt.Sprint("/etc/opensnitchd"), // Deprecated: will be removed in future versions.
}
)
// if path has been specified, try to load the module from there.
if path != "" {
paths = []string{path}
}
modulePath := ""
moduleError := fmt.Errorf(`Module not found (%s) in any of the paths.
You may need to install the corresponding package`, module)
logLevel := ebpf.LogLevel(0)
if log.GetLogLevel() == log.DEBUG {
logLevel = (ebpf.LogLevelBranch | ebpf.LogLevelInstruction | ebpf.LogLevelStats)
}
collOpts := ebpf.CollectionOptions{
Programs: ebpf.ProgramOptions{LogLevel: logLevel},
}
for _, p := range paths {
modulePath = fmt.Sprint(p, "/", module)
log.Debug("[eBPF] trying to load %s", modulePath)
if !Exists(modulePath) {
continue
}
specs, err := ebpf.LoadCollectionSpec(modulePath)
if err != nil {
log.Error("[eBPF] module specs error: %s", err)
continue
}
m, err := ebpf.NewCollectionWithOptions(specs, collOpts)
if err != nil {
log.Error("[eBPF] module collection error: %s", err)
continue
}
log.Info("[eBPF] module loaded: %s", modulePath)
return m, nil
}
moduleError = fmt.Errorf(`
unable to load eBPF module (%s). Your kernel version (%s) might not be compatible.
If this error persists, change process monitor method to 'proc'`, module, GetKernelVersion())
return m, moduleError
}
================================================
FILE: daemon/core/gzip.go
================================================
package core
import (
"compress/gzip"
"io/ioutil"
"os"
)
// ReadGzipFile reads a gzip to text.
func ReadGzipFile(filename string) ([]byte, error) {
fd, err := os.Open(filename)
if err != nil {
return nil, err
}
defer fd.Close()
gz, err := gzip.NewReader(fd)
if err != nil {
return nil, err
}
defer gz.Close()
s, err := ioutil.ReadAll(gz)
if err != nil {
return nil, err
}
return s, nil
}
================================================
FILE: daemon/core/system.go
================================================
package core
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"regexp"
"strings"
"github.com/evilsocket/opensnitch/daemon/log"
)
var (
// IPv6Enabled indicates if IPv6 protocol is enabled in the system
IPv6Enabled = Exists("/proc/sys/net/ipv6")
)
// GetHostname returns the name of the host where the daemon is running.
func GetHostname() string {
hostname, _ := ioutil.ReadFile("/proc/sys/kernel/hostname")
return strings.Replace(string(hostname), "\n", "", -1)
}
// GetKernelVersion returns the kernel version.
func GetKernelVersion() string {
version, _ := ioutil.ReadFile("/proc/sys/kernel/osrelease")
return strings.Replace(string(version), "\n", "", -1)
}
// GetMounts returns the mounts of the system
func GetMounts() []string {
buf, _ := ioutil.ReadFile("/proc/mounts")
return strings.Split(string(buf), "\n")
}
// HasTraceFS returns if tracefs is mounted
func IsTraceFSMounted() bool {
for _, line := range GetMounts() {
if strings.Contains(line, "tracefs") {
return true
}
}
return false
}
// CheckSysRequirements checks system features we need to work properly
func CheckSysRequirements() {
type checksT struct {
RegExps []string
Reason string
}
type ReqsList struct {
Item string
Checks checksT
}
kVer := GetKernelVersion()
log.Raw("\n\t%sChecking system requirements for kernel version %s%s\n", log.FG_WHITE+log.BG_LBLUE, kVer, log.RESET)
log.Raw("%s------------------------------------------------------------------------------%s\n\n", log.FG_WHITE+log.BG_LBLUE, log.RESET)
confPaths := []string{
fmt.Sprint("/boot/config-", kVer),
"/proc/config.gz",
// Fedora SilverBlue
fmt.Sprint("/usr/lib/modules/", kVer, "/config"),
}
var fileContent []byte
var err error
for _, confFile := range confPaths {
if !Exists(confFile) {
err = fmt.Errorf("%s not found", confFile)
log.Debug(err.Error())
continue
}
if confFile[len(confFile)-2:] == "gz" {
fileContent, err = ReadGzipFile(confFile)
} else {
fileContent, err = ioutil.ReadFile(confFile)
}
if err == nil {
break
}
}
if err != nil {
fmt.Printf("\n\t%s kernel config not found (%s) in any of the expected paths.\n", log.Bold(log.Red("✘")), kVer)
fmt.Printf("\tPlease, open a new issue on github specifying your kernel and distro version (/etc/os-release).\n\n")
return
}
// TODO: check loaded/configured modules (nfnetlink, nfnetlink_queue, xt_NFQUEUE, etc)
// Other items to check:
// CONFIG_NETFILTER_NETLINK
// CONFIG_NETFILTER_NETLINK_QUEUE
const reqsList = `
[
{
"Item": "kprobes",
"Checks": {
"Regexps": [
"CONFIG_KPROBES=y",
"CONFIG_KPROBES_ON_FTRACE=y",
"CONFIG_HAVE_KPROBES=y",
"CONFIG_HAVE_KPROBES_ON_FTRACE=y",
"CONFIG_KPROBE_EVENTS=y"
],
"Reason": " - KPROBES not fully supported by this kernel."
}
},
{
"Item": "uprobes",
"Checks": {
"Regexps": [
"CONFIG_UPROBES=y",
"CONFIG_UPROBE_EVENTS=y"
],
"Reason": " * UPROBES not supported. Common error => cannot open uprobe_events: open /sys/kernel/debug/tracing/uprobe_events"
}
},
{
"Item": "ftrace",
"Checks": {
"Regexps": [
"CONFIG_FTRACE=y"
],
"Reason": " - CONFIG_FTRACE=y not set. Common error => Error while loading kprobes: invalid argument."
}
},
{
"Item": "syscalls",
"Checks": {
"Regexps": [
"CONFIG_HAVE_SYSCALL_TRACEPOINTS=y",
"CONFIG_FTRACE_SYSCALLS=y",
"CONFIG_TRACING=[my]",
"CONFIG_EVENT_TRACING=[my]"
],
"Reason": " - CONFIG_FTRACE_SYSCALLS, CONFIG_HAVE_SYSCALL_TRACEPOINTS, CONFIG_TRACE or CONFIG_EVENT_TRACING not set. Common error => error enabling tracepoint tracepoint/syscalls/sys_enter_execve: cannot read tracepoint id"
}
},
{
"Item": "nfqueue",
"Checks": {
"Regexps": [
"CONFIG_NETFILTER_NETLINK_QUEUE=[my]",
"CONFIG_NFT_QUEUE=[my]",
"CONFIG_NETFILTER_XT_TARGET_NFQUEUE=[my]"
],
"Reason": " * NFQUEUE netfilter extensions not supported by this kernel (CONFIG_NETFILTER_NETLINK_QUEUE, CONFIG_NFT_QUEUE, CONFIG_NETFILTER_XT_TARGET_NFQUEUE)."
}
},
{
"Item": "netlink",
"Checks": {
"Regexps": [
"CONFIG_NETFILTER_NETLINK=[my]",
"CONFIG_NETFILTER_NETLINK_QUEUE=[my]",
"CONFIG_NETFILTER_NETLINK_ACCT=[my]",
"CONFIG_PROC_EVENTS=[my]"
],
"Reason": " * NETLINK extensions not supported by this kernel (CONFIG_NETFILTER_NETLINK, CONFIG_NETFILTER_NETLINK_QUEUE, CONFIG_NETFILTER_NETLINK_ACCT or CONFIG_PROC_EVENTS)."
}
},
{
"Item": "net diagnostics",
"Checks": {
"Regexps": [
"CONFIG_INET_DIAG=[my]",
"CONFIG_INET_TCP_DIAG=[my]",
"CONFIG_INET_UDP_DIAG=[my]",
"CONFIG_INET_DIAG_DESTROY=[my]"
],
"Reason": " * One or more socket monitoring interfaces are not enabled (CONFIG_INET_DIAG, CONFIG_INET_TCP_DIAG, CONFIG_INET_UDP_DIAG, CONFIG_DIAG_DESTROY (Reject feature))."
}
}
]
`
reqsFullfiled := true
dec := json.NewDecoder(strings.NewReader(reqsList))
for {
var reqs []ReqsList
if err := dec.Decode(&reqs); err == io.EOF {
break
} else if err != nil {
log.Error("%s", err)
break
}
for _, req := range reqs {
checkOk := true
for _, trex := range req.Checks.RegExps {
fmt.Printf("\tChecking => %s\n", trex)
re, err := regexp.Compile(trex)
if err != nil {
fmt.Printf("\t%s %s\n", log.Bold(log.Red("Invalid regexp =>")), log.Red(trex))
continue
}
if re.Find(fileContent) == nil {
fmt.Printf("\t%s\n", log.Red(req.Checks.Reason))
checkOk = false
}
}
if checkOk {
fmt.Printf("\n\t* %s\t %s\n", log.Bold(log.Green(req.Item)), log.Bold(log.Green("✔")))
} else {
reqsFullfiled = false
fmt.Printf("\n\t* %s\t %s\n", log.Bold(log.Red(req.Item)), log.Bold(log.Red("✘")))
}
fmt.Println()
}
}
if IsTraceFSMounted() {
fmt.Printf("\t* %s\t %s\n\n", log.Bold(log.Green("tracefs mount")), log.Bold(log.Green("✔")))
} else {
reqsFullfiled = false
fmt.Printf("\t* %s\t %s\n\n", log.Bold(log.Red("tracefs mount not found, needed for syscalls (mount -t tracefs none /sys/kernel/tracing/)")), log.Bold(log.Red("✘")))
}
if !reqsFullfiled {
log.Raw("\n%sWARNING:%s Your kernel doesn't support some of the features OpenSnitch needs:\nRead more: https://github.com/evilsocket/opensnitch/issues/774\n", log.FG_WHITE+log.BG_YELLOW, log.RESET)
}
}
================================================
FILE: daemon/core/version.go
================================================
package core
// version related consts
const (
Name = "opensnitch-daemon"
Version = "1.9.0"
Author = "Simone 'evilsocket' Margaritelli"
Website = "https://github.com/evilsocket/opensnitch"
)
================================================
FILE: daemon/data/default-config.json
================================================
{
"Server":
{
"Address":"unix:///tmp/osui.sock",
"Authentication": {
"Type": "simple",
"TLSOptions": {
"CACert": "",
"ServerCert": "",
"ClientCert": "",
"ClientKey": "",
"SkipVerify": false,
"ClientAuthType": "no-client-cert"
}
},
"LogFile":"/var/log/opensnitchd.log"
},
"DefaultAction": "allow",
"DefaultDuration": "once",
"InterceptUnknown": false,
"ProcMonitorMethod": "ebpf",
"LogLevel": 2,
"LogUTC": true,
"LogMicro": false,
"Firewall": "nftables",
"FwOptions": {
"ConfigPath": "/etc/opensnitchd/system-fw.json",
"MonitorInterval": "15s",
"QueueBypass": true
},
"Rules": {
"Path": "/etc/opensnitchd/rules/",
"EnableChecksums": false
},
"Ebpf": {
"EventsWorkers": 8,
"QueueEventsSize": 0
},
"Stats": {
"MaxEvents": 250,
"MaxStats": 25,
"Workers": 6
},
"Internal": {
"GCPercent": 100,
"FlushConnsOnStart": true
}
}
================================================
FILE: daemon/data/init/opensnitchd-dinit
================================================
# Application firewall OpenSnitch
type = process
command = /usr/bin/opensnitchd
restart = true
smooth-recovery = yes
restart-delay = 15
stop-timeout = 10
restart-limit-count = 0
================================================
FILE: daemon/data/init/opensnitchd-openrc
================================================
#!/sbin/openrc-run
# OpenSnitch firewall service
depend() {
before net
after iptables ip6tables
use logger
provide firewall
}
start_pre() {
/bin/mkdir -p /etc/opensnitchd/rules
/bin/chown -R root:root /etc/opensnitchd
/bin/chown root:root /var/log/opensnitchd.log
/bin/chmod -R 755 /etc/opensnitchd
/bin/chmod -R 0644 /etc/opensnitchd/rules
/bin/chmod 0600 /var/log/opensnitchd.log
}
start() {
ebegin "Starting application firewall"
# only if the verbose flag is not set (rc-service opensnitchd start -v)
if [ -z "$VERBOSE" ]; then
# redirect stdout and stderr to /dev/null
/usr/local/bin/opensnitchd > /dev/null 2>&1 &
else
/usr/local/bin/opensnitchd
fi
eend $?
}
stop() {
ebegin "Stopping application firewall"
/usr/bin/pkill -SIGINT opensnitchd
eend $?
}
================================================
FILE: daemon/data/init/opensnitchd.service
================================================
[Unit]
Description=Application firewall OpenSnitch
Documentation=https://github.com/evilsocket/opensnitch/wiki
[Service]
Type=simple
ExecStart=/usr/local/bin/opensnitchd
Restart=always
RestartSec=30
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target
================================================
FILE: daemon/data/network_aliases.json
================================================
{
"LAN": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"127.0.0.0/8",
"::1",
"fc00::/7"
],
"MULTICAST": [
"224.0.0.0/4",
"ff00::/8"
]
}
================================================
FILE: daemon/data/rules/000-allow-localhost.json
================================================
{
"created": "2025-04-09T23:21:35-06:00",
"updated": "2025-04-09T23:21:35-06:00",
"name": "000-allow-localhost",
"description": "Allow connections to localhost. More information:\n\nhttps://github.com/evilsocket/opensnitch/wiki/Rules#localhost-connections",
"action": "allow",
"duration": "always",
"operator": {
"operand": "dest.ip",
"data": "127.0.0.1",
"type": "simple",
"list": [],
"sensitive": false
},
"enabled": true,
"precedence": true,
"nolog": true
}
================================================
FILE: daemon/data/rules/000-allow-localhost6.json
================================================
{
"created": "2025-04-09T23:17:39-06:00",
"updated": "2025-04-09T23:17:39-06:00",
"name": "000-allow-localhost6",
"description": "Allow connections to localhost. More information:\n\nhttps://github.com/evilsocket/opensnitch/wiki/Rules#localhost-connections",
"action": "allow",
"duration": "always",
"operator": {
"operand": "dest.ip",
"data": "::1",
"type": "simple",
"list": [],
"sensitive": false
},
"enabled": true,
"precedence": true,
"nolog": true
}
================================================
FILE: daemon/data/system-fw.json
================================================
{
"Enabled": true,
"Version": 1,
"SystemRules": [
{
"Rule": {
"Table": "mangle",
"Chain": "OUTPUT",
"Enabled": false,
"Position": "0",
"Description": "Allow icmp",
"Parameters": "-p icmp",
"Expressions": [],
"Target": "ACCEPT",
"TargetParameters": ""
},
"Chains": []
},
{
"Chains": [
{
"Name": "filter_forward",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "filter",
"Hook": "forward",
"Policy": "accept",
"Rules": []
},
{
"Name": "filter_output",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "filter",
"Hook": "output",
"Policy": "accept",
"Rules": []
},
{
"Name": "filter_input",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "filter",
"Hook": "input",
"Policy": "accept",
"Rules": [
{
"Enabled": false,
"Position": "0",
"Description": "Allow SSH server connections when input policy is DROP",
"Parameters": "",
"Expressions": [
{
"Statement": {
"Op": "",
"Name": "tcp",
"Values": [
{
"Key": "dport",
"Value": "22"
}
]
}
}
],
"Target": "accept",
"TargetParameters": ""
}
]
},
{
"Name": "filter_prerouting",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "filter",
"Hook": "prerouting",
"Policy": "accept",
"Rules": []
},
{
"Name": "mangle_prerouting",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "mangle",
"Hook": "prerouting",
"Policy": "accept",
"Rules": []
},
{
"Name": "mangle_postrouting",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "mangle",
"Hook": "postrouting",
"Policy": "accept",
"Rules": []
},
{
"Name": "nat_prerouting",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "natdest",
"Hook": "prerouting",
"Policy": "accept",
"Rules": []
},
{
"Name": "nat_postrouting",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "natsource",
"Hook": "postrouting",
"Policy": "accept",
"Rules": []
},
{
"Name": "nat_input",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "natsource",
"Hook": "input",
"Policy": "accept",
"Rules": []
},
{
"Name": "nat_output",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "natdest",
"Hook": "output",
"Policy": "accept",
"Rules": []
},
{
"Name": "mangle_output",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "mangle",
"Hook": "output",
"Policy": "accept",
"Rules": [
{
"Enabled": false,
"Position": "0",
"Description": "allow localhost connections",
"Parameters": "",
"Expressions": [
{
"Statement": {
"Op": "==",
"Name": "ip",
"Values": [
{
"Key": "daddr",
"Value": "127.0.0.0-127.255.255.255"
}
]
}
}
],
"Target": "accept",
"TargetParameters": ""
},
{
"Enabled": true,
"Position": "0",
"Description": "Allow ICMP",
"Expressions": [
{
"Statement": {
"Op": "",
"Name": "icmp",
"Values": [
{
"Key": "type",
"Value": "echo-request,echo-reply,destination-unreachable"
}
]
}
}
],
"Target": "accept",
"TargetParameters": ""
},
{
"Enabled": true,
"Position": "0",
"Description": "Allow ICMPv6",
"Expressions": [
{
"Statement": {
"Op": "",
"Name": "icmpv6",
"Values": [
{
"Key": "type",
"Value": "echo-request,echo-reply,destination-unreachable"
}
]
}
}
],
"Target": "accept",
"TargetParameters": ""
},
{
"Enabled": false,
"Position": "0",
"Description": "Exclude WireGuard VPN from being intercepted",
"Parameters": "",
"Expressions": [
{
"Statement": {
"Op": "",
"Name": "udp",
"Values": [
{
"Key": "dport",
"Value": "51820"
}
]
}
}
],
"Target": "accept",
"TargetParameters": ""
}
]
},
{
"Name": "mangle_forward",
"Table": "opensnitch",
"Family": "inet",
"Priority": "",
"Type": "mangle",
"Hook": "forward",
"Policy": "accept",
"Rules": [
{
"UUID": "7d7394e1-100d-4b87-a90a-cd68c46edb0b",
"Enabled": false,
"Position": "0",
"Description": "Intercept forwarded connections (docker, etc)",
"Expressions": [
{
"Statement": {
"Op": "",
"Name": "ct",
"Values": [
{
"Key": "state",
"Value": "new"
}
]
}
}
],
"Target": "queue",
"TargetParameters": "num 0"
}
]
}
]
}
]
}
================================================
FILE: daemon/data/tasks/tasks.json
================================================
{
"tasks": []
}
================================================
FILE: daemon/dns/ebpfhook.go
================================================
package dns
import (
"bytes"
"debug/elf"
"encoding/binary"
"errors"
"fmt"
"net"
"os"
"os/signal"
"syscall"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/ringbuf"
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/log"
)
/*
#cgo LDFLAGS: -ldl
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <link.h>
#include <dlfcn.h>
#include <string.h>
char* find_libc() {
void *handle;
struct link_map * map;
handle = dlopen(NULL, RTLD_NOW);
if (handle == NULL) {
fprintf(stderr, "EBPF-DNS dlopen() failed: %s\n", dlerror());
return NULL;
}
if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == -1) {
fprintf(stderr, "EBPF-DNS: dlinfo failed: %s\n", dlerror());
return NULL;
}
while(1){
if(map == NULL){
break;
}
//printf("map->l_name: %s\n", map->l_name);
if(strstr(map->l_name, "libc.so")){
fprintf(stderr,"found %s\n", map->l_name);
return map->l_name;
}
map = map->l_next;
}
return NULL;
}
*/
import "C"
type nameLookupEvent struct {
AddrType uint32
IP [16]uint8
Host [252]byte
}
// ProbeDefs holds the hooks defined in the module
type ProbeDefs struct {
URProbeGethostByname *ebpf.Program `ebpf:"uretprobe__gethostbyname"`
UProbeGetAddrinfo *ebpf.Program `ebpf:"uprobe__getaddrinfo"`
URProbeGetAddrinfo *ebpf.Program `ebpf:"uretprobe__getaddrinfo"`
}
// MapDefs holds the maps defined in the module
type MapDefs struct {
// BPF_MAP_TYPE_RINGBUF
PerfEvents *ebpf.Map `ebpf:"events"`
}
// container of hooks and maps
type dnsDefsT struct {
ProbeDefs
MapDefs
}
func findLibc() (string, error) {
ret := C.find_libc()
if ret == nil {
return "", errors.New("Could not find path to libc.so")
}
str := C.GoString(ret)
return str, nil
}
// Iterates over all symbols in an elf file and returns the offset matching the provided symbol name.
func lookupSymbol(elffile *elf.File, symbolName string) (uint64, error) {
symbols, err := elffile.DynamicSymbols()
if err != nil {
return 0, err
}
for _, symb := range symbols {
if symb.Name == symbolName {
return symb.Value, nil
}
}
return 0, fmt.Errorf("Symbol: '%s' not found", symbolName)
}
// ListenerEbpf starts listening for DNS events.
func ListenerEbpf(ebpfModPath string) error {
probesAttached := 0
probesList := []link.Link{}
m, err := core.LoadEbpfModule("opensnitch-dns.o", ebpfModPath)
if err != nil {
return err
}
defer m.Close()
ebpfMod := dnsDefsT{}
if err := m.Assign(&ebpfMod); err != nil {
return err
}
// --------------
// libbcc resolves the offsets for us. without bcc the offset for uprobes must parsed from the elf files
// some how 0 must be replaced with the offset of getaddrinfo bcc does this using bcc_resolve_symname
// Attaching to uprobe using perf open might be a better aproach requires https://github.com/iovisor/gobpf/pull/277
libcFile, err := findLibc()
if err != nil {
log.Error("[eBPF DNS] Failed to find libc.so: %v", err)
return err
}
ex, err := link.OpenExecutable(libcFile)
if err != nil {
return err
}
// --------------
// User space needs to call perf_event_open() (...) before eBPF program can send data into it.
rd, err := ringbuf.NewReader(ebpfMod.PerfEvents)
if err != nil {
return err
}
defer rd.Close()
// --------------
urg, err := ex.Uretprobe("gethostbyname", ebpfMod.URProbeGethostByname, nil)
if err != nil {
log.Error("[eBPF DNS] uretprobe__gethostbyname: %s", err)
} else {
probesList = append(probesList, urg)
probesAttached++
}
up, err := ex.Uprobe("getaddrinfo", ebpfMod.UProbeGetAddrinfo, nil)
if err != nil {
log.Error("[eBPF DNS] uprobe__getaddrinfo: %s", err)
} else {
probesList = append(probesList, up)
probesAttached++
}
urp, err := ex.Uretprobe("getaddrinfo", ebpfMod.URProbeGetAddrinfo, nil)
if err != nil {
log.Error("[eBPF-DNS] uretprobe__getaddrinfo: %s", err)
} else {
probesList = append(probesList, urp)
probesAttached++
}
if probesAttached == 0 {
log.Warning("[eBPF DNS]: Failed to attach uprobes.")
return errors.New("Failed to attach uprobes")
}
// --------------
exitChannel := make(chan struct{})
// TODO: make these options configurable
// 30 is the maximum amount of IPs sent from kernel to user-space.
// Defined in opensnitch-dns.c.
perfChan := make(chan []byte, 30)
for i := 0; i < 4; i++ {
go dnsWorker(i, perfChan, exitChannel)
}
go func(perfChan chan []byte, rd *ringbuf.Reader) {
drainPerfChan := func() {
for {
select {
case <-perfChan:
default:
return
}
}
}
for {
select {
case <-exitChannel:
goto Exit
default:
record, err := rd.Read()
if err != nil {
if errors.Is(err, ringbuf.ErrClosed) {
goto Exit
}
log.Debug("[eBPF DNS] reader error: %s", err)
continue
}
select {
case perfChan <- record.RawSample:
default:
log.Debug("[eBPF DNS] events queue full, emptying queue (if you see this error too often, report it to the developers).")
drainPerfChan()
}
}
}
Exit:
log.Debug("[eBPF DNS] reader closed")
}(perfChan, rd)
sig := make(chan os.Signal, 1)
signal.Notify(sig,
syscall.SIGHUP,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGKILL,
syscall.SIGQUIT)
<-sig
log.Info("[eBPF DNS]: Received signal: terminating ebpf dns hook.")
for _, p := range probesList {
p.Close()
}
for i := 0; i < 4; i++ {
exitChannel <- struct{}{}
}
return nil
}
func dnsWorker(id int, channel chan []byte, exitChannel chan struct{}) {
log.Debug("[eBPF DNS] worker initialized #%d", id)
var event nameLookupEvent
var ip net.IP
for data := range channel {
select {
case <-exitChannel:
goto Exit
// case data := <-channel:
default:
event = nameLookupEvent{}
if len(data) > 0 {
log.Trace("(%d) [eBPF DNS]: LookupEvent %d %x %x %x", id, len(data), data[:4], data[4:20], data[20:])
}
err := binary.Read(bytes.NewBuffer(data), binary.LittleEndian, &event)
if err != nil {
log.Warning("(%d) [eBPF DNS]: Failed to decode ebpf nameLookupEvent: %s\n", id, err)
continue
}
// Convert C string (null-terminated) to Go string
host := string(event.Host[:bytes.IndexByte(event.Host[:], 0)])
// 2 -> AF_INET (ipv4)
if event.AddrType == 2 {
ip = net.IP(event.IP[:4])
} else {
ip = net.IP(event.IP[:])
}
log.Debug("(%d) [eBPF DNS]: Tracking Resolved Message: %s -> %s\n", id, host, ip.String())
Track(ip.String(), host)
}
}
Exit:
log.Debug("[eBPF DNS] worker #%d closed", id)
}
================================================
FILE: daemon/dns/parse.go
================================================
package dns
import (
"github.com/evilsocket/opensnitch/daemon/netfilter"
"github.com/google/gopacket/layers"
)
// GetQuestions retrieves the domain names a process is trying to resolve.
func GetQuestions(nfp *netfilter.Packet) (questions []string) {
dnsLayer := nfp.Packet.Layer(layers.LayerTypeDNS)
if dnsLayer == nil {
return questions
}
dns, _ := dnsLayer.(*layers.DNS)
for _, dnsQuestion := range dns.Questions {
questions = append(questions, string(dnsQuestion.Name))
}
return questions
}
================================================
FILE: daemon/dns/systemd/monitor.go
================================================
// Package systemd defines several utilities to interact with systemd.
//
// ResolvedMonitor:
// * To debug systemd-resolved queries and inspect the protocol:
// - resolvectl monitor
// * Resources:
// - https://github.com/systemd/systemd/blob/main/src/resolve/resolvectl.c
// - The protocol used to send and receive data is varlink:
// https://github.com/varlink/go
// https://github.com/systemd/systemd/blob/main/src/resolve/resolved-varlink.c
// - https://systemd.io/RESOLVED-VPNS/
package systemd
import (
"context"
"errors"
"fmt"
"sync"
"time"
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/varlink/go/varlink"
)
// whenever there's a new DNS response, this callback will be invoked.
// the second parameter is a MonitorResponse struct that will be filled with
// data.
type resolvedCallback func(context.Context, interface{}) (uint64, error)
const (
// SuccessState is the string returned by systemd-resolved when a DNS query is successful.
// Other states: https://github.com/systemd/systemd/blob/main/src/resolve/resolved-dns-transaction.c#L3608
SuccessState = "success"
socketPath = "/run/systemd/resolve/io.systemd.Resolve.Monitor"
resolvedSubscribeMethod = "io.systemd.Resolve.Monitor.SubscribeQueryResults"
// DNSTypeA A
DNSTypeA = 1
// DNSTypeAAAA AAAA
DNSTypeAAAA = 28
// DNSTypeCNAME cname
DNSTypeCNAME = 5
// DNSTypeSOA soa
DNSTypeSOA = 6
)
// QuestionMonitorResponse represents a DNS query
// "question": [{"class": 1, "type": 28,"name": "images.site.com"}],
type QuestionMonitorResponse struct {
Name string `json:"name"`
Class int `json:"class"`
Type int `json:"type"`
}
// KeyType holds question that generated the answer
/*answer: [{
"rr": {
"key": {
"class": 1,
"type": 28,
"name": "images.site.com"
},
"address": [100, 13, 45, 111]
},
"raw": "DFJFKE343443EFKEREKET=",
"ifindex": 3
}]*/
type KeyType struct {
Name string `json:"name"`
Class int `json:"class"`
Type int `json:"type"`
}
// RRType represents a DNS answer
// if the response is a CNAME, Address will be nil, and Name a domain name.
type RRType struct {
Name string `json:"name"`
Address []byte `json:"address"`
Key QuestionMonitorResponse `json:"key"`
}
// AnswerMonitorResponse represents the DNS answer of a DNS query.
type AnswerMonitorResponse struct {
Raw string `json:"raw"`
RR RRType `json:"rr"`
Ifindex int `json:"ifindex"`
}
// MonitorResponse represents the systemd-resolved protocol message
// sent over the wire, that holds the answer to a DNS query.
type MonitorResponse struct {
State string `json:"state"`
Question []QuestionMonitorResponse `json:"question"`
// CollectedQuestions
// "collectedQuestions":[{"class":1,"type":1,"name":"translate.google.com"}]
Answer []AnswerMonitorResponse `json:"answer"`
Continues bool `json:"continues"`
}
// ResolvedMonitor represents a systemd-resolved monitor
type ResolvedMonitor struct {
Ctx context.Context
Cancel context.CancelFunc
// connection with the systemd-resolved unix socket:
// /run/systemd/resolve/io.systemd.Resolve.Monitor
Conn *varlink.Connection
// channel where all the DNS respones will be sent
ChanResponse chan *MonitorResponse
// error channel to signal any problem
ChanConnError chan error
// callback that is emited when systemd-resolved resolves a domain name.
receiverCb resolvedCallback
mu *sync.RWMutex
connected bool
}
// NewResolvedMonitor returns a new ResolvedMonitor object.
// With this object you can passively read DNS answers.
func NewResolvedMonitor() (*ResolvedMonitor, error) {
if core.Exists(socketPath) == false {
return nil, fmt.Errorf("%s doesn't exist", socketPath)
}
ctx, cancel := context.WithCancel(context.Background())
return &ResolvedMonitor{
mu: &sync.RWMutex{},
Ctx: ctx,
Cancel: cancel,
ChanResponse: make(chan *MonitorResponse),
ChanConnError: make(chan error),
}, nil
}
// Connect opens a unix socket with systemd-resolved
func (r *ResolvedMonitor) Connect() (*varlink.Connection, error) {
r.mu.Lock()
defer r.mu.Unlock()
var err error
r.Conn, err = varlink.NewConnection(r.Ctx, fmt.Sprintf("unix://%s", socketPath))
if err != nil {
return nil, err
}
r.connected = true
go r.connPoller()
return r.Conn, nil
}
// if we're connected to the unix socket, check every few seconds if we're still
// connected, and if not, reconnect, to survive to systemd-resolved restarts.
func (r *ResolvedMonitor) connPoller() {
for {
select {
case <-time.After(5 * time.Second):
if r.isConnected() {
continue
}
log.Debug("ResolvedMonitor not connected")
if _, err := r.Connect(); err == nil {
r.Subscribe()
}
goto Exit
}
}
Exit:
log.Debug("ResolvedMonitor connection poller exit.")
}
// Subscribe sends the instruction to systemd-resolved to start monitoring
// DNS answers.
func (r *ResolvedMonitor) Subscribe() error {
if r.isConnected() == false {
return errors.New("Not connected")
}
var err error
type emptyT struct{}
empty := &emptyT{}
r.receiverCb, err = r.Conn.Send(r.Ctx, resolvedSubscribeMethod, empty, varlink.Continues|varlink.More)
if err != nil {
return err
}
go r.monitor(r.Ctx, r.ChanResponse, r.ChanConnError, r.receiverCb)
return nil
}
// monitor will listen for DNS answers from systemd-resolved.
func (r *ResolvedMonitor) monitor(ctx context.Context, chanResponse chan *MonitorResponse, chanConnError chan error, callback resolvedCallback) {
for {
m := &MonitorResponse{}
continues, err := callback(ctx, m)
if err != nil {
chanConnError <- err
goto Exit
}
if continues != varlink.Continues {
goto Exit
}
log.Trace("ResolvedMonitor >> new response: %#v", m)
chanResponse <- m
}
Exit:
r.mu.Lock()
r.connected = false
r.mu.Unlock()
log.Debug("ResolvedMonitor.monitor() exit.")
}
// GetDNSResponses returns a channel that you can use to read responses.
func (r *ResolvedMonitor) GetDNSResponses() chan *MonitorResponse {
return r.ChanResponse
}
// Exit returns a channel to listen for connection errors.
func (r *ResolvedMonitor) Exit() chan error {
return r.ChanConnError
}
// Close closes the unix socket with systemd-resolved
func (r *ResolvedMonitor) Close() {
r.ChanConnError <- nil
r.Cancel()
}
func (r *ResolvedMonitor) isConnected() bool {
r.mu.RLock()
defer r.mu.RUnlock()
return r.connected
}
================================================
FILE: daemon/dns/track.go
================================================
package dns
import (
"net"
"sync"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
var (
responses = make(map[string]string, 0)
lock = sync.RWMutex{}
)
// TrackAnswers obtains the resolved domains of a DNS query.
// If the packet is UDP DNS, the domain names are added to the list of resolved domains.
func TrackAnswers(packet gopacket.Packet) bool {
udpLayer := packet.Layer(layers.LayerTypeUDP)
if udpLayer == nil {
return false
}
udp, ok := udpLayer.(*layers.UDP)
if ok == false || udp == nil {
return false
}
if udp.SrcPort != 53 {
return false
}
dnsLayer := packet.Layer(layers.LayerTypeDNS)
if dnsLayer == nil {
return false
}
dnsAns, ok := dnsLayer.(*layers.DNS)
if ok == false || dnsAns == nil {
return false
}
for _, ans := range dnsAns.Answers {
if ans.Name != nil {
if ans.IP != nil {
Track(ans.IP.String(), string(ans.Name))
} else if ans.CNAME != nil {
Track(string(ans.CNAME), string(ans.Name))
}
}
}
return true
}
// Track adds a resolved domain to the list.
func Track(resolved string, hostname string) {
lock.Lock()
defer lock.Unlock()
if len(resolved) > 3 && resolved[0:4] == "127." {
return
}
if resolved == "::1" || resolved == hostname {
return
}
responses[resolved] = hostname
log.Debug("New DNS record: %s -> %s", resolved, hostname)
}
// Host returns if a resolved domain is in the list.
func Host(resolved string) (host string, found bool) {
lock.RLock()
defer lock.RUnlock()
host, found = responses[resolved]
return
}
// HostOr checks if an IP has a domain name already resolved.
// If the domain is in the list it's returned, otherwise the IP will be returned.
func HostOr(ip net.IP, or string) string {
if host, found := Host(ip.String()); found == true {
// host might have been CNAME; go back until we reach the "root"
seen := make(map[string]bool) // prevent possibility of loops
for {
orig, had := Host(host)
if seen[orig] {
break
}
if !had {
break
}
seen[orig] = true
host = orig
}
return host
}
return or
}
================================================
FILE: daemon/firewall/common/common.go
================================================
package common
import (
"sync"
"time"
"github.com/evilsocket/opensnitch/daemon/log"
)
// default arguments for various functions
var (
EnableRule = true
DoLogErrors = true
ForcedDelRules = true
ReloadRules = true
RestoreChains = true
BackupChains = true
ReloadConf = true
DefaultCheckInterval = 10 * time.Second
RulesCheckerDisabled = "0s"
)
type (
callback func()
callbackBool func() bool
// Common holds common fields and functionality of both firewalls,
// iptables and nftables.
Common struct {
RulesChecker *time.Ticker
ErrChan chan string
stopChecker chan struct{}
RulesCheckInterval time.Duration
QueueNum uint16
Running bool
Intercepting bool
FwEnabled bool
sync.RWMutex
}
)
// ErrorsChan returns the channel where the errors are sent to.
func (c *Common) ErrorsChan() <-chan string {
return c.ErrChan
}
// ErrChanEmpty checks if the errors channel is empty.
func (c *Common) ErrChanEmpty() bool {
return len(c.ErrChan) == 0
}
// SendError sends an error to the channel of errors.
func (c *Common) SendError(err string) {
log.Warning("%s", err)
if len(c.ErrChan) >= cap(c.ErrChan) {
log.Debug("fw errors channel full, emptying errChan")
for e := range c.ErrChan {
log.Warning("%s", e)
if c.ErrChanEmpty() {
break
}
}
return
}
select {
case c.ErrChan <- err:
case <-time.After(100 * time.Millisecond):
log.Warning("SendError() channel locked? REVIEW")
}
}
func (c *Common) SetRulesCheckerInterval(interval string) {
dur, err := time.ParseDuration(interval)
if err != nil {
log.Warning("Invalid rules checker interval (falling back to %s): %s", DefaultCheckInterval, err)
c.RulesCheckInterval = DefaultCheckInterval
return
}
c.RulesCheckInterval = dur
}
// SetQueueNum sets the queue number used by the firewall.
// It's the queue where all intercepted connections will be sent.
func (c *Common) SetQueueNum(qNum uint16) {
c.Lock()
defer c.Unlock()
c.QueueNum = qNum
}
// IsRunning returns if the firewall is running or not.
func (c *Common) IsRunning() bool {
c.RLock()
defer c.RUnlock()
return c != nil && c.Running
}
// IsFirewallEnabled returns if the firewall is running or not.
func (c *Common) IsFirewallEnabled() bool {
c.RLock()
defer c.RUnlock()
return c != nil && c.FwEnabled
}
// IsIntercepting returns if the firewall is running or not.
func (c *Common) IsIntercepting() bool {
c.RLock()
defer c.RUnlock()
return c != nil && c.Intercepting
}
// NewRulesChecker starts monitoring interception rules.
// We expect to have 2 rules loaded: one to intercept DNS responses and another one
// to intercept network traffic.
func (c *Common) NewRulesChecker(areRulesLoaded callbackBool, reloadRules callback) {
c.Lock()
defer c.Unlock()
if c.RulesCheckInterval.String() == RulesCheckerDisabled {
log.Info("Fw rules checker disabled ...")
return
}
if c.RulesChecker != nil {
c.RulesChecker.Stop()
select {
case c.stopChecker <- struct{}{}:
case <-time.After(5 * time.Millisecond):
log.Error("NewRulesChecker: timed out stopping monitor rules")
}
}
c.stopChecker = make(chan struct{}, 1)
log.Info("Starting new fw checker every %s ...", c.RulesCheckInterval)
c.RulesChecker = time.NewTicker(c.RulesCheckInterval)
go startCheckingRules(c.stopChecker, c.RulesChecker, areRulesLoaded, reloadRules)
}
// StartCheckingRules monitors if our rules are loaded.
// If the rules to intercept traffic are not loaded, we'll try to insert them again.
func startCheckingRules(exitChan <-chan struct{}, rulesChecker *time.Ticker, areRulesLoaded callbackBool, reloadRules callback) {
for {
select {
case <-exitChan:
goto Exit
case _, active := <-rulesChecker.C:
if !active {
goto Exit
}
if areRulesLoaded() == false {
reloadRules()
}
}
}
Exit:
log.Info("exit checking firewall rules")
}
// StopCheckingRules stops checking if firewall rules are loaded.
func (c *Common) StopCheckingRules() {
c.Lock()
defer c.Unlock()
if c.RulesChecker != nil {
select {
case c.stopChecker <- struct{}{}:
close(c.stopChecker)
case <-time.After(5 * time.Millisecond):
// We should not arrive here
log.Error("StopCheckingRules: timed out stopping monitor rules")
}
c.RulesChecker.Stop()
c.RulesChecker = nil
}
}
func (c *Common) reloadCallback(callback func()) {
callback()
}
================================================
FILE: daemon/firewall/config/config.go
================================================
// Package config provides functionality to load and monitor the system
// firewall rules.
// It's inherited by the different firewall packages (iptables, nftables).
//
// The firewall rules defined by the user are reloaded in these cases:
// - When the file system-fw.json changes.
// - When the firewall rules are not present when listing them.
package config
import (
"context"
"encoding/json"
"io/ioutil"
"os"
"sync"
"github.com/evilsocket/opensnitch/daemon/firewall/common"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/fsnotify/fsnotify"
)
var (
// DefaultConfigFile ..
DefaultConfigFile = "/etc/opensnitchd/system-fw.json"
)
// ExprValues holds the statements' options:
// "Name": "ct",
// "Values": [
// {
// "Key": "state",
// "Value": "established"
// },
// {
// "Key": "state",
// "Value": "related"
// }]
type ExprValues struct {
Key string
Value string
}
// ExprStatement holds the definition of matches to use against connections.
//{
// "Op": "!=",
// "Name": "tcp",
// "Values": [
// {
// "Key": "dport",
// "Value": "443"
// }
// ]
//}
type ExprStatement struct {
Op string // ==, !=, ... Only one per expression set.
Name string // tcp, udp, ct, daddr, log, ...
Values []*ExprValues // dport 8000
}
// Expressions holds the array of expressions that create the rules
type Expressions struct {
Statement *ExprStatement
}
// FwRule holds the fields of a rule
type FwRule struct {
*sync.RWMutex
// we need to keep old fields in the struct. Otherwise when receiving a conf from the GUI, the legacy rules would be deleted.
Chain string // TODO: deprecated, remove
Table string // TODO: deprecated, remove
Parameters string // TODO: deprecated, remove
UUID string
Description string
Target string
TargetParameters string
Expressions []*Expressions
Position uint64 `json:",string"`
Enabled bool
}
// FwChain holds the information that defines a firewall chain.
// It also contains the firewall table definition that it belongs to.
type FwChain struct {
// table fields
Table string
Family string
// chain fields
Name string
Description string
Priority string
Type string
Hook string
Policy string
Rules []*FwRule
}
// IsInvalid checks if the chain has been correctly configured.
func (fc *FwChain) IsInvalid() bool {
return fc.Name == "" || fc.Family == "" || fc.Table == ""
}
type rulesList struct {
Rule *FwRule
}
type chainsList struct {
Rule *FwRule // TODO: deprecated, remove
Chains []*FwChain
}
// SystemConfig holds the list of rules to be added to the system
type SystemConfig struct {
SystemRules []*chainsList
sync.RWMutex
Version uint32
Enabled bool
}
// Config holds the functionality to re/load the firewall configuration from disk.
// This is the configuration to manage the system firewall (iptables, nftables).
type Config struct {
watcher *fsnotify.Watcher
ctx context.Context
cancelMonitor context.CancelFunc
// preloadCallback is called before reloading the configuration,
// in order to delete old fw rules.
preloadCallback func()
// reloadCallback is called after the configuration is written.
reloadCallback func()
// preload will be called after daemon startup, whilst reload when a modification is performed.
file string
SysConfig SystemConfig
sync.Mutex
}
// NewSystemFwConfig initializes config fields
func (c *Config) NewSystemFwConfig(configPath string, preLoadCb, reLoadCb func()) (*Config, error) {
var err error
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Warning("Error creating firewall config watcher: %s", err)
return nil, err
}
c.Lock()
defer c.Unlock()
c.file = configPath
c.ctx, c.cancelMonitor = context.WithCancel(context.Background())
c.preloadCallback = preLoadCb
c.reloadCallback = reLoadCb
c.watcher = watcher
return c, nil
}
// SetConfigFile sets the absolute path to the configuration file to use.
// If it's empty, it'll be ignored (when changing the fw type for example).
func (c *Config) SetConfigFile(file string) {
if file == "" {
log.Debug("Firewall configuration file not provided, ignoring")
return
}
c.file = file
}
// LoadDiskConfiguration reads and loads the firewall configuration from disk
func (c *Config) LoadDiskConfiguration(reload bool) error {
c.Lock()
defer c.Unlock()
raw, err := ioutil.ReadFile(c.file)
if err != nil {
log.Error("Error reading firewall configuration from disk %s: %s", c.file, err)
return err
}
if err = c.loadConfiguration(raw); err != nil {
return err
}
// we need to monitor the configuration file for changes, regardless if it's
// malformed or not.
c.watcher.Remove(c.file)
if err := c.watcher.Add(c.file); err != nil {
log.Error("Could not watch firewall configuration: %s", err)
return err
}
if reload {
c.reloadCallback()
return nil
}
go c.monitorConfigWorker()
return nil
}
// loadConfigutation reads the system firewall rules from disk.
// Then the rules are added based on the configuration defined.
func (c *Config) loadConfiguration(rawConfig []byte) error {
c.SysConfig.Lock()
defer c.SysConfig.Unlock()
// delete old system rules, that may be different from the new ones
c.preloadCallback()
if err := json.Unmarshal(rawConfig, &c.SysConfig); err != nil {
// we only log the parser error, giving the user a chance to write a valid config
log.Error("Error parsing firewall configuration %s: %s", c.file, err)
return err
}
log.Info("fw configuration loaded")
return nil
}
// SaveConfiguration saves configuration to disk.
// This event dispatches a reload of the configuration.
func (c *Config) SaveConfiguration(rawConfig string) error {
conf, err := json.MarshalIndent([]byte(rawConfig), " ", " ")
if err != nil {
log.Error("saving json firewall configuration: %s %s", err, conf)
return err
}
if err = os.Chmod(c.file, 0600); err != nil {
log.Warning("unable to set system-fw.json permissions: %s", err)
}
if err = ioutil.WriteFile(c.file, []byte(rawConfig), 0600); err != nil {
log.Error("writing firewall configuration to disk: %s", err)
return err
}
return nil
}
// StopConfigWatcher stops the configuration watcher and stops the subroutine.
func (c *Config) StopConfigWatcher() {
c.Lock()
defer c.Unlock()
c.cancelMonitor()
if c.watcher != nil {
c.watcher.Remove(c.file)
c.watcher.Close()
}
}
func (c *Config) monitorConfigWorker() {
for {
select {
case <-c.ctx.Done():
goto Exit
case event := <-c.watcher.Events:
if (event.Op&fsnotify.Write == fsnotify.Write) || (event.Op&fsnotify.Remove == fsnotify.Remove) {
c.LoadDiskConfiguration(common.ReloadConf)
}
}
}
Exit:
log.Debug("stop monitoring firewall config file")
}
================================================
FILE: daemon/firewall/config/config_test.go
================================================
package config
import (
"testing"
)
func preloadConfCallback() {
}
func reloadConfCallback() {
}
func TestNftLoadFromDisk(t *testing.T) {
/*skipIfNotPrivileged(t)
conn, newNS = OpenSystemConn(t)
defer CleanupSystemConn(t, newNS)
nft.conn = conn
*/
cfg := &Config{}
cfg.NewSystemFwConfig("", preloadConfCallback, reloadConfCallback)
cfg.SetConfigFile("../nftables/testdata/test-sysfw-conf.json")
if err := cfg.LoadDiskConfiguration(false); err != nil {
t.Errorf("Error loading config from disk: %s", err)
}
}
================================================
FILE: daemon/firewall/iptables/iptables.go
================================================
package iptables
import (
"bytes"
"encoding/json"
"os/exec"
"regexp"
"strings"
"sync"
"github.com/evilsocket/opensnitch/daemon/firewall/common"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
"github.com/golang/protobuf/jsonpb"
)
// Action is the modifier we apply to a rule.
type Action string
const (
// Name is the name that identifies this firewall
Name = "iptables"
// SystemRulePrefix prefix added to each system rule
SystemRulePrefix = "opensnitch-filter"
)
// Actions we apply to the firewall.
const (
ADD = Action("-A")
INSERT = Action("-I")
DELETE = Action("-D")
FLUSH = Action("-F")
NEWCHAIN = Action("-N")
DELCHAIN = Action("-X")
POLICY = Action("-P")
DROP = Action("DROP")
ACCEPT = Action("ACCEPT")
)
// SystemRule blabla
type SystemRule struct {
Rule *config.FwRule
Table string
Chain string
}
// SystemChains keeps track of the fw rules that have been added to the system.
type SystemChains struct {
Rules map[string]*SystemRule
sync.RWMutex
}
// Iptables struct holds the fields of the iptables fw
type Iptables struct {
regexRulesQuery *regexp.Regexp
regexSystemRulesQuery *regexp.Regexp
bin string
bin6 string
chains SystemChains
bypassQueue bool
common.Common
config.Config
sync.Mutex
}
// Fw initializes a new Iptables object
func Fw() (*Iptables, error) {
if err := IsAvailable(); err != nil {
return nil, err
}
reRulesQuery, _ := regexp.Compile(`NFQUEUE.*ctstate NEW,RELATED.*NFQUEUE num.*`)
reSystemRulesQuery, _ := regexp.Compile(SystemRulePrefix + ".*")
ipt := &Iptables{
bin: "iptables",
bin6: "ip6tables",
regexRulesQuery: reRulesQuery,
regexSystemRulesQuery: reSystemRulesQuery,
chains: SystemChains{
Rules: make(map[string]*SystemRule),
},
}
return ipt, nil
}
// Name returns the firewall name
func (ipt *Iptables) Name() string {
return Name
}
// Init inserts the firewall rules and starts monitoring for firewall
// changes.
func (ipt *Iptables) Init(qNum uint16, configPath, monitorInterval string, bypassQueue bool) {
if ipt.IsRunning() {
return
}
ipt.bypassQueue = bypassQueue
ipt.SetQueueNum(qNum)
ipt.SetRulesCheckerInterval(monitorInterval)
ipt.ErrChan = make(chan string, 100)
// In order to clean up any existing firewall rule before start,
// we need to load the fw configuration first to know what rules
// were configured.
ipt.NewSystemFwConfig(configPath, ipt.preloadConfCallback, ipt.reloadRulesCallback)
ipt.LoadDiskConfiguration(!common.ReloadConf)
// start from a clean state
ipt.CleanRules(false)
ipt.EnableInterception()
ipt.AddSystemRules(!common.ReloadRules, common.BackupChains)
ipt.Running = true
}
// Stop deletes the firewall rules, allowing network traffic.
func (ipt *Iptables) Stop() {
ipt.ErrChan = make(chan string, 100)
if ipt.Running == false {
return
}
ipt.StopConfigWatcher()
ipt.StopCheckingRules()
ipt.CleanRules(log.GetLogLevel() == log.DEBUG)
ipt.Running = false
}
// IsAvailable checks if iptables is installed in the system.
// If it's not, we'll default to nftables.
func IsAvailable() error {
_, err := exec.Command("iptables", []string{"-V"}...).CombinedOutput()
if err != nil {
return err
}
return nil
}
// EnableInterception adds fw rules to intercept connections.
func (ipt *Iptables) EnableInterception() {
if err4, err6 := ipt.QueueConnections(common.EnableRule, true); err4 != nil || err6 != nil {
log.Fatal("Error while running conntrack firewall rule: %s %s", err4, err6)
} else if err4, err6 = ipt.QueueDNSResponses(common.EnableRule, true); err4 != nil || err6 != nil {
log.Error("Error while running DNS firewall rule: %s %s", err4, err6)
}
// start monitoring firewall rules to intercept network traffic
ipt.NewRulesChecker(ipt.AreRulesLoaded, ipt.reloadRulesCallback)
}
// DisableInterception removes firewall rules to intercept outbound connections.
func (ipt *Iptables) DisableInterception(logErrors bool) {
ipt.StopCheckingRules()
ipt.QueueDNSResponses(!common.EnableRule, logErrors)
ipt.QueueConnections(!common.EnableRule, logErrors)
}
// CleanRules deletes the rules we added.
func (ipt *Iptables) CleanRules(logErrors bool) {
ipt.DisableInterception(logErrors)
ipt.DeleteSystemRules(common.ForcedDelRules, common.BackupChains, logErrors)
}
// Serialize converts the configuration from json to protobuf
func (ipt *Iptables) Serialize() (*protocol.SysFirewall, error) {
sysfw := &protocol.SysFirewall{}
jun := jsonpb.Unmarshaler{
AllowUnknownFields: true,
}
rawConfig, err := json.Marshal(&ipt.SysConfig)
if err != nil {
log.Error("nfables.Serialize() struct to string error: %s", err)
return nil, err
}
// string to proto
if err := jun.Unmarshal(strings.NewReader(string(rawConfig)), sysfw); err != nil {
log.Error("nfables.Serialize() string to protobuf error: %s", err)
return nil, err
}
return sysfw, nil
}
// Deserialize converts a protocolbuffer structure to json.
func (ipt *Iptables) Deserialize(sysfw *protocol.SysFirewall) ([]byte, error) {
jun := jsonpb.Marshaler{
OrigName: true,
EmitDefaults: false,
Indent: " ",
}
var b bytes.Buffer
if err := jun.Marshal(&b, sysfw); err != nil {
log.Error("nfables.Deserialize() error 2: %s", err)
return nil, err
}
return b.Bytes(), nil
//return nil, fmt.Errorf("iptables.Deserialize() not implemented")
}
================================================
FILE: daemon/firewall/iptables/monitor.go
================================================
package iptables
import (
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/firewall/common"
"github.com/evilsocket/opensnitch/daemon/log"
)
// AreRulesLoaded checks if the firewall rules for intercept traffic are loaded.
func (ipt *Iptables) AreRulesLoaded() bool {
var outMangle6 string
outMangle, err := core.Exec("iptables", []string{"-n", "-L", "OUTPUT", "-t", "mangle"})
if err != nil {
return false
}
if core.IPv6Enabled {
outMangle6, err = core.Exec("ip6tables", []string{"-n", "-L", "OUTPUT", "-t", "mangle"})
if err != nil {
return false
}
}
systemRulesLoaded := true
ipt.chains.RLock()
if len(ipt.chains.Rules) > 0 {
for _, rule := range ipt.chains.Rules {
if chainOut4, err4 := core.Exec("iptables", []string{"-n", "-L", rule.Chain, "-t", rule.Table}); err4 == nil {
if ipt.regexSystemRulesQuery.FindString(chainOut4) == "" {
systemRulesLoaded = false
break
}
}
if core.IPv6Enabled {
if chainOut6, err6 := core.Exec("ip6tables", []string{"-n", "-L", rule.Chain, "-t", rule.Table}); err6 == nil {
if ipt.regexSystemRulesQuery.FindString(chainOut6) == "" {
systemRulesLoaded = false
break
}
}
}
}
}
ipt.chains.RUnlock()
result := ipt.regexRulesQuery.FindString(outMangle) != "" &&
systemRulesLoaded
if core.IPv6Enabled {
result = result && ipt.regexRulesQuery.FindString(outMangle6) != ""
}
return result
}
// reloadRulesCallback gets called when the interception rules are not present or after the configuration file changes.
func (ipt *Iptables) reloadRulesCallback() {
log.Important("firewall rules changed, reloading")
ipt.CleanRules(false)
ipt.AddSystemRules(common.ReloadRules, common.BackupChains)
ipt.EnableInterception()
}
// preloadConfCallback gets called before the fw configuration is reloaded
func (ipt *Iptables) preloadConfCallback() {
log.Info("iptables config changed, reloading")
ipt.DeleteSystemRules(common.ForcedDelRules, common.BackupChains, log.GetLogLevel() == log.DEBUG)
}
================================================
FILE: daemon/firewall/iptables/rules.go
================================================
package iptables
import (
"fmt"
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/vishvananda/netlink"
)
func (ipt *Iptables) getBypassQueue() string {
if !ipt.bypassQueue {
return ""
}
return "--queue-bypass"
}
// BuildQueueDNSRule returns the iptables rule arguments for queueing DNS responses.
func BuildQueueDNSRule(queueNum uint16, bypass bool) []string {
rule := []string{
"INPUT",
"--protocol", "udp",
"--sport", "53",
"-j", "NFQUEUE",
"--queue-num", fmt.Sprintf("%d", queueNum),
}
if bypass {
rule = append(rule, "--queue-bypass")
}
return rule
}
// BuildQueueConnectionsRule returns the iptables rule arguments for queueing connections.
func BuildQueueConnectionsRule(queueNum uint16, bypass bool) []string {
rule := []string{
"OUTPUT",
"-t", "mangle",
"-m", "conntrack",
"--ctstate", "NEW,RELATED",
"-j", "NFQUEUE",
"--queue-num", fmt.Sprintf("%d", queueNum),
}
if bypass {
rule = append(rule, "--queue-bypass")
}
return rule
}
// RunRule inserts or deletes a firewall rule.
func (ipt *Iptables) RunRule(action Action, enable bool, logError bool, rule []string) (err4, err6 error) {
if enable == false {
action = "-D"
}
// If the last argument of the rule is "", the iptables command fails.
// So if the user selects "QueueBypass: false", delete the last token of the rule,
// which will be "".
args := len(rule)
if rule[args-1] == "" {
rule = append(rule[:args-1], rule[args:]...)
}
rule = append([]string{string(action)}, rule...)
ipt.Lock()
defer ipt.Unlock()
if _, err4 = core.Exec(ipt.bin, rule); err4 != nil {
if logError {
log.Error("Error while running firewall rule, ipv4 err: %s", err4)
log.Error("rule: %s", rule)
}
}
// On some systems IPv6 is disabled
if core.IPv6Enabled {
if _, err6 = core.Exec(ipt.bin6, rule); err6 != nil {
if logError {
log.Error("Error while running firewall rule, ipv6 err: %s", err6)
log.Error("rule: %s", rule)
}
}
}
return
}
// QueueDNSResponses redirects DNS responses to us, in order to keep a cache
// of resolved domains.
// INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
func (ipt *Iptables) QueueDNSResponses(enable bool, logError bool) (err4, err6 error) {
return ipt.RunRule(INSERT, enable, logError, BuildQueueDNSRule(ipt.QueueNum, ipt.bypassQueue))
}
// QueueConnections inserts the firewall rule which redirects connections to us.
// Connections are queued until the user denies/accept them, or reaches a timeout.
// OUTPUT -t mangle -m conntrack --ctstate NEW,RELATED -j NFQUEUE --queue-num 0 --queue-bypass
func (ipt *Iptables) QueueConnections(enable bool, logError bool) (error, error) {
err4, err6 := ipt.RunRule(ADD, enable, logError, BuildQueueConnectionsRule(ipt.QueueNum, ipt.bypassQueue))
if enable {
// flush conntrack as soon as netfilter rule is set. This ensures that already-established
// connections will go to netfilter queue.
if err := netlink.ConntrackTableFlush(netlink.ConntrackTable); err != nil {
log.Error("error in ConntrackTableFlush %s", err)
}
}
return err4, err6
}
================================================
FILE: daemon/firewall/iptables/system.go
================================================
package iptables
import (
"strings"
"github.com/evilsocket/opensnitch/daemon/firewall/common"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
)
// CreateSystemRule creates the custom firewall chains and adds them to the system.
func (ipt *Iptables) CreateSystemRule(rule *config.FwRule, table, chain, hook string, logErrors bool) bool {
ipt.chains.Lock()
defer ipt.chains.Unlock()
if rule == nil {
return false
}
if table == "" {
table = "filter"
}
if hook == "" {
hook = rule.Chain
}
chainName := SystemRulePrefix + "-" + hook
if _, ok := ipt.chains.Rules[table+"-"+chainName]; ok {
return false
}
ipt.RunRule(NEWCHAIN, common.EnableRule, logErrors, []string{chainName, "-t", table})
// Insert the rule at the top of the chain
if err4, err6 := ipt.RunRule(INSERT, common.EnableRule, logErrors, []string{hook, "-t", table, "-j", chainName}); err4 == nil && err6 == nil {
ipt.chains.Rules[table+"-"+chainName] = &SystemRule{
Table: table,
Chain: chain,
Rule: rule,
}
}
return true
}
// AddSystemRules creates the system firewall from configuration.
func (ipt *Iptables) AddSystemRules(reload, backupExistingChains bool) {
// Version 0 has no Enabled field, so it'd be always false
if ipt.SysConfig.Enabled == false && ipt.SysConfig.Version > 0 {
return
}
for _, cfg := range ipt.SysConfig.SystemRules {
if cfg.Rule != nil {
ipt.CreateSystemRule(cfg.Rule, cfg.Rule.Table, cfg.Rule.Chain, cfg.Rule.Chain, common.EnableRule)
ipt.AddSystemRule(ADD, cfg.Rule, cfg.Rule.Table, cfg.Rule.Chain, common.EnableRule)
continue
}
if cfg.Chains != nil {
for _, chn := range cfg.Chains {
if chn.Hook != "" && chn.Type != "" {
ipt.ConfigureChainPolicy(chn.Type, chn.Hook, chn.Policy, true)
}
}
}
}
}
// DeleteSystemRules deletes the system rules.
// If force is false and the rule has not been previously added,
// it won't try to delete the rules. Otherwise it'll try to delete them.
func (ipt *Iptables) DeleteSystemRules(force, backupExistingChains, logErrors bool) {
ipt.chains.Lock()
defer ipt.chains.Unlock()
for _, fwCfg := range ipt.SysConfig.SystemRules {
if fwCfg.Rule == nil {
continue
}
chain := SystemRulePrefix + "-" + fwCfg.Rule.Chain
if _, ok := ipt.chains.Rules[fwCfg.Rule.Table+"-"+chain]; !ok && !force {
continue
}
ipt.RunRule(FLUSH, common.EnableRule, false, []string{chain, "-t", fwCfg.Rule.Table})
ipt.RunRule(DELETE, !common.EnableRule, logErrors, []string{fwCfg.Rule.Chain, "-t", fwCfg.Rule.Table, "-j", chain})
ipt.RunRule(DELCHAIN, common.EnableRule, false, []string{chain, "-t", fwCfg.Rule.Table})
delete(ipt.chains.Rules, fwCfg.Rule.Table+"-"+chain)
for _, chn := range fwCfg.Chains {
if chn.Table == "" {
chn.Table = "filter"
}
chain := SystemRulePrefix + "-" + chn.Hook
if _, ok := ipt.chains.Rules[chn.Type+"-"+chain]; !ok && !force {
continue
}
ipt.RunRule(FLUSH, common.EnableRule, logErrors, []string{chain, "-t", chn.Type})
ipt.RunRule(DELETE, !common.EnableRule, logErrors, []string{chn.Hook, "-t", chn.Type, "-j", chain})
ipt.RunRule(DELCHAIN, common.EnableRule, logErrors, []string{chain, "-t", chn.Type})
delete(ipt.chains.Rules, chn.Type+"-"+chain)
}
}
}
// DeleteSystemRule deletes a new rule.
func (ipt *Iptables) DeleteSystemRule(action Action, rule *config.FwRule, table, chain string, enable bool) (err4, err6 error) {
chainName := SystemRulePrefix + "-" + chain
if table == "" {
table = "filter"
}
r := []string{chainName, "-t", table}
if rule.Parameters != "" {
r = append(r, strings.Split(rule.Parameters, " ")...)
}
r = append(r, []string{"-j", rule.Target}...)
if rule.TargetParameters != "" {
r = append(r, strings.Split(rule.TargetParameters, " ")...)
}
return ipt.RunRule(action, enable, true, r)
}
// AddSystemRule inserts a new rule.
func (ipt *Iptables) AddSystemRule(action Action, rule *config.FwRule, table, chain string, enable bool) (err4, err6 error) {
if rule == nil {
return nil, nil
}
ipt.RLock()
defer ipt.RUnlock()
chainName := SystemRulePrefix + "-" + chain
if table == "" {
table = "filter"
}
r := []string{chainName, "-t", table}
if rule.Parameters != "" {
r = append(r, strings.Split(rule.Parameters, " ")...)
}
r = append(r, []string{"-j", rule.Target}...)
if rule.TargetParameters != "" {
r = append(r, strings.Split(rule.TargetParameters, " ")...)
}
return ipt.RunRule(ADD, enable, true, r)
}
// ConfigureChainPolicy configures chains policy.
func (ipt *Iptables) ConfigureChainPolicy(table, hook, policy string, logError bool) {
// TODO: list all policies before modify them, and restore the original state on exit.
// still, if we exit abruptly, we might left the system badly configured.
ipt.RunRule(POLICY, true, logError, []string{
hook,
strings.ToUpper(policy),
"-t", table,
})
}
================================================
FILE: daemon/firewall/nftables/chains.go
================================================
package nftables
import (
"fmt"
"strings"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/google/nftables"
)
// getChainKey returns the identifier that will be used to link chains and rules.
// When adding a new chain the key is stored, then later when adding a rule we get
// the chain that the rule belongs to by this key.
func getChainKey(name string, table *nftables.Table) string {
if table == nil {
return ""
}
return fmt.Sprintf("%s-%s-%d", name, table.Name, table.Family)
}
// GetChain gets an existing chain
func GetChain(name string, table *nftables.Table) *nftables.Chain {
key := getChainKey(name, table)
if ch, ok := sysChains.Load(key); ok {
return ch.(*nftables.Chain)
}
return nil
}
// AddChain adds a new chain to nftables.
// https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks#Priority_within_hook
func (n *Nft) AddChain(name, table, family string, priority *nftables.ChainPriority, ctype nftables.ChainType, hook *nftables.ChainHook, policy nftables.ChainPolicy) *nftables.Chain {
if family == "" {
family = exprs.NFT_FAMILY_INET
}
tbl := n.GetTable(table, family)
if tbl == nil {
log.Error("%s addChain, Error getting table: %s, %s", logTag, table, family)
return nil
}
var chain *nftables.Chain
// Verify if the chain already exists, and reuse it if it does.
// In some systems it fails adding a chain when it already exists, whilst in others
// it doesn't.
key := getChainKey(name, tbl)
chain = n.GetChain(name, tbl, family)
if chain != nil {
if _, exists := sysChains.Load(key); exists {
sysChains.Delete(key)
}
chain.Policy = &policy
n.Conn.AddChain(chain)
} else {
// nft list chains
chain = n.Conn.AddChain(&nftables.Chain{
Name: strings.ToLower(name),
Table: tbl,
Type: ctype,
Hooknum: hook,
Priority: priority,
Policy: &policy,
})
if chain == nil {
log.Debug("%s AddChain() chain == nil", logTag)
return nil
}
}
sysChains.Store(key, chain)
return chain
}
// GetChain checks if a chain in the given table exists.
func (n *Nft) GetChain(name string, table *nftables.Table, family string) *nftables.Chain {
if chains, err := n.Conn.ListChains(); err == nil {
for _, c := range chains {
if name == c.Name && table.Name == c.Table.Name && GetFamilyCode(family) == c.Table.Family {
return c
}
}
}
return nil
}
// regular chains are user-defined chains, to better organize fw rules.
// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_regular_chains
func (n *Nft) addRegularChain(name, table, family string) error {
tbl := n.GetTable(table, family)
if tbl == nil {
return fmt.Errorf("%s addRegularChain, Error getting table: %s, %s", logTag, table, family)
}
chain := n.Conn.AddChain(&nftables.Chain{
Name: name,
Table: tbl,
})
if chain == nil {
return fmt.Errorf("%s error adding regular chain: %s", logTag, name)
}
key := getChainKey(name, tbl)
sysChains.Store(key, chain)
return nil
}
// AddInterceptionChains adds the needed chains to intercept traffic.
func (n *Nft) AddInterceptionChains() error {
var filterPolicy nftables.ChainPolicy
var manglePolicy nftables.ChainPolicy
filterPolicy = nftables.ChainPolicyAccept
manglePolicy = nftables.ChainPolicyAccept
tbl := n.GetTable(exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET)
if tbl != nil {
key := getChainKey(exprs.CHAIN_FILTER_INPUT, tbl)
ch, found := sysChains.Load(key)
if key != "" && found {
filterPolicy = *ch.(*nftables.Chain).Policy
}
}
if tbl != nil {
key := getChainKey(exprs.CHAIN_MANGLE_OUTPUT, tbl)
ch, found := sysChains.Load(key)
if key != "" && found {
manglePolicy = *ch.(*nftables.Chain).Policy
}
}
// nft list tables
n.AddChain(exprs.CHAIN_FILTER_INPUT, exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET,
nftables.ChainPriorityFilter, nftables.ChainTypeFilter, nftables.ChainHookInput, filterPolicy)
if !n.Commit() {
return fmt.Errorf("Error adding DNS interception chain filter_input-opensnitch-inet")
}
n.AddChain(exprs.CHAIN_MANGLE_OUTPUT, exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET,
nftables.ChainPriorityMangle, nftables.ChainTypeRoute, nftables.ChainHookOutput, manglePolicy)
if !n.Commit() {
log.Error("(1) Error adding interception chain mangle_output-opensnitch-inet, trying with type Filter instead of Route")
// Workaround for kernels 4.x and maybe others.
// @see firewall/nftables/utils.go:GetChainPriority()
chainPrio, chainType := GetChainPriority(exprs.NFT_FAMILY_INET, exprs.NFT_CHAIN_MANGLE, exprs.NFT_HOOK_OUTPUT)
n.AddChain(exprs.CHAIN_MANGLE_OUTPUT, exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET,
chainPrio, chainType, nftables.ChainHookOutput, manglePolicy)
if !n.Commit() {
return fmt.Errorf("(2) Error adding interception chain mangle_output-opensnitch-inet with type Filter. Report it on github please, specifying the distro and the kernel")
}
}
return nil
}
// DelChain deletes a chain from the system.
func (n *Nft) DelChain(chain *nftables.Chain) error {
n.Conn.DelChain(chain)
sysChains.Delete(getChainKey(chain.Name, chain.Table))
if !n.Commit() {
return fmt.Errorf("[nftables] error deleting chain %s, %s", chain.Name, chain.Table.Name)
}
return nil
}
// backupExistingChains saves chains with Accept policy.
// If the user configures the chain policy to Drop, we need to set it back to Accept,
// in order not to block incoming connections.
func (n *Nft) backupExistingChains() {
if chains, err := n.Conn.ListChains(); err == nil {
for _, c := range chains {
if c.Policy != nil && *c.Policy == nftables.ChainPolicyAccept {
log.Debug("%s backing up existing chain with policy ACCEPT: %s, %s", logTag, c.Name, c.Table.Name)
origSysChains[getChainKey(c.Name, c.Table)] = c
}
}
}
}
func (n *Nft) restoreBackupChains() {
for _, c := range origSysChains {
log.Debug("%s Restoring chain policy to accept: %s, %s", logTag, c.Name, c.Table.Name)
*c.Policy = nftables.ChainPolicyAccept
n.Conn.AddChain(c)
}
n.Commit()
}
================================================
FILE: daemon/firewall/nftables/chains_test.go
================================================
package nftables_test
import (
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables"
)
func TestChains(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
if nftest.Fw.AddInterceptionTables() != nil {
t.Error("Error adding interception tables")
}
t.Run("AddChain", func(t *testing.T) {
filterPolicy := nftables.ChainPolicyAccept
chn := nftest.Fw.AddChain(
exprs.CHAIN_FILTER_INPUT,
exprs.TABLE_OPENSNITCH,
exprs.NFT_FAMILY_INET,
nftables.ChainPriorityFilter,
nftables.ChainTypeFilter,
nftables.ChainHookInput,
filterPolicy)
if chn == nil {
t.Error("chain filter_input-opensnitch-inet not created")
}
if !nftest.Fw.Commit() {
t.Error("error adding filter_input-opensnitch-inet chain")
}
})
t.Run("getChain", func(t *testing.T) {
tblfilter := nftest.Fw.GetTable(exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET)
if tblfilter == nil {
t.Error("table opensnitch-inet not created")
}
chn := nftest.Fw.GetChain(exprs.CHAIN_FILTER_INPUT, tblfilter, exprs.NFT_FAMILY_INET)
if chn == nil {
t.Error("chain filter_input-opensnitch-inet not added")
}
})
t.Run("delChain", func(t *testing.T) {
tblfilter := nftest.Fw.GetTable(exprs.TABLE_OPENSNITCH, exprs.NFT_FAMILY_INET)
if tblfilter == nil {
t.Error("table opensnitch-inet not created")
}
chn := nftest.Fw.GetChain(exprs.CHAIN_FILTER_INPUT, tblfilter, exprs.NFT_FAMILY_INET)
if chn == nil {
t.Error("chain filter_input-opensnitch-inet not added")
}
if err := nftest.Fw.DelChain(chn); err != nil {
t.Error("error deleting chain filter_input-opensnitch-inet")
}
})
nftest.Fw.DelSystemTables()
}
// TestAddInterceptionChains checks if the needed tables and chains have been created.
// We use 2: mangle_output-opensnitch-inet for intercepting outbound connections, and filter_input-opensnitch-inet for DNS responses interception
/*func TestAddInterceptionChains(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
if err := nftest.Fw.AddInterceptionTables(); err != nil {
t.Errorf("Error adding interception tables: %s", err)
}
if err := nftest.Fw.AddInterceptionChains(); err != nil {
t.Errorf("Error adding interception chains: %s", err)
}
nftest.Fw.DelSystemTables()
}*/
================================================
FILE: daemon/firewall/nftables/exprs/counter.go
================================================
package exprs
import (
"github.com/google/nftables/expr"
)
// NewExprCounter returns a counter for packets or bytes.
func NewExprCounter(counterName string) *[]expr.Any {
return &[]expr.Any{
&expr.Objref{
Type: 1,
Name: counterName,
},
}
}
================================================
FILE: daemon/firewall/nftables/exprs/counter_test.go
================================================
package exprs_test
import (
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables"
)
func TestExprNamedCounter(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
// we must create the table before the counter object.
tbl, _ := nftest.Fw.AddTable("yyy", exprs.NFT_FAMILY_INET)
nftest.Fw.Conn.AddObj(
&nftables.CounterObj{
Table: &nftables.Table{
Name: "yyy",
Family: nftables.TableFamilyINet,
},
Name: "xxx-counter",
Bytes: 0,
Packets: 0,
},
)
r, _ := nftest.AddTestRule(t, conn, exprs.NewExprCounter("xxx-counter"))
if r == nil {
t.Error("Error adding counter rule")
return
}
objs, err := nftest.Fw.Conn.GetObjects(tbl)
if err != nil {
t.Errorf("Error retrieving objects from table %s: %s", tbl.Name, err)
}
if len(objs) != 1 {
t.Errorf("%d objects found, expected 1", len(objs))
}
counter, ok := objs[0].(*nftables.CounterObj)
if !ok {
t.Errorf("returned Obj is not CounterObj: %+v", objs[0])
}
if counter.Name != "xxx-counter" {
t.Errorf("CounterObj name differs: %s, expected 'xxx-counter'", counter.Name)
}
}
================================================
FILE: daemon/firewall/nftables/exprs/ct.go
================================================
package exprs
import (
"fmt"
"strconv"
"strings"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
)
// Example https://github.com/google/nftables/blob/master/nftables_test.go#L1234
// https://wiki.nftables.org/wiki-nftables/index.php/Setting_packet_metainformation
// NewExprCtMark returns a new ct expression.
// # set
// # nft --debug netlink add rule filter output mark set 1
// ip filter output
// [ immediate reg 1 0x00000001 ]
// [ meta set mark with reg 1 ]
//
// match mark:
// nft --debug netlink add rule mangle prerouting ct mark 123
// [ ct load mark => reg 1 ]
// [ cmp eq reg 1 0x0000007b ]
func NewExprCtMark(setMark bool, value string, cmpOp *expr.CmpOp) (*[]expr.Any, error) {
mark, err := strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("Invalid conntrack mark: %s (%s)", err, value)
}
exprCtMark := []expr.Any{}
exprCtMark = append(exprCtMark, []expr.Any{
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(mark)),
},
&expr.Ct{
Key: expr.CtKeyMARK,
Register: 1,
SourceRegister: setMark,
},
}...)
if setMark == false {
exprCtMark = append(exprCtMark, []expr.Any{
&expr.Cmp{Op: *cmpOp, Register: 1, Data: binaryutil.NativeEndian.PutUint32(uint32(mark))},
}...)
}
return &exprCtMark, nil
}
// NewExprCtState returns a new ct expression.
func NewExprCtState(ctFlags []*config.ExprValues) (*[]expr.Any, error) {
mask := uint32(0)
for _, flag := range ctFlags {
found, msk, err := parseInlineCtStates(flag.Value)
if err != nil {
return nil, err
}
if found {
mask |= msk
continue
}
msk, err = getCtState(flag.Value)
if err != nil {
return nil, err
}
mask |= msk
}
return &[]expr.Any{
&expr.Ct{
Register: 1, SourceRegister: false, Key: expr.CtKeySTATE,
},
&expr.Bitwise{
SourceRegister: 1,
DestRegister: 1,
Len: 4,
Mask: binaryutil.NativeEndian.PutUint32(mask),
Xor: binaryutil.NativeEndian.PutUint32(0),
},
}, nil
}
func parseInlineCtStates(flags string) (found bool, mask uint32, err error) {
// a "state" flag may be compounded of multiple values, separated by commas:
// related,established
fgs := strings.Split(flags, ",")
if len(fgs) > 0 {
for _, fg := range fgs {
msk, err := getCtState(fg)
if err != nil {
return false, 0, err
}
mask |= msk
found = true
}
}
return
}
func getCtState(flag string) (mask uint32, err error) {
switch strings.ToLower(flag) {
case CT_STATE_NEW:
mask |= expr.CtStateBitNEW
case CT_STATE_ESTABLISHED:
mask |= expr.CtStateBitESTABLISHED
case CT_STATE_RELATED:
mask |= expr.CtStateBitRELATED
case CT_STATE_INVALID:
mask |= expr.CtStateBitINVALID
default:
return 0, fmt.Errorf("Invalid conntrack flag: %s", flag)
}
return
}
================================================
FILE: daemon/firewall/nftables/exprs/ct_test.go
================================================
package exprs_test
import (
"fmt"
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
)
func TestExprCtMark(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
type ctTestsT struct {
nftest.TestsT
setMark bool
}
cmp := expr.CmpOpEq
tests := []ctTestsT{
{
TestsT: nftest.TestsT{
Name: "test-ct-set-mark-666",
Parms: "666",
ExpectedExprsNum: 2,
ExpectedExprs: []interface{}{
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(666)),
},
&expr.Ct{
Key: expr.CtKeyMARK,
Register: 1,
SourceRegister: true,
},
},
},
setMark: true,
},
{
TestsT: nftest.TestsT{
Name: "test-ct-check-mark-666",
Parms: "666",
ExpectedExprsNum: 3,
ExpectedExprs: []interface{}{
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(666)),
},
&expr.Ct{
Key: expr.CtKeyMARK,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Op: cmp,
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(666)),
},
},
},
setMark: false,
},
{
TestsT: nftest.TestsT{
Name: "test-invalid-ct-check-mark",
Parms: "0x29a",
ExpectedExprsNum: 3,
ExpectedExprs: []interface{}{},
ExpectedFail: true,
},
setMark: false,
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
quotaExpr, err := exprs.NewExprCtMark(test.setMark, test.TestsT.Parms, &cmp)
if err != nil && !test.ExpectedFail {
t.Errorf("Error creating expr Ct: %s", quotaExpr)
return
} else if err != nil && test.ExpectedFail {
return
}
r, _ := nftest.AddTestRule(t, conn, quotaExpr)
if r == nil && !test.ExpectedFail {
t.Error("Error adding rule with Ct expression")
}
if !nftest.AreExprsValid(t, &test.TestsT, r) {
return
}
if test.ExpectedFail {
t.Errorf("test should have failed")
}
})
}
}
func TestExprCtState(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
type ctTestsT struct {
nftest.TestsT
setMark bool
}
tests := []nftest.TestsT{
{
Name: "test-ct-single-state",
Parms: "",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_CT_STATE,
Value: exprs.CT_STATE_NEW,
},
},
ExpectedExprsNum: 2,
ExpectedExprs: []interface{}{
&expr.Ct{
Register: 1, SourceRegister: false, Key: expr.CtKeySTATE,
},
&expr.Bitwise{
SourceRegister: 1,
DestRegister: 1,
Len: 4,
Mask: binaryutil.NativeEndian.PutUint32(expr.CtStateBitNEW),
Xor: binaryutil.NativeEndian.PutUint32(0),
},
},
ExpectedFail: false,
},
{
Name: "test-ct-multiple-states",
Parms: "",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_CT_STATE,
Value: fmt.Sprint(exprs.CT_STATE_NEW, ",", exprs.CT_STATE_ESTABLISHED),
},
},
ExpectedExprsNum: 2,
ExpectedExprs: []interface{}{
&expr.Ct{
Register: 1, SourceRegister: false, Key: expr.CtKeySTATE,
},
&expr.Bitwise{
SourceRegister: 1,
DestRegister: 1,
Len: 4,
Mask: binaryutil.NativeEndian.PutUint32(expr.CtStateBitNEW | expr.CtStateBitESTABLISHED),
Xor: binaryutil.NativeEndian.PutUint32(0),
},
},
ExpectedFail: false,
},
{
Name: "test-invalid-ct-state",
Parms: "",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_CT_STATE,
Value: "xxx",
},
},
ExpectedExprsNum: 2,
ExpectedExprs: []interface{}{},
ExpectedFail: true,
},
{
Name: "test-invalid-ct-states",
Parms: "",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_CT_STATE,
Value: "new,xxx",
},
},
ExpectedExprsNum: 2,
ExpectedExprs: []interface{}{},
ExpectedFail: true,
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
quotaExpr, err := exprs.NewExprCtState(test.Values)
if err != nil && !test.ExpectedFail {
t.Errorf("Error creating expr Ct: %s", quotaExpr)
return
} else if err != nil && test.ExpectedFail {
return
}
r, _ := nftest.AddTestRule(t, conn, quotaExpr)
if r == nil && !test.ExpectedFail {
t.Error("Error adding rule with Quota expression")
}
if !nftest.AreExprsValid(t, &test, r) {
return
}
if test.ExpectedFail {
t.Errorf("test should have failed")
}
})
}
}
================================================
FILE: daemon/firewall/nftables/exprs/enums.go
================================================
package exprs
// keywords used in the configuration to define rules.
const (
TABLE_OPENSNITCH = "opensnitch"
CHAIN_FILTER_INPUT = "filter_input"
CHAIN_MANGLE_OUTPUT = "mangle_output"
CHAIN_MANGLE_FORWARD = "mangle_forward"
// https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks#Priority_within_hook
NFT_CHAIN_MANGLE = "mangle"
NFT_CHAIN_FILTER = "filter"
NFT_CHAIN_RAW = "raw"
NFT_CHAIN_SECURITY = "security"
NFT_CHAIN_NATDEST = "natdest"
NFT_CHAIN_NATSOURCE = "natsource"
NFT_CHAIN_CONNTRACK = "conntrack"
NFT_CHAIN_SELINUX = "selinux"
NFT_HOOK_INPUT = "input"
NFT_HOOK_OUTPUT = "output"
NFT_HOOK_PREROUTING = "prerouting"
NFT_HOOK_POSTROUTING = "postrouting"
NFT_HOOK_INGRESS = "ingress"
NFT_HOOK_EGRESS = "egress"
NFT_HOOK_FORWARD = "forward"
NFT_TABLE_INET = "inet"
NFT_TABLE_NAT = "nat"
// TODO
NFT_TABLE_ARP = "arp"
NFT_TABLE_BRIDGE = "bridge"
NFT_TABLE_NETDEV = "netdev"
NFT_FAMILY_IP = "ip"
NFT_FAMILY_IP6 = "ip6"
NFT_FAMILY_INET = "inet"
NFT_FAMILY_BRIDGE = "bridge"
NFT_FAMILY_ARP = "arp"
NFT_FAMILY_NETDEV = "netdev"
VERDICT_ACCEPT = "accept"
VERDICT_DROP = "drop"
VERDICT_REJECT = "reject"
VERDICT_RETURN = "return"
VERDICT_QUEUE = "queue"
VERDICT_JUMP = "jump"
// TODO
VERDICT_GOTO = "goto"
VERDICT_STOP = "stop"
VERDICT_STOLEN = "stolen"
VERDICT_CONTINUE = "continue"
VERDICT_MASQUERADE = "masquerade"
VERDICT_DNAT = "dnat"
VERDICT_SNAT = "snat"
VERDICT_REDIRECT = "redirect"
VERDICT_TPROXY = "tproxy"
NFT_PARM_TO = "to"
NFT_QUEUE_NUM = "num"
NFT_QUEUE_BY_PASS = "queue-bypass"
NFT_MASQ_RANDOM = "random"
NFT_MASQ_FULLY_RANDOM = "fully-random"
NFT_MASQ_PERSISTENT = "persistent"
NFT_PROTOCOL = "protocol"
NFT_SPORT = "sport"
NFT_DPORT = "dport"
NFT_SADDR = "saddr"
NFT_DADDR = "daddr"
NFT_ICMP_CODE = "code"
NFT_ICMP_TYPE = "type"
NFT_ETHER = "ether"
NFT_IIFNAME = "iifname"
NFT_OIFNAME = "oifname"
NFT_LOG = "log"
NFT_LOG_PREFIX = "prefix"
// TODO
NFT_LOG_LEVEL = "level"
NFT_LOG_LEVEL_EMERG = "emerg"
NFT_LOG_LEVEL_ALERT = "alert"
NFT_LOG_LEVEL_CRIT = "crit"
NFT_LOG_LEVEL_ERR = "err"
NFT_LOG_LEVEL_WARN = "warn"
NFT_LOG_LEVEL_NOTICE = "notice"
NFT_LOG_LEVEL_INFO = "info"
NFT_LOG_LEVEL_DEBUG = "debug"
NFT_LOG_LEVEL_AUDIT = "audit"
NFT_LOG_FLAGS = "flags"
NFT_CT = "ct"
NFT_CT_STATE = "state"
NFT_CT_SET_MARK = "set"
NFT_CT_MARK = "mark"
CT_STATE_NEW = "new"
CT_STATE_ESTABLISHED = "established"
CT_STATE_RELATED = "related"
CT_STATE_INVALID = "invalid"
NFT_NOTRACK = "notrack"
NFT_QUOTA = "quota"
NFT_QUOTA_UNTIL = "until"
NFT_QUOTA_OVER = "over"
NFT_QUOTA_USED = "used"
NFT_QUOTA_UNIT_BYTES = "bytes"
NFT_QUOTA_UNIT_KB = "kbytes"
NFT_QUOTA_UNIT_MB = "mbytes"
NFT_QUOTA_UNIT_GB = "gbytes"
NFT_COUNTER = "counter"
NFT_COUNTER_NAME = "name"
NFT_COUNTER_PACKETS = "packets"
NFT_COUNTER_BYTES = "bytes"
NFT_LIMIT = "limit"
NFT_LIMIT_OVER = "over"
NFT_LIMIT_BURST = "burst"
NFT_LIMIT_UNITS_RATE = "rate-units"
NFT_LIMIT_UNITS_TIME = "time-units"
NFT_LIMIT_UNITS = "units"
NFT_LIMIT_UNIT_SECOND = "second"
NFT_LIMIT_UNIT_MINUTE = "minute"
NFT_LIMIT_UNIT_HOUR = "hour"
NFT_LIMIT_UNIT_DAY = "day"
NFT_LIMIT_UNIT_KBYTES = "kbytes"
NFT_LIMIT_UNIT_MBYTES = "mbytes"
NFT_META = "meta"
NFT_META_MARK = "mark"
NFT_META_SET_MARK = "set"
NFT_META_PRIORITY = "priority"
NFT_META_NFTRACE = "nftrace"
NFT_META_SET = "set"
NFT_META_SKUID = "skuid"
NFT_META_SKGID = "skgid"
NFT_META_L4PROTO = "l4proto"
NFT_META_PROTOCOL = "protocol"
NFT_PROTO_UDP = "udp"
NFT_PROTO_UDPLITE = "udplite"
NFT_PROTO_TCP = "tcp"
NFT_PROTO_SCTP = "sctp"
NFT_PROTO_DCCP = "dccp"
NFT_PROTO_ICMP = "icmp"
NFT_PROTO_ICMPX = "icmpx"
NFT_PROTO_ICMPv6 = "icmpv6"
NFT_PROTO_AH = "ah"
NFT_PROTO_ETHERNET = "ethernet"
NFT_PROTO_GRE = "gre"
NFT_PROTO_IP = "ip"
NFT_PROTO_IPIP = "ipip"
NFT_PROTO_L2TP = "l2tp"
NFT_PROTO_COMP = "comp"
NFT_PROTO_IGMP = "igmp"
NFT_PROTO_ESP = "esp"
NFT_PROTO_RAW = "raw"
NFT_PROTO_ENCAP = "encap"
ICMP_NO_ROUTE = "no-route"
ICMP_PROT_UNREACHABLE = "prot-unreachable"
ICMP_PORT_UNREACHABLE = "port-unreachable"
ICMP_NET_UNREACHABLE = "net-unreachable"
ICMP_ADDR_UNREACHABLE = "addr-unreachable"
ICMP_HOST_UNREACHABLE = "host-unreachable"
ICMP_NET_PROHIBITED = "net-prohibited"
ICMP_HOST_PROHIBITED = "host-prohibited"
ICMP_ADMIN_PROHIBITED = "admin-prohibited"
ICMP_REJECT_ROUTE = "reject-route"
ICMP_REJECT_POLICY_FAIL = "policy-fail"
ICMP_ECHO_REPLY = "echo-reply"
ICMP_ECHO_REQUEST = "echo-request"
ICMP_SOURCE_QUENCH = "source-quench"
ICMP_DEST_UNREACHABLE = "destination-unreachable"
ICMP_REDIRECT = "redirect"
ICMP_TIME_EXCEEDED = "time-exceeded"
ICMP_INFO_REQUEST = "info-request"
ICMP_INFO_REPLY = "info-reply"
ICMP_PARAMETER_PROBLEM = "parameter-problem"
ICMP_TIMESTAMP_REQUEST = "timestamp-request"
ICMP_TIMESTAMP_REPLY = "timestamp-reply"
ICMP_ROUTER_ADVERTISEMENT = "router-advertisement"
ICMP_ROUTER_SOLICITATION = "router-solicitation"
ICMP_ADDRESS_MASK_REQUEST = "address-mask-request"
ICMP_ADDRESS_MASK_REPLY = "address-mask-reply"
ICMP_PACKET_TOO_BIG = "packet-too-big"
ICMP_NEIGHBOUR_SOLICITATION = "neighbour-solicitation"
ICMP_NEIGHBOUR_ADVERTISEMENT = "neighbour-advertisement"
)
================================================
FILE: daemon/firewall/nftables/exprs/ether.go
================================================
package exprs
import (
"encoding/hex"
"fmt"
"strings"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/google/nftables/expr"
)
// NewExprEther creates a new expression to match ethernet MAC addresses
func NewExprEther(values []*config.ExprValues) (*[]expr.Any, error) {
etherExpr := []expr.Any{}
macDir := uint32(6)
for _, eth := range values {
if eth.Key == NFT_DADDR {
macDir = uint32(0)
} else {
macDir = uint32(6)
}
macaddr, err := parseMACAddr(eth.Value)
if err != nil {
return nil, err
}
etherExpr = append(etherExpr, []expr.Any{
&expr.Meta{Key: expr.MetaKeyIIFTYPE, Register: 1},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{0x01, 0x00},
},
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseLLHeader,
Offset: macDir,
Len: 6,
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: macaddr,
},
}...)
}
return ðerExpr, nil
}
func parseMACAddr(macValue string) ([]byte, error) {
mac := strings.Split(macValue, ":")
macaddr := make([]byte, 0)
if len(mac) != 6 {
return nil, fmt.Errorf("Invalid MAC address: %s", macValue)
}
for i, m := range mac {
mm, err := hex.DecodeString(m)
if err != nil {
return nil, fmt.Errorf("Invalid MAC byte: %c (%s)", mm[i], macValue)
}
macaddr = append(macaddr, mm[0])
}
return macaddr, nil
}
================================================
FILE: daemon/firewall/nftables/exprs/ether_test.go
================================================
package exprs_test
import (
"bytes"
"reflect"
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/expr"
)
func TestExprEther(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
values := []*config.ExprValues{
&config.ExprValues{
Key: "ether",
Value: "de:ad:be:af:ca:fe",
},
}
etherExpr, err := exprs.NewExprEther(values)
if err != nil {
t.Errorf("Error creating Ether expression: %s, %+v", err, values)
}
r, _ := nftest.AddTestRule(t, conn, etherExpr)
if r == nil {
t.Error("Error adding Ether rule")
return
}
if len(r.Exprs) != 4 {
t.Errorf("invalid rule created, we expected 4 expressions, got: %d", len(r.Exprs))
}
/*
expr Meta
expr Cmp
expr Payload
expr Cmp
*/
t.Run("test-ether-expr meta", func(t *testing.T) {
e := r.Exprs[0] // meta
if reflect.TypeOf(e).String() != "*expr.Meta" {
t.Errorf("first expression should be *expr.Meta, instead of: %s", reflect.TypeOf(e))
}
lMeta, ok := e.(*expr.Meta)
if !ok {
t.Errorf("invalid meta expr: %T", e)
}
if lMeta.Key != expr.MetaKeyIIFTYPE {
t.Errorf("invalid meta Key: %d, instead of %d", lMeta.Key, expr.MetaKeyIIFTYPE)
}
})
t.Run("test-ether-expr cmp", func(t *testing.T) {
e := r.Exprs[1] // cmp
if reflect.TypeOf(e).String() != "*expr.Cmp" {
t.Errorf("second expression should be *expr.Cmp, instead of: %s", reflect.TypeOf(e))
}
lCmp, ok := e.(*expr.Cmp)
if !ok {
t.Errorf("invalid cmp expr: %T", e)
}
if !bytes.Equal(lCmp.Data, []byte{0x01, 0x00}) {
t.Errorf("invalid cmp data: %v", lCmp.Data)
}
})
t.Run("test-ether-expr payload", func(t *testing.T) {
e := r.Exprs[2] // payload
if reflect.TypeOf(e).String() != "*expr.Payload" {
t.Errorf("third expression should be *expr.Payload, instead of: %s", reflect.TypeOf(e))
}
lPayload, ok := e.(*expr.Payload)
if !ok {
t.Errorf("invalid payload expr: %T", e)
}
if lPayload.Base != expr.PayloadBaseLLHeader || lPayload.Offset != 6 || lPayload.Len != 6 {
t.Errorf("invalid payload data: %v", lPayload)
}
})
t.Run("test-ether-expr cmp", func(t *testing.T) {
e := r.Exprs[3] // cmp
if reflect.TypeOf(e).String() != "*expr.Cmp" {
t.Errorf("fourth expression should be *expr.Cmp, instead of: %s", reflect.TypeOf(e))
}
lCmp, ok := e.(*expr.Cmp)
if !ok {
t.Errorf("invalid cmp expr: %T", e)
}
if !bytes.Equal(lCmp.Data, []byte{222, 173, 190, 175, 202, 254}) {
t.Errorf("invalid cmp data: %q", lCmp.Data)
}
})
}
================================================
FILE: daemon/firewall/nftables/exprs/iface.go
================================================
package exprs
import (
"github.com/google/nftables/expr"
)
// NewExprIface returns a new network interface expression
func NewExprIface(iface string, isOut bool, cmpOp expr.CmpOp) *[]expr.Any {
keyDev := expr.MetaKeyIIFNAME
if isOut {
keyDev = expr.MetaKeyOIFNAME
}
return &[]expr.Any{
&expr.Meta{Key: keyDev, Register: 1},
&expr.Cmp{
Op: cmpOp,
Register: 1,
Data: ifname(iface),
},
}
}
// https://github.com/google/nftables/blob/master/nftables_test.go#L81
func ifname(n string) []byte {
buf := make([]byte, 16)
length := len(n)
// allow wildcards
if n[length-1:] == "*" {
return []byte(n[:length-1])
}
copy(buf, []byte(n+"\x00"))
return buf
}
================================================
FILE: daemon/firewall/nftables/exprs/iface_test.go
================================================
package exprs_test
import (
"bytes"
"reflect"
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/expr"
)
// https://github.com/evilsocket/opensnitch/blob/master/daemon/firewall/nftables/exprs/iface.go#L22
func ifname(n string) []byte {
buf := make([]byte, 16)
length := len(n)
// allow wildcards
if n[length-1:] == "*" {
return []byte(n[:length-1])
}
copy(buf, []byte(n+"\x00"))
return buf
}
func TestExprIface(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
type ifaceTestsT struct {
name string
iface string
out bool
}
tests := []ifaceTestsT{
{"test-in-iface-xxx", "in-iface0", false},
{"test-out-iface-xxx", "out-iface0", true},
{"test-out-iface-xxx-wildcard", "out-iface*", true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ifaceExpr := exprs.NewExprIface(test.iface, test.out, expr.CmpOpEq)
r, _ := nftest.AddTestRule(t, conn, ifaceExpr)
if r == nil {
t.Error("Error adding rule with iface expression")
}
if total := len(r.Exprs); total != 2 {
t.Errorf("expected 2 expressions, got %d: %+v", total, r.Exprs)
}
e := r.Exprs[0]
if reflect.TypeOf(e).String() != "*expr.Meta" {
t.Errorf("first expression should be *expr.Meta, instead of: %s", reflect.TypeOf(e))
}
lExpr, ok := e.(*expr.Meta)
if !ok {
t.Errorf("invalid iface meta expr: %T", e)
}
if test.out && lExpr.Key != expr.MetaKeyOIFNAME {
t.Errorf("iface Key should be MetaKeyOIFNAME instead of: %+v", lExpr)
} else if !test.out && lExpr.Key != expr.MetaKeyIIFNAME {
t.Errorf("iface Key should be MetaKeyIIFNAME instead of: %+v", lExpr)
}
e = r.Exprs[1]
if reflect.TypeOf(e).String() != "*expr.Cmp" {
t.Errorf("second expression should be *expr.Cmp, instead of: %s", reflect.TypeOf(e))
}
lCmp, ok := e.(*expr.Cmp)
if !ok {
t.Errorf("invalid iface cmp expr: %T", e)
}
if !bytes.Equal(lCmp.Data, ifname(test.iface)) {
t.Errorf("iface Cmp does not match: %v, expected: %v", lCmp.Data, ifname(test.iface))
}
})
}
}
================================================
FILE: daemon/firewall/nftables/exprs/ip.go
================================================
package exprs
import (
"fmt"
"net"
"strings"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
// NewExprIP returns a new IP expression.
// You can use multiple statements to specify daddr + saddr, or combine them
// in a single statement expression:
// Example 1 (filtering by source and dest address):
// "Name": "ip",
// "Values": [ {"Key": "saddr": "Value": "1.2.3.4"},{"Key": "daddr": "Value": "1.2.3.5"} ]
// Example 2 (filtering by multiple dest addrs IPs):
// "Name": "ip",
// "Values": [
// {"Key": "daddr": "Value": "1.2.3.4"},
// {"Key": "daddr": "Value": "1.2.3.5"}
// ]
// Example 3 (filtering by network range):
// "Name": "ip",
// "Values": [
// {"Key": "daddr": "Value": "1.2.3.4-1.2.9.254"}
// ]
// TODO (filter by multiple dest addrs separated by commas):
// "Values": [
// {"Key": "daddr": "Value": "1.2.3.4,1.2.9.254"}
// ]
func NewExprIP(family string, ipOptions []*config.ExprValues, cmpOp expr.CmpOp) (*[]expr.Any, error) {
var exprIP []expr.Any
// if the table family is inet, we need to specify the protocol of the IP being added.
if family == NFT_FAMILY_INET {
exprIP = append(exprIP, &expr.Meta{Key: expr.MetaKeyNFPROTO, Register: 1})
exprIP = append(exprIP, &expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte{unix.NFPROTO_IPV4}})
}
for _, ipOpt := range ipOptions {
// TODO: ipv6
switch ipOpt.Key {
case NFT_SADDR, NFT_DADDR:
payload := getExprIPPayload(ipOpt.Key)
exprIP = append(exprIP, payload)
if strings.Index(ipOpt.Value, "-") == -1 {
exprIPtemp, err := getExprIP(ipOpt.Value, cmpOp)
if err != nil {
return nil, err
}
exprIP = append(exprIP, *exprIPtemp...)
} else {
exprIPtemp, err := getExprRangeIP(ipOpt.Value, cmpOp)
if err != nil {
return nil, err
}
exprIP = append(exprIP, *exprIPtemp...)
}
case NFT_PROTOCOL:
payload := getExprIPPayload(ipOpt.Key)
exprIP = append(exprIP, payload)
protoCode, err := getProtocolCode(ipOpt.Value)
if err != nil {
return nil, err
}
exprIP = append(exprIP, []expr.Any{
&expr.Cmp{
Op: cmpOp,
Register: 1,
Data: []byte{byte(protoCode)},
},
}...)
}
}
return &exprIP, nil
}
func getExprIPPayload(what string) *expr.Payload {
switch what {
case NFT_PROTOCOL:
return &expr.Payload{
DestRegister: 1,
Offset: 9, // daddr
Base: expr.PayloadBaseNetworkHeader,
Len: 1, // 16 ipv6
}
case NFT_DADDR:
// NOTE 1: if "what" is daddr and SourceRegister is part of the Payload{} expression,
// the rule is not added.
return &expr.Payload{
DestRegister: 1,
Offset: 16, // daddr
Base: expr.PayloadBaseNetworkHeader,
Len: 4, // 16 ipv6
}
default:
return &expr.Payload{
SourceRegister: 1,
DestRegister: 1,
Offset: 12, // saddr
Base: expr.PayloadBaseNetworkHeader,
Len: 4, // 16 ipv6
}
}
}
// Supported IP types: a.b.c.d, a.b.c.d-w.x.y.z
// TODO: support IPs separated by commas: a.b.c.d, e.f.g.h,...
func getExprIP(value string, cmpOp expr.CmpOp) (*[]expr.Any, error) {
ip := net.ParseIP(value)
if ip == nil {
return nil, fmt.Errorf("Invalid IP: %s", value)
}
return &[]expr.Any{
&expr.Cmp{
Op: cmpOp,
Register: 1,
Data: ip.To4(),
},
}, nil
}
// Supported IP types: a.b.c.d, a.b.c.d-w.x.y.z
// TODO: support IPs separated by commas: a.b.c.d, e.f.g.h,...
func getExprRangeIP(value string, cmpOp expr.CmpOp) (*[]expr.Any, error) {
ips := strings.Split(value, "-")
ipSrc := net.ParseIP(ips[0])
ipDst := net.ParseIP(ips[1])
if ipSrc == nil || ipDst == nil {
return nil, fmt.Errorf("Invalid IPs range: %v", ips)
}
return &[]expr.Any{
&expr.Range{
Op: cmpOp,
Register: 1,
FromData: ipSrc.To4(),
ToData: ipDst.To4(),
},
}, nil
}
================================================
FILE: daemon/firewall/nftables/exprs/ip_test.go
================================================
package exprs_test
import (
"net"
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
func TestExprIP(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
tests := []nftest.TestsT{
{
"test-ip-daddr",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1.1",
},
},
2,
[]interface{}{
&expr.Payload{
SourceRegister: 0,
DestRegister: 1,
Offset: 16,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Cmp{
Data: net.ParseIP("1.1.1.1").To4(),
},
},
false,
},
{
"test-ip-saddr",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "saddr",
Value: "1.1.1.1",
},
},
2,
[]interface{}{
&expr.Payload{
SourceRegister: 1,
DestRegister: 1,
Offset: 12,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Cmp{
Data: net.ParseIP("1.1.1.1").To4(),
},
},
false,
},
{
"test-inet-daddr",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1.1",
},
},
4,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyNFPROTO, Register: 1,
},
&expr.Cmp{
Data: []byte{unix.NFPROTO_IPV4},
},
&expr.Payload{
SourceRegister: 0,
DestRegister: 1,
Offset: 16,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Cmp{
Data: net.ParseIP("1.1.1.1").To4(),
},
},
false,
},
{
"test-ip-daddr-invalid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1",
},
},
0,
[]interface{}{},
true,
},
{
"test-ip-daddr-invalid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1..1.1.1",
},
},
0,
[]interface{}{},
true,
},
{
"test-ip-daddr-invalid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "www.test.com",
},
},
0,
[]interface{}{},
true,
},
{
"test-ip-daddr-invalid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "",
},
},
0,
[]interface{}{},
true,
},
{
"test-inet-saddr",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "saddr",
Value: "1.1.1.1",
},
},
4,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyNFPROTO, Register: 1,
},
&expr.Cmp{
Data: []byte{unix.NFPROTO_IPV4},
},
&expr.Payload{
SourceRegister: 1,
DestRegister: 1,
Offset: 12,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Cmp{
Data: net.ParseIP("1.1.1.1").To4(),
},
},
false,
},
{
"test-inet-daddr-invalid",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1..1.1.1",
},
},
0,
[]interface{}{},
true,
},
{
"test-inet-saddr-invalid",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "saddr",
Value: "1..1.1.1",
},
},
0,
[]interface{}{},
true,
},
{
"test-inet-range-daddr",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1.1-2.2.2.2",
},
},
4,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyNFPROTO, Register: 1,
},
&expr.Cmp{
Data: []byte{unix.NFPROTO_IPV4},
},
&expr.Payload{
SourceRegister: 0,
DestRegister: 1,
Offset: 16,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Range{
Register: 1,
FromData: net.ParseIP("1.1.1.1").To4(),
ToData: net.ParseIP("2.2.2.2").To4(),
},
},
false,
},
{
"test-inet-range-saddr",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "saddr",
Value: "1.1.1.1-2.2.2.2",
},
},
4,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyNFPROTO, Register: 1,
},
&expr.Cmp{
Data: []byte{unix.NFPROTO_IPV4},
},
&expr.Payload{
SourceRegister: 1,
DestRegister: 1,
Offset: 12,
Base: expr.PayloadBaseNetworkHeader,
Len: 4,
},
&expr.Range{
Register: 1,
FromData: net.ParseIP("1.1.1.1").To4(),
ToData: net.ParseIP("2.2.2.2").To4(),
},
},
false,
},
{
"test-inet-daddr-range-invalid",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1.1--2.2.2.2",
},
},
0,
[]interface{}{},
true,
},
{
"test-inet-daddr-range-invalid",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
Value: "1.1.1.1-1..2.2.2",
},
},
0,
[]interface{}{},
true,
},
{
"test-inet-daddr-range-invalid",
exprs.NFT_FAMILY_INET,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: "daddr",
// TODO: not supported yet
Value: "1.1.1.1/24",
},
},
0,
[]interface{}{},
true,
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
ipExpr, err := exprs.NewExprIP(test.Family, test.Values, expr.CmpOpEq)
if err != nil && !test.ExpectedFail {
t.Errorf("Error creating expr IP: %s", ipExpr)
return
} else if err != nil && test.ExpectedFail {
return
}
r, _ := nftest.AddTestRule(t, conn, ipExpr)
if r == nil && !test.ExpectedFail {
t.Error("Error adding rule with IP expression")
}
if !nftest.AreExprsValid(t, &test, r) {
return
}
if test.ExpectedFail {
t.Errorf("test should have failed")
}
})
}
}
================================================
FILE: daemon/firewall/nftables/exprs/limit.go
================================================
package exprs
import (
"fmt"
"strconv"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/google/nftables/expr"
)
// NewExprLimit returns a new limit expression.
// limit rate [over] 1/second
// to express bytes units, we use: 10-mbytes instead of nft's 10 mbytes
func NewExprLimit(statement *config.ExprStatement) (*[]expr.Any, error) {
var err error
exprLimit := &expr.Limit{
Type: expr.LimitTypePkts,
Over: false,
Unit: expr.LimitTimeSecond,
}
for _, values := range statement.Values {
switch values.Key {
case NFT_LIMIT_OVER:
exprLimit.Over = true
case NFT_LIMIT_UNITS:
exprLimit.Rate, err = strconv.ParseUint(values.Value, 10, 64)
if err != nil {
return nil, fmt.Errorf("Invalid limit rate: %s", values.Value)
}
case NFT_LIMIT_BURST:
limitBurst := 0
limitBurst, err = strconv.Atoi(values.Value)
if err != nil || limitBurst == 0 {
return nil, fmt.Errorf("Invalid burst limit: %s, err: %s", values.Value, err)
}
exprLimit.Burst = uint32(limitBurst)
case NFT_LIMIT_UNITS_RATE:
// units rate must be placed AFTER the rate
exprLimit.Type, exprLimit.Rate = getLimitRate(values.Value, exprLimit.Rate)
case NFT_LIMIT_UNITS_TIME:
exprLimit.Unit = getLimitUnits(values.Value)
}
}
return &[]expr.Any{exprLimit}, nil
}
func getLimitUnits(units string) (limitUnits expr.LimitTime) {
switch units {
case NFT_LIMIT_UNIT_MINUTE:
limitUnits = expr.LimitTimeMinute
case NFT_LIMIT_UNIT_HOUR:
limitUnits = expr.LimitTimeHour
case NFT_LIMIT_UNIT_DAY:
limitUnits = expr.LimitTimeDay
default:
limitUnits = expr.LimitTimeSecond
}
return limitUnits
}
func getLimitRate(units string, rate uint64) (limitType expr.LimitType, limitRate uint64) {
switch units {
case NFT_LIMIT_UNIT_KBYTES:
limitRate = rate * 1024
limitType = expr.LimitTypePktBytes
case NFT_LIMIT_UNIT_MBYTES:
limitRate = (rate * 1024) * 1024
limitType = expr.LimitTypePktBytes
default:
limitType = expr.LimitTypePkts
limitRate, _ = strconv.ParseUint(units, 10, 64)
}
return
}
================================================
FILE: daemon/firewall/nftables/exprs/log.go
================================================
package exprs
import (
"fmt"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/log"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
// NewExprLog returns a new log expression.
func NewExprLog(statement *config.ExprStatement) (*[]expr.Any, error) {
prefix := "opensnitch"
logExpr := expr.Log{
Key: 1 << unix.NFTA_LOG_PREFIX,
Data: []byte(prefix),
}
for _, values := range statement.Values {
switch values.Key {
case NFT_LOG_PREFIX:
if values.Value == "" {
return nil, fmt.Errorf("Invalid log prefix, it's empty")
}
logExpr.Data = []byte(values.Value)
case NFT_LOG_LEVEL:
lvl, err := getLogLevel(values.Value)
if err != nil {
log.Warning("%s", err)
return nil, err
}
logExpr.Key |= 1 << unix.NFTA_LOG_LEVEL
logExpr.Level = lvl
// TODO
// https://github.com/google/nftables/blob/main/nftables_test.go#L623
//case exprs.NFT_LOG_FLAGS:
//case exprs.NFT_LOG_GROUP:
//case exprs.NFT_LOG_QTHRESHOLD:
}
}
return &[]expr.Any{
&logExpr,
}, nil
}
func getLogLevel(what string) (expr.LogLevel, error) {
switch what {
// https://github.com/google/nftables/blob/main/expr/log.go#L28
case NFT_LOG_LEVEL_EMERG:
return expr.LogLevelEmerg, nil
case NFT_LOG_LEVEL_ALERT:
return expr.LogLevelAlert, nil
case NFT_LOG_LEVEL_CRIT:
return expr.LogLevelCrit, nil
case NFT_LOG_LEVEL_ERR:
return expr.LogLevelErr, nil
case NFT_LOG_LEVEL_WARN:
return expr.LogLevelWarning, nil
case NFT_LOG_LEVEL_NOTICE:
return expr.LogLevelNotice, nil
case NFT_LOG_LEVEL_INFO:
return expr.LogLevelInfo, nil
case NFT_LOG_LEVEL_DEBUG:
return expr.LogLevelDebug, nil
case NFT_LOG_LEVEL_AUDIT:
return expr.LogLevelAudit, nil
}
return 0, fmt.Errorf("Invalid log level: %s", what)
}
================================================
FILE: daemon/firewall/nftables/exprs/log_test.go
================================================
package exprs_test
import (
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
exprs "github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
func TestExprLog(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
type logTestsT struct {
nftest.TestsT
statem *config.ExprStatement
}
tests := []logTestsT{
{
TestsT: nftest.TestsT{
Name: "test-log-prefix-simple",
Values: []*config.ExprValues{
&config.ExprValues{
Key: "prefix",
Value: "counter-test",
},
},
ExpectedExprs: []interface{}{
&expr.Log{
Key: 1 << unix.NFTA_LOG_PREFIX,
Data: []byte("counter-test"),
},
},
ExpectedExprsNum: 1,
ExpectedFail: false,
},
statem: &config.ExprStatement{
Op: "==",
Name: "log",
},
},
{
TestsT: nftest.TestsT{
Name: "test-log-prefix-emerg",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_LOG_PREFIX,
Value: "counter-test-emerg",
},
&config.ExprValues{
Key: exprs.NFT_LOG_LEVEL,
Value: exprs.NFT_LOG_LEVEL_EMERG,
},
},
ExpectedExprs: []interface{}{
&expr.Log{
Key: (1 << unix.NFTA_LOG_PREFIX) | (1 << unix.NFTA_LOG_LEVEL),
Level: expr.LogLevelEmerg,
Data: []byte("counter-test-emerg"),
},
},
ExpectedExprsNum: 1,
ExpectedFail: false,
},
statem: &config.ExprStatement{
Op: "==",
Name: "log",
},
},
{
TestsT: nftest.TestsT{
Name: "test-invalid-log-prefix",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_LOG_PREFIX,
Value: "",
},
&config.ExprValues{
Key: exprs.NFT_LOG_LEVEL,
Value: exprs.NFT_LOG_LEVEL_EMERG,
},
},
ExpectedExprs: []interface{}{},
ExpectedExprsNum: 0,
ExpectedFail: true,
},
statem: &config.ExprStatement{
Op: "==",
Name: "log",
},
},
{
TestsT: nftest.TestsT{
Name: "test-invalid-log-level",
Values: []*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_LOG_PREFIX,
Value: "counter-invalid-level",
},
&config.ExprValues{
Key: exprs.NFT_LOG_LEVEL,
Value: "",
},
},
ExpectedExprs: []interface{}{},
ExpectedExprsNum: 0,
ExpectedFail: true,
},
statem: &config.ExprStatement{
Op: "==",
Name: "log",
},
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
test.statem.Values = test.TestsT.Values
logExpr, err := exprs.NewExprLog(test.statem)
if err != nil && !test.ExpectedFail {
t.Errorf("Error creating expr Log: %s", logExpr)
return
} else if err != nil && test.ExpectedFail {
return
}
r, _ := nftest.AddTestRule(t, conn, logExpr)
if r == nil {
t.Error("Error adding rule with log expression")
return
}
if !nftest.AreExprsValid(t, &test.TestsT, r) {
return
}
if test.ExpectedFail {
t.Errorf("test should have failed")
}
})
}
}
================================================
FILE: daemon/firewall/nftables/exprs/meta.go
================================================
package exprs
import (
"fmt"
"strconv"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
)
// NewExprMeta creates a new meta selector to match or set packet metainformation.
// https://wiki.nftables.org/wiki-nftables/index.php/Matching_packet_metainformation
func NewExprMeta(values []*config.ExprValues, cmpOp *expr.CmpOp) (*[]expr.Any, error) {
setMark := false
metaExpr := []expr.Any{}
for _, meta := range values {
switch meta.Key {
case NFT_META_SET_MARK:
setMark = true
continue
case NFT_META_MARK:
metaKey, err := getMetaKey(meta.Key)
if err != nil {
return nil, err
}
metaVal, err := getMetaValue(meta.Value)
if err != nil {
return nil, err
}
if setMark {
metaExpr = append(metaExpr, []expr.Any{
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(metaVal)),
}}...)
metaExpr = append(metaExpr, []expr.Any{
&expr.Meta{Key: metaKey, Register: 1, SourceRegister: setMark}}...)
} else {
metaExpr = append(metaExpr, []expr.Any{
&expr.Meta{Key: metaKey, Register: 1, SourceRegister: setMark},
&expr.Cmp{
Op: *cmpOp,
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(metaVal)),
}}...)
}
setMark = false
return &metaExpr, nil
case NFT_META_L4PROTO:
mexpr, err := NewExprProtocol(meta.Key)
if err != nil {
return nil, err
}
metaExpr = append(metaExpr, *mexpr...)
return &metaExpr, nil
case NFT_META_PRIORITY,
NFT_META_SKUID, NFT_META_SKGID,
NFT_META_PROTOCOL:
metaKey, err := getMetaKey(meta.Key)
if err != nil {
return nil, err
}
metaVal, err := getProtocolCode(meta.Value)
if err != nil {
return nil, err
}
metaExpr = append(metaExpr, []expr.Any{
&expr.Meta{Key: metaKey, Register: 1, SourceRegister: setMark},
&expr.Cmp{
Op: *cmpOp,
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(metaVal)),
}}...)
setMark = false
return &metaExpr, nil
case NFT_META_NFTRACE:
mark, err := getMetaValue(meta.Value)
if err != nil {
return nil, err
}
if mark != 0 && mark != 1 {
return nil, fmt.Errorf("%s Invalid nftrace value: %d. Only 1 or 0 allowed", "nftables", mark)
}
// TODO: not working yet
return &[]expr.Any{
&expr.Meta{Key: expr.MetaKeyNFTRACE, Register: 1},
&expr.Cmp{
Op: *cmpOp,
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(uint32(mark)),
},
}, nil
default:
// not supported yet
}
}
return nil, fmt.Errorf("%s meta keyword not supported yet, open a new issue on github", "nftables")
}
func getMetaValue(value string) (int, error) {
metaVal, err := strconv.Atoi(value)
if err != nil {
return 0, err
}
return metaVal, nil
}
// https://github.com/google/nftables/blob/main/expr/expr.go#L168
func getMetaKey(value string) (expr.MetaKey, error) {
switch value {
case NFT_META_MARK:
return expr.MetaKeyMARK, nil
case NFT_META_PRIORITY:
return expr.MetaKeyPRIORITY, nil
case NFT_META_SKUID:
return expr.MetaKeySKUID, nil
case NFT_META_SKGID:
return expr.MetaKeySKGID, nil
// ip, ip6, arp, vlan
case NFT_META_PROTOCOL:
return expr.MetaKeyPROTOCOL, nil
case NFT_META_L4PROTO:
return expr.MetaKeyL4PROTO, nil
}
return expr.MetaKeyPRANDOM, fmt.Errorf("meta key %s not supported (yet)", value)
}
================================================
FILE: daemon/firewall/nftables/exprs/meta_test.go
================================================
package exprs_test
import (
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
)
func TestExprMeta(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
tests := []nftest.TestsT{
{
"test-meta-mark",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_MARK,
Value: "666",
},
},
2,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyMARK,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Data: binaryutil.NativeEndian.PutUint32(uint32(666)),
},
},
false,
},
{
"test-meta-set-mark",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_SET_MARK,
Value: "",
},
&config.ExprValues{
Key: exprs.NFT_META_MARK,
Value: "666",
},
},
2,
[]interface{}{
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(666),
},
&expr.Meta{
Key: expr.MetaKeyMARK,
Register: 1,
SourceRegister: true,
},
},
false,
},
{
"test-meta-priority",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_PRIORITY,
Value: "1",
},
},
2,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyPRIORITY,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Data: binaryutil.NativeEndian.PutUint32(uint32(1)),
},
},
false,
},
{
"test-meta-skuid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_SKUID,
Value: "1",
},
},
2,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeySKUID,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Data: binaryutil.NativeEndian.PutUint32(uint32(1)),
},
},
false,
},
{
"test-meta-skgid",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_SKGID,
Value: "1",
},
},
2,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeySKGID,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Data: binaryutil.NativeEndian.PutUint32(uint32(1)),
},
},
false,
},
{
"test-meta-protocol",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_PROTOCOL,
Value: "15",
},
},
2,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyPROTOCOL,
Register: 1,
SourceRegister: false,
},
&expr.Cmp{
Data: binaryutil.NativeEndian.PutUint32(uint32(15)),
},
},
false,
},
// tested more in depth in protocol_test.go
{
"test-meta-l4proto",
exprs.NFT_FAMILY_IP,
"",
[]*config.ExprValues{
&config.ExprValues{
Key: exprs.NFT_META_L4PROTO,
Value: "15",
},
},
1,
[]interface{}{
&expr.Meta{
Key: expr.MetaKeyL4PROTO,
Register: 1,
SourceRegister: false,
},
},
false,
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
cmp := expr.CmpOpEq
metaExpr, err := exprs.NewExprMeta(test.Values, &cmp)
if err != nil && !test.ExpectedFail {
t.Errorf("Error creating expr Meta: %s", metaExpr)
return
} else if err != nil && test.ExpectedFail {
return
}
r, _ := nftest.AddTestRule(t, conn, metaExpr)
if r == nil && !test.ExpectedFail {
t.Error("Error adding rule with Meta expression")
}
if !nftest.AreExprsValid(t, &test, r) {
return
}
if test.ExpectedFail {
t.Errorf("test should have failed")
}
})
}
}
================================================
FILE: daemon/firewall/nftables/exprs/nat.go
================================================
package exprs
import (
"fmt"
"net"
"strconv"
"strings"
"github.com/google/nftables"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
// NewExprNATFlags returns the nat flags configured.
// common to masquerade, snat and dnat
func NewExprNATFlags(parms string) (random, fullrandom, persistent bool) {
masqParms := strings.Split(parms, ",")
for _, mParm := range masqParms {
switch mParm {
case NFT_MASQ_RANDOM:
random = true
case NFT_MASQ_FULLY_RANDOM:
fullrandom = true
case NFT_MASQ_PERSISTENT:
persistent = true
}
}
return
}
// NewExprNAT parses the redirection of redirect, snat, dnat, tproxy and masquerade verdict:
// to x.y.z.a:abcd
// If only the IP is specified (to 1.2.3.4), only NAT.RegAddrMin must be present (regAddr == true)
// If only the port is specified (to :1234), only NAT.RegPortMin must be present (regPort == true)
// If both addr and port are specified (to 1.2.3.4:1234), NAT.RegPortMin and NAT.RegAddrMin must be present.
func NewExprNAT(parms, verdict string) (bool, bool, *[]expr.Any, error) {
regAddr := false
regProto := false
exprNAT := []expr.Any{}
NATParms := strings.Split(parms, " ")
idx := 0
// exclude first parameter if it's "to"
if NATParms[idx] == NFT_PARM_TO {
idx++
}
if idx == len(NATParms) {
return regAddr, regProto, &exprNAT, fmt.Errorf("Invalid parms: %s", parms)
}
dParms := strings.Split(NATParms[idx], ":")
// masquerade doesn't allow "to IP"
if dParms[0] != "" && verdict != VERDICT_MASQUERADE {
dIP := dParms[0]
destIP := net.ParseIP(dIP)
if destIP == nil {
return regAddr, regProto, &exprNAT, fmt.Errorf("Invalid IP: %s", dIP)
}
exprNAT = append(exprNAT, []expr.Any{
&expr.Immediate{
Register: 1,
Data: destIP.To4(),
}}...)
regAddr = true
}
if len(dParms) == 2 {
dPort := dParms[1]
// TODO: support ranges. 9000-9100
destPort, err := strconv.Atoi(dPort)
if err != nil {
return regAddr, regProto, &exprNAT, fmt.Errorf("Invalid Port: %s", dPort)
}
reg := uint32(2)
toPort := binaryutil.BigEndian.PutUint16(uint16(destPort))
// if reg=1 (RegAddrMin=1) is not set, this error appears listing the rules
// "netlink: Error: NAT statement has no proto expression"
if verdict == VERDICT_TPROXY || verdict == VERDICT_MASQUERADE || verdict == VERDICT_REDIRECT {
// according to https://github.com/google/nftables/blob/8a10f689006bf728a5cff35787713047f68e308a/nftables_test.go#L4871
// Masquerade ports should be specified like this:
// toPort = binaryutil.BigEndian.PutUint32(uint32(destPort) << 16)
// but then it's not added/listed correctly with nft.
reg = 1
}
exprNAT = append(exprNAT, []expr.Any{
&expr.Immediate{
Register: reg,
Data: toPort,
}}...)
regProto = true
}
return regAddr, regProto, &exprNAT, nil
}
// NewExprMasquerade returns a new masquerade expression.
func NewExprMasquerade(toPorts, random, fullRandom, persistent bool) *[]expr.Any {
exprMasq := &expr.Masq{
ToPorts: toPorts,
Random: random,
FullyRandom: fullRandom,
Persistent: persistent,
}
if toPorts {
exprMasq.RegProtoMin = 1
}
return &[]expr.Any{
exprMasq,
}
}
// NewExprRedirect returns a new redirect expression.
func NewExprRedirect() *[]expr.Any {
return &[]expr.Any{
// Redirect is a special case of DNAT where the destination is the current machine
&expr.Redir{
RegisterProtoMin: 1,
},
}
}
// NewExprSNAT returns a new snat expression.
func NewExprSNAT() *expr.NAT {
return &expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
}
}
// NewExprDNAT returns a new dnat expression.
func NewExprDNAT() *expr.NAT {
return &expr.NAT{
Type: expr.NATTypeDestNAT,
Family: unix.NFPROTO_IPV4,
}
}
// NewExprTproxy returns a new tproxy expression.
// XXX: is "to x.x.x.x:1234" supported by google/nftables lib? or only "to :1234"?
// it creates an erronous rule.
func NewExprTproxy() *[]expr.Any {
return &[]expr.Any{
&expr.TProxy{
Family: byte(nftables.TableFamilyIPv4),
TableFamily: byte(nftables.TableFamilyIPv4),
RegPort: 1,
}}
}
================================================
FILE: daemon/firewall/nftables/exprs/nat_test.go
================================================
package exprs_test
import (
"net"
"testing"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables/nftest"
"github.com/google/nftables"
"github.com/google/nftables/binaryutil"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
)
func TestExprVerdictSNAT(t *testing.T) {
nftest.SkipIfNotPrivileged(t)
conn, newNS := nftest.OpenSystemConn(t)
defer nftest.CleanupSystemConn(t, newNS)
nftest.Fw.Conn = conn
// TODO: test random, permanent, persistent flags.
tests := []nftest.TestsT{
{
"test-nat-snat-to-127001",
exprs.NFT_FAMILY_IP,
"to 127.0.0.1",
nil,
2,
[]interface{}{
&expr.Immediate{
Register: 1,
Data: net.ParseIP("127.0.0.1").To4(),
},
&expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
Random: false,
FullyRandom: false,
Persistent: false,
RegAddrMin: 1,
},
},
false,
},
{
"test-nat-snat-127001",
exprs.NFT_FAMILY_IP,
"127.0.0.1",
nil,
2,
[]interface{}{
&expr.Immediate{
Register: 1,
Data: net.ParseIP("127.0.0.1").To4(),
},
&expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
Random: false,
FullyRandom: false,
Persistent: false,
RegAddrMin: 1,
},
},
false,
},
{
"test-nat-snat-to-127001:12345",
exprs.NFT_FAMILY_IP,
"to 127.0.0.1:12345",
nil,
3,
[]interface{}{
&expr.Immediate{
Register: 1,
Data: net.ParseIP("127.0.0.1").To4(),
},
&expr.Immediate{
Register: uint32(2),
Data: binaryutil.BigEndian.PutUint16(uint16(12345)),
},
&expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
Random: false,
FullyRandom: false,
Persistent: false,
RegAddrMin: 1,
RegProtoMin: 2,
},
},
false,
},
{
"test-nat-snat-to-:12345",
exprs.NFT_FAMILY_IP,
"to :12345",
nil,
2,
[]interface{}{
&expr.Immediate{
Register: uint32(2),
Data: binaryutil.BigEndian.PutUint16(uint16(12345)),
},
&expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
Random: false,
FullyRandom: false,
Persistent: false,
RegAddrMin: 0,
RegProtoMin: 2,
},
},
false,
},
{
"test-nat-snat-127001:12345",
exprs.NFT_FAMILY_IP,
"127.0.0.1:12345",
nil,
3,
[]interface{}{
&expr.Immediate{
Register: 1,
Data: net.ParseIP("127.0.0.1").To4(),
},
&expr.Immediate{
Register: uint32(2),
Data: binaryutil.BigEndian.PutUint16(uint16(12345)),
},
&expr.NAT{
Type: expr.NATTypeSourceNAT,
Family: unix.NFPROTO_IPV4,
Random: false,
FullyRandom: false,
Persistent: false,
RegAddrMin: 1,
RegProtoMin: 2,
},
},
false,
},
{
"test-invalid-nat-snat-to-",
exprs.NFT_FAMILY_IP,
"to",
nil,
3,
[]interface{}{},
true,
},
{
"test-invalid-nat-snat-to-invalid-ip",
exprs.NFT_FAMILY_IP,
"to 127..0.0.1",
nil,
3,
[]interface{}{},
true,
},
{
"test-invalid-nat-snat-to-invalid-port",
exprs.NFT_FAMILY_IP,
gitextract_fp8zrzif/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── config.yml
│ │ └── feature-request.md
│ └── workflows/
│ ├── build_ebpf_modules.yml
│ ├── generic_validations.yml
│ └── go.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── daemon/
│ ├── .gitignore
│ ├── Gopkg.toml
│ ├── Makefile
│ ├── conman/
│ │ ├── connection.go
│ │ └── connection_test.go
│ ├── core/
│ │ ├── core.go
│ │ ├── ebpf.go
│ │ ├── gzip.go
│ │ ├── system.go
│ │ └── version.go
│ ├── data/
│ │ ├── default-config.json
│ │ ├── init/
│ │ │ ├── opensnitchd-dinit
│ │ │ ├── opensnitchd-openrc
│ │ │ └── opensnitchd.service
│ │ ├── network_aliases.json
│ │ ├── rules/
│ │ │ ├── 000-allow-localhost.json
│ │ │ └── 000-allow-localhost6.json
│ │ ├── system-fw.json
│ │ └── tasks/
│ │ └── tasks.json
│ ├── dns/
│ │ ├── ebpfhook.go
│ │ ├── parse.go
│ │ ├── systemd/
│ │ │ └── monitor.go
│ │ └── track.go
│ ├── firewall/
│ │ ├── common/
│ │ │ └── common.go
│ │ ├── config/
│ │ │ ├── config.go
│ │ │ └── config_test.go
│ │ ├── iptables/
│ │ │ ├── iptables.go
│ │ │ ├── monitor.go
│ │ │ ├── rules.go
│ │ │ └── system.go
│ │ ├── nftables/
│ │ │ ├── chains.go
│ │ │ ├── chains_test.go
│ │ │ ├── exprs/
│ │ │ │ ├── counter.go
│ │ │ │ ├── counter_test.go
│ │ │ │ ├── ct.go
│ │ │ │ ├── ct_test.go
│ │ │ │ ├── enums.go
│ │ │ │ ├── ether.go
│ │ │ │ ├── ether_test.go
│ │ │ │ ├── iface.go
│ │ │ │ ├── iface_test.go
│ │ │ │ ├── ip.go
│ │ │ │ ├── ip_test.go
│ │ │ │ ├── limit.go
│ │ │ │ ├── log.go
│ │ │ │ ├── log_test.go
│ │ │ │ ├── meta.go
│ │ │ │ ├── meta_test.go
│ │ │ │ ├── nat.go
│ │ │ │ ├── nat_test.go
│ │ │ │ ├── notrack.go
│ │ │ │ ├── operator.go
│ │ │ │ ├── port.go
│ │ │ │ ├── port_test.go
│ │ │ │ ├── protocol.go
│ │ │ │ ├── protocol_test.go
│ │ │ │ ├── quota.go
│ │ │ │ ├── quota_test.go
│ │ │ │ ├── utils.go
│ │ │ │ ├── verdict.go
│ │ │ │ └── verdict_test.go
│ │ │ ├── monitor.go
│ │ │ ├── monitor_test.go
│ │ │ ├── nftables.go
│ │ │ ├── nftest/
│ │ │ │ ├── nftest.go
│ │ │ │ ├── test_utils.go
│ │ │ │ └── utils.go
│ │ │ ├── parser.go
│ │ │ ├── rule_helpers.go
│ │ │ ├── rules.go
│ │ │ ├── rules_test.go
│ │ │ ├── system.go
│ │ │ ├── system_test.go
│ │ │ ├── tables.go
│ │ │ ├── tables_test.go
│ │ │ ├── testdata/
│ │ │ │ └── test-sysfw-conf.json
│ │ │ ├── utils.go
│ │ │ └── utils_test.go
│ │ └── rules.go
│ ├── go.mod
│ ├── go.sum
│ ├── internal/
│ │ └── testutil/
│ │ └── network.go
│ ├── log/
│ │ ├── formats/
│ │ │ ├── csv.go
│ │ │ ├── formats.go
│ │ │ ├── json.go
│ │ │ ├── rfc3164.go
│ │ │ └── rfc5424.go
│ │ ├── log.go
│ │ └── loggers/
│ │ ├── logger.go
│ │ ├── remote.go
│ │ ├── remote_syslog.go
│ │ └── syslog.go
│ ├── main.go
│ ├── netfilter/
│ │ ├── netfilter_test.go
│ │ ├── packet.go
│ │ ├── queue.c
│ │ ├── queue.go
│ │ └── queue.h
│ ├── netlink/
│ │ ├── ifaces.go
│ │ ├── procmon/
│ │ │ └── procmon.go
│ │ ├── socket.go
│ │ ├── socket_linux.go
│ │ ├── socket_packet.go
│ │ ├── socket_test.go
│ │ └── socket_xdp.go
│ ├── netstat/
│ │ ├── entry.go
│ │ ├── find.go
│ │ ├── parse.go
│ │ └── parse_packet.go
│ ├── procmon/
│ │ ├── activepids.go
│ │ ├── audit/
│ │ │ ├── client.go
│ │ │ ├── config.go
│ │ │ └── parse.go
│ │ ├── cache.go
│ │ ├── cache_events.go
│ │ ├── cache_events_test.go
│ │ ├── cache_test.go
│ │ ├── details.go
│ │ ├── ebpf/
│ │ │ ├── cache.go
│ │ │ ├── config.go
│ │ │ ├── debug.go
│ │ │ ├── ebpf.go
│ │ │ ├── ebpf_test.go
│ │ │ ├── events.go
│ │ │ ├── find.go
│ │ │ ├── monitor.go
│ │ │ └── utils.go
│ │ ├── find.go
│ │ ├── find_test.go
│ │ ├── monitor/
│ │ │ └── init.go
│ │ ├── parse.go
│ │ ├── process.go
│ │ ├── process_test.go
│ │ └── testdata/
│ │ └── proc-environ
│ ├── rule/
│ │ ├── loader.go
│ │ ├── loader_test.go
│ │ ├── operator.go
│ │ ├── operator_aliases.go
│ │ ├── operator_lists.go
│ │ ├── operator_test.go
│ │ ├── rule.go
│ │ ├── rule_test.go
│ │ └── testdata/
│ │ ├── 000-allow-chrome.json
│ │ ├── 001-deny-chrome.json
│ │ ├── invalid-regexp-list.json
│ │ ├── invalid-regexp.json
│ │ ├── lists/
│ │ │ ├── domains/
│ │ │ │ └── domainlists.txt
│ │ │ ├── ips/
│ │ │ │ └── ips.txt
│ │ │ ├── nets/
│ │ │ │ └── nets.txt
│ │ │ └── regexp/
│ │ │ └── domainsregexp.txt
│ │ ├── live_reload/
│ │ │ ├── test-live-reload-delete.json
│ │ │ └── test-live-reload-remove.json
│ │ ├── rule-disabled-operator-list-expanded.json
│ │ ├── rule-disabled-operator-list.json
│ │ ├── rule-operator-list-data-empty.json
│ │ └── rule-operator-list.json
│ ├── statistics/
│ │ ├── event.go
│ │ └── stats.go
│ ├── tasks/
│ │ ├── base/
│ │ │ └── main.go
│ │ ├── config/
│ │ │ ├── main.go
│ │ │ ├── monitor.go
│ │ │ └── utils.go
│ │ ├── doc.go
│ │ ├── downloader/
│ │ │ ├── README.md
│ │ │ ├── config.go
│ │ │ ├── downloader.go
│ │ │ ├── main.go
│ │ │ └── utils.go
│ │ ├── iocscanner/
│ │ │ ├── README.md
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── main.go
│ │ │ ├── run_tools.go
│ │ │ └── tools/
│ │ │ ├── base/
│ │ │ │ └── base.go
│ │ │ ├── dpkg/
│ │ │ │ └── dpkg.go
│ │ │ ├── executer/
│ │ │ │ └── executer.go
│ │ │ ├── generic/
│ │ │ │ └── generic.go
│ │ │ └── yara/
│ │ │ └── yara.go
│ │ ├── load.go
│ │ ├── looptask/
│ │ │ └── main.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── nodemonitor/
│ │ │ ├── main.go
│ │ │ └── main_test.go
│ │ ├── pidmonitor/
│ │ │ ├── main.go
│ │ │ └── main_test.go
│ │ ├── scheduler/
│ │ │ ├── daily.go
│ │ │ └── scheduler.go
│ │ └── socketsmonitor/
│ │ ├── dump.go
│ │ ├── main.go
│ │ └── options.go
│ └── ui/
│ ├── alerts.go
│ ├── auth/
│ │ └── auth.go
│ ├── client.go
│ ├── client_test.go
│ ├── config/
│ │ └── config.go
│ ├── config_utils.go
│ ├── notifications.go
│ ├── notifications_tasks.go
│ ├── protocol/
│ │ └── .gitkeep
│ └── testdata/
│ ├── config-invalid-procmon.json
│ ├── default-config.json
│ └── default-config.json.orig
├── ebpf_prog/
│ ├── Makefile
│ ├── README
│ ├── arm-clang-asm-fix.patch
│ ├── bpf_headers/
│ │ ├── bpf_core_read.h
│ │ ├── bpf_helper_defs.h
│ │ ├── bpf_helpers.h
│ │ └── bpf_tracing.h
│ ├── common.h
│ ├── common_defs.h
│ ├── opensnitch-dns.c
│ ├── opensnitch-procs.c
│ └── opensnitch.c
├── proto/
│ ├── .gitignore
│ ├── Makefile
│ └── ui.proto
├── release.sh
├── ui/
│ ├── .gitignore
│ ├── LICENSE
│ ├── MANIFEST.in
│ ├── Makefile
│ ├── bin/
│ │ └── opensnitch-ui
│ ├── i18n/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── generate_i18n.sh
│ │ ├── locales/
│ │ │ ├── ar/
│ │ │ │ └── opensnitch-ar.ts
│ │ │ ├── cs_CZ/
│ │ │ │ └── opensnitch-cs_CZ.ts
│ │ │ ├── de_DE/
│ │ │ │ └── opensnitch-de_DE.ts
│ │ │ ├── es_ES/
│ │ │ │ └── opensnitch-es_ES.ts
│ │ │ ├── eu_ES/
│ │ │ │ └── opensnitch-eu_ES.ts
│ │ │ ├── fi_FI/
│ │ │ │ └── opensnitch-fi_FI.ts
│ │ │ ├── fr_FR/
│ │ │ │ └── opensnitch-fr_FR.ts
│ │ │ ├── he_IL/
│ │ │ │ └── opensnitch-he_IL.ts
│ │ │ ├── hi_IN/
│ │ │ │ └── opensnitch-hi_IN.ts
│ │ │ ├── hu_HU/
│ │ │ │ └── opensnitch-hu_HU.ts
│ │ │ ├── id_ID/
│ │ │ │ └── opensnitch-id_ID.ts
│ │ │ ├── it_IT/
│ │ │ │ └── opensnitch-it_IT.ts
│ │ │ ├── ja_JP/
│ │ │ │ └── opensnitch-ja_JP.ts
│ │ │ ├── lt_LT/
│ │ │ │ └── opensnitch-lt_LT.ts
│ │ │ ├── nb_NO/
│ │ │ │ └── opensnitch-nb_NO.ts
│ │ │ ├── nl_NL/
│ │ │ │ └── opensnitch-nl_NL.ts
│ │ │ ├── pt_BR/
│ │ │ │ └── opensnitch-pt_BR.ts
│ │ │ ├── ro_RO/
│ │ │ │ └── opensnitch-ro_RO.ts
│ │ │ ├── ru_RU/
│ │ │ │ └── opensnitch-ru_RU.ts
│ │ │ ├── sq_AL/
│ │ │ │ └── opensnitch-sq_AL.ts
│ │ │ ├── sv_SE/
│ │ │ │ └── opensnitch-sv_SE.ts
│ │ │ ├── tr_TR/
│ │ │ │ └── opensnitch-tr_TR.ts
│ │ │ ├── uk_UA/
│ │ │ │ └── opensnitch-uk_UA.ts
│ │ │ ├── zh_Hans/
│ │ │ │ └── opensnitch-zh_Hans.ts
│ │ │ └── zh_TW/
│ │ │ └── opensnitch-zh_TW.ts
│ │ └── opensnitch_i18n.pro
│ ├── opensnitch/
│ │ ├── __init__.py
│ │ ├── actions/
│ │ │ ├── __init__.py
│ │ │ ├── default_configs.py
│ │ │ ├── enums.py
│ │ │ └── utils.py
│ │ ├── auth/
│ │ │ └── __init__.py
│ │ ├── config.py
│ │ ├── customwidgets/
│ │ │ ├── __init__.py
│ │ │ ├── addresstablemodel.py
│ │ │ ├── colorizeddelegate.py
│ │ │ ├── completer.py
│ │ │ ├── firewalltableview.py
│ │ │ ├── generictableview.py
│ │ │ ├── itemwidgetcentered.py
│ │ │ ├── main.py
│ │ │ ├── netstattablemodel.py
│ │ │ └── updownbtndelegate.py
│ │ ├── database/
│ │ │ ├── __init__.py
│ │ │ ├── enums.py
│ │ │ └── migrations/
│ │ │ ├── upgrade_1.sql
│ │ │ ├── upgrade_2.sql
│ │ │ └── upgrade_3.sql
│ │ ├── desktop_parser.py
│ │ ├── dialogs/
│ │ │ ├── __init__.py
│ │ │ ├── conndetails.py
│ │ │ ├── events/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── config.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── menu_actions.py
│ │ │ │ ├── menus.py
│ │ │ │ ├── nodes.py
│ │ │ │ ├── queries.py
│ │ │ │ ├── tasks/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── netstat.py
│ │ │ │ │ └── nodemon.py
│ │ │ │ └── views.py
│ │ │ ├── firewall.py
│ │ │ ├── firewall_rule/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── notifications.py
│ │ │ │ ├── rules.py
│ │ │ │ ├── statements.py
│ │ │ │ └── utils.py
│ │ │ ├── preferences/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── dialog.py
│ │ │ │ ├── sections/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── db.py
│ │ │ │ │ ├── nodes.py
│ │ │ │ │ └── ui.py
│ │ │ │ ├── settings.py
│ │ │ │ ├── signals.py
│ │ │ │ └── utils.py
│ │ │ ├── processdetails.py
│ │ │ ├── prompt/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── checksums.py
│ │ │ │ ├── constants.py
│ │ │ │ ├── details.py
│ │ │ │ ├── dialog.py
│ │ │ │ └── utils.py
│ │ │ └── ruleseditor/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── dialog.py
│ │ │ ├── nodes.py
│ │ │ ├── rules.py
│ │ │ ├── signals.py
│ │ │ └── utils.py
│ │ ├── firewall/
│ │ │ ├── __init__.py
│ │ │ ├── chains.py
│ │ │ ├── enums.py
│ │ │ ├── exprs.py
│ │ │ ├── profiles.py
│ │ │ ├── rules.py
│ │ │ └── utils.py
│ │ ├── nodes.py
│ │ ├── notifications.py
│ │ ├── plugins/
│ │ │ ├── __init__.py
│ │ │ ├── downloader/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _gui.py
│ │ │ │ ├── downloader.py
│ │ │ │ └── example/
│ │ │ │ └── downloaders.json
│ │ │ ├── highlight/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── example/
│ │ │ │ │ ├── commonActionsDelegate.json
│ │ │ │ │ └── rulesActionsDelegate.json
│ │ │ │ └── highlight.py
│ │ │ ├── sample/
│ │ │ │ ├── __init__.py
│ │ │ │ └── sample.py
│ │ │ ├── versionchecker/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── versionchecker.json
│ │ │ │ └── versionchecker.py
│ │ │ └── virustotal/
│ │ │ ├── __init__.py
│ │ │ ├── _models.py
│ │ │ ├── _popups.py
│ │ │ ├── _procdialog.py
│ │ │ ├── _utils.py
│ │ │ ├── example/
│ │ │ │ └── virustotal.json
│ │ │ └── virustotal.py
│ │ ├── proto/
│ │ │ ├── __init__.py
│ │ │ ├── enums.py
│ │ │ ├── pre3200/
│ │ │ │ ├── ui_pb2.py
│ │ │ │ └── ui_pb2_grpc.py
│ │ │ ├── ui_pb2.py
│ │ │ └── ui_pb2_grpc.py
│ │ ├── res/
│ │ │ ├── __init__.py
│ │ │ ├── firewall.ui
│ │ │ ├── firewall_rule.ui
│ │ │ ├── preferences.ui
│ │ │ ├── process_details.ui
│ │ │ ├── prompt.ui
│ │ │ ├── resources.qrc
│ │ │ ├── ruleseditor.ui
│ │ │ ├── stats.ui
│ │ │ └── themes/
│ │ │ └── dark/
│ │ │ └── icons/
│ │ │ └── LICENSE
│ │ ├── rules.py
│ │ ├── service.py
│ │ ├── themes/
│ │ │ ├── README.md
│ │ │ └── dark_white.xml
│ │ ├── utils/
│ │ │ ├── __init__.py
│ │ │ ├── duration/
│ │ │ │ ├── __init__.py
│ │ │ │ └── duration.py
│ │ │ ├── infowindow.py
│ │ │ ├── languages.py
│ │ │ ├── logger/
│ │ │ │ ├── __init__.py
│ │ │ │ └── logger.py
│ │ │ ├── network_aliases/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── network_aliases.json
│ │ │ │ └── network_aliases.py
│ │ │ ├── qvalidator.py
│ │ │ ├── sockets.py
│ │ │ ├── themes/
│ │ │ │ ├── __init__.py
│ │ │ │ └── themes.py
│ │ │ └── xdg.py
│ │ └── version.py
│ ├── requirements.txt
│ ├── resources/
│ │ ├── io.github.evilsocket.opensnitch.appdata.xml
│ │ ├── kcm_opensnitch.desktop
│ │ └── opensnitch_ui.desktop
│ ├── setup.py
│ └── tests/
│ ├── README.md
│ ├── __init__.py
│ ├── conftest.py
│ ├── dialogs/
│ │ ├── __init__.py
│ │ ├── test_preferences.py
│ │ └── test_ruleseditor.py
│ └── test_nodes.py
└── utils/
├── legacy/
│ └── make_ads_rules.py
├── packaging/
│ ├── build_modules.sh
│ ├── daemon/
│ │ ├── deb/
│ │ │ └── debian/
│ │ │ ├── NEWS
│ │ │ ├── changelog
│ │ │ ├── control
│ │ │ ├── copyright
│ │ │ ├── gbp.conf
│ │ │ ├── gitlab-ci.yml
│ │ │ ├── opensnitch.init
│ │ │ ├── opensnitch.install
│ │ │ ├── opensnitch.logrotate
│ │ │ ├── opensnitch.service
│ │ │ ├── rules
│ │ │ ├── source/
│ │ │ │ └── format
│ │ │ └── watch
│ │ └── rpm/
│ │ └── opensnitch.spec
│ └── ui/
│ ├── deb/
│ │ └── debian/
│ │ ├── changelog
│ │ ├── compat
│ │ ├── control
│ │ ├── copyright
│ │ ├── postinst
│ │ ├── postrm
│ │ ├── rules
│ │ └── source/
│ │ ├── format
│ │ └── options
│ └── rpm/
│ └── opensnitch-ui.spec
└── scripts/
├── ads/
│ └── update_adlists.sh
├── debug-ebpf-maps.sh
├── ipasn_db_sync.sh
├── ipasn_db_update.sh
└── restart-opensnitch-onsleep.sh
Showing preview only (245K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3167 symbols across 263 files)
FILE: daemon/conman/connection.go
type Connection (line 24) | type Connection struct
method parseDirection (line 215) | func (c *Connection) parseDirection(protoType string) bool {
method swapFields (line 275) | func (c *Connection) swapFields() {
method getDomains (line 292) | func (c *Connection) getDomains(nfp *netfilter.Packet, con *Connection) {
method To (line 303) | func (c *Connection) To() string {
method String (line 310) | func (c *Connection) String() string {
method Serialize (line 323) | func (c *Connection) Serialize() *protocol.Connection {
function Parse (line 42) | func Parse(nfp netfilter.Packet, interceptUnknown bool) *Connection {
function newConnectionImpl (line 71) | func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType s...
function NewConnection (line 177) | func NewConnection(nfp *netfilter.Packet) (c *Connection, err error) {
function NewConnection6 (line 197) | func NewConnection6(nfp *netfilter.Packet) (c *Connection, err error) {
FILE: daemon/conman/connection_test.go
function NewTCPPacket (line 17) | func NewTCPPacket() gopacket.Packet {
function NewUDPPacket (line 27) | func NewUDPPacket() gopacket.Packet {
function EstablishConnection (line 40) | func EstablishConnection(proto, dst string) (net.Conn, error) {
function ListenOnPort (line 49) | func ListenOnPort(proto, port string) (net.Listener, error) {
function NewPacket (line 58) | func NewPacket(pkt gopacket.Packet) *netfilter.Packet {
function NewDummyConnection (line 66) | func NewDummyConnection(src, dst net.IP) *Connection {
function TestParseTCPDirection (line 74) | func TestParseTCPDirection(t *testing.T) {
function TestParseUDPDirection (line 102) | func TestParseUDPDirection(t *testing.T) {
FILE: daemon/core/core.go
constant defaultTrimSet (line 14) | defaultTrimSet = "\r\n\t "
function Trim (line 18) | func Trim(s string) string {
function Exec (line 23) | func Exec(executable string, args []string) (string, error) {
function Exists (line 37) | func Exists(path string) bool {
function ExpandPath (line 45) | func ExpandPath(path string) (string, error) {
function IsAbsPath (line 62) | func IsAbsPath(path string) bool {
function GetFileModTime (line 67) | func GetFileModTime(filepath string) (time.Time, error) {
function ConcatStrings (line 76) | func ConcatStrings(args ...string) string {
FILE: daemon/core/ebpf.go
function LoadEbpfModule (line 12) | func LoadEbpfModule(module, path string) (m *ebpf.Collection, err error) {
FILE: daemon/core/gzip.go
function ReadGzipFile (line 10) | func ReadGzipFile(filename string) ([]byte, error) {
FILE: daemon/core/system.go
function GetHostname (line 20) | func GetHostname() string {
function GetKernelVersion (line 26) | func GetKernelVersion() string {
function GetMounts (line 32) | func GetMounts() []string {
function IsTraceFSMounted (line 38) | func IsTraceFSMounted() bool {
function CheckSysRequirements (line 49) | func CheckSysRequirements() {
FILE: daemon/core/version.go
constant Name (line 5) | Name = "opensnitch-daemon"
constant Version (line 6) | Version = "1.9.0"
constant Author (line 7) | Author = "Simone 'evilsocket' Margaritelli"
constant Website (line 8) | Website = "https://github.com/evilsocket/opensnitch"
FILE: daemon/dns/ebpfhook.go
type nameLookupEvent (line 64) | type nameLookupEvent struct
type ProbeDefs (line 71) | type ProbeDefs struct
type MapDefs (line 78) | type MapDefs struct
type dnsDefsT (line 84) | type dnsDefsT struct
function findLibc (line 89) | func findLibc() (string, error) {
function lookupSymbol (line 101) | func lookupSymbol(elffile *elf.File, symbolName string) (uint64, error) {
function ListenerEbpf (line 115) | func ListenerEbpf(ebpfModPath string) error {
function dnsWorker (line 254) | func dnsWorker(id int, channel chan []byte, exitChannel chan struct{}) {
FILE: daemon/dns/parse.go
function GetQuestions (line 9) | func GetQuestions(nfp *netfilter.Packet) (questions []string) {
FILE: daemon/dns/systemd/monitor.go
type resolvedCallback (line 30) | type resolvedCallback
constant SuccessState (line 35) | SuccessState = "success"
constant socketPath (line 37) | socketPath = "/run/systemd/resolve/io.systemd.Resolve.Monitor"
constant resolvedSubscribeMethod (line 38) | resolvedSubscribeMethod = "io.systemd.Resolve.Monitor.SubscribeQueryResu...
constant DNSTypeA (line 41) | DNSTypeA = 1
constant DNSTypeAAAA (line 43) | DNSTypeAAAA = 28
constant DNSTypeCNAME (line 45) | DNSTypeCNAME = 5
constant DNSTypeSOA (line 47) | DNSTypeSOA = 6
type QuestionMonitorResponse (line 52) | type QuestionMonitorResponse struct
type KeyType (line 71) | type KeyType struct
type RRType (line 79) | type RRType struct
type AnswerMonitorResponse (line 86) | type AnswerMonitorResponse struct
type MonitorResponse (line 94) | type MonitorResponse struct
type ResolvedMonitor (line 104) | type ResolvedMonitor struct
method Connect (line 141) | func (r *ResolvedMonitor) Connect() (*varlink.Connection, error) {
method connPoller (line 158) | func (r *ResolvedMonitor) connPoller() {
method Subscribe (line 178) | func (r *ResolvedMonitor) Subscribe() error {
method monitor (line 195) | func (r *ResolvedMonitor) monitor(ctx context.Context, chanResponse ch...
method GetDNSResponses (line 218) | func (r *ResolvedMonitor) GetDNSResponses() chan *MonitorResponse {
method Exit (line 223) | func (r *ResolvedMonitor) Exit() chan error {
method Close (line 228) | func (r *ResolvedMonitor) Close() {
method isConnected (line 233) | func (r *ResolvedMonitor) isConnected() bool {
function NewResolvedMonitor (line 125) | func NewResolvedMonitor() (*ResolvedMonitor, error) {
FILE: daemon/dns/track.go
function TrackAnswers (line 20) | func TrackAnswers(packet gopacket.Packet) bool {
function Track (line 58) | func Track(resolved string, hostname string) {
function Host (line 74) | func Host(resolved string) (host string, found bool) {
function HostOr (line 84) | func HostOr(ip net.IP, or string) string {
FILE: daemon/firewall/common/common.go
type callback (line 25) | type callback
type callbackBool (line 26) | type callbackBool
type Common (line 30) | type Common struct
method ErrorsChan (line 44) | func (c *Common) ErrorsChan() <-chan string {
method ErrChanEmpty (line 49) | func (c *Common) ErrChanEmpty() bool {
method SendError (line 54) | func (c *Common) SendError(err string) {
method SetRulesCheckerInterval (line 74) | func (c *Common) SetRulesCheckerInterval(interval string) {
method SetQueueNum (line 87) | func (c *Common) SetQueueNum(qNum uint16) {
method IsRunning (line 94) | func (c *Common) IsRunning() bool {
method IsFirewallEnabled (line 102) | func (c *Common) IsFirewallEnabled() bool {
method IsIntercepting (line 110) | func (c *Common) IsIntercepting() bool {
method NewRulesChecker (line 120) | func (c *Common) NewRulesChecker(areRulesLoaded callbackBool, reloadRu...
method StopCheckingRules (line 166) | func (c *Common) StopCheckingRules() {
method reloadCallback (line 184) | func (c *Common) reloadCallback(callback func()) {
function startCheckingRules (line 145) | func startCheckingRules(exitChan <-chan struct{}, rulesChecker *time.Tic...
FILE: daemon/firewall/config/config.go
type ExprValues (line 38) | type ExprValues struct
type ExprStatement (line 54) | type ExprStatement struct
type Expressions (line 61) | type Expressions struct
type FwRule (line 66) | type FwRule struct
type FwChain (line 83) | type FwChain struct
method IsInvalid (line 98) | func (fc *FwChain) IsInvalid() bool {
type rulesList (line 102) | type rulesList struct
type chainsList (line 106) | type chainsList struct
type SystemConfig (line 112) | type SystemConfig struct
type Config (line 121) | type Config struct
method NewSystemFwConfig (line 138) | func (c *Config) NewSystemFwConfig(configPath string, preLoadCb, reLoa...
method SetConfigFile (line 159) | func (c *Config) SetConfigFile(file string) {
method LoadDiskConfiguration (line 168) | func (c *Config) LoadDiskConfiguration(reload bool) error {
method loadConfiguration (line 201) | func (c *Config) loadConfiguration(rawConfig []byte) error {
method SaveConfiguration (line 220) | func (c *Config) SaveConfiguration(rawConfig string) error {
method StopConfigWatcher (line 238) | func (c *Config) StopConfigWatcher() {
method monitorConfigWorker (line 250) | func (c *Config) monitorConfigWorker() {
FILE: daemon/firewall/config/config_test.go
function preloadConfCallback (line 7) | func preloadConfCallback() {
function reloadConfCallback (line 10) | func reloadConfCallback() {
function TestNftLoadFromDisk (line 13) | func TestNftLoadFromDisk(t *testing.T) {
FILE: daemon/firewall/iptables/iptables.go
type Action (line 19) | type Action
constant Name (line 23) | Name = "iptables"
constant SystemRulePrefix (line 25) | SystemRulePrefix = "opensnitch-filter"
constant ADD (line 30) | ADD = Action("-A")
constant INSERT (line 31) | INSERT = Action("-I")
constant DELETE (line 32) | DELETE = Action("-D")
constant FLUSH (line 33) | FLUSH = Action("-F")
constant NEWCHAIN (line 34) | NEWCHAIN = Action("-N")
constant DELCHAIN (line 35) | DELCHAIN = Action("-X")
constant POLICY (line 36) | POLICY = Action("-P")
constant DROP (line 38) | DROP = Action("DROP")
constant ACCEPT (line 39) | ACCEPT = Action("ACCEPT")
type SystemRule (line 43) | type SystemRule struct
type SystemChains (line 50) | type SystemChains struct
type Iptables (line 56) | type Iptables struct
method Name (line 91) | func (ipt *Iptables) Name() string {
method Init (line 97) | func (ipt *Iptables) Init(qNum uint16, configPath, monitorInterval str...
method Stop (line 121) | func (ipt *Iptables) Stop() {
method EnableInterception (line 144) | func (ipt *Iptables) EnableInterception() {
method DisableInterception (line 155) | func (ipt *Iptables) DisableInterception(logErrors bool) {
method CleanRules (line 162) | func (ipt *Iptables) CleanRules(logErrors bool) {
method Serialize (line 168) | func (ipt *Iptables) Serialize() (*protocol.SysFirewall, error) {
method Deserialize (line 188) | func (ipt *Iptables) Deserialize(sysfw *protocol.SysFirewall) ([]byte,...
function Fw (line 70) | func Fw() (*Iptables, error) {
function IsAvailable (line 135) | func IsAvailable() error {
FILE: daemon/firewall/iptables/monitor.go
method AreRulesLoaded (line 10) | func (ipt *Iptables) AreRulesLoaded() bool {
method reloadRulesCallback (line 58) | func (ipt *Iptables) reloadRulesCallback() {
method preloadConfCallback (line 66) | func (ipt *Iptables) preloadConfCallback() {
FILE: daemon/firewall/iptables/rules.go
method getBypassQueue (line 11) | func (ipt *Iptables) getBypassQueue() string {
function BuildQueueDNSRule (line 20) | func BuildQueueDNSRule(queueNum uint16, bypass bool) []string {
function BuildQueueConnectionsRule (line 35) | func BuildQueueConnectionsRule(queueNum uint16, bypass bool) []string {
method RunRule (line 51) | func (ipt *Iptables) RunRule(action Action, enable bool, logError bool, ...
method QueueDNSResponses (line 91) | func (ipt *Iptables) QueueDNSResponses(enable bool, logError bool) (err4...
method QueueConnections (line 98) | func (ipt *Iptables) QueueConnections(enable bool, logError bool) (error...
FILE: daemon/firewall/iptables/system.go
method CreateSystemRule (line 11) | func (ipt *Iptables) CreateSystemRule(rule *config.FwRule, table, chain,...
method AddSystemRules (line 43) | func (ipt *Iptables) AddSystemRules(reload, backupExistingChains bool) {
method DeleteSystemRules (line 69) | func (ipt *Iptables) DeleteSystemRules(force, backupExistingChains, logE...
method DeleteSystemRule (line 105) | func (ipt *Iptables) DeleteSystemRule(action Action, rule *config.FwRule...
method AddSystemRule (line 123) | func (ipt *Iptables) AddSystemRule(action Action, rule *config.FwRule, t...
method ConfigureChainPolicy (line 147) | func (ipt *Iptables) ConfigureChainPolicy(table, hook, policy string, lo...
FILE: daemon/firewall/nftables/chains.go
function getChainKey (line 15) | func getChainKey(name string, table *nftables.Table) string {
function GetChain (line 23) | func GetChain(name string, table *nftables.Table) *nftables.Chain {
method AddChain (line 33) | func (n *Nft) AddChain(name, table, family string, priority *nftables.Ch...
method GetChain (line 76) | func (n *Nft) GetChain(name string, table *nftables.Table, family string...
method addRegularChain (line 89) | func (n *Nft) addRegularChain(name, table, family string) error {
method AddInterceptionChains (line 109) | func (n *Nft) AddInterceptionChains() error {
method DelChain (line 156) | func (n *Nft) DelChain(chain *nftables.Chain) error {
method backupExistingChains (line 169) | func (n *Nft) backupExistingChains() {
method restoreBackupChains (line 180) | func (n *Nft) restoreBackupChains() {
FILE: daemon/firewall/nftables/chains_test.go
function TestChains (line 11) | func TestChains(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/counter.go
function NewExprCounter (line 8) | func NewExprCounter(counterName string) *[]expr.Any {
FILE: daemon/firewall/nftables/exprs/counter_test.go
function TestExprNamedCounter (line 11) | func TestExprNamedCounter(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/ct.go
function NewExprCtMark (line 27) | func NewExprCtMark(setMark bool, value string, cmpOp *expr.CmpOp) (*[]ex...
function NewExprCtState (line 55) | func NewExprCtState(ctFlags []*config.ExprValues) (*[]expr.Any, error) {
function parseInlineCtStates (line 89) | func parseInlineCtStates(flags string) (found bool, mask uint32, err err...
function getCtState (line 106) | func getCtState(flag string) (mask uint32, err error) {
FILE: daemon/firewall/nftables/exprs/ct_test.go
function TestExprCtMark (line 14) | func TestExprCtMark(t *testing.T) {
function TestExprCtState (line 110) | func TestExprCtState(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/enums.go
constant TABLE_OPENSNITCH (line 5) | TABLE_OPENSNITCH = "opensnitch"
constant CHAIN_FILTER_INPUT (line 6) | CHAIN_FILTER_INPUT = "filter_input"
constant CHAIN_MANGLE_OUTPUT (line 7) | CHAIN_MANGLE_OUTPUT = "mangle_output"
constant CHAIN_MANGLE_FORWARD (line 8) | CHAIN_MANGLE_FORWARD = "mangle_forward"
constant NFT_CHAIN_MANGLE (line 11) | NFT_CHAIN_MANGLE = "mangle"
constant NFT_CHAIN_FILTER (line 12) | NFT_CHAIN_FILTER = "filter"
constant NFT_CHAIN_RAW (line 13) | NFT_CHAIN_RAW = "raw"
constant NFT_CHAIN_SECURITY (line 14) | NFT_CHAIN_SECURITY = "security"
constant NFT_CHAIN_NATDEST (line 15) | NFT_CHAIN_NATDEST = "natdest"
constant NFT_CHAIN_NATSOURCE (line 16) | NFT_CHAIN_NATSOURCE = "natsource"
constant NFT_CHAIN_CONNTRACK (line 17) | NFT_CHAIN_CONNTRACK = "conntrack"
constant NFT_CHAIN_SELINUX (line 18) | NFT_CHAIN_SELINUX = "selinux"
constant NFT_HOOK_INPUT (line 20) | NFT_HOOK_INPUT = "input"
constant NFT_HOOK_OUTPUT (line 21) | NFT_HOOK_OUTPUT = "output"
constant NFT_HOOK_PREROUTING (line 22) | NFT_HOOK_PREROUTING = "prerouting"
constant NFT_HOOK_POSTROUTING (line 23) | NFT_HOOK_POSTROUTING = "postrouting"
constant NFT_HOOK_INGRESS (line 24) | NFT_HOOK_INGRESS = "ingress"
constant NFT_HOOK_EGRESS (line 25) | NFT_HOOK_EGRESS = "egress"
constant NFT_HOOK_FORWARD (line 26) | NFT_HOOK_FORWARD = "forward"
constant NFT_TABLE_INET (line 28) | NFT_TABLE_INET = "inet"
constant NFT_TABLE_NAT (line 29) | NFT_TABLE_NAT = "nat"
constant NFT_TABLE_ARP (line 31) | NFT_TABLE_ARP = "arp"
constant NFT_TABLE_BRIDGE (line 32) | NFT_TABLE_BRIDGE = "bridge"
constant NFT_TABLE_NETDEV (line 33) | NFT_TABLE_NETDEV = "netdev"
constant NFT_FAMILY_IP (line 35) | NFT_FAMILY_IP = "ip"
constant NFT_FAMILY_IP6 (line 36) | NFT_FAMILY_IP6 = "ip6"
constant NFT_FAMILY_INET (line 37) | NFT_FAMILY_INET = "inet"
constant NFT_FAMILY_BRIDGE (line 38) | NFT_FAMILY_BRIDGE = "bridge"
constant NFT_FAMILY_ARP (line 39) | NFT_FAMILY_ARP = "arp"
constant NFT_FAMILY_NETDEV (line 40) | NFT_FAMILY_NETDEV = "netdev"
constant VERDICT_ACCEPT (line 42) | VERDICT_ACCEPT = "accept"
constant VERDICT_DROP (line 43) | VERDICT_DROP = "drop"
constant VERDICT_REJECT (line 44) | VERDICT_REJECT = "reject"
constant VERDICT_RETURN (line 45) | VERDICT_RETURN = "return"
constant VERDICT_QUEUE (line 46) | VERDICT_QUEUE = "queue"
constant VERDICT_JUMP (line 48) | VERDICT_JUMP = "jump"
constant VERDICT_GOTO (line 50) | VERDICT_GOTO = "goto"
constant VERDICT_STOP (line 51) | VERDICT_STOP = "stop"
constant VERDICT_STOLEN (line 52) | VERDICT_STOLEN = "stolen"
constant VERDICT_CONTINUE (line 53) | VERDICT_CONTINUE = "continue"
constant VERDICT_MASQUERADE (line 54) | VERDICT_MASQUERADE = "masquerade"
constant VERDICT_DNAT (line 55) | VERDICT_DNAT = "dnat"
constant VERDICT_SNAT (line 56) | VERDICT_SNAT = "snat"
constant VERDICT_REDIRECT (line 57) | VERDICT_REDIRECT = "redirect"
constant VERDICT_TPROXY (line 58) | VERDICT_TPROXY = "tproxy"
constant NFT_PARM_TO (line 60) | NFT_PARM_TO = "to"
constant NFT_QUEUE_NUM (line 62) | NFT_QUEUE_NUM = "num"
constant NFT_QUEUE_BY_PASS (line 63) | NFT_QUEUE_BY_PASS = "queue-bypass"
constant NFT_MASQ_RANDOM (line 65) | NFT_MASQ_RANDOM = "random"
constant NFT_MASQ_FULLY_RANDOM (line 66) | NFT_MASQ_FULLY_RANDOM = "fully-random"
constant NFT_MASQ_PERSISTENT (line 67) | NFT_MASQ_PERSISTENT = "persistent"
constant NFT_PROTOCOL (line 69) | NFT_PROTOCOL = "protocol"
constant NFT_SPORT (line 70) | NFT_SPORT = "sport"
constant NFT_DPORT (line 71) | NFT_DPORT = "dport"
constant NFT_SADDR (line 72) | NFT_SADDR = "saddr"
constant NFT_DADDR (line 73) | NFT_DADDR = "daddr"
constant NFT_ICMP_CODE (line 74) | NFT_ICMP_CODE = "code"
constant NFT_ICMP_TYPE (line 75) | NFT_ICMP_TYPE = "type"
constant NFT_ETHER (line 77) | NFT_ETHER = "ether"
constant NFT_IIFNAME (line 79) | NFT_IIFNAME = "iifname"
constant NFT_OIFNAME (line 80) | NFT_OIFNAME = "oifname"
constant NFT_LOG (line 82) | NFT_LOG = "log"
constant NFT_LOG_PREFIX (line 83) | NFT_LOG_PREFIX = "prefix"
constant NFT_LOG_LEVEL (line 85) | NFT_LOG_LEVEL = "level"
constant NFT_LOG_LEVEL_EMERG (line 86) | NFT_LOG_LEVEL_EMERG = "emerg"
constant NFT_LOG_LEVEL_ALERT (line 87) | NFT_LOG_LEVEL_ALERT = "alert"
constant NFT_LOG_LEVEL_CRIT (line 88) | NFT_LOG_LEVEL_CRIT = "crit"
constant NFT_LOG_LEVEL_ERR (line 89) | NFT_LOG_LEVEL_ERR = "err"
constant NFT_LOG_LEVEL_WARN (line 90) | NFT_LOG_LEVEL_WARN = "warn"
constant NFT_LOG_LEVEL_NOTICE (line 91) | NFT_LOG_LEVEL_NOTICE = "notice"
constant NFT_LOG_LEVEL_INFO (line 92) | NFT_LOG_LEVEL_INFO = "info"
constant NFT_LOG_LEVEL_DEBUG (line 93) | NFT_LOG_LEVEL_DEBUG = "debug"
constant NFT_LOG_LEVEL_AUDIT (line 94) | NFT_LOG_LEVEL_AUDIT = "audit"
constant NFT_LOG_FLAGS (line 95) | NFT_LOG_FLAGS = "flags"
constant NFT_CT (line 97) | NFT_CT = "ct"
constant NFT_CT_STATE (line 98) | NFT_CT_STATE = "state"
constant NFT_CT_SET_MARK (line 99) | NFT_CT_SET_MARK = "set"
constant NFT_CT_MARK (line 100) | NFT_CT_MARK = "mark"
constant CT_STATE_NEW (line 101) | CT_STATE_NEW = "new"
constant CT_STATE_ESTABLISHED (line 102) | CT_STATE_ESTABLISHED = "established"
constant CT_STATE_RELATED (line 103) | CT_STATE_RELATED = "related"
constant CT_STATE_INVALID (line 104) | CT_STATE_INVALID = "invalid"
constant NFT_NOTRACK (line 106) | NFT_NOTRACK = "notrack"
constant NFT_QUOTA (line 108) | NFT_QUOTA = "quota"
constant NFT_QUOTA_UNTIL (line 109) | NFT_QUOTA_UNTIL = "until"
constant NFT_QUOTA_OVER (line 110) | NFT_QUOTA_OVER = "over"
constant NFT_QUOTA_USED (line 111) | NFT_QUOTA_USED = "used"
constant NFT_QUOTA_UNIT_BYTES (line 112) | NFT_QUOTA_UNIT_BYTES = "bytes"
constant NFT_QUOTA_UNIT_KB (line 113) | NFT_QUOTA_UNIT_KB = "kbytes"
constant NFT_QUOTA_UNIT_MB (line 114) | NFT_QUOTA_UNIT_MB = "mbytes"
constant NFT_QUOTA_UNIT_GB (line 115) | NFT_QUOTA_UNIT_GB = "gbytes"
constant NFT_COUNTER (line 117) | NFT_COUNTER = "counter"
constant NFT_COUNTER_NAME (line 118) | NFT_COUNTER_NAME = "name"
constant NFT_COUNTER_PACKETS (line 119) | NFT_COUNTER_PACKETS = "packets"
constant NFT_COUNTER_BYTES (line 120) | NFT_COUNTER_BYTES = "bytes"
constant NFT_LIMIT (line 122) | NFT_LIMIT = "limit"
constant NFT_LIMIT_OVER (line 123) | NFT_LIMIT_OVER = "over"
constant NFT_LIMIT_BURST (line 124) | NFT_LIMIT_BURST = "burst"
constant NFT_LIMIT_UNITS_RATE (line 125) | NFT_LIMIT_UNITS_RATE = "rate-units"
constant NFT_LIMIT_UNITS_TIME (line 126) | NFT_LIMIT_UNITS_TIME = "time-units"
constant NFT_LIMIT_UNITS (line 127) | NFT_LIMIT_UNITS = "units"
constant NFT_LIMIT_UNIT_SECOND (line 128) | NFT_LIMIT_UNIT_SECOND = "second"
constant NFT_LIMIT_UNIT_MINUTE (line 129) | NFT_LIMIT_UNIT_MINUTE = "minute"
constant NFT_LIMIT_UNIT_HOUR (line 130) | NFT_LIMIT_UNIT_HOUR = "hour"
constant NFT_LIMIT_UNIT_DAY (line 131) | NFT_LIMIT_UNIT_DAY = "day"
constant NFT_LIMIT_UNIT_KBYTES (line 132) | NFT_LIMIT_UNIT_KBYTES = "kbytes"
constant NFT_LIMIT_UNIT_MBYTES (line 133) | NFT_LIMIT_UNIT_MBYTES = "mbytes"
constant NFT_META (line 135) | NFT_META = "meta"
constant NFT_META_MARK (line 136) | NFT_META_MARK = "mark"
constant NFT_META_SET_MARK (line 137) | NFT_META_SET_MARK = "set"
constant NFT_META_PRIORITY (line 138) | NFT_META_PRIORITY = "priority"
constant NFT_META_NFTRACE (line 139) | NFT_META_NFTRACE = "nftrace"
constant NFT_META_SET (line 140) | NFT_META_SET = "set"
constant NFT_META_SKUID (line 141) | NFT_META_SKUID = "skuid"
constant NFT_META_SKGID (line 142) | NFT_META_SKGID = "skgid"
constant NFT_META_L4PROTO (line 143) | NFT_META_L4PROTO = "l4proto"
constant NFT_META_PROTOCOL (line 144) | NFT_META_PROTOCOL = "protocol"
constant NFT_PROTO_UDP (line 146) | NFT_PROTO_UDP = "udp"
constant NFT_PROTO_UDPLITE (line 147) | NFT_PROTO_UDPLITE = "udplite"
constant NFT_PROTO_TCP (line 148) | NFT_PROTO_TCP = "tcp"
constant NFT_PROTO_SCTP (line 149) | NFT_PROTO_SCTP = "sctp"
constant NFT_PROTO_DCCP (line 150) | NFT_PROTO_DCCP = "dccp"
constant NFT_PROTO_ICMP (line 151) | NFT_PROTO_ICMP = "icmp"
constant NFT_PROTO_ICMPX (line 152) | NFT_PROTO_ICMPX = "icmpx"
constant NFT_PROTO_ICMPv6 (line 153) | NFT_PROTO_ICMPv6 = "icmpv6"
constant NFT_PROTO_AH (line 154) | NFT_PROTO_AH = "ah"
constant NFT_PROTO_ETHERNET (line 155) | NFT_PROTO_ETHERNET = "ethernet"
constant NFT_PROTO_GRE (line 156) | NFT_PROTO_GRE = "gre"
constant NFT_PROTO_IP (line 157) | NFT_PROTO_IP = "ip"
constant NFT_PROTO_IPIP (line 158) | NFT_PROTO_IPIP = "ipip"
constant NFT_PROTO_L2TP (line 159) | NFT_PROTO_L2TP = "l2tp"
constant NFT_PROTO_COMP (line 160) | NFT_PROTO_COMP = "comp"
constant NFT_PROTO_IGMP (line 161) | NFT_PROTO_IGMP = "igmp"
constant NFT_PROTO_ESP (line 162) | NFT_PROTO_ESP = "esp"
constant NFT_PROTO_RAW (line 163) | NFT_PROTO_RAW = "raw"
constant NFT_PROTO_ENCAP (line 164) | NFT_PROTO_ENCAP = "encap"
constant ICMP_NO_ROUTE (line 166) | ICMP_NO_ROUTE = "no-route"
constant ICMP_PROT_UNREACHABLE (line 167) | ICMP_PROT_UNREACHABLE = "prot-unreachable"
constant ICMP_PORT_UNREACHABLE (line 168) | ICMP_PORT_UNREACHABLE = "port-unreachable"
constant ICMP_NET_UNREACHABLE (line 169) | ICMP_NET_UNREACHABLE = "net-unreachable"
constant ICMP_ADDR_UNREACHABLE (line 170) | ICMP_ADDR_UNREACHABLE = "addr-unreachable"
constant ICMP_HOST_UNREACHABLE (line 171) | ICMP_HOST_UNREACHABLE = "host-unreachable"
constant ICMP_NET_PROHIBITED (line 172) | ICMP_NET_PROHIBITED = "net-prohibited"
constant ICMP_HOST_PROHIBITED (line 173) | ICMP_HOST_PROHIBITED = "host-prohibited"
constant ICMP_ADMIN_PROHIBITED (line 174) | ICMP_ADMIN_PROHIBITED = "admin-prohibited"
constant ICMP_REJECT_ROUTE (line 175) | ICMP_REJECT_ROUTE = "reject-route"
constant ICMP_REJECT_POLICY_FAIL (line 176) | ICMP_REJECT_POLICY_FAIL = "policy-fail"
constant ICMP_ECHO_REPLY (line 178) | ICMP_ECHO_REPLY = "echo-reply"
constant ICMP_ECHO_REQUEST (line 179) | ICMP_ECHO_REQUEST = "echo-request"
constant ICMP_SOURCE_QUENCH (line 180) | ICMP_SOURCE_QUENCH = "source-quench"
constant ICMP_DEST_UNREACHABLE (line 181) | ICMP_DEST_UNREACHABLE = "destination-unreachable"
constant ICMP_REDIRECT (line 182) | ICMP_REDIRECT = "redirect"
constant ICMP_TIME_EXCEEDED (line 183) | ICMP_TIME_EXCEEDED = "time-exceeded"
constant ICMP_INFO_REQUEST (line 184) | ICMP_INFO_REQUEST = "info-request"
constant ICMP_INFO_REPLY (line 185) | ICMP_INFO_REPLY = "info-reply"
constant ICMP_PARAMETER_PROBLEM (line 186) | ICMP_PARAMETER_PROBLEM = "parameter-problem"
constant ICMP_TIMESTAMP_REQUEST (line 187) | ICMP_TIMESTAMP_REQUEST = "timestamp-request"
constant ICMP_TIMESTAMP_REPLY (line 188) | ICMP_TIMESTAMP_REPLY = "timestamp-reply"
constant ICMP_ROUTER_ADVERTISEMENT (line 189) | ICMP_ROUTER_ADVERTISEMENT = "router-advertisement"
constant ICMP_ROUTER_SOLICITATION (line 190) | ICMP_ROUTER_SOLICITATION = "router-solicitation"
constant ICMP_ADDRESS_MASK_REQUEST (line 191) | ICMP_ADDRESS_MASK_REQUEST = "address-mask-request"
constant ICMP_ADDRESS_MASK_REPLY (line 192) | ICMP_ADDRESS_MASK_REPLY = "address-mask-reply"
constant ICMP_PACKET_TOO_BIG (line 194) | ICMP_PACKET_TOO_BIG = "packet-too-big"
constant ICMP_NEIGHBOUR_SOLICITATION (line 195) | ICMP_NEIGHBOUR_SOLICITATION = "neighbour-solicitation"
constant ICMP_NEIGHBOUR_ADVERTISEMENT (line 196) | ICMP_NEIGHBOUR_ADVERTISEMENT = "neighbour-advertisement"
FILE: daemon/firewall/nftables/exprs/ether.go
function NewExprEther (line 13) | func NewExprEther(values []*config.ExprValues) (*[]expr.Any, error) {
function parseMACAddr (line 50) | func parseMACAddr(macValue string) ([]byte, error) {
FILE: daemon/firewall/nftables/exprs/ether_test.go
function TestExprEther (line 14) | func TestExprEther(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/iface.go
function NewExprIface (line 8) | func NewExprIface(iface string, isOut bool, cmpOp expr.CmpOp) *[]expr.Any {
function ifname (line 24) | func ifname(n string) []byte {
FILE: daemon/firewall/nftables/exprs/iface_test.go
function ifname (line 14) | func ifname(n string) []byte {
function TestExprIface (line 25) | func TestExprIface(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/ip.go
function NewExprIP (line 34) | func NewExprIP(family string, ipOptions []*config.ExprValues, cmpOp expr...
function getExprIPPayload (line 81) | func getExprIPPayload(what string) *expr.Payload {
function getExprIP (line 114) | func getExprIP(value string, cmpOp expr.CmpOp) (*[]expr.Any, error) {
function getExprRangeIP (line 131) | func getExprRangeIP(value string, cmpOp expr.CmpOp) (*[]expr.Any, error) {
FILE: daemon/firewall/nftables/exprs/ip_test.go
function TestExprIP (line 14) | func TestExprIP(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/limit.go
function NewExprLimit (line 14) | func NewExprLimit(statement *config.ExprStatement) (*[]expr.Any, error) {
function getLimitUnits (line 54) | func getLimitUnits(units string) (limitUnits expr.LimitTime) {
function getLimitRate (line 69) | func getLimitRate(units string, rate uint64) (limitType expr.LimitType, ...
FILE: daemon/firewall/nftables/exprs/log.go
function NewExprLog (line 13) | func NewExprLog(statement *config.ExprStatement) (*[]expr.Any, error) {
function getLogLevel (line 49) | func getLogLevel(what string) (expr.LogLevel, error) {
FILE: daemon/firewall/nftables/exprs/log_test.go
function TestExprLog (line 13) | func TestExprLog(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/meta.go
function NewExprMeta (line 14) | func NewExprMeta(values []*config.ExprValues, cmpOp *expr.CmpOp) (*[]exp...
function getMetaValue (line 111) | func getMetaValue(value string) (int, error) {
function getMetaKey (line 120) | func getMetaKey(value string) (expr.MetaKey, error) {
FILE: daemon/firewall/nftables/exprs/meta_test.go
function TestExprMeta (line 13) | func TestExprMeta(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/nat.go
function NewExprNATFlags (line 17) | func NewExprNATFlags(parms string) (random, fullrandom, persistent bool) {
function NewExprNAT (line 38) | func NewExprNAT(parms, verdict string) (bool, bool, *[]expr.Any, error) {
function NewExprMasquerade (line 101) | func NewExprMasquerade(toPorts, random, fullRandom, persistent bool) *[]...
function NewExprRedirect (line 117) | func NewExprRedirect() *[]expr.Any {
function NewExprSNAT (line 127) | func NewExprSNAT() *expr.NAT {
function NewExprDNAT (line 135) | func NewExprDNAT() *expr.NAT {
function NewExprTproxy (line 145) | func NewExprTproxy() *[]expr.Any {
FILE: daemon/firewall/nftables/exprs/nat_test.go
function TestExprVerdictSNAT (line 15) | func TestExprVerdictSNAT(t *testing.T) {
function TestExprVerdictDNAT (line 200) | func TestExprVerdictDNAT(t *testing.T) {
function TestExprVerdictMasquerade (line 385) | func TestExprVerdictMasquerade(t *testing.T) {
function TestExprVerdictRedirect (line 469) | func TestExprVerdictRedirect(t *testing.T) {
function TestExprVerdictTProxy (line 544) | func TestExprVerdictTProxy(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/notrack.go
function NewNoTrack (line 6) | func NewNoTrack() *[]expr.Any {
FILE: daemon/firewall/nftables/exprs/operator.go
function NewOperator (line 8) | func NewOperator(operator string) expr.CmpOp {
function NewExprOperator (line 26) | func NewExprOperator(op expr.CmpOp) *[]expr.Any {
FILE: daemon/firewall/nftables/exprs/port.go
function NewExprPort (line 14) | func NewExprPort(port string, op *expr.CmpOp) (*[]expr.Any, error) {
function NewExprPortRange (line 28) | func NewExprPortRange(sport string, cmpOp *expr.CmpOp) (*[]expr.Any, err...
function NewExprPortSet (line 50) | func NewExprPortSet(portv string) *[]nftables.SetElement {
function exprPortSubSet (line 63) | func exprPortSubSet(portv string) *[]nftables.SetElement {
function NewExprPortDirection (line 77) | func NewExprPortDirection(direction string) (*expr.Payload, error) {
FILE: daemon/firewall/nftables/exprs/port_test.go
type portTestsT (line 15) | type portTestsT struct
function TestExprPort (line 22) | func TestExprPort(t *testing.T) {
function TestExprPortRange (line 73) | func TestExprPortRange(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/protocol.go
function NewExprProtocol (line 13) | func NewExprProtocol(proto string) (*[]expr.Any, error) {
function NewExprProtoSet (line 115) | func NewExprProtoSet(l4prots string) *[]nftables.SetElement {
function NewExprL4Proto (line 134) | func NewExprL4Proto(name string, cmpOp *expr.CmpOp) *[]expr.Any {
FILE: daemon/firewall/nftables/exprs/protocol_test.go
function TestExprProtocol (line 14) | func TestExprProtocol(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/quota.go
function NewQuota (line 13) | func NewQuota(opts []*config.ExprValues) (*[]expr.Any, error) {
FILE: daemon/firewall/nftables/exprs/quota_test.go
function TestExprQuota (line 12) | func TestExprQuota(t *testing.T) {
FILE: daemon/firewall/nftables/exprs/utils.go
function GetICMPRejectCode (line 11) | func GetICMPRejectCode(reason string) uint8 {
function GetICMPxRejectCode (line 31) | func GetICMPxRejectCode(reason string) uint8 {
function GetICMPType (line 49) | func GetICMPType(icmpType string) uint8 {
function GetICMPv6Type (line 86) | func GetICMPv6Type(icmpType string) uint8 {
function GetICMPv6RejectCode (line 115) | func GetICMPv6RejectCode(reason string) uint8 {
function getProtocolCode (line 136) | func getProtocolCode(value string) (byte, error) {
FILE: daemon/firewall/nftables/exprs/verdict.go
function NewExprVerdict (line 13) | func NewExprVerdict(verdict, parms string) *[]expr.Any {
function NewExprAccept (line 158) | func NewExprAccept() *[]expr.Any {
function NewExprReject (line 168) | func NewExprReject(parms string) *expr.Reject {
FILE: daemon/firewall/nftables/exprs/verdict_test.go
type verdictTestsT (line 15) | type verdictTestsT struct
function TestExprVerdict (line 23) | func TestExprVerdict(t *testing.T) {
function TestExprVerdictReject (line 80) | func TestExprVerdictReject(t *testing.T) {
function TestExprVerdictQueue (line 291) | func TestExprVerdictQueue(t *testing.T) {
FILE: daemon/firewall/nftables/monitor.go
method AreRulesLoaded (line 12) | func (n *Nft) AreRulesLoaded() bool {
method ReloadConfCallback (line 57) | func (n *Nft) ReloadConfCallback() {
method ReloadRulesCallback (line 64) | func (n *Nft) ReloadRulesCallback() {
method PreloadConfCallback (line 72) | func (n *Nft) PreloadConfCallback() {
FILE: daemon/firewall/nftables/monitor_test.go
function addInterceptionRules (line 15) | func addInterceptionRules(nft *nftb.Nft, t *testing.T) {
function _testMonitorReload (line 33) | func _testMonitorReload(t *testing.T, conn *nftables.Conn, nft *nftb.Nft) {
function TestAreRulesLoaded (line 63) | func TestAreRulesLoaded(t *testing.T) {
function TestMonitorReload (line 81) | func TestMonitorReload(t *testing.T) {
FILE: daemon/firewall/nftables/nftables.go
type Action (line 19) | type Action
constant fwKey (line 23) | fwKey = "opensnitch-key"
constant InterceptionRuleKey (line 24) | InterceptionRuleKey = fwKey + "-interception"
constant SystemRuleKey (line 25) | SystemRuleKey = fwKey + "-system"
constant Name (line 26) | Name = "nftables"
type Nft (line 30) | type Nft struct
method Name (line 56) | func (n *Nft) Name() string {
method Init (line 62) | func (n *Nft) Init(qNum uint16, configPath, monitorInterval string, by...
method Stop (line 90) | func (n *Nft) Stop() {
method EnableInterception (line 105) | func (n *Nft) EnableInterception() {
method DisableInterception (line 126) | func (n *Nft) DisableInterception(logErrors bool) {
method CleanRules (line 132) | func (n *Nft) CleanRules(logErrors bool) {
method Commit (line 140) | func (n *Nft) Commit() bool {
method Serialize (line 149) | func (n *Nft) Serialize() (*protocol.SysFirewall, error) {
method Deserialize (line 169) | func (n *Nft) Deserialize(sysfw *protocol.SysFirewall) ([]byte, error) {
function NewNft (line 41) | func NewNft() *nftables.Conn {
function Fw (line 46) | func Fw() (*Nft, error) {
FILE: daemon/firewall/nftables/nftest/nftest.go
function init (line 21) | func init() {
function SkipIfNotPrivileged (line 29) | func SkipIfNotPrivileged(t *testing.T) {
function OpenSystemConn (line 37) | func OpenSystemConn(t *testing.T) (*nftables.Conn, netns.NsHandle) {
function CleanupSystemConn (line 57) | func CleanupSystemConn(t *testing.T, newNS netns.NsHandle) {
FILE: daemon/firewall/nftables/nftest/test_utils.go
type TestsT (line 14) | type TestsT struct
function AreExprsValid (line 26) | func AreExprsValid(t *testing.T, test *TestsT, rule *nftables.Rule) bool {
FILE: daemon/firewall/nftables/nftest/utils.go
function AddTestRule (line 12) | func AddTestRule(t *testing.T, conn *nftables.Conn, exp *[]expr.Any) (*n...
function AddTestSNATRule (line 48) | func AddTestSNATRule(t *testing.T, conn *nftables.Conn, exp *[]expr.Any)...
function AddTestDNATRule (line 84) | func AddTestDNATRule(t *testing.T, conn *nftables.Conn, exp *[]expr.Any)...
FILE: daemon/firewall/nftables/parser.go
method parseExpression (line 33) | func (n *Nft) parseExpression(table, chain, family string, expression *c...
FILE: daemon/firewall/nftables/rule_helpers.go
method buildICMPRule (line 16) | func (n *Nft) buildICMPRule(table, family string, icmpProtoVersion strin...
method buildConntrackRule (line 106) | func (n *Nft) buildConntrackRule(ctOptions []*config.ExprValues, cmpOp *...
method buildL4ProtoRule (line 157) | func (n *Nft) buildL4ProtoRule(table, family, l4prots string, cmpOp *exp...
method buildPortsRule (line 188) | func (n *Nft) buildPortsRule(table, family, ports string, cmpOp *expr.Cm...
FILE: daemon/firewall/nftables/rules.go
method QueueDNSResponses (line 18) | func (n *Nft) QueueDNSResponses(enable, logError bool) (error, error) {
method QueueConnections (line 80) | func (n *Nft) QueueConnections(enable, logError bool) (error, error) {
method InsertRule (line 182) | func (n *Nft) InsertRule(chain, table, family string, position uint64, e...
method AddRule (line 210) | func (n *Nft) AddRule(chain, table, family string, position uint64, key ...
method delRulesByKey (line 237) | func (n *Nft) delRulesByKey(key string) error {
method DelInterceptionRules (line 281) | func (n *Nft) DelInterceptionRules() {
FILE: daemon/firewall/nftables/rules_test.go
function getRulesList (line 12) | func getRulesList(t *testing.T, conn *nftables.Conn, family, tblName, ch...
function getRule (line 31) | func getRule(t *testing.T, conn *nftables.Conn, tblName, chnName, key st...
function TestAddRule (line 58) | func TestAddRule(t *testing.T) {
function TestInsertRule (line 101) | func TestInsertRule(t *testing.T) {
function TestQueueConnections (line 137) | func TestQueueConnections(t *testing.T) {
function TestQueueDNSResponses (line 171) | func TestQueueDNSResponses(t *testing.T) {
FILE: daemon/firewall/nftables/system.go
type sysTablesT (line 18) | type sysTablesT struct
method Add (line 23) | func (t *sysTablesT) Add(name string, tbl *nftables.Table) {
method Get (line 29) | func (t *sysTablesT) Get(name string) *nftables.Table {
method List (line 35) | func (t *sysTablesT) List() map[string]*nftables.Table {
method Del (line 41) | func (t *sysTablesT) Del(name string) {
function InitMapsStore (line 56) | func InitMapsStore() {
method CreateSystemRule (line 66) | func (n *Nft) CreateSystemRule(chain *config.FwChain, logErrors bool) bo...
method AddSystemRules (line 103) | func (n *Nft) AddSystemRules(reload, backupExistingChains bool) {
method DeleteSystemRules (line 139) | func (n *Nft) DeleteSystemRules(force, restoreExistingChains, logErrors ...
method AddSystemRule (line 156) | func (n *Nft) AddSystemRule(rule *config.FwRule, chain *config.FwChain) ...
FILE: daemon/firewall/nftables/system_test.go
type sysChainsListT (line 10) | type sysChainsListT struct
function TestAddSystemRules (line 21) | func TestAddSystemRules(t *testing.T) {
function TestFwConfDisabled (line 66) | func TestFwConfDisabled(t *testing.T) {
function TestDeleteSystemRules (line 105) | func TestDeleteSystemRules(t *testing.T) {
FILE: daemon/firewall/nftables/tables.go
method AddTable (line 12) | func (n *Nft) AddTable(name, family string) (*nftables.Table, error) {
method GetTable (line 29) | func (n *Nft) GetTable(name, family string) *nftables.Table {
function getTableKey (line 33) | func getTableKey(name string, family interface{}) string {
method AddInterceptionTables (line 38) | func (n *Nft) AddInterceptionTables() error {
method nonSystemRules (line 46) | func (n *Nft) nonSystemRules(tbl *nftables.Table) int {
method DelSystemTables (line 67) | func (n *Nft) DelSystemTables() {
FILE: daemon/firewall/nftables/tables_test.go
function tableExists (line 12) | func tableExists(t *testing.T, conn *nftables.Conn, origtbl *nftables.Ta...
function TestAddTable (line 29) | func TestAddTable(t *testing.T) {
function TestAddInterceptionTables (line 84) | func TestAddInterceptionTables(t *testing.T) {
FILE: daemon/firewall/nftables/utils.go
method getBypassFlag (line 12) | func (n *Nft) getBypassFlag() expr.QueueFlag {
function GetFamilyCode (line 20) | func GetFamilyCode(family string) nftables.TableFamily {
function GetHook (line 44) | func GetHook(chain string) *nftables.ChainHook {
function GetChainPriority (line 69) | func GetChainPriority(family, cType, hook string) (*nftables.ChainPriori...
function GetConntrackPriority (line 164) | func GetConntrackPriority(hook string) (*nftables.ChainPriority, nftable...
FILE: daemon/firewall/nftables/utils_test.go
type chainPrioT (line 11) | type chainPrioT struct
function TestGetConntrackPriority (line 24) | func TestGetConntrackPriority(t *testing.T) {
function TestGetChainPriority (line 59) | func TestGetChainPriority(t *testing.T) {
function TestInvalidChainPriority (line 166) | func TestInvalidChainPriority(t *testing.T) {
FILE: daemon/firewall/rules.go
type Firewall (line 15) | type Firewall interface
function Init (line 49) | func Init(fwType, configPath, monitorInterval string, bypassQueue bool, ...
function IsRunning (line 95) | func IsRunning() bool {
function ErrorsChan (line 100) | func ErrorsChan() <-chan string {
function ErrChanEmpty (line 105) | func ErrChanEmpty() bool {
function CleanRules (line 110) | func CleanRules(logErrors bool) {
function Reload (line 118) | func Reload(fwtype, configPath, monitorInterval string, bypassQueue bool...
function ReloadSystemRules (line 125) | func ReloadSystemRules() {
function EnableInterception (line 131) | func EnableInterception() error {
function DisableInterception (line 140) | func DisableInterception() error {
function Stop (line 149) | func Stop() {
function SaveConfiguration (line 157) | func SaveConfiguration(rawConfig []byte) error {
function Serialize (line 162) | func Serialize() (*protocol.SysFirewall, error) {
function Deserialize (line 170) | func Deserialize(sysfw *protocol.SysFirewall) ([]byte, error) {
FILE: daemon/internal/testutil/network.go
type TestNetwork (line 60) | type TestNetwork interface
type NativeNetwork (line 71) | type NativeNetwork struct
method Setup (line 75) | func (n *NativeNetwork) Setup() error {
method Exec (line 79) | func (n *NativeNetwork) Exec(name string, args ...string) ([]byte, err...
method ExecPassthrough (line 84) | func (n *NativeNetwork) ExecPassthrough(name string, args ...string) e...
method NamespaceName (line 92) | func (n *NativeNetwork) NamespaceName() string {
method AddCleanup (line 97) | func (n *NativeNetwork) AddCleanup(name string, args ...string) {
method Cleanup (line 101) | func (n *NativeNetwork) Cleanup() {
method IsNative (line 109) | func (n *NativeNetwork) IsNative() bool {
type NamespacedNetwork (line 115) | type NamespacedNetwork struct
method Setup (line 119) | func (n *NamespacedNetwork) Setup() error {
method Exec (line 136) | func (n *NamespacedNetwork) Exec(name string, args ...string) ([]byte,...
method ExecPassthrough (line 142) | func (n *NamespacedNetwork) ExecPassthrough(name string, args ...strin...
method NamespaceName (line 151) | func (n *NamespacedNetwork) NamespaceName() string {
method Cleanup (line 155) | func (n *NamespacedNetwork) Cleanup() {
method IsNative (line 161) | func (n *NamespacedNetwork) IsNative() bool {
function NewTestNetwork (line 167) | func NewTestNetwork() TestNetwork {
function IsSubprocess (line 200) | func IsSubprocess() bool {
function GetTestRunPattern (line 206) | func GetTestRunPattern(args []string) string {
function RunTestsIsolated (line 222) | func RunTestsIsolated(testNet TestNetwork, tests []string, args []string...
function buildSubprocessArgs (line 251) | func buildSubprocessArgs(testName string, originalArgs []string) []string {
FILE: daemon/log/formats/csv.go
constant CSV (line 10) | CSV = "csv"
type Csv (line 13) | type Csv struct
method Transform (line 22) | func (c *Csv) Transform(args ...interface{}) (out string) {
function NewCSV (line 17) | func NewCSV() *Csv {
FILE: daemon/log/formats/formats.go
type LoggerFormat (line 17) | type LoggerFormat interface
function init (line 26) | func init() {
function connToSD (line 32) | func connToSD(out string, val interface{}) string {
FILE: daemon/log/formats/json.go
constant JSON (line 12) | JSON = "json"
constant EvConnection (line 16) | EvConnection = iota
constant EvExec (line 17) | EvExec
constant EvTaskNotification (line 18) | EvTaskNotification
type JSONEventFormat (line 23) | type JSONEventFormat struct
method Transform (line 37) | func (j *JSONEventFormat) Transform(args ...interface{}) (out string) {
function NewJSON (line 32) | func NewJSON() *JSONEventFormat {
FILE: daemon/log/formats/rfc3164.go
constant RFC3164 (line 12) | RFC3164 = "rfc3164"
type Rfc3164 (line 15) | type Rfc3164 struct
method Transform (line 26) | func (r *Rfc3164) Transform(args ...interface{}) (out string) {
function NewRfc3164 (line 21) | func NewRfc3164() *Rfc3164 {
FILE: daemon/log/formats/rfc5424.go
constant RFC5424 (line 12) | RFC5424 = "rfc5424"
type Rfc5424 (line 15) | type Rfc5424 struct
method Transform (line 26) | func (r *Rfc5424) Transform(args ...interface{}) (out string) {
function NewRfc5424 (line 21) | func NewRfc5424() *Rfc5424 {
FILE: daemon/log/log.go
type Handler (line 11) | type Handler
constant BOLD (line 15) | BOLD = "\033[1m"
constant DIM (line 16) | DIM = "\033[2m"
constant RED (line 18) | RED = "\033[31m"
constant GREEN (line 19) | GREEN = "\033[32m"
constant BLUE (line 20) | BLUE = "\033[34m"
constant YELLOW (line 21) | YELLOW = "\033[33m"
constant FG_BLACK (line 23) | FG_BLACK = "\033[30m"
constant FG_WHITE (line 24) | FG_WHITE = "\033[97m"
constant BG_PURPLE (line 26) | BG_PURPLE = "\033[45m"
constant BG_RED (line 27) | BG_RED = "\033[41m"
constant BG_GREEN (line 28) | BG_GREEN = "\033[42m"
constant BG_YELLOW (line 29) | BG_YELLOW = "\033[43m"
constant BG_DGRAY (line 30) | BG_DGRAY = "\033[100m"
constant BG_LBLUE (line 31) | BG_LBLUE = "\033[104m"
constant RESET (line 33) | RESET = "\033[0m"
constant DEBUG (line 38) | DEBUG = iota
constant INFO (line 39) | INFO
constant IMPORTANT (line 40) | IMPORTANT
constant WARNING (line 41) | WARNING
constant ERROR (line 42) | ERROR
constant FATAL (line 43) | FATAL
constant TRACE (line 45) | TRACE = -1
function Wrap (line 80) | func Wrap(s, effect string) string {
function Dim (line 88) | func Dim(s string) string {
function Bold (line 93) | func Bold(s string) string {
function Red (line 98) | func Red(s string) string {
function Green (line 103) | func Green(s string) string {
function Blue (line 108) | func Blue(s string) string {
function Yellow (line 113) | func Yellow(s string) string {
function Raw (line 118) | func Raw(format string, args ...interface{}) {
function SetLogLevel (line 125) | func SetLogLevel(newLevel int) {
function GetLogLevel (line 132) | func GetLogLevel() int {
function SetLogUTC (line 140) | func SetLogUTC(newLogUTC bool) {
function GetLogUTC (line 147) | func GetLogUTC() bool {
function SetLogMicro (line 155) | func SetLogMicro(newLogMicro bool) {
function GetLogMicro (line 162) | func GetLogMicro() bool {
function Log (line 170) | func Log(level int, format string, args ...interface{}) {
function setDefaultLogOutput (line 198) | func setDefaultLogOutput() {
function OpenFile (line 205) | func OpenFile(logFile string) (err error) {
function Close (line 222) | func Close() {
function Trace (line 229) | func Trace(format string, args ...interface{}) {
function Debug (line 234) | func Debug(format string, args ...interface{}) {
function Info (line 239) | func Info(format string, args ...interface{}) {
function Important (line 244) | func Important(format string, args ...interface{}) {
function Warning (line 249) | func Warning(format string, args ...interface{}) {
function Error (line 254) | func Error(format string, args ...interface{}) {
function Fatal (line 259) | func Fatal(format string, args ...interface{}) {
FILE: daemon/log/loggers/logger.go
constant logTag (line 12) | logTag = "opensnitch"
type Logger (line 16) | type Logger interface
type LoggerConfig (line 23) | type LoggerConfig struct
type LoggerManager (line 54) | type LoggerManager struct
method Load (line 80) | func (l *LoggerManager) Load(configs []LoggerConfig) {
method Reload (line 124) | func (l *LoggerManager) Reload() {
method Stop (line 130) | func (l *LoggerManager) Stop() {
method write (line 144) | func (l *LoggerManager) write(args ...interface{}) {
method Log (line 167) | func (l *LoggerManager) Log(args ...interface{}) {
function NewLoggerManager (line 67) | func NewLoggerManager() *LoggerManager {
function newWorker (line 153) | func newWorker(id int, done <-chan struct{}, msgs chan []interface{}, wr...
FILE: daemon/log/loggers/remote.go
constant LOGGER_REMOTE (line 20) | LOGGER_REMOTE = "remote"
constant maxAllowedErrors (line 23) | maxAllowedErrors = 10
constant DISCONNECTED (line 35) | DISCONNECTED = iota
constant CONNECTED (line 36) | CONNECTED
constant CONNECTING (line 37) | CONNECTING
type Remote (line 43) | type Remote struct
method Open (line 126) | func (s *Remote) Open() (net.Conn, bool) {
method Dial (line 162) | func (s *Remote) Dial(proto, addr string, connTimeout time.Duration) (...
method Close (line 180) | func (s *Remote) Close() (err error) {
method isConnected (line 186) | func (s *Remote) isConnected() bool {
method Transform (line 192) | func (s *Remote) Transform(args ...interface{}) (out string) {
method Write (line 201) | func (s *Remote) Write(msg string) {
method formatLine (line 209) | func (s *Remote) formatLine(msg string) string {
function NewRemote (line 73) | func NewRemote(cfg LoggerConfig) (*Remote, error) {
function writerWorker (line 219) | func writerWorker(id int, sys *Remote, msgs <-chan string, done <-chan s...
FILE: daemon/log/loggers/remote_syslog.go
constant LOGGER_REMOTE_SYSLOG (line 8) | LOGGER_REMOTE_SYSLOG = "remote_syslog"
type RemoteSyslog (line 11) | type RemoteSyslog struct
method formatLine (line 30) | func (rs *RemoteSyslog) formatLine(msg string) string {
function NewRemoteSyslog (line 17) | func NewRemoteSyslog(cfg LoggerConfig) (*RemoteSyslog, error) {
FILE: daemon/log/loggers/syslog.go
constant LOGGER_SYSLOG (line 11) | LOGGER_SYSLOG = "syslog"
type Syslog (line 16) | type Syslog struct
method Open (line 55) | func (s *Syslog) Open() error {
method Close (line 63) | func (s *Syslog) Close() error {
method Transform (line 68) | func (s *Syslog) Transform(args ...interface{}) (out string) {
method Write (line 75) | func (s *Syslog) Write(msg string) {
function NewSyslog (line 26) | func NewSyslog(cfg LoggerConfig) (*Syslog, error) {
FILE: daemon/main.go
function init (line 103) | func init() {
function loadDiskConfiguration (line 133) | func loadDiskConfiguration() (*config.Config, error) {
function overwriteLogging (line 151) | func overwriteLogging() bool {
function overwriteFw (line 156) | func overwriteFw(cfg *config.Config, qNum uint16, fwCfg string) {
function setupQueues (line 170) | func setupQueues(qNum uint16) {
function setupLogging (line 195) | func setupLogging() {
function setupProfiling (line 224) | func setupProfiling() {
function setupSignals (line 251) | func setupSignals() {
function worker (line 270) | func worker(id int) {
function setupWorkers (line 289) | func setupWorkers() {
function listenToEvents (line 299) | func listenToEvents() {
function initSystemdResolvedMonitor (line 316) | func initSystemdResolvedMonitor() {
function doCleanup (line 371) | func doCleanup(queue, repeatQueue *netfilter.Queue) {
function onPacket (line 400) | func onPacket(packet netfilter.Packet) {
function applyDefaultAction (line 431) | func applyDefaultAction(packet *netfilter.Packet, con *conman.Connection) {
function acceptOrDeny (line 443) | func acceptOrDeny(packet *netfilter.Packet, con *conman.Connection) *rul...
function main (line 560) | func main() {
FILE: daemon/netfilter/netfilter_test.go
function TestMain (line 63) | func TestMain(m *testing.M) {
function runCmd (line 84) | func runCmd(name string, args ...string) ([]byte, error) {
function augmentRule (line 90) | func augmentRule(baseRule []string, protocol string, port uint16, mark s...
function TestVerdictEncoding (line 127) | func TestVerdictEncoding(t *testing.T) {
function TestIsIPv4 (line 160) | func TestIsIPv4(t *testing.T) {
function TestQueueCreation (line 184) | func TestQueueCreation(t *testing.T) {
function TestPacketCapture (line 204) | func TestPacketCapture(t *testing.T) {
function TestVerdictAccept (line 275) | func TestVerdictAccept(t *testing.T) {
function TestVerdictDrop (line 323) | func TestVerdictDrop(t *testing.T) {
function TestVerdictMark (line 372) | func TestVerdictMark(t *testing.T) {
function TestSetRequeueVerdict (line 427) | func TestSetRequeueVerdict(t *testing.T) {
function TestSetVerdictWithPacket (line 476) | func TestSetVerdictWithPacket(t *testing.T) {
function TestMultipleQueues (line 528) | func TestMultipleQueues(t *testing.T) {
function TestConcurrentPacketHandling (line 614) | func TestConcurrentPacketHandling(t *testing.T) {
function TestProductionRules (line 742) | func TestProductionRules(t *testing.T) {
FILE: daemon/netfilter/packet.go
constant IPv4 (line 11) | IPv4 = 4
type Verdict (line 15) | type Verdict
type VerdictContainer (line 18) | type VerdictContainer struct
type Packet (line 25) | type Packet struct
method SetVerdict (line 36) | func (p *Packet) SetVerdict(v Verdict) {
method SetVerdictAndMark (line 42) | func (p *Packet) SetVerdictAndMark(v Verdict, mark uint32) {
method SetRequeueVerdict (line 47) | func (p *Packet) SetRequeueVerdict(newQueueID uint16) {
method SetVerdictWithPacket (line 55) | func (p *Packet) SetVerdictWithPacket(v Verdict, packet []byte) {
method IsIPv4 (line 60) | func (p *Packet) IsIPv4() bool {
FILE: daemon/netfilter/queue.go
constant AF_INET (line 27) | AF_INET = 2
constant AF_INET6 (line 28) | AF_INET6 = 10
constant NF_DROP (line 30) | NF_DROP Verdict = 0
constant NF_ACCEPT (line 31) | NF_ACCEPT Verdict = 1
constant NF_STOLEN (line 32) | NF_STOLEN Verdict = 2
constant NF_QUEUE (line 33) | NF_QUEUE Verdict = 3
constant NF_REPEAT (line 34) | NF_REPEAT Verdict = 4
constant NF_STOP (line 35) | NF_STOP Verdict = 5
constant NF_DEFAULT_QUEUE_SIZE (line 37) | NF_DEFAULT_QUEUE_SIZE uint32 = 4096
constant NF_DEFAULT_PACKET_SIZE (line 38) | NF_DEFAULT_PACKET_SIZE uint32 = 4096
type VerdictContainerC (line 51) | type VerdictContainerC
type Queue (line 57) | type Queue struct
method create (line 83) | func (q *Queue) create(queueID uint16) (err error) {
method setup (line 112) | func (q *Queue) setup() (err error) {
method run (line 136) | func (q *Queue) run() {
method Close (line 147) | func (q *Queue) Close() {
method destroy (line 156) | func (q *Queue) destroy() {
method closeNfq (line 175) | func (q *Queue) closeNfq() {
method Packets (line 184) | func (q *Queue) Packets() <-chan Packet {
function NewQueue (line 66) | func NewQueue(queueID uint16) (q *Queue, err error) {
function go_callback (line 191) | func go_callback(queueID C.int, data *C.uchar, length C.int, mark C.uint...
FILE: daemon/netfilter/queue.h
type verdictContainer (line 17) | typedef struct {
function configure_uid_if_available (line 31) | static inline void configure_uid_if_available(struct nfq_q_handle *qh){
function nf_callback (line 52) | static int nf_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, ...
type nfq_q_handle (line 87) | struct nfq_q_handle
type nfq_handle (line 87) | struct nfq_handle
type nfq_q_handle (line 88) | struct nfq_q_handle
function stop_reading_packets (line 97) | static inline void stop_reading_packets() {
function Run (line 101) | static inline int Run(struct nfq_handle *h, int fd) {
FILE: daemon/netlink/ifaces.go
function isPrivate (line 12) | func isPrivate(ip net.IP) bool {
function GetLocalAddrs (line 22) | func GetLocalAddrs() map[string]netlink.Addr {
function AddrUpdateToAddr (line 38) | func AddrUpdateToAddr(addr *netlink.AddrUpdate) netlink.Addr {
FILE: daemon/netlink/procmon/procmon.go
type ProcEvent (line 18) | type ProcEvent struct
method Msg (line 122) | func (pe *ProcEvent) Msg() interface{} {
method Pid (line 127) | func (pe *ProcEvent) Pid() uint32 {
method IsFork (line 132) | func (pe *ProcEvent) IsFork() bool {
method IsExec (line 137) | func (pe *ProcEvent) IsExec() bool {
method IsComm (line 142) | func (pe *ProcEvent) IsComm() bool {
method IsExit (line 147) | func (pe *ProcEvent) IsExit() bool {
function ProcEventsMonitor (line 32) | func ProcEventsMonitor(done <-chan struct{}) {
function NewProcEvent (line 89) | func NewProcEvent(ev netlink.ProcEvent) ProcEvent {
FILE: daemon/netlink/socket.go
function GetSocketInfo (line 29) | func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.I...
function GetSocketInfoByInode (line 110) | func GetSocketInfoByInode(inodeStr string) (*Socket, error) {
function KillSocket (line 139) | func KillSocket(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, ...
function KillSockets (line 166) | func KillSockets(fam, proto uint8, excludeLocal bool) error {
function KillAllSockets (line 192) | func KillAllSockets() {
function FlushConnections (line 214) | func FlushConnections() {
function SocketsAreEqual (line 227) | func SocketsAreEqual(aSocket, bSocket *Socket) bool {
FILE: daemon/netlink/socket_linux.go
constant SOCK_DESTROY (line 18) | SOCK_DESTROY = 21
constant sizeofSocketID (line 19) | sizeofSocketID = 0x30
constant sizeofSocketRequest (line 20) | sizeofSocketRequest = sizeofSocketID + 0x8
constant sizeofSocket (line 21) | sizeofSocket = sizeofSocketID + 0x18
constant TCP_INVALID (line 26) | TCP_INVALID = iota
constant TCP_ESTABLISHED (line 27) | TCP_ESTABLISHED
constant TCP_SYN_SENT (line 28) | TCP_SYN_SENT
constant TCP_SYN_RECV (line 29) | TCP_SYN_RECV
constant TCP_FIN_WAIT1 (line 30) | TCP_FIN_WAIT1
constant TCP_FIN_WAIT2 (line 31) | TCP_FIN_WAIT2
constant TCP_TIME_WAIT (line 32) | TCP_TIME_WAIT
constant TCP_CLOSE (line 33) | TCP_CLOSE
constant TCP_CLOSE_WAIT (line 34) | TCP_CLOSE_WAIT
constant TCP_LAST_ACK (line 35) | TCP_LAST_ACK
constant TCP_LISTEN (line 36) | TCP_LISTEN
constant TCP_CLOSING (line 37) | TCP_CLOSING
constant TCP_NEW_SYN_RECV (line 38) | TCP_NEW_SYN_RECV
constant TCP_MAX_STATES (line 39) | TCP_MAX_STATES
type SocketID (line 65) | type SocketID struct
type Socket (line 75) | type Socket struct
method deserialize (line 157) | func (s *Socket) deserialize(b []byte) error {
type SocketRequest (line 89) | type SocketRequest struct
method Serialize (line 115) | func (r *SocketRequest) Serialize() []byte {
method Len (line 138) | func (r *SocketRequest) Len() int { return sizeofSocketRequest }
type writeBuffer (line 98) | type writeBuffer struct
method Write (line 103) | func (b *writeBuffer) Write(c byte) {
method Next (line 108) | func (b *writeBuffer) Next(n int) []byte {
type readBuffer (line 140) | type readBuffer struct
method Read (line 145) | func (b *readBuffer) Read() byte {
method Next (line 151) | func (b *readBuffer) Next(n int) []byte {
function SocketKill (line 189) | func SocketKill(family, proto uint8, sockID SocketID) error {
function SocketGet (line 209) | func SocketGet(family uint8, proto uint8, srcPort, dstPort uint16, local...
function SocketsDump (line 226) | func SocketsDump(family uint8, proto uint8) ([]*Socket, error) {
function netlinkRequest (line 235) | func netlinkRequest(sockReq *SocketRequest, family uint8, proto uint8, s...
FILE: daemon/netlink/socket_packet.go
constant PACKET_SHOW_INFO (line 31) | PACKET_SHOW_INFO = 0x00000001
constant PACKET_SHOW_MCLIST (line 32) | PACKET_SHOW_MCLIST = 0x00000002
constant PACKET_SHOW_RING_CFG (line 33) | PACKET_SHOW_RING_CFG = 0x00000004
constant PACKET_SHOW_FANOUT (line 34) | PACKET_SHOW_FANOUT = 0x00000008
constant PACKET_SHOW_MEMINFO (line 35) | PACKET_SHOW_MEMINFO = 0x00000010
constant PACKET_SHOW_FILTER (line 36) | PACKET_SHOW_FILTER = 0x00000020
constant PACKET_DIAG_INFO (line 42) | PACKET_DIAG_INFO = iota
constant PACKET_DIAG_MCLIST (line 43) | PACKET_DIAG_MCLIST
constant PACKET_DIAG_RX_RING (line 44) | PACKET_DIAG_RX_RING
constant PACKET_DIAG_TX_RING (line 45) | PACKET_DIAG_TX_RING
constant PACKET_DIAG_FANOUT (line 46) | PACKET_DIAG_FANOUT
constant PACKET_DIAG_UID (line 47) | PACKET_DIAG_UID
constant PACKET_DIAG_MEMINFO (line 48) | PACKET_DIAG_MEMINFO
constant PACKET_DIAG_FILTER (line 49) | PACKET_DIAG_FILTER
constant sizePktDiagReq (line 53) | sizePktDiagReq = 20
constant sizePktDiagMclist (line 54) | sizePktDiagMclist = 28
type PacketDiagMsg (line 59) | type PacketDiagMsg struct
method deserialize (line 79) | func (pm *PacketDiagMsg) deserialize(b []byte) error {
type PacketDiagMclist (line 71) | type PacketDiagMclist struct
type PacketDiagReq (line 116) | type PacketDiagReq struct
method Serialize (line 126) | func (p *PacketDiagReq) Serialize() []byte {
method Len (line 140) | func (p *PacketDiagReq) Len() int { return sizePktDiagReq }
function SocketDiagPacket (line 143) | func SocketDiagPacket(proto uint8) ([]*PacketDiagMsg, error) {
FILE: daemon/netlink/socket_test.go
type Connection (line 12) | type Connection struct
function EstablishConnection (line 22) | func EstablishConnection(proto, dst string) (net.Conn, error) {
function ListenOnPort (line 31) | func ListenOnPort(proto, port string) (net.Listener, error) {
function setupConnection (line 41) | func setupConnection(proto string, connChan chan *Connection) {
function TestNetlinkTCPQueries (line 69) | func TestNetlinkTCPQueries(t *testing.T) {
FILE: daemon/netlink/socket_xdp.go
function SocketGetXDP (line 8) | func SocketGetXDP() ([]*vnl.XDPDiagInfoResp, error) {
FILE: daemon/netstat/entry.go
type Entry (line 11) | type Entry struct
function NewEntry (line 23) | func NewEntry(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, ds...
FILE: daemon/netstat/find.go
function FindEntry (line 12) | func FindEntry(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, d...
function findEntryForProtocol (line 37) | func findEntryForProtocol(proto string, srcIP net.IP, srcPort uint, dstI...
FILE: daemon/netstat/parse.go
function decToInt (line 30) | func decToInt(n string) int {
function hexToInt (line 38) | func hexToInt(h string) uint {
function hexToInt2 (line 46) | func hexToInt2(h string) (uint, uint) {
function hexToIP (line 66) | func hexToIP(h string) net.IP {
function Parse (line 84) | func Parse(proto string) ([]Entry, error) {
FILE: daemon/netstat/parse_packet.go
function ParsePacket (line 29) | func ParsePacket() ([]Entry, error) {
FILE: daemon/procmon/activepids.go
type value (line 10) | type value struct
function MonitorProcEvents (line 23) | func MonitorProcEvents(stop <-chan struct{}) {
FILE: daemon/procmon/audit/client.go
type Event (line 46) | type Event struct
constant MaxEventAge (line 79) | MaxEventAge = int(10)
constant OpensnitchRulesKey (line 106) | OpensnitchRulesKey = "key=\"opensnitch\""
function GetEvents (line 110) | func GetEvents() []*Event {
function GetEventByPid (line 115) | func GetEventByPid(pid int) *Event {
function sortEvents (line 130) | func sortEvents() {
function cleanOldEvents (line 146) | func cleanOldEvents() {
function deleteEvent (line 163) | func deleteEvent(pid int) {
function deleteEventByIndex (line 172) | func deleteEventByIndex(index int) {
function AddEvent (line 182) | func AddEvent(aevent *Event) {
function startEventsCleaner (line 206) | func startEventsCleaner() {
function addRules (line 219) | func addRules() bool {
function configureSyscalls (line 231) | func configureSyscalls() {
function deleteRules (line 240) | func deleteRules() bool {
function checkRules (line 252) | func checkRules() bool {
function checkStatus (line 257) | func checkStatus() bool {
function Reader (line 265) | func Reader(r io.Reader, eventChan chan<- Event) {
function StartChannel (line 302) | func StartChannel() {
function reconnect (line 306) | func reconnect() (net.Conn, error) {
function connect (line 312) | func connect() (net.Conn, error) {
function Stop (line 319) | func Stop() {
function Start (line 345) | func Start(auditOpts Config) (net.Conn, error) {
FILE: daemon/procmon/audit/config.go
type Config (line 6) | type Config struct
function setConfig (line 10) | func setConfig(auditOpts Config) {
FILE: daemon/procmon/audit/parse.go
constant sockSTREAM (line 34) | sockSTREAM = "1"
constant sockDGRAM (line 35) | sockDGRAM = "2"
constant sockRAW (line 36) | sockRAW = "3"
constant sockSEQPACKET (line 37) | sockSEQPACKET = "5"
constant sockPACKET (line 38) | sockPACKET = "10"
constant pfUNSPEC (line 41) | pfUNSPEC = "0"
constant pfLOCAL (line 42) | pfLOCAL = "1"
constant pfINET (line 43) | pfINET = "2"
constant pfINET6 (line 44) | pfINET6 = "10"
constant protoIP (line 47) | protoIP = "0"
constant protoTCP (line 48) | protoTCP = "6"
constant protoUDP (line 49) | protoUDP = "17"
constant AuditTypePROCTITLE (line 54) | AuditTypePROCTITLE = "type=PROCTITLE"
constant AuditTypeCWD (line 55) | AuditTypeCWD = "type=CWD"
constant AuditTypePATH (line 56) | AuditTypePATH = "type=PATH"
constant AuditTypeEXECVE (line 57) | AuditTypeEXECVE = "type=EXECVE"
constant AuditTypeSOCKADDR (line 58) | AuditTypeSOCKADDR = "type=SOCKADDR"
constant AuditTypeSOCKETCALL (line 59) | AuditTypeSOCKETCALL = "type=SOCKETCALL"
constant AuditTypeEOE (line 60) | AuditTypeEOE = "type=EOE"
function parseNetLine (line 73) | func parseNetLine(line string, decode bool) (family string, dstHost net....
function decodeString (line 119) | func decodeString(s string) string {
function extractFields (line 128) | func extractFields(rawMessage string, newEvent *map[string]string) {
function populateEvent (line 147) | func populateEvent(aevent *Event, eventFields *map[string]string) *Event {
function parseEvent (line 232) | func parseEvent(rawMessage string, eventChan chan<- Event) {
FILE: daemon/procmon/cache.go
type InodeItem (line 14) | type InodeItem struct
method updateTime (line 87) | func (i *InodeItem) updateTime() {
method getTime (line 93) | func (i *InodeItem) getTime() int64 {
type ProcItem (line 22) | type ProcItem struct
method updateTime (line 99) | func (p *ProcItem) updateTime() {
method updateDescriptors (line 105) | func (p *ProcItem) updateDescriptors(descriptors []string) {
type CacheProcs (line 31) | type CacheProcs struct
method add (line 114) | func (c *CacheProcs) add(fdPath string, fdList []string, pid int) {
method sort (line 138) | func (c *CacheProcs) sort(pid int) {
method delete (line 153) | func (c *CacheProcs) delete(pid int) {
method deleteItem (line 166) | func (c *CacheProcs) deleteItem(pos int) {
method setItems (line 173) | func (c *CacheProcs) setItems(newItems []*ProcItem, oldItems []*ProcIt...
method getItem (line 177) | func (c *CacheProcs) getItem(index int) *ProcItem {
method getItems (line 188) | func (c *CacheProcs) getItems() []*ProcItem {
method countItems (line 192) | func (c *CacheProcs) countItems() int {
method getPid (line 200) | func (c *CacheProcs) getPid(inode int, inodeKey string, expect string)...
type CacheInodes (line 39) | type CacheInodes struct
method add (line 233) | func (i *CacheInodes) add(key, descLink string, pid int) {
method delete (line 247) | func (i *CacheInodes) delete(pid int) {
method getPid (line 258) | func (i *CacheInodes) getPid(inodeKey string) int {
method delItem (line 272) | func (i *CacheInodes) delItem(inodeKey string) {
method getItem (line 278) | func (i *CacheInodes) getItem(inodeKey string) *InodeItem {
method getItems (line 285) | func (i *CacheInodes) getItems() map[string]*InodeItem {
method isInCache (line 292) | func (i *CacheInodes) isInCache(inodeKey string) (*InodeItem, bool) {
method cleanup (line 302) | func (i *CacheInodes) cleanup() {
function CacheCleanerTask (line 68) | func CacheCleanerTask() {
function NewCacheOfInodes (line 78) | func NewCacheOfInodes() *CacheInodes {
function getPidDescriptorsFromCache (line 319) | func getPidDescriptorsFromCache(fdPath, inodeKey, expect string, descrip...
FILE: daemon/procmon/cache_events.go
function init (line 29) | func init() {
type ProcessEvent (line 35) | type ProcessEvent struct
type ExecEventItem (line 45) | type ExecEventItem struct
method isValid (line 52) | func (e *ExecEventItem) isValid() bool {
type EventsStore (line 60) | type EventsStore struct
method Add (line 84) | func (e *EventsStore) Add(proc *Process) {
method UpdateItem (line 98) | func (e *EventsStore) UpdateItem(proc *Process) {
method ReplaceItem (line 123) | func (e *EventsStore) ReplaceItem(oldProc, newProc *Process) {
method Update (line 149) | func (e *EventsStore) Update(oldProc, proc *Process) {
method needsUpdate (line 184) | func (e *EventsStore) needsUpdate(cachedProc, proc *Process) bool {
method IsInStore (line 220) | func (e *EventsStore) IsInStore(key int, proc *Process) (item ExecEven...
method IsInStoreByPID (line 237) | func (e *EventsStore) IsInStoreByPID(key int) (item ExecEventItem, fou...
method Len (line 254) | func (e *EventsStore) Len() int {
method Delete (line 261) | func (e *EventsStore) Delete(key int) {
method DeleteOldItems (line 283) | func (e *EventsStore) DeleteOldItems() {
method ComputeChecksums (line 297) | func (e *EventsStore) ComputeChecksums(proc *Process) bool {
method AddChecksumHash (line 309) | func (e *EventsStore) AddChecksumHash(hash string) {
method DelChecksumHash (line 316) | func (e *EventsStore) DelChecksumHash(hash string) {
method SetComputeChecksums (line 327) | func (e *EventsStore) SetComputeChecksums(compute bool) {
method DisableChecksums (line 353) | func (e *EventsStore) DisableChecksums() {
method GetComputeChecksums (line 365) | func (e *EventsStore) GetComputeChecksums() bool {
function NewEventsStore (line 68) | func NewEventsStore() *EventsStore {
function monitorEventsCache (line 371) | func monitorEventsCache() {
FILE: daemon/procmon/cache_events_test.go
function createNewProc (line 13) | func createNewProc(pid int) *Process {
function TestCacheEvents (line 27) | func TestCacheEvents(t *testing.T) {
function TestCacheEvents2 (line 62) | func TestCacheEvents2(t *testing.T) {
function TestCacheEventsUpdate (line 103) | func TestCacheEventsUpdate(t *testing.T) {
function TestCacheEventsDeleteOldItems (line 141) | func TestCacheEventsDeleteOldItems(t *testing.T) {
function BenchmarkAdd (line 171) | func BenchmarkAdd(b *testing.B) {
function BenchmarkIsInStoreByPID (line 179) | func BenchmarkIsInStoreByPID(b *testing.B) {
function BenchmarkIsNOTInStoreByPID (line 188) | func BenchmarkIsNOTInStoreByPID(b *testing.B) {
FILE: daemon/procmon/cache_test.go
function TestCacheProcs (line 9) | func TestCacheProcs(t *testing.T) {
function BenchmarkGetPid (line 97) | func BenchmarkGetPid(b *testing.B) {
FILE: daemon/procmon/details.go
method GetParent (line 31) | func (p *Process) GetParent() {
method BuildTree (line 59) | func (p *Process) BuildTree() {
method TreeInsertItem (line 82) | func (p *Process) TreeInsertItem(path string, pid int) {
method GetDetails (line 94) | func (p *Process) GetDetails() error {
method GetExtraInfo (line 125) | func (p *Process) GetExtraInfo() error {
method ReadPPID (line 135) | func (p *Process) ReadPPID() {
method ReadComm (line 155) | func (p *Process) ReadComm() error {
method ReadCwd (line 168) | func (p *Process) ReadCwd() error {
method ReadEnv (line 181) | func (p *Process) ReadEnv() {
method ReadMaps (line 208) | func (p *Process) ReadMaps() {
method ReadStatm (line 218) | func (p *Process) ReadStatm() {
method ReadExeLink (line 238) | func (p *Process) ReadExeLink() (string, error) {
method ReadRoot (line 251) | func (p *Process) ReadRoot() {
method ReadPath (line 272) | func (p *Process) ReadPath() error {
method SetPath (line 298) | func (p *Process) SetPath(path string) {
method ReadCmdline (line 322) | func (p *Process) ReadCmdline() {
method CleanArgs (line 352) | func (p *Process) CleanArgs() {
method readDescriptors (line 358) | func (p *Process) readDescriptors() {
method readIOStats (line 398) | func (p *Process) readIOStats() (err error) {
method readStatus (line 429) | func (p *Process) readStatus() {
method CleanPath (line 449) | func (p *Process) CleanPath() {
method IsAlive (line 485) | func (p *Process) IsAlive() bool {
method IsChild (line 490) | func (p *Process) IsChild() bool {
method ChecksumsCount (line 497) | func (p *Process) ChecksumsCount() int {
method ResetChecksums (line 504) | func (p *Process) ResetChecksums() {
method ComputeChecksums (line 512) | func (p *Process) ComputeChecksums(hashes map[string]uint) {
method ComputeChecksum (line 524) | func (p *Process) ComputeChecksum(algo string) {
type MemoryMapping (line 598) | type MemoryMapping struct
method DumpImage (line 605) | func (p *Process) DumpImage() ([]byte, error) {
method dumpFileImage (line 611) | func (p *Process) dumpFileImage(filePath string) ([]byte, error) {
method readMem (line 676) | func (p *Process) readMem(mappings []MemoryMapping) ([]byte, error) {
FILE: daemon/procmon/ebpf/cache.go
type ebpfCacheItem (line 8) | type ebpfCacheItem struct
method isValid (line 38) | func (i *ebpfCacheItem) isValid() bool {
type ebpfCacheType (line 15) | type ebpfCacheType struct
method addNewItem (line 54) | func (e *ebpfCacheType) addNewItem(key interface{}, itemKey []byte, pi...
method isInCache (line 60) | func (e *ebpfCacheType) isInCache(key interface{}) (item *ebpfCacheIte...
method update (line 81) | func (e *ebpfCacheType) update(key interface{}, item *ebpfCacheItem) {
method Len (line 86) | func (e *ebpfCacheType) Len() int {
method DeleteOldItems (line 92) | func (e *ebpfCacheType) DeleteOldItems() {
method delete (line 105) | func (e *ebpfCacheType) delete(key interface{}) {
method clear (line 114) | func (e *ebpfCacheType) clear() {
function NewEbpfCacheItem (line 29) | func NewEbpfCacheItem(key []byte, pid, uid int) *ebpfCacheItem {
function NewEbpfCache (line 46) | func NewEbpfCache() *ebpfCacheType {
FILE: daemon/procmon/ebpf/config.go
type Config (line 6) | type Config struct
function setConfig (line 26) | func setConfig(ebpfOpts Config) {
FILE: daemon/procmon/ebpf/debug.go
function PrintEverything (line 15) | func PrintEverything() {
FILE: daemon/procmon/ebpf/ebpf.go
type KProbeDefs (line 23) | type KProbeDefs struct
type MapDefs (line 38) | type MapDefs struct
type ebpfDefsT (line 46) | type ebpfDefsT struct
type ebpfMapsForProto (line 52) | type ebpfMapsForProto struct
type bpf_lookup_elem_t (line 60) | type bpf_lookup_elem_t struct
type alreadyEstablishedConns (line 67) | type alreadyEstablishedConns struct
constant NoError (line 75) | NoError = iota
constant NotAvailable (line 76) | NotAvailable
constant EventsNotAvailable (line 77) | EventsNotAvailable
type Error (line 81) | type Error struct
function Start (line 122) | func Start(ebpfOpts Config) *Error {
function saveEstablishedConnections (line 227) | func saveEstablishedConnections(commDomain uint8) error {
function setRunning (line 249) | func setRunning(status bool) {
function Stop (line 257) | func Stop() {
function makeBpfSyscall (line 294) | func makeBpfSyscall(bpf_lookup *bpf_lookup_elem_t) uintptr {
function dispatchErrorEvent (line 304) | func dispatchErrorEvent(what string) {
function dispatchEvent (line 309) | func dispatchEvent(data interface{}) {
function Events (line 320) | func Events() <-chan interface{} {
FILE: daemon/procmon/ebpf/ebpf_test.go
function getTestDir (line 39) | func getTestDir() string {
function findEbpfModule (line 45) | func findEbpfModule(name string) string {
function TestEbpfModuleLoad (line 68) | func TestEbpfModuleLoad(t *testing.T) {
function TestEbpfMapOperations (line 118) | func TestEbpfMapOperations(t *testing.T) {
type tcpKey (line 156) | type tcpKey struct
type tcpValue (line 164) | type tcpValue struct
function TestTCPv4ConnectIntegration (line 175) | func TestTCPv4ConnectIntegration(t *testing.T) {
function htons (line 311) | func htons(v uint16) uint16 {
function ntohs (line 318) | func ntohs(v uint16) uint16 {
type tcpv6Key (line 324) | type tcpv6Key struct
function loadEbpfCollection (line 341) | func loadEbpfCollection(t *testing.T) *ebpf.Collection {
function trimComm (line 367) | func trimComm(comm [16]byte) string {
function TestTCPv6ConnectIntegration (line 377) | func TestTCPv6ConnectIntegration(t *testing.T) {
function TestUDPv4SendIntegration (line 473) | func TestUDPv4SendIntegration(t *testing.T) {
function TestUDPv6SendIntegration (line 560) | func TestUDPv6SendIntegration(t *testing.T) {
function TestInetDgramConnectIntegration (line 648) | func TestInetDgramConnectIntegration(t *testing.T) {
function TestExecveIntegration (line 749) | func TestExecveIntegration(t *testing.T) {
function findLibc (line 850) | func findLibc() string {
function TestGetaddrinfoIntegration (line 866) | func TestGetaddrinfoIntegration(t *testing.T) {
function TestIPTunnelXmitIntegration (line 997) | func TestIPTunnelXmitIntegration(t *testing.T) {
function TestUDPTunnel6XmitIntegration (line 1090) | func TestUDPTunnel6XmitIntegration(t *testing.T) {
function TestExecveExitIntegration (line 1179) | func TestExecveExitIntegration(t *testing.T) {
function TestExecveatIntegration (line 1302) | func TestExecveatIntegration(t *testing.T) {
function TestProcessExitIntegration (line 1420) | func TestProcessExitIntegration(t *testing.T) {
function TestGethostbynameIntegration (line 1539) | func TestGethostbynameIntegration(t *testing.T) {
FILE: daemon/procmon/ebpf/events.go
constant MaxPathLen (line 19) | MaxPathLen = 4096
constant MaxArgs (line 22) | MaxArgs = 20
constant MaxArgLen (line 27) | MaxArgLen = 256
constant TaskCommLen (line 30) | TaskCommLen = 16
type execEvent (line 32) | type execEvent struct
type networkEventT (line 49) | type networkEventT struct
constant EV_TYPE_NONE (line 58) | EV_TYPE_NONE = iota
constant EV_TYPE_EXEC (line 59) | EV_TYPE_EXEC
constant EV_TYPE_EXECVEAT (line 60) | EV_TYPE_EXECVEAT
constant EV_TYPE_FORK (line 61) | EV_TYPE_FORK
constant EV_TYPE_SCHED_EXIT (line 62) | EV_TYPE_SCHED_EXIT
type EventsProgsDefs (line 66) | type EventsProgsDefs struct
type EventsMapsDefs (line 78) | type EventsMapsDefs struct
type eventsDefsT (line 84) | type eventsDefsT struct
function initEventsStreamer (line 89) | func initEventsStreamer() *Error {
function initPerfMap (line 151) | func initPerfMap(events *ebpf.Map) error {
function streamEventsWorker (line 209) | func streamEventsWorker(id int, chn chan []byte, kernelEvents chan inter...
function processExecEvent (line 259) | func processExecEvent(event *execEvent) {
function event2process (line 291) | func event2process(event *execEvent) (proc *procmon.Process) {
function getProcDetails (line 334) | func getProcDetails(event *execEvent, proc *procmon.Process) {
function processExitEvent (line 341) | func processExitEvent(event *execEvent) {
FILE: daemon/procmon/ebpf/find.go
function GetPid (line 22) | func GetPid(proto string, srcPort uint, srcIP net.IP, dstIP net.IP, dstP...
function getPidFromEbpf (line 69) | func getPidFromEbpf(proto string, srcPort uint, srcIP net.IP, dstIP net....
function isPIDinEventsCache (line 173) | func isPIDinEventsCache(pid, uid int) (proc *procmon.Process) {
function findConnProcess (line 190) | func findConnProcess(value *networkEventT, connKey string) (proc *procmo...
function findInAlreadyEstablishedTCP (line 209) | func findInAlreadyEstablishedTCP(proto string, srcPort uint, srcIP net.I...
function findAddressInLocalAddresses (line 230) | func findAddressInLocalAddresses(addr net.IP) bool {
FILE: daemon/procmon/ebpf/monitor.go
function monitorMaps (line 15) | func monitorMaps() {
function monitorCache (line 35) | func monitorCache() {
function monitorLocalAddresses (line 48) | func monitorLocalAddresses() {
function monitorAlreadyEstablished (line 91) | func monitorAlreadyEstablished() {
FILE: daemon/procmon/ebpf/utils.go
function determineHostByteOrder (line 13) | func determineHostByteOrder() {
function mountTraceFS (line 29) | func mountTraceFS() error {
function byteArrayToString (line 55) | func byteArrayToString(arr []byte) string {
function deleteEbpfEntry (line 60) | func deleteEbpfEntry(proto string, key []byte) bool {
function getItems (line 68) | func getItems(proto string, isIPv6 bool) (items uint) {
function deleteOldItems (line 100) | func deleteOldItems(proto string, isIPv6 bool, maxToDelete uint) (delete...
FILE: daemon/procmon/find.go
function sortPidsByTime (line 11) | func sortPidsByTime(fdList []os.FileInfo) []os.FileInfo {
function inodeFound (line 25) | func inodeFound(pidsPath, expect, inodeKey string, inode, pid int) bool {
function lookupPidInProc (line 48) | func lookupPidInProc(pidsPath, expect, inodeKey string, inode int) int {
function lookupPidDescriptors (line 61) | func lookupPidDescriptors(fdPath string, pid int) []string {
function getProcPids (line 87) | func getProcPids(pidsPath string) []int {
FILE: daemon/procmon/find_test.go
function TestGetProcPids (line 8) | func TestGetProcPids(t *testing.T) {
function TestLookupPidDescriptors (line 16) | func TestLookupPidDescriptors(t *testing.T) {
function TestLookupPidInProc (line 23) | func TestLookupPidInProc(t *testing.T) {
function BenchmarkGetProcs (line 32) | func BenchmarkGetProcs(b *testing.B) {
function BenchmarkLookupPidDescriptors (line 38) | func BenchmarkLookupPidDescriptors(b *testing.B) {
FILE: daemon/procmon/monitor/init.go
constant NoError (line 21) | NoError = iota
constant ProcFsErr (line 22) | ProcFsErr
constant AuditdErr (line 23) | AuditdErr
constant EbpfErr (line 24) | EbpfErr
constant EbpfEventsErr (line 25) | EbpfEventsErr
type Error (line 29) | type Error struct
function startProcMonitors (line 34) | func startProcMonitors() {
function stopProcMonitors (line 45) | func stopProcMonitors() {
function ReconfigureMonitorMethod (line 53) | func ReconfigureMonitorMethod(newMonitorMethod string, ebpfCfg ebpf.Conf...
function End (line 74) | func End() {
function Init (line 85) | func Init(ebpfCfg ebpf.Config, auditCfg audit.Config) (errm *Error) {
FILE: daemon/procmon/parse.go
function getPIDFromAuditEvents (line 13) | func getPIDFromAuditEvents(inode int, inodeKey string, expect string) (i...
function GetInodeFromNetstat (line 34) | func GetInodeFromNetstat(netEntry *netstat.Entry, inodeList *[]int, prot...
function GetPIDFromINode (line 57) | func GetPIDFromINode(inode int, inodeKey string) int {
function FindProcess (line 95) | func FindProcess(pid int, interceptUnknown bool) *Process {
FILE: daemon/procmon/process.go
constant MethodProc (line 21) | MethodProc = "proc"
constant MethodAudit (line 22) | MethodAudit = "audit"
constant MethodEbpf (line 23) | MethodEbpf = "ebpf"
constant KernelConnection (line 25) | KernelConnection = "Kernel connection"
constant ProcPrefix (line 26) | ProcPrefix = "/proc"
constant ProcSelf (line 27) | ProcSelf = "/proc/self/"
constant ProcSelfExe (line 28) | ProcSelfExe = "/proc/self/exe"
constant HashMD5 (line 30) | HashMD5 = "process.hash.md5"
constant HashSHA1 (line 31) | HashSHA1 = "process.hash.sha1"
type procIOstats (line 35) | type procIOstats struct
type procNetStats (line 44) | type procNetStats struct
type procDescriptors (line 49) | type procDescriptors struct
type procStatm (line 56) | type procStatm struct
type Process (line 67) | type Process struct
method Lock (line 185) | func (p *Process) Lock() {
method Unlock (line 190) | func (p *Process) Unlock() {
method RLock (line 195) | func (p *Process) RLock() {
method RUnlock (line 200) | func (p *Process) RUnlock() {
method Serialize (line 205) | func (p *Process) Serialize() *protocol.Process {
function NewProcessEmpty (line 125) | func NewProcessEmpty(pid int, comm string) *Process {
function NewProcess (line 159) | func NewProcess(pid int, comm string) *Process {
function NewProcessWithParent (line 172) | func NewProcessWithParent(pid, ppid int, comm string) *Process {
function SetMonitorMethod (line 234) | func SetMonitorMethod(newMonitorMethod string) {
function GetMonitorMethod (line 242) | func GetMonitorMethod() string {
function MethodIsEbpf (line 250) | func MethodIsEbpf() bool {
function MethodIsAudit (line 258) | func MethodIsAudit() bool {
function MethodIsProc (line 265) | func MethodIsProc() bool {
FILE: daemon/procmon/process_test.go
function TestNewProcess (line 17) | func TestNewProcess(t *testing.T) {
function TestProcPath (line 26) | func TestProcPath(t *testing.T) {
function TestProcCwd (line 35) | func TestProcCwd(t *testing.T) {
function TestProcCmdline (line 43) | func TestProcCmdline(t *testing.T) {
function TestProcDescriptors (line 51) | func TestProcDescriptors(t *testing.T) {
function TestProcEnv (line 59) | func TestProcEnv(t *testing.T) {
function TestProcIOStats (line 87) | func TestProcIOStats(t *testing.T) {
function TestProcStatus (line 95) | func TestProcStatus(t *testing.T) {
function TestProcCleanPath (line 133) | func TestProcCleanPath(t *testing.T) {
function TestProcCleanArgs (line 163) | func TestProcCleanArgs(t *testing.T) {
function BenchmarkProcReadEnv (line 175) | func BenchmarkProcReadEnv(b *testing.B) {
FILE: daemon/rule/loader.go
type Loader (line 25) | type Loader struct
method NumRules (line 56) | func (l *Loader) NumRules() int {
method GetAll (line 63) | func (l *Loader) GetAll() map[string]*Rule {
method EnableChecksums (line 70) | func (l *Loader) EnableChecksums(enable bool) {
method HasChecksums (line 78) | func (l *Loader) HasChecksums(op Operand) {
method Reload (line 90) | func (l *Loader) Reload(path string) error {
method Load (line 121) | func (l *Loader) Load(path string) error {
method Add (line 159) | func (l *Loader) Add(rule *Rule, saveToDisk bool) error {
method Replace (line 169) | func (l *Loader) Replace(rule *Rule, saveToDisk bool) error {
method Save (line 184) | func (l *Loader) Save(rule *Rule, path string) error {
method Delete (line 202) | func (l *Loader) Delete(ruleName string) error {
method loadRule (line 223) | func (l *Loader) loadRule(fileName string) error {
method deleteRule (line 280) | func (l *Loader) deleteRule(filePath string) {
method deleteRuleFromDisk (line 293) | func (l *Loader) deleteRuleFromDisk(ruleName string) error {
method deleteOldRuleFromDisk (line 300) | func (l *Loader) deleteOldRuleFromDisk(oldRule, newRule *Rule) {
method cleanListsRule (line 310) | func (l *Loader) cleanListsRule(oldRule *Rule) {
method isTemporary (line 323) | func (l *Loader) isTemporary(r *Rule) bool {
method isUniqueName (line 327) | func (l *Loader) isUniqueName(name string) bool {
method setUniqueName (line 332) | func (l *Loader) setUniqueName(rule *Rule) {
method setLiveReloadRunning (line 344) | func (l *Loader) setLiveReloadRunning(running bool) {
method isLiveReloadRunning (line 350) | func (l *Loader) isLiveReloadRunning() bool {
method unmarshalOperatorList (line 357) | func (l *Loader) unmarshalOperatorList(op *Operator) error {
method sortRules (line 368) | func (l *Loader) sortRules() {
method addUserRule (line 380) | func (l *Loader) addUserRule(rule *Rule) {
method replaceUserRule (line 389) | func (l *Loader) replaceUserRule(rule *Rule) (err error) {
method scheduleTemporaryRule (line 434) | func (l *Loader) scheduleTemporaryRule(rule Rule) error {
method liveReloadWorker (line 457) | func (l *Loader) liveReloadWorker() {
method FindFirstMatch (line 497) | func (l *Loader) FindFirstMatch(con *conman.Connection) (match *Rule) {
function NewLoader (line 40) | func NewLoader(liveReload bool) (*Loader, error) {
FILE: daemon/rule/loader_test.go
function TestMain (line 14) | func TestMain(m *testing.M) {
function TestRuleLoader (line 21) | func TestRuleLoader(t *testing.T) {
function TestRuleLoaderInvalidRegexp (line 66) | func TestRuleLoaderInvalidRegexp(t *testing.T) {
function TestRuleLoaderList (line 109) | func TestRuleLoaderList(t *testing.T) {
function TestLiveReload (line 150) | func TestLiveReload(t *testing.T) {
function randString (line 188) | func randString() string {
function Copy (line 198) | func Copy(src, dst string) error {
function testNumRules (line 218) | func testNumRules(t *testing.T, l *Loader, num int) {
function testRulesOrder (line 224) | func testRulesOrder(t *testing.T, l *Loader) {
function testSortRules (line 236) | func testSortRules(t *testing.T, l *Loader) {
function testFindMatch (line 248) | func testFindMatch(t *testing.T, l *Loader) {
function testFindPriorityMatch (line 258) | func testFindPriorityMatch(t *testing.T, l *Loader) {
function testFindDenyMatch (line 270) | func testFindDenyMatch(t *testing.T, l *Loader) {
function testFindAllowMatch (line 283) | func testFindAllowMatch(t *testing.T, l *Loader) {
function testFindEnabled (line 297) | func testFindEnabled(t *testing.T, l *Loader) {
function testDurationChange (line 314) | func testDurationChange(t *testing.T, l *Loader) {
FILE: daemon/rule/operator.go
type Type (line 20) | type Type
type Sensitive (line 23) | type Sensitive
type Operand (line 26) | type Operand
constant Simple (line 30) | Simple = Type("simple")
constant Regexp (line 31) | Regexp = Type("regexp")
constant Complex (line 32) | Complex = Type("complex")
constant List (line 33) | List = Type("list")
constant Network (line 34) | Network = Type("network")
constant Lists (line 35) | Lists = Type("lists")
constant Range (line 36) | Range = Type("range")
constant OpTrue (line 41) | OpTrue = Operand("true")
constant OpProcessID (line 42) | OpProcessID = Operand("process.id")
constant OpProcessPath (line 43) | OpProcessPath = Operand("process.path")
constant OpProcessParentPath (line 44) | OpProcessParentPath = Operand("process.parent.path")
constant OpProcessCmd (line 45) | OpProcessCmd = Operand("process.command")
constant OpProcessEnvPrefix (line 46) | OpProcessEnvPrefix = Operand("process.env.")
constant OpProcessEnvPrefixLen (line 47) | OpProcessEnvPrefixLen = 12
constant OpProcessHashMD5 (line 48) | OpProcessHashMD5 = Operand("process.hash.md5")
constant OpProcessHashSHA1 (line 49) | OpProcessHashSHA1 = Operand("process.hash.sha1")
constant OpUserID (line 50) | OpUserID = Operand("user.id")
constant OpUserName (line 51) | OpUserName = Operand("user.name")
constant OpSrcIP (line 52) | OpSrcIP = Operand("source.ip")
constant OpSrcPort (line 53) | OpSrcPort = Operand("source.port")
constant OpDstIP (line 54) | OpDstIP = Operand("dest.ip")
constant OpDstHost (line 55) | OpDstHost = Operand("dest.host")
constant OpDstPort (line 56) | OpDstPort = Operand("dest.port")
constant OpDstNetwork (line 57) | OpDstNetwork = Operand("dest.network")
constant OpSrcNetwork (line 58) | OpSrcNetwork = Operand("source.network")
constant OpProto (line 59) | OpProto = Operand("protocol")
constant OpIfaceIn (line 60) | OpIfaceIn = Operand("iface.in")
constant OpIfaceOut (line 61) | OpIfaceOut = Operand("iface.out")
constant OpList (line 62) | OpList = Operand("list")
constant OpDomainsLists (line 63) | OpDomainsLists = Operand("lists.domains")
constant OpDomainsRegexpLists (line 64) | OpDomainsRegexpLists = Operand("lists.domains_regexp")
constant OpIPLists (line 65) | OpIPLists = Operand("lists.ips")
constant OpNetLists (line 66) | OpNetLists = Operand("lists.nets")
constant OpHashMD5Lists (line 67) | OpHashMD5Lists = Operand("lists.hash.md5")
type opCallback (line 75) | type opCallback
type opGenericCallback (line 76) | type opGenericCallback
type Operator (line 79) | type Operator struct
method Compile (line 113) | func (o *Operator) Compile() error {
method compileNetwork (line 202) | func (o *Operator) compileNetwork() error {
method compileRange (line 230) | func (o *Operator) compileRange() error {
method String (line 256) | func (o *Operator) String() string {
method simpleCmp (line 264) | func (o *Operator) simpleCmp(v string) bool {
method reCmp (line 271) | func (o *Operator) reCmp(data string) bool {
method rangeCmp (line 278) | func (o *Operator) rangeCmp(value string) bool {
method cmpNetwork (line 283) | func (o *Operator) cmpNetwork(destIP interface{}) bool {
method matchListsCmp (line 292) | func (o *Operator) matchListsCmp(msg, what string) bool {
method domainsListsCmp (line 304) | func (o *Operator) domainsListsCmp(data string) bool {
method simpleListsCmp (line 315) | func (o *Operator) simpleListsCmp(what string) bool {
method ipNetCmp (line 323) | func (o *Operator) ipNetCmp(dstIP interface{}) bool {
method reListCmp (line 337) | func (o *Operator) reListCmp(data string) bool {
method hashCmp (line 357) | func (o *Operator) hashCmp(hash string) bool {
method listMatch (line 364) | func (o *Operator) listMatch(con *conman.Connection, hasChecksums bool...
method Match (line 373) | func (o *Operator) Match(con *conman.Connection, hasChecksums bool) bo...
function NewOperator (line 101) | func NewOperator(t Type, s Sensitive, o Operand, data string, list []Ope...
FILE: daemon/rule/operator_aliases.go
function LoadAliases (line 12) | func LoadAliases(filename string) error {
function GetAliasByIP (line 41) | func GetAliasByIP(ip string) string {
method SerializeData (line 55) | func (o *Operator) SerializeData() string {
FILE: daemon/rule/operator_lists.go
method monitorLists (line 17) | func (o *Operator) monitorLists() {
method ClearLists (line 87) | func (o *Operator) ClearLists() {
method StopMonitoringLists (line 99) | func (o *Operator) StopMonitoringLists() {
function filterDomains (line 107) | func filterDomains(line, defValue string) (bool, string, string) {
function filterSimple (line 127) | func filterSimple(line, hashPath string) (bool, string, string) {
method readTupleList (line 133) | func (o *Operator) readTupleList(raw, fileName string, filter func(line,...
method readNetList (line 154) | func (o *Operator) readNetList(raw, fileName string) (dups uint64) {
method readRegexpList (line 179) | func (o *Operator) readRegexpList(raw, fileName string) (dups uint64) {
method readSimpleList (line 207) | func (o *Operator) readSimpleList(raw, fileName string) (dups uint64) {
method readLists (line 227) | func (o *Operator) readLists() error {
method loadLists (line 274) | func (o *Operator) loadLists() {
FILE: daemon/rule/operator_test.go
function compileListOperators (line 46) | func compileListOperators(list *[]Operator, t *testing.T) {
function unmarshalListData (line 55) | func unmarshalListData(data string, t *testing.T) (op *[]Operator) {
function restoreConnection (line 63) | func restoreConnection() {
function TestNewOperatorSimple (line 70) | func TestNewOperatorSimple(t *testing.T) {
function TestNewOperatorNetwork (line 228) | func TestNewOperatorNetwork(t *testing.T) {
function TestNewOperatorRegexp (line 261) | func TestNewOperatorRegexp(t *testing.T) {
function TestNewOperatorInvalidRegexp (line 281) | func TestNewOperatorInvalidRegexp(t *testing.T) {
function TestNewOperatorRegexpSensitive (line 298) | func TestNewOperatorRegexpSensitive(t *testing.T) {
function TestNewOperatorList (line 344) | func TestNewOperatorList(t *testing.T) {
function TestNewOperatorListsSimple (line 431) | func TestNewOperatorListsSimple(t *testing.T) {
function TestNewOperatorListsIPs (line 465) | func TestNewOperatorListsIPs(t *testing.T) {
function TestNewOperatorListsNETs (line 519) | func TestNewOperatorListsNETs(t *testing.T) {
function TestNewOperatorListsComplex (line 573) | func TestNewOperatorListsComplex(t *testing.T) {
function TestNewOperatorListsDomainsRegexp (line 617) | func TestNewOperatorListsDomainsRegexp(t *testing.T) {
function TestRaceNewOperatorListsDomainsRegexp (line 674) | func TestRaceNewOperatorListsDomainsRegexp(t *testing.T) {
function TestNewOperatorRegexpBareIpNoHostName (line 748) | func TestNewOperatorRegexpBareIpNoHostName(t *testing.T) {
function TestNewOperatorSimpleBareIpNoHostName (line 770) | func TestNewOperatorSimpleBareIpNoHostName(t *testing.T) {
function TestNewOperatorRange (line 792) | func TestNewOperatorRange(t *testing.T) {
FILE: daemon/rule/rule.go
constant DefaultPath (line 14) | DefaultPath = "/etc/opensnitchd/rules"
type Action (line 18) | type Action
constant Allow (line 22) | Allow = Action("allow")
constant Deny (line 23) | Deny = Action("deny")
constant Reject (line 24) | Reject = Action("reject")
type Duration (line 28) | type Duration
constant Once (line 32) | Once = Duration("once")
constant Restart (line 33) | Restart = Duration("until restart")
constant Always (line 34) | Always = Duration("always")
type Rule (line 40) | type Rule struct
method String (line 70) | func (r *Rule) String() string {
method Match (line 80) | func (r *Rule) Match(con *conman.Connection, hasChecksums bool) bool {
method Serialize (line 133) | func (r *Rule) Serialize() *protocol.Rule {
function Create (line 56) | func Create(name, description string, enabled, precedence, nolog bool, a...
function Deserialize (line 85) | func Deserialize(reply *protocol.Rule) (*Rule, error) {
FILE: daemon/rule/rule_test.go
function TestCreate (line 7) | func TestCreate(t *testing.T) {
function TestRuleSerializers (line 51) | func TestRuleSerializers(t *testing.T) {
FILE: daemon/statistics/event.go
type Event (line 11) | type Event struct
method Serialize (line 25) | func (e *Event) Serialize() *protocol.Event {
function NewEvent (line 17) | func NewEvent(con *conman.Connection, match *rule.Rule) *Event {
FILE: daemon/statistics/stats.go
type StatsConfig (line 18) | type StatsConfig struct
type conEvent (line 24) | type conEvent struct
type Statistics (line 32) | type Statistics struct
method SetLoggers (line 91) | func (s *Statistics) SetLoggers(loggermgr *loggers.LoggerManager) {
method SetLimits (line 100) | func (s *Statistics) SetLimits(config StatsConfig) {
method OnConnectionEvent (line 122) | func (s *Statistics) OnConnectionEvent(con *conman.Connection, match *...
method OnDNSResponse (line 139) | func (s *Statistics) OnDNSResponse() {
method OnIgnored (line 147) | func (s *Statistics) OnIgnored() {
method incMap (line 154) | func (s *Statistics) incMap(m *map[string]uint64, key string) {
method eventWorker (line 180) | func (s *Statistics) eventWorker(id int, done <-chan struct{}) {
method onConnection (line 195) | func (s *Statistics) onConnection(con *conman.Connection, match *rule....
method serializeEvents (line 236) | func (s *Statistics) serializeEvents() []*protocol.Event {
method emptyStats (line 249) | func (s *Statistics) emptyStats() {
method Serialize (line 261) | func (s *Statistics) Serialize() *protocol.Statistics {
function New (line 67) | func New(rules *rule.Loader) (stats *Statistics) {
FILE: daemon/tasks/base/main.go
constant PID_MON (line 8) | PID_MON = 9000
constant NODE_MON (line 9) | NODE_MON = 9001
constant SOCKETS_MON (line 10) | SOCKETS_MON = 9002
constant DOWNLOADER (line 11) | DOWNLOADER = 9003
constant NETSNIFFER (line 12) | NETSNIFFER = 9004
constant IOCS_SCANNER (line 13) | IOCS_SCANNER = 9005
constant REDFLAGS (line 14) | REDFLAGS = 9006
type TaskBase (line 19) | type TaskBase struct
method SetID (line 44) | func (t *TaskBase) SetID(id uint64) {
method GetID (line 48) | func (t *TaskBase) GetID() uint64 {
method IsTemporary (line 52) | func (t *TaskBase) IsTemporary() bool {
type TaskResults (line 56) | type TaskResults struct
type Task (line 62) | type Task interface
type TaskNotification (line 90) | type TaskNotification struct
FILE: daemon/tasks/config/main.go
type TaskData (line 29) | type TaskData struct
type TaskConfig (line 42) | type TaskConfig struct
type TasksList (line 61) | type TasksList struct
type Loader (line 65) | type Loader struct
method Load (line 91) | func (l *Loader) Load(path string) ([]TaskConfig, error) {
function NewTasksLoader (line 78) | func NewTasksLoader() (*Loader, error) {
FILE: daemon/tasks/config/monitor.go
method AddWatch (line 12) | func (l *Loader) AddWatch(path string) error {
method RemoveWatch (line 18) | func (l *Loader) RemoveWatch(path string) error {
method AddWatches (line 24) | func (l *Loader) AddWatches() {
method setLiveReloadRunning (line 45) | func (l *Loader) setLiveReloadRunning(running bool) {
method isLiveReloadRunning (line 51) | func (l *Loader) isLiveReloadRunning() bool {
method liveReloadWorker (line 57) | func (l *Loader) liveReloadWorker() {
FILE: daemon/tasks/config/utils.go
function LoadTaskData (line 11) | func LoadTaskData(path string) (TaskData, error) {
FILE: daemon/tasks/downloader/config.go
type NotifyType (line 11) | type NotifyType
type NotifyObj (line 18) | type NotifyObj
type NotifyStatus (line 20) | type NotifyStatus struct
type NotifyOpts (line 25) | type NotifyOpts struct
type UrlOptions (line 31) | type UrlOptions struct
type DownloaderConfig (line 38) | type DownloaderConfig struct
function loadConfig (line 46) | func loadConfig(data map[string]interface{}) (DownloaderConfig, error) {
FILE: daemon/tasks/downloader/downloader.go
type DownProgress (line 21) | type DownProgress struct
type DownMgr (line 28) | type DownMgr struct
method Start (line 49) | func (nd *DownMgr) Start() *sync.WaitGroup {
method downloadFile (line 59) | func (nd *DownMgr) downloadFile(wg *sync.WaitGroup, url, localFile str...
method Progress (line 102) | func (nd *DownMgr) Progress() <-chan DownProgress {
function NewDownloaderMgr (line 40) | func NewDownloaderMgr(urls map[string]string, timeout time.Duration) *Do...
FILE: daemon/tasks/downloader/main.go
type Downloader (line 31) | type Downloader struct
method Start (line 63) | func (pm *Downloader) Start(ctx context.Context, cancel context.Cancel...
method GetName (line 151) | func (pm *Downloader) GetName() string {
method Pause (line 157) | func (pm *Downloader) Pause() error {
method Resume (line 162) | func (pm *Downloader) Resume() error {
method Stop (line 167) | func (pm *Downloader) Stop() error {
method Results (line 186) | func (pm *Downloader) Results() <-chan interface{} {
method Errors (line 191) | func (pm *Downloader) Errors() <-chan error {
function New (line 41) | func New(config map[string]interface{}, stopOnDisconnect bool) *Download...
FILE: daemon/tasks/downloader/utils.go
method parseInterval (line 16) | func (pm *Downloader) parseInterval() (time.Duration, error) {
method parseTimeout (line 23) | func (pm *Downloader) parseTimeout() (time.Duration, error) {
method loadUrls (line 42) | func (pm *Downloader) loadUrls() error {
FILE: daemon/tasks/iocscanner/config/config.go
type NotifyType (line 13) | type NotifyType
type ActionType (line 14) | type ActionType
type ActionData (line 15) | type ActionData
type ReportType (line 17) | type ReportType
type NotifyStatus (line 30) | type NotifyStatus struct
type NotifyOpts (line 35) | type NotifyOpts struct
type ActionsOpts (line 41) | type ActionsOpts struct
type List (line 46) | type List struct
type ExclusionsOpts (line 50) | type ExclusionsOpts struct
type ReportOpts (line 56) | type ReportOpts struct
type ScanOpts (line 90) | type ScanOpts struct
type ToolOpts (line 140) | type ToolOpts struct
type IOCConfig (line 189) | type IOCConfig struct
function LoadConfig (line 197) | func LoadConfig(data map[string]interface{}) (IOCConfig, error) {
FILE: daemon/tasks/iocscanner/main.go
type Config (line 33) | type Config struct
type IOCScanner (line 38) | type IOCScanner struct
method Start (line 82) | func (pm *IOCScanner) Start(ctx context.Context, cancel context.Cancel...
method GetName (line 154) | func (pm *IOCScanner) GetName() string {
method Pause (line 160) | func (pm *IOCScanner) Pause() error {
method Resume (line 166) | func (pm *IOCScanner) Resume() error {
method Stop (line 172) | func (pm *IOCScanner) Stop() error {
method Results (line 194) | func (pm *IOCScanner) Results() <-chan interface{} {
method Errors (line 199) | func (pm *IOCScanner) Errors() <-chan error {
function New (line 51) | func New(name string, taskcfg map[string]interface{}, stopOnDisconnect b...
FILE: daemon/tasks/iocscanner/run_tools.go
method runTool (line 18) | func (pm *IOCScanner) runTool(tool base.Tool) {
FILE: daemon/tasks/iocscanner/tools/base/base.go
constant MsgStart (line 14) | MsgStart = "IOC scanner started"
constant MsgEnd (line 15) | MsgEnd = "IOC scanner finished"
constant PropName (line 17) | PropName = "name"
constant PropMsgStart (line 18) | PropMsgStart = "msgstart"
constant PropMsgEnd (line 19) | PropMsgEnd = "msgend"
type ToolBase (line 22) | type ToolBase struct
method GetProperty (line 35) | func (t *ToolBase) GetProperty(prop string) string {
method Log (line 47) | func (t *ToolBase) Log(line string) {
method TransformLogline (line 50) | func (t *ToolBase) TransformLogline(line string) string {
method Done (line 54) | func (t *ToolBase) Done() <-chan struct{} {
method Stdout (line 58) | func (t *ToolBase) Stdout() chan string {
method Stderr (line 62) | func (t *ToolBase) Stderr() chan string {
method Cleanup (line 66) | func (t *ToolBase) Cleanup() {}
method Workers (line 68) | func (t *ToolBase) Workers() int {
method SetWorkers (line 72) | func (t *ToolBase) SetWorkers(wrks int) {
type Tool (line 79) | type Tool interface
FILE: daemon/tasks/iocscanner/tools/dpkg/dpkg.go
constant PrefixDpkg (line 30) | PrefixDpkg = "dpkg"
constant PrefixDebsums (line 31) | PrefixDebsums = "debsums"
type DpkgTool (line 34) | type DpkgTool struct
method Log (line 38) | func (d *DpkgTool) Log(line string) {
method Start (line 46) | func (d *DpkgTool) Start() {
method TransformLogline (line 52) | func (d *DpkgTool) TransformLogline(line string) string {
method Cleanup (line 95) | func (d *DpkgTool) Cleanup() {
method Stop (line 101) | func (d *DpkgTool) Stop() {
function New (line 108) | func New(opts config.ToolOpts) *DpkgTool {
FILE: daemon/tasks/iocscanner/tools/executer/executer.go
type Executer (line 18) | type Executer struct
method Start (line 41) | func (e *Executer) Start(bin string, args []string) {
method SetPriority (line 94) | func (e *Executer) SetPriority(prio int) {
method setRunning (line 98) | func (e *Executer) setRunning(running bool) {
method Running (line 104) | func (e *Executer) Running() bool {
method Stop (line 110) | func (e *Executer) Stop() {
function New (line 31) | func New() *Executer {
FILE: daemon/tasks/iocscanner/tools/generic/generic.go
constant Prefix (line 32) | Prefix = "script"
type GenericTool (line 35) | type GenericTool struct
method Log (line 39) | func (d *GenericTool) Log(line string) {
method Start (line 47) | func (d *GenericTool) Start() {
method TransformLogline (line 53) | func (d *GenericTool) TransformLogline(line string) string {
method Cleanup (line 68) | func (d *GenericTool) Cleanup() {
method Stop (line 74) | func (d *GenericTool) Stop() {
function New (line 81) | func New(opts config.ToolOpts) *GenericTool {
FILE: daemon/tasks/iocscanner/tools/yara/yara.go
constant Prefix (line 30) | Prefix = "yara"
type YaraTool (line 39) | type YaraTool struct
method Start (line 45) | func (y *YaraTool) Start() {
method Log (line 50) | func (y *YaraTool) Log(line string) {
method TransformLogline (line 58) | func (y *YaraTool) TransformLogline(line string) string {
method Cleanup (line 63) | func (y *YaraTool) Cleanup() {
method Stop (line 76) | func (y *YaraTool) Stop() {
function New (line 83) | func New(opts config.ToolOpts) *YaraTool {
FILE: daemon/tasks/load.go
method ReloadTaskFile (line 14) | func (tm *TaskManager) ReloadTaskFile(cfgfile string) error {
method LoadTaskFile (line 29) | func (tm *TaskManager) LoadTaskFile(cfgfile string) error {
method loadDiskTasks (line 80) | func (tm *TaskManager) loadDiskTasks(tasks []config.TaskConfig) {
method loadDiskTask (line 109) | func (tm *TaskManager) loadDiskTask(name string, taskConf config.TaskDat...
FILE: daemon/tasks/looptask/main.go
type Config (line 22) | type Config struct
type Looper (line 27) | type Looper struct
method Start (line 49) | func (fm *Looper) Start(ctx context.Context, cancel context.CancelFunc...
method Pause (line 84) | func (fm *Looper) Pause() error {
method Resume (line 90) | func (fm *Looper) Resume() error {
method Stop (line 96) | func (fm *Looper) Stop() error {
method Results (line 113) | func (fm *Looper) Results() <-chan interface{} {
method Errors (line 118) | func (fm *Looper) Errors() <-chan error {
method GetName (line 122) | func (fm *Looper) GetName() string {
function New (line 35) | func New(name, interval string) (string, *Looper) {
FILE: daemon/tasks/main.go
type EventTask (line 17) | type EventTask struct
type TaskManager (line 25) | type TaskManager struct
method AddTask (line 55) | func (tm *TaskManager) AddTask(name string, task base.Task) (context.C...
method RemoveTask (line 96) | func (tm *TaskManager) RemoveTask(name string) error {
method PauseAll (line 120) | func (tm *TaskManager) PauseAll() {
method ResumeAll (line 128) | func (tm *TaskManager) ResumeAll() {
method StopAll (line 136) | func (tm *TaskManager) StopAll() {
method StopTempTasks (line 149) | func (tm *TaskManager) StopTempTasks() {
method GetTask (line 162) | func (tm *TaskManager) GetTask(name string) (tk base.Task, found bool) {
method UpdateTask (line 170) | func (tm *TaskManager) UpdateTask(name string, task base.Task) (contex...
method Stop (line 184) | func (tm *TaskManager) Stop() {
function NewTaskManager (line 37) | func NewTaskManager() *TaskManager {
FILE: daemon/tasks/main_test.go
type BasicTask (line 10) | type BasicTask struct
method Start (line 14) | func (pm *BasicTask) Start(ctx context.Context, cancel context.CancelF...
method Pause (line 17) | func (pm *BasicTask) Pause() error {
method Resume (line 20) | func (pm *BasicTask) Resume() error {
method Stop (line 23) | func (pm *BasicTask) Stop() error {
method Errors (line 26) | func (pm *BasicTask) Errors() <-chan error {
method Results (line 29) | func (pm *BasicTask) Results() <-chan interface{} {
function taskEvents (line 41) | func taskEvents(tm *TaskManager, t *testing.T) {
function TestTaskManager (line 52) | func TestTaskManager(t *testing.T) {
FILE: daemon/tasks/nodemonitor/main.go
type Config (line 20) | type Config struct
type NodeMonitor (line 26) | type NodeMonitor struct
method Start (line 51) | func (pm *NodeMonitor) Start(ctx context.Context, cancel context.Cance...
method Pause (line 99) | func (pm *NodeMonitor) Pause() error {
method Resume (line 105) | func (pm *NodeMonitor) Resume() error {
method Stop (line 111) | func (pm *NodeMonitor) Stop() error {
method Results (line 126) | func (pm *NodeMonitor) Results() <-chan interface{} {
method Errors (line 131) | func (pm *NodeMonitor) Errors() <-chan error {
function New (line 36) | func New(node, interval string, stopOnDisconnect bool) (string, *NodeMon...
FILE: daemon/tasks/nodemonitor/main_test.go
function taskEvents (line 15) | func taskEvents(tm *tasks.TaskManager, t *testing.T) {
function TestNodeMonitor (line 26) | func TestNodeMonitor(t *testing.T) {
FILE: daemon/tasks/pidmonitor/main.go
type Config (line 21) | type Config struct
type PIDMonitor (line 27) | type PIDMonitor struct
method Start (line 50) | func (pm *PIDMonitor) Start(ctx context.Context, cancel context.Cancel...
method Pause (line 107) | func (pm *PIDMonitor) Pause() error {
method Resume (line 113) | func (pm *PIDMonitor) Resume() error {
method Stop (line 119) | func (pm *PIDMonitor) Stop() error {
method Results (line 134) | func (pm *PIDMonitor) Results() <-chan interface{} {
method Errors (line 139) | func (pm *PIDMonitor) Errors() <-chan error {
function New (line 36) | func New(pid int, interval string, stopOnDisconnect bool) (string, *PIDM...
FILE: daemon/tasks/pidmonitor/main_test.go
function taskEvents (line 16) | func taskEvents(tm *tasks.TaskManager, t *testing.T) {
function TestPIDMonitor (line 27) | func TestPIDMonitor(t *testing.T) {
FILE: daemon/tasks/scheduler/daily.go
function timeHasDrifted (line 18) | func timeHasDrifted(now, tms *time.Time) bool {
function waitToStart (line 22) | func waitToStart(ctx context.Context, id int, t string, wait time.Durati...
function calcDailyTicker (line 46) | func calcDailyTicker(tm string) (*time.Time, time.Duration) {
function NewDailyTicker (line 77) | func NewDailyTicker(tm string) (*time.Ticker, *time.Time, time.Duration) {
method stopTimer (line 82) | func (s *Scheduler) stopTimer(id int, t *time.Ticker) {
method restartTimers (line 91) | func (s *Scheduler) restartTimers(drifted chan struct{}) {
method SetupDailyTimers (line 105) | func (s *Scheduler) SetupDailyTimers() {
FILE: daemon/tasks/scheduler/scheduler.go
type Config (line 15) | type Config struct
type Scheduler (line 39) | type Scheduler struct
method Start (line 65) | func (s *Scheduler) Start() {
method Stop (line 155) | func (s *Scheduler) Stop() {
method Tick (line 171) | func (s *Scheduler) Tick() <-chan time.Time {
function New (line 51) | func New(ctx context.Context, cancel context.CancelFunc, config Config) ...
FILE: daemon/tasks/socketsmonitor/dump.go
constant AnySocket (line 20) | AnySocket = 0
type Socket (line 25) | type Socket struct
type SocketsTable (line 34) | type SocketsTable struct
method dumpSockets (line 40) | func (pm *SocketsMonitor) dumpSockets() *SocketsTable {
function dumpXDPSockets (line 84) | func dumpXDPSockets(ctx context.Context, conf *monConfig, socketList *So...
function dumpPacketSockets (line 108) | func dumpPacketSockets(ctx context.Context, conf *monConfig, socketList ...
function exclude (line 167) | func exclude(expected, what uint8) bool {
function addSocketToTable (line 171) | func addSocketToTable(ctx context.Context, wg *sync.WaitGroup, proto uin...
FILE: daemon/tasks/socketsmonitor/main.go
type monConfig (line 20) | type monConfig struct
type SocketsMonitor (line 28) | type SocketsMonitor struct
method Start (line 81) | func (pm *SocketsMonitor) Start(ctx context.Context, cancel context.Ca...
method Pause (line 120) | func (pm *SocketsMonitor) Pause() error {
method Resume (line 126) | func (pm *SocketsMonitor) Resume() error {
method Stop (line 132) | func (pm *SocketsMonitor) Stop() error {
method Results (line 147) | func (pm *SocketsMonitor) Results() <-chan interface{} {
method Errors (line 152) | func (pm *SocketsMonitor) Errors() <-chan error {
function initConfig (line 42) | func initConfig(config interface{}) (*monConfig, error) {
function New (line 63) | func New(name string, config interface{}, stopOnDisconnect bool) (*Socke...
FILE: daemon/tasks/socketsmonitor/options.go
type Protos (line 10) | type Protos struct
FILE: daemon/ui/alerts.go
function NewWarningAlert (line 16) | func NewWarningAlert(what protocol.Alert_What, data interface{}) *protoc...
function NewErrorAlert (line 21) | func NewErrorAlert(what protocol.Alert_What, data interface{}) *protocol...
function NewAlert (line 26) | func NewAlert(atype protocol.Alert_Type, what protocol.Alert_What, actio...
method SendInfoAlert (line 59) | func (c *Client) SendInfoAlert(data interface{}) {
method SendWarningAlert (line 64) | func (c *Client) SendWarningAlert(data interface{}) {
method SendErrorAlert (line 69) | func (c *Client) SendErrorAlert(data interface{}) {
method alertsDispatcher (line 75) | func (c *Client) alertsDispatcher() {
method dispatchAlert (line 118) | func (c *Client) dispatchAlert(pbAlert protocol.Alert) {
FILE: daemon/ui/auth/auth.go
constant AuthSimple (line 28) | AuthSimple = "simple"
constant AuthTLSSimple (line 32) | AuthTLSSimple = "tls-simple"
constant AuthTLSMutual (line 36) | AuthTLSMutual = "tls-mutual"
function New (line 41) | func New(config *config.Config) (grpc.DialOption, error) {
FILE: daemon/ui/client.go
type Client (line 42) | type Client struct
method Connect (line 107) | func (c *Client) Connect() {
method Close (line 116) | func (c *Client) Close() {
method ProcMonitorMethod (line 123) | func (c *Client) ProcMonitorMethod() string {
method InterceptUnknown (line 130) | func (c *Client) InterceptUnknown() bool {
method GetFirewallType (line 137) | func (c *Client) GetFirewallType() string {
method DefaultAction (line 147) | func (c *Client) DefaultAction() rule.Action {
method DefaultDuration (line 162) | func (c *Client) DefaultDuration() rule.Duration {
method Connected (line 169) | func (c *Client) Connected() bool {
method GetIsAsking (line 179) | func (c *Client) GetIsAsking() bool {
method SetIsAsking (line 186) | func (c *Client) SetIsAsking(flag bool) {
method poller (line 192) | func (c *Client) poller() {
method onStatusChange (line 235) | func (c *Client) onStatusChange(connected bool) {
method connect (line 250) | func (c *Client) connect() (err error) {
method openSocket (line 275) | func (c *Client) openSocket() (err error) {
method disconnect (line 305) | func (c *Client) disconnect() {
method ping (line 321) | func (c *Client) ping(ts time.Time) (err error) {
method Ask (line 360) | func (c *Client) Ask(con *conman.Connection) *rule.Rule {
method PostAlert (line 382) | func (c *Client) PostAlert(atype protocol.Alert_Type, awhat protocol.A...
method monitorConfigWorker (line 394) | func (c *Client) monitorConfigWorker() {
function NewClient (line 70) | func NewClient(socketPath, localConfigFile string, stats *statistics.Sta...
FILE: daemon/ui/client_test.go
function restoreConfigFile (line 50) | func restoreConfigFile(t *testing.T) {
function validateConfig (line 62) | func validateConfig(t *testing.T, uiClient *Client, cfg *config.Config) {
function validateInvalidProcMonConfig (line 83) | func validateInvalidProcMonConfig(t *testing.T, uiClient *Client, cfg *c...
function TestClientDefaultConfig (line 106) | func TestClientDefaultConfig(t *testing.T) {
function TestClientReloadingConfig (line 125) | func TestClientReloadingConfig(t *testing.T) {
function TestClientInvalidProcMon (line 167) | func TestClientInvalidProcMon(t *testing.T) {
FILE: daemon/ui/config/config.go
type ServerTLSOptions (line 19) | type ServerTLSOptions struct
type ServerAuth (line 37) | type ServerAuth struct
type ServerConfig (line 44) | type ServerConfig struct
type RulesOptions (line 52) | type RulesOptions struct
type FwOptions (line 58) | type FwOptions struct
type TasksOptions (line 66) | type TasksOptions struct
type InternalOptions (line 71) | type InternalOptions struct
type Config (line 78) | type Config struct
function Parse (line 99) | func Parse(rawConfig interface{}) (conf Config, err error) {
function Marshal (line 108) | func Marshal(conf Config) ([]byte, error) {
function Load (line 113) | func Load(configFile string) ([]byte, error) {
function Save (line 123) | func Save(configFile, rawConfig string) (err error) {
FILE: daemon/ui/config_utils.go
method getSocketPath (line 19) | func (c *Client) getSocketPath(socketPath string) string {
method getCurrentSocketPath (line 38) | func (c *Client) getCurrentSocketPath() string {
method setSocketPath (line 45) | func (c *Client) setSocketPath(socketPath string) {
method isProcMonitorEqual (line 52) | func (c *Client) isProcMonitorEqual(newMonitorMethod string) bool {
method loadDiskConfiguration (line 59) | func (c *Client) loadDiskConfiguration(reload bool) {
method loadConfiguration (line 92) | func (c *Client) loadConfiguration(reload bool, rawConfig []byte) (errf ...
method reloadConfiguration (line 110) | func (c *Client) reloadConfiguration(reload bool, newConfig *config.Conf...
FILE: daemon/ui/notifications.go
function NewReply (line 27) | func NewReply(rID uint64, replyCode protocol.NotificationReplyCode, data...
method getClientConfig (line 35) | func (c *Client) getClientConfig() *protocol.ClientConfig {
method handleActionChangeConfig (line 63) | func (c *Client) handleActionChangeConfig(stream protocol.UI_Notificatio...
method handleActionEnableRule (line 87) | func (c *Client) handleActionEnableRule(stream protocol.UI_Notifications...
method handleActionDisableRule (line 100) | func (c *Client) handleActionDisableRule(stream protocol.UI_Notification...
method handleActionChangeRule (line 111) | func (c *Client) handleActionChangeRule(stream protocol.UI_Notifications...
method handleActionDeleteRule (line 128) | func (c *Client) handleActionDeleteRule(stream protocol.UI_Notifications...
method handleActionTaskStart (line 140) | func (c *Client) handleActionTaskStart(stream protocol.UI_NotificationsC...
method handleActionTaskStop (line 181) | func (c *Client) handleActionTaskStop(stream protocol.UI_NotificationsCl...
method handleActionEnableInterception (line 221) | func (c *Client) handleActionEnableInterception(stream protocol.UI_Notif...
method handleActionDisableInterception (line 236) | func (c *Client) handleActionDisableInterception(stream protocol.UI_Noti...
method handleActionReloadFw (line 247) | func (c *Client) handleActionReloadFw(stream protocol.UI_NotificationsCl...
method handleNotification (line 288) | func (c *Client) handleNotification(stream protocol.UI_NotificationsClie...
method sendNotificationReply (line 324) | func (c *Client) sendNotificationReply(stream protocol.UI_NotificationsC...
method Subscribe (line 345) | func (c *Client) Subscribe() {
method listenForNotifications (line 371) | func (c *Client) listenForNotifications() {
FILE: daemon/ui/notifications_tasks.go
method monitorTaskManager (line 18) | func (c *Client) monitorTaskManager(tm *tasks.TaskManager) {
method monitorTaskEvents (line 43) | func (c *Client) monitorTaskEvents(ctx context.Context, taskName string,...
method monitorSockets (line 90) | func (c *Client) monitorSockets(config interface{}, stream protocol.UI_N...
method monitorNode (line 104) | func (c *Client) monitorNode(node, interval string, stream protocol.UI_N...
method monitorProcessDetails (line 114) | func (c *Client) monitorProcessDetails(pid int, interval string, stream ...
FILE: ebpf_prog/bpf_headers/bpf_core_read.h
type bpf_field_info_kind (line 13) | enum bpf_field_info_kind {
type bpf_type_id_kind (line 23) | enum bpf_type_id_kind {
type bpf_type_info_kind (line 29) | enum bpf_type_info_kind {
type bpf_enum_value_kind (line 36) | enum bpf_enum_value_kind {
FILE: ebpf_prog/bpf_headers/bpf_helper_defs.h
type bpf_fib_lookup (line 4) | struct bpf_fib_lookup
type bpf_sk_lookup (line 5) | struct bpf_sk_lookup
type bpf_perf_event_data (line 6) | struct bpf_perf_event_data
type bpf_perf_event_value (line 7) | struct bpf_perf_event_value
type bpf_pidns_info (line 8) | struct bpf_pidns_info
type bpf_redir_neigh (line 9) | struct bpf_redir_neigh
type bpf_sock (line 10) | struct bpf_sock
type bpf_sock_addr (line 11) | struct bpf_sock_addr
type bpf_sock_ops (line 12) | struct bpf_sock_ops
type bpf_sock_tuple (line 13) | struct bpf_sock_tuple
type bpf_spin_lock (line 14) | struct bpf_spin_lock
type bpf_sysctl (line 15) | struct bpf_sysctl
type bpf_tcp_sock (line 16) | struct bpf_tcp_sock
type bpf_tunnel_key (line 17) | struct bpf_tunnel_key
type bpf_xfrm_state (line 18) | struct bpf_xfrm_state
type linux_binprm (line 19) | struct linux_binprm
type pt_regs (line 20) | struct pt_regs
type sk_reuseport_md (line 21) | struct sk_reuseport_md
type sockaddr (line 22) | struct sockaddr
type tcphdr (line 23) | struct tcphdr
type seq_file (line 24) | struct seq_file
type tcp6_sock (line 25) | struct tcp6_sock
type tcp_sock (line 26) | struct tcp_sock
type tcp_timewait_sock (line 27) | struct tcp_timewait_sock
type tcp_request_sock (line 28) | struct tcp_request_sock
type udp6_sock (line 29) | struct udp6_sock
type unix_sock (line 30) | struct unix_sock
type task_struct (line 31) | struct task_struct
type __sk_buff (line 32) | struct __sk_buff
type sk_msg_md (line 33) | struct sk_msg_md
type xdp_md (line 34) | struct xdp_md
type path (line 35) | struct path
type btf_ptr (line 36) | struct btf_ptr
type inode (line 37) | struct inode
type socket (line 38) | struct socket
type file (line 39) | struct file
type bpf_timer (line 40) | struct bpf_timer
type mptcp_sock (line 41) | struct mptcp_sock
type bpf_dynptr (line 42) | struct bpf_dynptr
type iphdr (line 43) | struct iphdr
type ipv6hdr (line 44) | struct ipv6hdr
type __sk_buff (line 226) | struct __sk_buff
type __sk_buff (line 255) | struct __sk_buff
type __sk_buff (line 291) | struct __sk_buff
type __sk_buff (line 354) | struct __sk_buff
type __sk_buff (line 423) | struct __sk_buff
type __sk_buff (line 443) | struct __sk_buff
type __sk_buff (line 459) | struct __sk_buff
type __sk_buff (line 514) | struct __sk_buff
type bpf_tunnel_key (line 514) | struct bpf_tunnel_key
type __sk_buff (line 555) | struct __sk_buff
type bpf_tunnel_key (line 555) | struct bpf_tunnel_key
type __sk_buff (line 643) | struct __sk_buff
type __sk_buff (line 812) | struct __sk_buff
type __sk_buff (line 826) | struct __sk_buff
type __sk_buff (line 857) | struct __sk_buff
type __sk_buff (line 888) | struct __sk_buff
type __sk_buff (line 903) | struct __sk_buff
type __sk_buff (line 923) | struct __sk_buff
type __sk_buff (line 1000) | struct __sk_buff
type __sk_buff (line 1041) | struct __sk_buff
type __sk_buff (line 1057) | struct __sk_buff
type __sk_buff (line 1071) | struct __sk_buff
type __sk_buff (line 1111) | struct __sk_buff
type xdp_md (line 1130) | struct xdp_md
type __sk_buff (line 1178) | struct __sk_buff
type __sk_buff (line 1189) | struct __sk_buff
type __sk_buff (line 1278) | struct __sk_buff
type __sk_buff (line 1322) | struct __sk_buff
type bpf_sock_ops (line 1345) | struct bpf_sock_ops
type xdp_md (line 1378) | struct xdp_md
type bpf_perf_event_value (line 1432) | struct bpf_perf_event_value
type bpf_perf_event_data (line 1447) | struct bpf_perf_event_data
type bpf_perf_event_value (line 1447) | struct bpf_perf_event_value
type pt_regs (line 1505) | struct pt_regs
type bpf_sock_ops (line 1553) | struct bpf_sock_ops
type sk_msg_md (line 1571) | struct sk_msg_md
type sk_msg_md (line 1609) | struct sk_msg_md
type sk_msg_md (line 1631) | struct sk_msg_md
type sk_msg_md (line 1666) | struct sk_msg_md
type bpf_sock_addr (line 1688) | struct bpf_sock_addr
type sockaddr (line 1688) | struct sockaddr
type xdp_md (line 1706) | struct xdp_md
type __sk_buff (line 1726) | struct __sk_buff
type bpf_xfrm_state (line 1726) | struct bpf_xfrm_state
type bpf_fib_lookup (line 1827) | struct bpf_fib_lookup
type bpf_sock_ops (line 1850) | struct bpf_sock_ops
type sk_msg_md (line 1868) | struct sk_msg_md
type __sk_buff (line 1886) | struct __sk_buff
type __sk_buff (line 1927) | struct __sk_buff
type __sk_buff (line 1946) | struct __sk_buff
type __sk_buff (line 1966) | struct __sk_buff
type __sk_buff (line 1999) | struct __sk_buff
type __sk_buff (line 2072) | struct __sk_buff
type sk_reuseport_md (line 2119) | struct sk_reuseport_md
type __sk_buff (line 2141) | struct __sk_buff
type bpf_sock (line 2182) | struct bpf_sock
type bpf_sock_tuple (line 2182) | struct bpf_sock_tuple
type bpf_sock (line 2223) | struct bpf_sock
type bpf_sock_tuple (line 2223) | struct bpf_sock_tuple
type sk_msg_md (line 2289) | struct sk_msg_md
type sk_msg_md (line 2305) | struct sk_msg_md
type bpf_spin_lock (line 2375) | struct bpf_spin_lock
type bpf_spin_lock (line 2386) | struct bpf_spin_lock
type bpf_sock (line 2398) | struct bpf_sock
type bpf_sock (line 2398) | struct bpf_sock
type bpf_tcp_sock (line 2410) | struct bpf_tcp_sock
type bpf_sock (line 2410) | struct bpf_sock
type __sk_buff (line 2424) | struct __sk_buff
type bpf_sock (line 2436) | struct bpf_sock
type bpf_sock (line 2436) | struct bpf_sock
type bpf_sock (line 2459) | struct bpf_sock
type bpf_sock_tuple (line 2459) | struct bpf_sock_tuple
type tcphdr (line 2479) | struct tcphdr
type bpf_sysctl (line 2499) | struct bpf_sysctl
type bpf_sysctl (line 2522) | struct bpf_sysctl
type bpf_sysctl (line 2543) | struct bpf_sysctl
type bpf_sysctl (line 2564) | struct bpf_sysctl
type tcphdr (line 2717) | struct tcphdr
type bpf_perf_event_data (line 2889) | struct bpf_perf_event_data
type bpf_pidns_info (line 2905) | struct bpf_pidns_info
type seq_file (line 3052) | struct seq_file
type seq_file (line 3066) | struct seq_file
type __sk_buff (line 3232) | struct __sk_buff
type tcp6_sock (line 3242) | struct tcp6_sock
type tcp_sock (line 3252) | struct tcp_sock
type tcp_timewait_sock (line 3262) | struct tcp_timewait_sock
type tcp_request_sock (line 3272) | struct tcp_request_sock
type udp6_sock (line 3282) | struct udp6_sock
type task_struct (line 3318) | struct task_struct
type bpf_sock_ops (line 3385) | struct bpf_sock_ops
type bpf_sock_ops (line 3422) | struct bpf_sock_ops
type bpf_sock_ops (line 3448) | struct bpf_sock_ops
type path (line 3508) | struct path
type btf_ptr (line 3559) | struct btf_ptr
type seq_file (line 3571) | struct seq_file
type btf_ptr (line 3571) | struct btf_ptr
type __sk_buff (line 3584) | struct __sk_buff
type bpf_redir_neigh (line 3609) | struct bpf_redir_neigh
type task_struct (line 3698) | struct task_struct
type task_struct (line 3710) | struct task_struct
type task_struct (line 3722) | struct task_struct
type linux_binprm (line 3736) | struct linux_binprm
type inode (line 3764) | struct inode
type socket (line 3776) | struct socket
type file (line 3776) | struct file
type bpf_timer (line 3963) | struct bpf_timer
type bpf_timer (line 3978) | struct bpf_timer
type bpf_timer (line 4008) | struct bpf_timer
type bpf_timer (line 4022) | struct bpf_timer
type task_struct (line 4061) | struct task_struct
type unix_sock (line 4110) | struct unix_sock
type task_struct (line 4152) | struct task_struct
type xdp_md (line 4265) | struct xdp_md
type xdp_md (line 4278) | struct xdp_md
type xdp_md (line 4289) | struct xdp_md
type task_struct (line 4303) | struct task_struct
type __sk_buff (line 4337) | struct __sk_buff
type file (line 4351) | struct file
type mptcp_sock (line 4388) | struct mptcp_sock
type bpf_dynptr (line 4403) | struct bpf_dynptr
type bpf_dynptr (line 4418) | struct bpf_dynptr
type bpf_dynptr (line 4433) | struct bpf_dynptr
type bpf_dynptr (line 4447) | struct bpf_dynptr
type bpf_dynptr (line 4461) | struct bpf_dynptr
type bpf_dynptr (line 4475) | struct bpf_dynptr
type bpf_dynptr (line 4490) | struct bpf_dynptr
type iphdr (line 4514) | struct iphdr
type tcphdr (line 4514) | struct tcphdr
type ipv6hdr (line 4540) | struct ipv6hdr
type tcphdr (line 4540) | struct tcphdr
type iphdr (line 4559) | struct iphdr
type tcphdr (line 4559) | struct tcphdr
type ipv6hdr (line 4580) | struct ipv6hdr
type tcphdr (line 4580) | struct tcphdr
FILE: ebpf_prog/bpf_headers/bpf_helpers.h
function __always_inline (line 135) | static __always_inline void
type bpf_map_defold (line 167) | struct bpf_map_defold {
type libbpf_pin_type (line 175) | enum libbpf_pin_type {
type libbpf_tristate (line 181) | enum libbpf_tristate {
FILE: ebpf_prog/bpf_headers/bpf_tracing.h
type pt_regs___s390 (line 135) | struct pt_regs___s390 {
type pt_regs___arm64 (line 169) | struct pt_regs___arm64 {
type pt_regs (line 285) | struct pt_regs
type pt_regs (line 461) | struct pt_regs
FILE: ebpf_prog/common.h
type events_type (line 29) | enum events_type {
type trace_ev_common (line 37) | struct trace_ev_common {
type trace_sys_enter_execve (line 44) | struct trace_sys_enter_execve {
type trace_sys_enter_execveat (line 53) | struct trace_sys_enter_execveat {
type trace_sys_exit_execve (line 63) | struct trace_sys_exit_execve {
type data_t (line 70) | struct data_t {
type data_t (line 91) | struct data_t
FILE: ebpf_prog/common_defs.h
type u64 (line 27) | typedef u64 pid_size_t;
type u64 (line 28) | typedef u64 uid_size_t;
type bpf_pin_type (line 30) | enum bpf_pin_type {
FILE: ebpf_prog/opensnitch-dns.c
type nameLookupEvent (line 40) | struct nameLookupEvent {
type hostent (line 46) | struct hostent {
type addrinfo (line 57) | struct addrinfo {
type addrinfo_args_cache (line 68) | struct addrinfo_args_cache {
type addrinfo_args_cache (line 76) | struct addrinfo_args_cache
function uretprobe__gethostbyname (line 95) | int uretprobe__gethostbyname(struct pt_regs *ctx) {
function uprobe__getaddrinfo (line 152) | int uprobe__getaddrinfo(struct pt_regs *ctx) {
function uretprobe__getaddrinfo (line 174) | int uretprobe__getaddrinfo(struct pt_regs *ctx) {
FILE: ebpf_prog/opensnitch-procs.c
type data_t (line 19) | struct data_t
function __always_inline (line 23) | static __always_inline void new_event(struct data_t* data)
function __always_inline (line 44) | static __always_inline void __handle_exit_execve(struct trace_sys_exit_e...
function tracepoint__sched_sched_process_exit (line 67) | int tracepoint__sched_sched_process_exit(struct pt_regs *ctx)
function tracepoint__syscalls_sys_exit_execve (line 90) | int tracepoint__syscalls_sys_exit_execve(struct trace_sys_exit_execve *ctx)
function tracepoint__syscalls_sys_exit_execveat (line 97) | int tracepoint__syscalls_sys_exit_execveat(struct trace_sys_exit_execve ...
function tracepoint__syscalls_sys_enter_execve (line 104) | int tracepoint__syscalls_sys_enter_execve(struct trace_sys_enter_execve*...
function tracepoint__syscalls_sys_enter_execveat (line 166) | int tracepoint__syscalls_sys_enter_execveat(struct trace_sys_enter_execv...
FILE: ebpf_prog/opensnitch.c
type tcp_key_t (line 9) | struct tcp_key_t {
type tcp_value_t (line 16) | struct tcp_value_t {
type ipV6 (line 23) | struct ipV6 {
type tcpv6_key_t (line 28) | struct tcpv6_key_t {
type tcpv6_value_t (line 35) | struct tcpv6_value_t{
type udp_key_t (line 41) | struct udp_key_t {
type udp_value_t (line 48) | struct udp_value_t{
type udpv6_key_t (line 54) | struct udpv6_key_t {
type udpv6_value_t (line 61) | struct udpv6_value_t{
type sock_on_x86_32_t (line 70) | struct sock_on_x86_32_t {
type tcp_key_t (line 80) | struct tcp_key_t
type tcp_value_t (line 81) | struct tcp_value_t
type tcpv6_key_t (line 87) | struct tcpv6_key_t
type tcpv6_value_t (line 88) | struct tcpv6_value_t
type udp_key_t (line 94) | struct udp_key_t
type udp_value_t (line 95) | struct udp_value_t
type udpv6_key_t (line 101) | struct udpv6_key_t
type udpv6_value_t (line 102) | struct udpv6_value_t
function kprobe__tcp_v4_connect (line 135) | int kprobe__tcp_v4_connect(struct pt_regs *ctx)
function kretprobe__tcp_v4_connect (line 152) | int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
function kprobe__tcp_v6_connect (line 181) | int kprobe__tcp_v6_connect(struct pt_regs *ctx)
function kretprobe__tcp_v6_connect (line 196) | int kretprobe__tcp_v6_connect(struct pt_regs *ctx)
function kprobe__udp_sendmsg (line 233) | int kprobe__udp_sendmsg(struct pt_regs *ctx)
function kprobe__udpv6_sendmsg (line 287) | int kprobe__udpv6_sendmsg(struct pt_regs *ctx)
function kprobe__udp_tunnel6_xmit_skb (line 346) | int kprobe__udp_tunnel6_xmit_skb(struct pt_regs *ctx)
function kprobe__inet_dgram_connect (line 421) | int kprobe__inet_dgram_connect(struct pt_regs *ctx)
function kretprobe__inet_dgram_connect (line 435) | int kretprobe__inet_dgram_connect(int retval)
function kprobe__iptunnel_xmit (line 547) | int kprobe__iptunnel_xmit(struct pt_regs *ctx)
FILE: ui/opensnitch/actions/__init__.py
class Actions (line 20) | class Actions(QObject):
method instance (line 113) | def instance():
method __init__ (line 118) | def __init__(self, parent=None):
method _load_default_configs (line 130) | def _load_default_configs(self):
method load (line 137) | def load(self, action_file):
method loadAll (line 150) | def loadAll(self):
method compile (line 167) | def compile(self, json_obj):
method getAll (line 210) | def getAll(self):
method deleteAll (line 213) | def deleteAll(self):
method get (line 216) | def get(self, name):
method getByType (line 223) | def getByType(self, acttype):
method delete (line 241) | def delete(self, name):
method isValid (line 249) | def isValid(self):
FILE: ui/opensnitch/actions/utils.py
function getColorNames (line 3) | def getColorNames():
FILE: ui/opensnitch/auth/__init__.py
function load_file (line 15) | def load_file(file_path):
function get_tls_credentials (line 25) | def get_tls_credentials(ca_cert, server_cert, server_key):
FILE: ui/opensnitch/config.py
class Config (line 4) | class Config:
method init (line 181) | def init():
method get (line 186) | def get():
method __init__ (line 191) | def __init__(self):
method reload (line 212) | def reload(self):
method hasKey (line 215) | def hasKey(self, key):
method setSettings (line 218) | def setSettings(self, path, value):
method getSettings (line 222) | def getSettings(self, path, default=None):
method getBool (line 225) | def getBool(self, path, default_value=False):
method getInt (line 228) | def getInt(self, path, default_value=0):
method getDefaultAction (line 234) | def getDefaultAction(self):
method setRulesDurationFilter (line 242) | def setRulesDurationFilter(self, ignore_temporary_rules=False, temp_ru...
method getMaxMsgLength (line 267) | def getMaxMsgLength(self):
FILE: ui/opensnitch/customwidgets/addresstablemodel.py
class AddressTableModel (line 8) | class AddressTableModel(GenericTableModel):
method __init__ (line 10) | def __init__(self, tableName, headerLabels):
method reconfigureColumns (line 15) | def reconfigureColumns(self):
method lastQuery (line 25) | def lastQuery(self):
method update_col_count (line 28) | def update_col_count(self):
method fillVisibleRows (line 37) | def fillVisibleRows(self, q, upperBound, force=False):
FILE: ui/opensnitch/customwidgets/colorizeddelegate.py
class ColorizedDelegate (line 6) | class ColorizedDelegate(QItemDelegate):
method __init__ (line 12) | def __init__(self, parent=None, *args, actions={}):
method setConfig (line 18) | def setConfig(self, actions):
method paint (line 22) | def paint(self, painter, option, index):
FILE: ui/opensnitch/customwidgets/completer.py
class Completer (line 20) | class Completer(QCompleter):
method __init__ (line 21) | def __init__(self, parent=None):
method pathFromIndex (line 24) | def pathFromIndex(self, modelIdx):
method splitPath (line 48) | def splitPath(self, path):
FILE: ui/opensnitch/customwidgets/firewalltableview.py
class FirewallTableModel (line 13) | class FirewallTableModel(QStandardItemModel):
method __init__ (line 67) | def __init__(self, tableName):
method headers (line 79) | def headers(self):
method filterByNode (line 82) | def filterByNode(self, addr):
method filterAll (line 86) | def filterAll(self):
method filterByTable (line 90) | def filterByTable(self, addr, name, family):
method filterByChain (line 94) | def filterByChain(self, addr, table, family, chain, hook):
method filterByQuery (line 98) | def filterByQuery(self, query):
method reorderRows (line 102) | def reorderRows(self, action, row):
method sort (line 131) | def sort(self, column, order=QtCore.Qt.SortOrder.AscendingOrder):
method refresh (line 136) | def refresh(self, force=False):
method query (line 141) | def query(self):
method lastError (line 145) | def lastError(self):
method clear (line 149) | def clear(self):
method setModelColumns (line 156) | def setModelColumns(self, headers):
method query (line 164) | def query(self):
method setQuery (line 167) | def setQuery(self, q, db, args=None, limit=0, offset=0):
method nextRecord (line 170) | def nextRecord(self, offset):
method prevRecord (line 173) | def prevRecord(self, offset):
method fillVisibleRows (line 176) | def fillVisibleRows(self, upperBound, force, *data):
method addRows (line 221) | def addRows(self, rules):
method dumpRows (line 232) | def dumpRows(self, nolimits=None):
class FirewallTableView (line 235) | class FirewallTableView(QTableView):
method __init__ (line 241) | def __init__(self, parent):
method _cb_fw_rules_updated (line 256) | def _cb_fw_rules_updated(self):
method _cb_column_count_changed (line 259) | def _cb_column_count_changed(self, num):
method _cb_fw_rule_position_changed (line 263) | def _cb_fw_rule_position_changed(self, action, row):
method _cb_rows_reordered (line 266) | def _cb_rows_reordered(self, view, node_addr, uuid, old_pos, new_pos):
method _cb_rows_updated (line 271) | def _cb_rows_updated(self, view, data):
method filterAll (line 292) | def filterAll(self):
method filterByNode (line 295) | def filterByNode(self, addr):
method filterByTable (line 298) | def filterByTable(self, addr, name, family):
method filterByChain (line 301) | def filterByChain(self, addr, table, family, chain, hook):
method filterByQuery (line 304) | def filterByQuery(self, query):
method refresh (line 307) | def refresh(self):
method clearSelection (line 310) | def clearSelection(self):
method selectedRows (line 313) | def selectedRows(self):
method setModel (line 329) | def setModel(self, model):
method setTrackingColumn (line 336) | def setTrackingColumn(self, col):
FILE: ui/opensnitch/customwidgets/generictableview.py
class GenericTableModel (line 16) | class GenericTableModel(QStandardItemModel):
method __init__ (line 41) | def __init__(self, tableName, headerLabels):
method headers (line 48) | def headers(self):
method getLimitQuery (line 51) | def getLimitQuery(self, offset, forward=True):
method query (line 75) | def query(self):
method lastQuery (line 79) | def lastQuery(self):
method lastError (line 83) | def lastError(self):
method clear (line 87) | def clear(self):
method refresh (line 90) | def refresh(self):
method rowCount (line 95) | def rowCount(self, index=None):
method total (line 99) | def total(self):
method data (line 108) | def data(self, index, role=Qt.ItemDataRole.DisplayRole):
method update_row_count (line 117) | def update_row_count(self):
method update_col_count (line 122) | def update_col_count(self):
method setModelColumns (line 129) | def setModelColumns(self, newColumns):
method setQuery (line 145) | def setQuery(self, q, db, binds=None, limit=None, offset=None):
method nextRecord (line 178) | def nextRecord(self, offset):
method prevRecord (line 187) | def prevRecord(self, offset):
method refreshViewport (line 196) | def refreshViewport(self, scrollValue, maxRowsInViewport, force=False):
method fillVisibleRows (line 228) | def fillVisibleRows(self, q, upperBound, force=False):
method dumpRows (line 260) | def dumpRows(self, nolimits=False, first_row=QSql.Location.BeforeFirst...
method copySelectedRows (line 282) | def copySelectedRows(self, start=QSql.Location.BeforeFirstRow.value, e...
class GenericTableView (line 298) | class GenericTableView(QTableView):
method __init__ (line 301) | def __init__(self, parent):
method setVerticalScrollBar (line 332) | def setVerticalScrollBar(self, vScrollBar):
method setModel (line 337) | def setModel(self, model):
method setTrackingColumn (line 345) | def setTrackingColumn(self, col):
method selectAll (line 349) | def selectAll(self):
method getRowCells (line 354) | def getRowCells(self, row):
method selectDbRows (line 361) | def selectDbRows(self, first, last):
method getMinViewportRow (line 377) | def getMinViewportRow(self):
method getMaxViewportRow (line 381) | def getMaxViewportRow(self):
method getViewportRowPos (line 385) | def getViewportRowPos(self, row):
method clear (line 389) | def clear(self):
method refresh (line 392) | def refresh(self):
method forceViewRefresh (line 399) | def forceViewRefresh(self):
method calculateRowsInViewport (line 402) | def calculateRowsInViewport(self):
method scrollViewport (line 407) | def scrollViewport(self, row):
method mouseReleaseEvent (line 420) | def mouseReleaseEvent(self, event):
method mouseMoveEvent (line 462) | def mouseMoveEvent(self, event):
method mousePressEvent (line 477) | def mousePressEvent(self, event):
method handleShiftPressed (line 560) | def handleShiftPressed(self):
method handleMouseMoveEvent (line 565) | def handleMouseMoveEvent(self, row, clickedItem, selected):
method onBeginViewportRefresh (line 578) | def onBeginViewportRefresh(self):
method onEndViewportRefresh (line 584) | def onEndViewportRefresh(self):
method resizeEvent (line 594) | def resizeEvent(self, event):
method onRowCountChanged (line 602) | def onRowCountChanged(self):
method clearSelection (line 623) | def clearSelection(self):
method selectedRows (line 634) | def selectedRows(self, limit=""):
method getCurrentIndex (line 654) | def getCurrentIndex(self):
method selectItem (line 657) | def selectItem(self, _data, _column):
method selectIndices (line 667) | def selectIndices(self):
method _selectLastRow (line 682) | def _selectLastRow(self):
method _selectRow (line 689) | def _selectRow(self, pos):
method onScrollbarValueChanged (line 696) | def onScrollbarValueChanged(self, vSBNewValue):
method onKeyUp (line 717) | def onKeyUp(self):
method onKeyDown (line 735) | def onKeyDown(self):
method onKeyHome (line 754) | def onKeyHome(self):
method onKeyEnd (line 766) | def onKeyEnd(self):
method onKeyPageUp (line 775) | def onKeyPageUp(self):
method onKeyPageDown (line 779) | def onKeyPageDown(self):
method onKeySpace (line 786) | def onKeySpace(self):
method eventFilter (line 793) | def eventFilter(self, obj, event):
FILE: ui/opensnitch/customwidgets/itemwidgetcentered.py
class IconTextItem (line 25) | class IconTextItem(QWidget):
method __init__ (line 27) | def __init__(self, icon: QIcon, text: str, parent=None, size=24):
FILE: ui/opensnitch/customwidgets/main.py
class ColorizedQSqlQueryModel (line 10) | class ColorizedQSqlQueryModel(QSqlQueryModel):
method __init__ (line 24) | def __init__(self, modelData={}):
method data (line 28) | def data(self, index, role=QtCore.Qt.DisplayRole):
class ConnectionsTableModel (line 45) | class ConnectionsTableModel(QStandardItemModel):
method __init__ (line 82) | def __init__(self):
method query (line 97) | def query(self):
method lastQuery (line 101) | def lastQuery(self):
method lastError (line 105) | def lastError(self):
method clear (line 109) | def clear(self):
method setQuery (line 112) | def setQuery(self, q, db):
method buildMap (line 177) | def buildMap(self):
method updateDistinctIfNeeded (line 214) | def updateDistinctIfNeeded(self, force=False):
method refreshViewport (line 234) | def refreshViewport(self, value, maxRowsInViewport):
method getMatch (line 308) | def getMatch (self, filterStr):
method getFilterStr (line 339) | def getFilterStr(self):
method getActionStr (line 346) | def getActionStr(self):
method dumpRows (line 353) | def dumpRows(self):
class ConnectionsTableView (line 368) | class ConnectionsTableView(QTableView):
method __init__ (line 375) | def __init__(self, parent):
method setVerticalScrollBar (line 385) | def setVerticalScrollBar(self, vScrollBar):
method setModel (line 390) | def setModel(self, model):
method onRowsInsertedOrRemoved (line 401) | def onRowsInsertedOrRemoved(self, parent, start, end):
method resizeEvent (line 407) | def resizeEvent(self, event):
method calculateRowsInViewport (line 414) | def calculateRowsInViewport(self):
method onValueChanged (line 419) | def onValueChanged(self, vSBNewValue):
method onRowCountChanged (line 429) | def onRowCountChanged(self):
method onKeyUp (line 454) | def onKeyUp(self):
method onKeyDown (line 458) | def onKeyDown(self):
method onKeyHome (line 462) | def onKeyHome(self):
method onKeyEnd (line 466) | def onKeyEnd(self):
method onKeyPageUp (line 470) | def onKeyPageUp(self):
method onKeyPageDown (line 476) | def onKeyPageDown(self):
method eventFilter (line 482) | def eventFilter(self, obj, event):
FILE: ui/opensnitch/customwidgets/netstattablemodel.py
class NetstatTableModel (line 6) | class NetstatTableModel(GenericTableModel):
method __init__ (line 8) | def __init__(self, tableName, headerLabels):
method data (line 15) | def data(self, index, role=Qt.ItemDataRole.DisplayRole):
FILE: ui/opensnitch/customwidgets/updownbtndelegate.py
class UpDownButtonDelegate (line 6) | class UpDownButtonDelegate(QItemDelegate):
method paint (line 12) | def paint(self, painter, option, index):
method createEditor (line 19) | def createEditor(self, parent, option, index):
method _cb_button_clicked (line 41) | def _cb_button_clicked(self, action, idx):
method updateEditorGeometry (line 44) | def updateEditorGeometry(self, editor, option, index):
FILE: ui/opensnitch/database/__init__.py
class Database (line 9) | class Database:
method instance (line 31) | def instance():
method __init__ (line 36) | def __init__(self, dbname="db"):
method initialize (line 44) | def initialize(self, dbtype=DB_TYPE_MEMORY, dbfile=DB_IN_MEMORY, dbjrn...
method close (line 80) | def close(self):
method is_db_ok (line 88) | def is_db_ok(self):
method get_db (line 101) | def get_db(self):
method get_db_file (line 104) | def get_db_file(self):
method get_new_qsql_model (line 107) | def get_new_qsql_model(self):
method get_db_name (line 110) | def get_db_name(self):
method _create_tables (line 113) | def _create_tables(self):
method get_schema_version (line 264) | def get_schema_version(self):
method set_schema_version (line 273) | def set_schema_version(self, version):
method get_journal_mode (line 279) | def get_journal_mode(self):
method set_journal_mode (line 287) | def set_journal_mode(self, mode):
method _upgrade_db_schema (line 314) | def _upgrade_db_schema(self):
method _apply_db_upgrade (line 330) | def _apply_db_upgrade(self, file):
method optimize (line 344) | def optimize(self):
method clean (line 350) | def clean(self, table):
method vacuum (line 355) | def vacuum(self):
method clone_db (line 359) | def clone_db(self, name):
method clone (line 362) | def clone(self):
method transaction (line 366) | def transaction(self):
method commit (line 369) | def commit(self):
method rollback (line 372) | def rollback(self):
method get_total_records (line 375) | def get_total_records(self):
method get_newest_record (line 383) | def get_newest_record(self):
method get_oldest_record (line 392) | def get_oldest_record(self):
method purge_oldest (line 401) | def purge_oldest(self, max_days_to_keep):
method select (line 425) | def select(self, qstr):
method remove (line 433) | def remove(self, qstr, args=None):
method _insert (line 451) | def _insert(self, query_str, columns):
method insert (line 472) | def insert(self, table, fields, columns, update_field=None, update_val...
method update (line 496) | def update(self, table, fields, values, condition=None, action_on_conf...
method _insert_batch (line 515) | def _insert_batch(self, query_str, fields, values):
method insert_batch (line 537) | def insert_batch(self, table, db_fields, db_columns, fields, values, u...
method update_batch (line 550) | def update_batch(self, table, db_fields, db_columns, fields, values, u...
method dump (line 561) | def dump(self):
method get_query (line 565) | def get_query(self, table, fields):
method empty_rule (line 568) | def empty_rule(self, name=""):
method delete_rule (line 581) | def delete_rule(self, name, node_addr):
method delete_rules_by_field (line 599) | def delete_rules_by_field(self, field, values):
method get_connection_by_field (line 623) | def get_connection_by_field(self, field, date):
method get_rule (line 635) | def get_rule(self, rule_name, node_addr=None):
method get_rule_by_field (line 652) | def get_rule_by_field(self, node_addr=None, field=None, value=None):
method get_rules (line 671) | def get_rules(self, node_addr):
method insert_rule (line 684) | def insert_rule(self, rule, node_addr):
method rule_exists (line 694) | def rule_exists(self, rule, node_addr):
method delete_alert (line 719) | def delete_alert(self, time, node_addr=None):
method get_alert (line 737) | def get_alert(self, alert_time, node_addr=None):
FILE: ui/opensnitch/database/enums.py
class ConnFields (line 2) | class ConnFields():
class RuleFields (line 19) | class RuleFields():
class AlertFields (line 36) | class AlertFields():
FILE: ui/opensnitch/desktop_parser.py
class LinuxDesktopParser (line 21) | class LinuxDesktopParser(threading.Thread):
method __init__ (line 22) | def __init__(self):
method get_locale (line 53) | def get_locale(self):
method _parse_exec (line 61) | def _parse_exec(self, cmd):
method get_app_description (line 89) | def get_app_description(self, parser):
method discover_app_icon (line 103) | def discover_app_icon(app_name):
method _parse_desktop_file (line 114) | def _parse_desktop_file(self, desktop_path):
method get_info_by_path (line 154) | def get_info_by_path(self, path, default_icon):
method get_info_by_binname (line 177) | def get_info_by_binname(self, name, default_icon):
method run (line 181) | def run(self):
FILE: ui/opensnitch/dialogs/conndetails.py
class ConnDetails (line 9) | class ConnDetails(InfoWindow):
method __init__ (line 13) | def __init__(self, parent):
method showByField (line 19) | def showByField(self, field, value):
FILE: ui/opensnitch/dialogs/events/base.py
class EventsBase (line 12) | class EventsBase(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
method __init__ (line 13) | def __init__(self, parent=None):
method add_tab (line 17) | def add_tab(self, widget, icon, label):
method set_current_tab (line 21) | def set_current_tab(self, idx, block_events=False):
method add_toolbar_buton (line 28) | def add_toolbar_buton(self):
method add_tree_items (line 32) | def add_tree_items(self, level, labels, clean=True):
method get_tree_item (line 47) | def get_tree_item(self, idx):
method find_tree_items (line 53) | def find_tree_items(self, idx, data):
method get_tree_selected_items (line 65) | def get_tree_selected_items(self, tree_idx):
method set_tree_selected_items (line 84) | def set_tree_selected_items(self, selected, expanded):
method get_current_view_idx (line 95) | def get_current_view_idx(self):
method get_central_widget (line 98) | def get_central_widget(self):
method get_data_view (line 101) | def get_data_view(self, idx):
method get_search_widget (line 104) | def get_search_widget(self):
method get_search_text (line 107) | def get_search_text(self):
method set_search_text (line 110) | def set_search_text(self, text):
FILE: ui/opensnitch/dialogs/events/config.py
class ConfigManager (line 7) | class ConfigManager:
method __init__ (line 8) | def __init__(self, parent):
method default_views_config (line 531) | def default_views_config(self):
FILE: ui/opensnitch/dialogs/events/dialog.py
class StatsDialog (line 44) | class StatsDialog(menus.MenusManager, menu_actions.MenuActions, views.Vi...
method __init__ (line 57) | def __init__(self, parent=None, address=None, db=None, dbname="db", ap...
method changeEvent (line 368) | def changeEvent(self, event):
method show (line 377) | def show(self):
method eventFilter (line 394) | def eventFilter(self, source, event):
method _configure_plugins (line 411) | def _configure_plugins(self):
method _configure_buttons_icons (line 420) | def _configure_buttons_icons(self):
method _load_settings (line 461) | def _load_settings(self):
method _save_settings (line 532) | def _save_settings(self):
method _cb_fw_rules_updated (line 559) | def _cb_fw_rules_updated(self):
method _cb_app_rules_updated (line 562) | def _cb_app_rules_updated(self, what):
method _cb_nodes_updated (line 565) | def _cb_nodes_updated(self, count):
method _cb_fw_table_rows_reordered (line 570) | def _cb_fw_table_rows_reordered(self, node_addr):
method _cb_tree_edit_firewall_clicked (line 575) | def _cb_tree_edit_firewall_clicked(self):
method _cb_proc_details_clicked (line 578) | def _cb_proc_details_clicked(self):
method _cb_notification_callback (line 591) | def _cb_notification_callback(self, node_addr, reply):
method _cb_tab_changed (line 627) | def _cb_tab_changed(self, index):
method _cb_table_context_menu (line 659) | def _cb_table_context_menu(self, pos):
method _cb_table_header_clicked (line 684) | def _cb_table_header_clicked(self, pos, sortIdx):
method _cb_events_filter_line_changed (line 688) | def _cb_events_filter_line_changed(self, text):
method _cb_limit_combo_changed (line 691) | def _cb_limit_combo_changed(self, idx):
method _cb_combo_action_changed (line 708) | def _cb_combo_action_changed(self, idx):
method _cb_clean_sql_clicked (line 715) | def _cb_clean_sql_clicked(self, idx):
method _cb_cmd_back_clicked (line 725) | def _cb_cmd_back_clicked(self, idx):
method _cb_main_table_double_clicked (line 728) | def _cb_main_table_double_clicked(self, row):
method _cb_table_clicked (line 813) | def _cb_table_clicked(self, idx):
method _cb_table_double_clicked (line 816) | def _cb_table_double_clicked(self, row):
method _cb_prefs_clicked (line 912) | def _cb_prefs_clicked(self):
method _cb_rules_filter_combo_changed (line 915) | def _cb_rules_filter_combo_changed(self, idx):
method _cb_rules_tree_item_expanded (line 927) | def _cb_rules_tree_item_expanded(self, item):
method _cb_rules_tree_item_double_clicked (line 931) | def _cb_rules_tree_item_double_clicked(self, item, col):
method _cb_rules_tree_item_clicked (line 935) | def _cb_rules_tree_item_clicked(self, item, col):
method _cb_splitter_moved (line 993) | def _cb_splitter_moved(self, tab, pos, index):
method _cb_start_clicked (line 996) | def _cb_start_clicked(self):
method _cb_node_start_clicked (line 1016) | def _cb_node_start_clicked(self):
method _cb_node_prefs_clicked (line 1029) | def _cb_node_prefs_clicked(self):
method _cb_node_delete_clicked (line 1035) | def _cb_node_delete_clicked(self):
method _cb_new_rule_clicked (line 1038) | def _cb_new_rule_clicked(self):
method _cb_edit_rule_clicked (line 1041) | def _cb_edit_rule_clicked(self):
method _cb_del_rule_clicked (line 1049) | def _cb_del_rule_clicked(self):
method _cb_enable_rule_toggled (line 1062) | def _cb_enable_rule_toggled(self, state):
method _cb_prev_button_clicked (line 1065) | def _cb_prev_button_clicked(self):
method _cb_next_button_clicked (line 1069) | def _cb_next_button_clicked(self):
method _cb_help_button_clicked (line 1073) | def _cb_help_button_clicked(self):
method open_firewall (line 1091) | def open_firewall(self):
method new_fw_rule (line 1097) | def new_fw_rule(self):
method load_fw_rule (line 1102) | def load_fw_rule(self, node, uuid):
method open_settings (line 1107) | def open_settings(self, addr=None):
method enable_rule (line 1117) | def enable_rule(self, state):
method del_by_field (line 1133) | def del_by_field(self, cur_idx, table, value):
method del_rule (line 1157) | def del_rule(self, rule_name, node_addr):
method display_alert_info (line 1166) | def display_alert_info(self, time, node):
method _update_status_label (line 1192) | def _update_status_label(self, running=False, text=FIREWALL_DISABLED):
method _add_rulesTree_nodes (line 1204) | def _add_rulesTree_nodes(self):
method _add_rulesTree_fw_chains (line 1215) | def _add_rulesTree_fw_chains(self):
method get_rule (line 1276) | def get_rule(self, rule_name, node_name):
method _on_settings_saved (line 1291) | def _on_settings_saved(self):
method _on_menu_exit_clicked (line 1296) | def _on_menu_exit_clicked(self, triggered):
method update (line 1300) | def update(self, is_local=True, stats=None, need_query_update=True):
method _on_update_triggered (line 1310) | def _on_update_triggered(self, is_local, need_query_update=False):
method closeEvent (line 1334) | def closeEvent(self, e):
method hideEvent (line 1349) | def hideEvent(self, e):
method keyPressEvent (line 1353) | def keyPressEvent(self, event):
FILE: ui/opensnitch/dialogs/events/menu_actions.py
class MenuActions (line 20) | class MenuActions(views.ViewsManager):
method __init__ (line 21) | def __init__(self, parent):
method table_menu_new_rule_from_row (line 24) | def table_menu_new_rule_from_row(self, cur_idx, model, selection):
method table_menu_export_clipboard (line 36) | def table_menu_export_clipboard(self, cur_idx, model, selection):
method table_menu_export_disk (line 74) | def table_menu_export_disk(self, cur_idx, model, selection):
method table_menu_duplicate (line 110) | def table_menu_duplicate(self, cur_idx, model, selection):
method table_menu_apply_to_node (line 138) | def table_menu_apply_to_node(self, cur_idx, model, selection, node_addr):
method table_menu_apply_to_all_nodes (line 177) | def table_menu_apply_to_all_nodes(self, cur_idx, model, selection, nod...
method table_menu_change_rule_field (line 229) | def table_menu_change_rule_field(self, cur_idx, model, selection, fiel...
method table_menu_enable (line 269) | def table_menu_enable(self, cur_idx, model, selection, is_rule_enabled):
method table_menu_delete (line 307) | def table_menu_delete(self, cur_idx, model, selection):
method table_menu_edit (line 362) | def table_menu_edit(self, cur_idx, model, selection):
FILE: ui/opensnitch/dialogs/events/menus.py
class MenusManager (line 16) | class MenusManager(views.ViewsManager):
method __init__ (line 17) | def __init__(self, parent):
method configure_main_btn_menu (line 20) | def configure_main_btn_menu(self):
method configure_header_contextual_menu (line 54) | def configure_header_contextual_menu(self, pos):
method configure_events_contextual_menu (line 101) | def configure_events_contextual_menu(self, pos):
method configure_fwrules_contextual_menu (line 140) | def configure_fwrules_contextual_menu(self, pos):
method configure_rules_contextual_menu (line 247) | def configure_rules_contextual_menu(self, pos):
method configure_alerts_contextual_menu (line 370) | def configure_alerts_contextual_menu(self, pos):
FILE: ui/opensnitch/dialogs/events/nodes.py
class NodesManager (line 4) | class NodesManager:
method __init__ (line 5) | def __init__(self, parent):
method node_start_interception (line 10) | def node_start_interception(self, addr=None, callback=None):
method node_stop_interception (line 13) | def node_stop_interception(self, addr=None, callback=None):
method node_get (line 16) | def node_get(self, addr):
method node_delete (line 19) | def node_delete(self, addr):
method node_del_rule (line 22) | def node_del_rule(self, addr, name, callback):
method node_hostname (line 25) | def node_hostname(self, addr):
method nodes_count (line 28) | def nodes_count(self):
method node_list (line 31) | def node_list(self):
method node_add_rules (line 34) | def node_add_rules(self, addr, rules):
method node_rule_to_json (line 37) | def node_rule_to_json(self, addr, name):
method node_export_rule (line 40) | def node_export_rule(self, addr, name, outdir):
method node_export_rules (line 43) | def node_export_rules(self, addr, outdir):
method node_import_all_rules (line 46) | def node_import_all_rules(self, rulesdir, callback):
method node_reload_fw (line 50) | def node_reload_fw(self, addr, fw_config, callback):
method send_notification (line 53) | def send_notification(self, addr, ntf, callback):
method send_notifications (line 56) | def send_notifications(self, ntf, callback):
method save_ntf (line 64) | def save_ntf(self, nid, ntf):
method del_notification (line 67) | def del_notification(self, nid):
method ntf_reply_exists (line 70) | def ntf_reply_exists(self, nid):
method get_notification (line 73) | def get_notification(self, nid):
FILE: ui/opensnitch/dialogs/events/queries.py
class Queries (line 32) | class Queries:
method __init__ (line 33) | def __init__(self, win):
method get_completer (line 108) | def get_completer(self, idx):
method get_query (line 125) | def get_query(self, table, fields):
method get_view_query (line 128) | def get_view_query(self, model, idx, where_clause=None):
method advanced_search (line 145) | def advanced_search(self, text):
method get_filter_line (line 202) | def get_filter_line(self, idx, text, adv_search=None):
method get_indetail_filter (line 245) | def get_indetail_filter(self, indetail_view, lastQuery, text, advanced...
method get_nodes_filter (line 300) | def get_nodes_filter(self, indetail_view, lastQuery, text, advanced_fi...
method get_events_generic_filter (line 356) | def get_events_generic_filter(self, action, filter_text):
method set_rules_filter (line 373) | def set_rules_filter(self, parent_row=constants.NO_PARENT, item_row=0,...
method set_fw_rules_filter (line 438) | def set_fw_rules_filter(self, parent_row=constants.NO_PARENT, item_row...
method set_events_query (line 477) | def set_events_query(self, advanced_filter=None):
method set_nodes_query (line 511) | def set_nodes_query(self, data):
method set_rules_query (line 520) | def set_rules_query(self, rule_name="", node=""):
method set_hosts_query (line 542) | def set_hosts_query(self, data):
method set_process_query (line 551) | def set_process_query(self, data):
method set_addrs_query (line 561) | def set_addrs_query(self, data):
method set_ports_query (line 571) | def set_ports_query(self, data):
method set_users_query (line 582) | def set_users_query(self, data):
method setQuery (line 596) | def setQuery(self, model, q, binds=None, limit=0, offset=None):
FILE: ui/opensnitch/dialogs/events/tasks/netstat.py
class Netstat (line 17) | class Netstat:
method __init__ (line 18) | def __init__(self, win, cfg, db):
method cb_combo_netstat_changed (line 31) | def cb_combo_netstat_changed(self, combo, idx):
method configure (line 47) | def configure(self):
method configure_combos (line 82) | def configure_combos(self):
method update_node_list (line 100) | def update_node_list(self, count, node_list):
method monitor_node (line 128) | def monitor_node(self):
method unmonitor_node (line 174) | def unmonitor_node(self, node_addr):
method update_node (line 197) | def update_node(self, node_addr, data):
FILE: ui/opensnitch/dialogs/events/tasks/nodemon.py
class Nodemon (line 15) | class Nodemon:
method __init__ (line 16) | def __init__(self, win):
method reset_node_info (line 19) | def reset_node_info(self, status=""):
method monitor_selected_node (line 30) | def monitor_selected_node(self, node_addr, col_uptime, col_hostname, c...
method unmonitor_deselected_node (line 62) | def unmonitor_deselected_node(self, last_addr):
method update_node_info (line 84) | def update_node_info(self, data):
FILE: ui/opensnitch/dialogs/events/views.py
class ViewsManager (line 26) | class ViewsManager(config.ConfigManager, nodes.NodesManager, base.Events...
method __init__ (line 27) | def __init__(self, parent):
method view_setup (line 67) | def view_setup(
method cb_scrollbar_pressed (line 122) | def cb_scrollbar_pressed(self):
method cb_scrollbar_released (line 125) | def cb_scrollbar_released(self):
method reset_statusbar (line 128) | def reset_statusbar(self):
method needs_refresh (line 135) | def needs_refresh(self):
method in_detail_view (line 142) | def in_detail_view(self, idx):
method set_in_detail_view (line 145) | def set_in_detail_view(self, idx, state):
method set_last_selected_item (line 148) | def set_last_selected_item(self, what):
method get_view_context_menu (line 151) | def get_view_context_menu(self, idx):
method set_view_context_menu (line 154) | def set_view_context_menu(self, idx, menu):
method set_scrollbar_active (line 157) | def set_scrollbar_active(self, state):
method is_scrollbar_active (line 160) | def is_scrollbar_active(self):
method set_context_menu_active (line 163) | def set_context_menu_active(self, state):
method is_context_menu_active (line 166) | def is_context_menu_active(self):
method get_view_limit (line 169) | def get_view_limit(self):
method get_query_limit (line 175) | def get_query_limit(self):
method get_view_order (line 181) | def get_view_order(self, field=None):
method get_view_config (line 188) | def get_view_config(self, idx):
method set_view_config (line 191) | def set_view_config(self, idx, config):
method get_view_name (line 194) | def get_view_name(self, idx):
method get_view (line 197) | def get_view(self, idx):
method set_view (line 200) | def set_view(self, idx, view):
method update_interception_status (line 203) | def update_interception_status(self, enabled):
method clear_rows_selection (line 211) | def clear_rows_selection(self):
method are_rows_selected (line 215) | def are_rows_selected(self):
method set_filter_line_color (line 223) | def set_filter_line_color(self, text):
method copy_selected_rows (line 230) | def copy_selected_rows(self):
method show_columns (line 246) | def show_columns(self):
method show_view_columns (line 254) | def show_view_columns(self, idx):
method on_filter_line_changed (line 263) | def on_filter_line_changed(self, text):
method on_splitter_moved (line 306) | def on_splitter_moved(self, tab, pos, index):
method on_table_clicked (line 316) | def on_table_clicked(self, idx):
method on_table_header_clicked (line 352) | def on_table_header_clicked(self, pos, sortOrder):
method on_menu_export_csv_clicked (line 375) | def on_menu_export_csv_clicked(self, tab_idx):
method on_menu_node_export_clicked (line 408) | def on_menu_node_export_clicked(self, triggered):
method on_menu_node_import_clicked (line 432) | def on_menu_node_import_clicked(self, triggered):
method on_menu_export_clicked (line 464) | def on_menu_export_clicked(self, triggered):
method on_menu_import_clicked (line 497) | def on_menu_import_clicked(self, triggered):
method on_cmd_back_clicked (line 528) | def on_cmd_back_clicked(self, idx):
method set_active_widgets (line 557) | def set_active_widgets(self, prev_idx, state, label_txt=""):
method set_rules_tab_active (line 597) | def set_rules_tab_active(self, row, cur_idx, name_idx, node_idx):
method get_active_table (line 612) | def get_active_table(self):
method refresh_active_table (line 620) | def refresh_active_table(self):
method restore_scroll_value (line 631) | def restore_scroll_value(self):
method restore_last_selected_row (line 638) | def restore_last_selected_row(self):
method restore_details_view_columns (line 649) | def restore_details_view_columns(self, header, settings_key):
method restore_rules_tab_widgets (line 665) | def restore_rules_tab_widgets(self, active):
method view_delete_node (line 699) | def view_delete_node(self):
method update_nodes_interception_status (line 721) | def update_nodes_interception_status(self, show=True, disable=False):
method update_status (line 742) | def update_status(self):
FILE: ui/opensnitch/dialogs/firewall.py
class FirewallDialog (line 21) | class FirewallDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
method __init__ (line 35) | def __init__(self, parent=None, appicon=None, node=None):
method _cb_notification_callback (line 93) | def _cb_notification_callback(self, addr, reply):
method _cb_nodes_updated (line 109) | def _cb_nodes_updated(self, total):
method _cb_combo_nodes_changed (line 114) | def _cb_combo_nodes_changed(self, idx):
method _cb_combo_profile_changed (line 122) | def _cb_combo_profile_changed(self, idx):
method _cb_combo_policy_changed (line 138) | def _cb_combo_policy_changed(self, combo):
method _cb_new_rule_clicked (line 194) | def _cb_new_rule_clicked(self):
method _cb_allow_out_service_clicked (line 197) | def _cb_allow_out_service_clicked(self):
method _cb_allow_in_service_clicked (line 200) | def _cb_allow_in_service_clicked(self):
method _cb_enable_fw_changed (line 203) | def _cb_enable_fw_changed(self, enable):
method _cb_close_clicked (line 213) | def _cb_close_clicked(self):
method _close (line 216) | def _close(self):
method _change_fw_backend (line 219) | def _change_fw_backend(self, addr, node_cfg):
method showEvent (line 223) | def showEvent(self, event):
method _load_nodes (line 234) | def _load_nodes(self):
method send_notification (line 251) | def send_notification(self, node_addr, fw_config):
method load_fw_policies (line 266) | def load_fw_policies(self, node_addr=None):
method load_node_fw_policy (line 305) | def load_node_fw_policy(self, addr):
method fw_is_incompatible (line 342) | def fw_is_incompatible(self, addr, node):
method change_fw (line 373) | def change_fw(self, addr, node_cfg):
method enable_fw (line 387) | def enable_fw(self, addr, enable):
method load_rule (line 449) | def load_rule(self, addr, uuid):
method new_rule (line 452) | def new_rule(self):
method allow_out_service (line 455) | def allow_out_service(self):
method allow_in_service (line 458) | def allow_in_service(self):
method _set_status_error (line 461) | def _set_status_error(self, msg):
method _set_status_successful (line 466) | def _set_status_successful(self, msg):
method _set_status_message (line 471) | def _set_status_message(self, msg):
method _reset_status_message (line 476) | def _reset_status_message(self):
method _reset_fields (line 480) | def _reset_fields(self):
method block_combo_signals (line 483) | def block_combo_signals(self, state=True):
method _disable_widgets (line 489) | def _disable_widgets(self, disable=True):
FILE: ui/opensnitch/dialogs/firewall_rule/dialog.py
class FwRuleDialog (line 33) | class FwRuleDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
method __init__ (line 37) | def __init__(self, parent=None, appicon=None):
method show (line 92) | def show(self):
method init (line 96) | def init(self):
method _close (line 121) | def _close(self):
method cb_notification_callback (line 127) | def cb_notification_callback(self, addr, reply):
method cb_nodes_updated (line 132) | def cb_nodes_updated(self, total):
method cb_combo_nodes_changed (line 135) | def cb_combo_nodes_changed(self, idx):
method closeEvent (line 141) | def closeEvent(self, e):
method cb_check_enable_toggled (line 144) | def cb_check_enable_toggled(self, status):
method cb_description_changed (line 147) | def cb_description_changed(self, text):
method cb_help_button_clicked (line 150) | def cb_help_button_clicked(self):
method cb_close_clicked (line 162) | def cb_close_clicked(self):
method cb_delete_clicked (line 165) | def cb_delete_clicked(self):
method cb_save_clicked (line 168) | def cb_save_clicked(self):
method cb_add_clicked (line 171) | def cb_add_clicked(self):
method cb_reset_clicked (line 183) | def cb_reset_clicked(self):
method cb_add_new_statement (line 187) | def cb_add_new_statement(self):
method cb_del_statement (line 191) | def cb_del_statement(self):
method del_statement (line 194) | def del_statement(self):
method cb_statem_combo_changed (line 210) | def cb_statem_combo_changed(self, idx):
method cb_statem_value_changed (line 220) | def cb_statem_value_changed(self, val):
method cb_statem_value_index_changed (line 226) | def cb_statem_value_index_changed(self, idx):
method cb_statem_op_changed (line 246) | def cb_statem_op_changed(self, idx):
method cb_statem_opts_changed (line 252) | def cb_statem_opts_changed(self, idx):
method cb_direction_changed (line 258) | def cb_direction_changed(self, idx):
method cb_verdict_changed (line 262) | def cb_verdict_changed(self, idx):
method cb_verdict_parms_changed (line 270) | def cb_verdict_parms_changed(self, idx):
method reorder_toolbox_pages (line 273) | def reorder_toolbox_pages(self):
method add_new_statement (line 279) | def add_new_statement(self, title="", topWidget=None):
method load (line 283) | def load(self, addr, uuid):
method new (line 288) | def new(self):
method exclude_service (line 293) | def exclude_service(self, direction):
method save (line 298) | def save(self):
method delete (line 331) | def delete(self):
method form_to_protobuf (line 353) | def form_to_protobuf(self):
FILE: ui/opensnitch/dialogs/firewall_rule/notifications.py
function send (line 11) | def send(win, node_addr, fw_config, op, uuid):
function send_all (line 15) | def send_all(win, fw_config, op):
function handle (line 20) | def handle(win, addr, reply):
FILE: ui/opensnitch/dialogs/firewall_rule/rules.py
function new (line 18) | def new(win):
function exclude_service (line 39) | def exclude_service(win, direction):
function add (line 70) | def add(win, nIdx):
function is_valid (line 96) | def is_valid(win):
function has_verdict_parms (line 124) | def has_verdict_parms(win, idx):
function add_rule (line 135) | def add_rule(win, addr, node, chain):
function save (line 142) | def save(win, addr, node, chain, uuid):
function delete (line 150) | def delete(win, addr, node, uuid):
function configure_verdict_parms (line 157) | def configure_verdict_parms(win, idx):
function load (line 187) | def load(win, addr, uuid):
FILE: ui/opensnitch/dialogs/firewall_rule/statements.py
function add_new (line 294) | def add_new(win, title="", topWidget=None):
function configure_value_opts (line 367) | def configure_value_opts(win, st_idx):
function load_meta (line 435) | def load_meta(win, exp, idx):
function load_limit (line 499) | def load_limit(win, exp, idx):
function load_ct (line 519) | def load_ct(win, exp, idx):
function set_title (line 562) | def set_title(win, st_idx, value=None):
FILE: ui/opensnitch/dialogs/firewall_rule/utils.py
function load_nodes (line 6) | def load_nodes(win):
function reset_widgets (line 27) | def reset_widgets(win, title, topWidget):
function set_status_error (line 45) | def set_status_error(win, msg):
function set_status_successful (line 50) | def set_status_successful(win, msg):
function set_status_message (line 55) | def set_status_message(win, msg):
function reset_status_message (line 60) | def reset_status_message(win):
function reset_fields (line 64) | def reset_fields(win):
function enable_save (line 96) | def enable_save(win, enable=True):
function enable_buttons (line 103) | def enable_buttons(win, enable=True):
function disable_buttons (line 110) | def disable_buttons(win, disabled=True):
function disable_controls (line 115) | def disable_controls(win):
function is_valid_int_value (line 119) | def is_valid_int_value(value):
FILE: ui/opensnitch/dialogs/preferences/dialog.py
class PreferencesDialog (line 37) | class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH...
method __init__ (line 73) | def __init__(self, parent=None, appicon=None):
method showEvent (line 209) | def showEvent(self, event):
method add_section (line 213) | def add_section(self, widget, icon, lbl):
method insert_section (line 217) | def insert_section(self, idx, widget, lbl):
method remove_section (line 221) | def remove_section(self, idx):
method enable_section (line 225) | def enable_section(self, idx, enable):
method set_section_title (line 229) | def set_section_title(self, idx, text):
method set_section_visible (line 233) | def set_section_visible(self, idx, visible):
method get_section (line 237) | def get_section(self, idx):
method show_node_prefs (line 241) | def show_node_prefs(self, addr):
method init (line 249) | def init(self):
method cb_notification_callback (line 283) | def cb_notification_callback(self, addr, reply):
method cb_list_item_activated (line 295) | def cb_list_item_activated(self, item):
method cb_line_certs_changed (line 299) | def cb_line_certs_changed(self, text):
method cb_node_line_certs_changed (line 304) | def cb_node_line_certs_changed(self, text):
method cb_cmd_node_rulespath_clicked (line 310) | def cb_cmd_node_rulespath_clicked(self):
method cb_file_db_clicked (line 323) | def cb_file_db_clicked(self):
method cb_server_logoutput_combo_changed (line 341) | def cb_server_logoutput_combo_changed(self, idx):
method cb_cmd_server_logfile_clicked (line 348) | def cb_cmd_server_logfile_clicked(self):
method cb_line_server_logfile_changed (line 353) | def cb_line_server_logfile_changed(self, text):
method cb_combo_uirules_changed (line 358) | def cb_combo_uirules_changed(self, idx):
method cb_db_type_changed (line 367) | def cb_db_type_changed(self):
method cb_accept_button_clicked (line 373) | def cb_accept_button_clicked(self):
method cb_apply_button_clicked (line 378) | def cb_apply_button_clicked(self):
method cb_cancel_button_clicked (line 381) | def cb_cancel_button_clicked(self):
method cb_help_button_clicked (line 384) | def cb_help_button_clicked(self):
method cb_popups_check_toggled (line 387) | def cb_popups_check_toggled(self, checked):
method cb_node_combo_changed (line 395) | def cb_node_combo_changed(self, index):
method cb_node_needs_update (line 400) | def cb_node_needs_update(self):
method cb_server_settings_changed (line 405) | def cb_server_settings_changed(self):
method cb_ui_check_rules_toggled (line 410) | def cb_ui_check_rules_toggled(self, state):
method cb_combo_themes_changed (line 415) | def cb_combo_themes_changed(self, index):
method cb_spin_uidensity_changed (line 421) | def cb_spin_uidensity_changed(self, value):
method cb_ui_check_auto_scale_toggled (line 426) | def cb_ui_check_auto_scale_toggled(self, checked):
method cb_ui_screen_factor_changed (line 432) | def cb_ui_screen_factor_changed(self, text):
method cb_combo_auth_type_changed (line 437) | def cb_combo_auth_type_changed(self, index):
method cb_combo_node_auth_type_changed (line 443) | def cb_combo_node_auth_type_changed(self, index):
method cb_db_max_days_toggled (line 448) | def cb_db_max_days_toggled(self, state):
method cb_db_jrnl_wal_toggled (line 454) | def cb_db_jrnl_wal_toggled(self, state):
method cb_cmd_spin_clicked (line 459) | def cb_cmd_spin_clicked(self, spinWidget, operation):
method cb_radio_system_notifications (line 462) | def cb_radio_system_notifications(self):
method cb_test_notifs_clicked (line 465) | def cb_test_notifs_clicked(self):
FILE: ui/opensnitch/dialogs/preferences/sections/db.py
function save_config (line 8) | def save_config(win):
function enable_db_cleaner_options (line 39) | def enable_db_cleaner_options(win, enable, db_max_days):
function enable_db_jrnl_wal (line 51) | def enable_db_jrnl_wal(win, enable, db_jrnl_wal):
function type_changed (line 55) | def type_changed(win):
FILE: ui/opensnitch/dialogs/preferences/sections/nodes.py
function load (line 7) | def load(win):
function get_node_addr (line 21) | def get_node_addr(win):
function config_auth_type (line 26) | def config_auth_type(win, idx):
function reset_node_settings (line 41) | def reset_node_settings(win):
function load_node_settings (line 62) | def load_node_settings(win):
function load_node_auth_settings (line 154) | def load_node_auth_settings(win, config):
FILE: ui/opensnitch/dialogs/preferences/sections/ui.py
function load_langs (line 8) | def load_langs(win):
function load_themes (line 21) | def load_themes(win):
function get_theme_name (line 49) | def get_theme_name(win):
function change_theme (line 53) | def change_theme(win):
function show_ui_density_widgets (line 60) | def show_ui_density_widgets(win, idx):
function show_ui_scalefactor_widgets (line 70) | def show_ui_scalefactor_widgets(win, show=False):
function load_ui_settings (line 74) | def load_ui_settings(win):
function load_ui_columns_config (line 153) | def load_ui_columns_config(win):
FILE: ui/opensnitch/dialogs/preferences/settings.py
function save (line 22) | def save(win):
function load (line 34) | def load(win):
function save_ui_config (line 105) | def save_ui_config(win):
function save_ui_columns_config (line 250) | def save_ui_columns_config(win):
function save_nodes_config (line 283) | def save_nodes_config(win):
function save_node_config (line 317) | def save_node_config(win, notifObject, addr):
function save_node_auth_config (line 361) | def save_node_auth_config(win, config):
function build_node_config (line 387) | def build_node_config(win, addr):
FILE: ui/opensnitch/dialogs/preferences/signals.py
function connect_all (line 2) | def connect_all(win):
FILE: ui/opensnitch/dialogs/preferences/utils.py
function validate_certs (line 12) | def validate_certs(win):
function needs_restart (line 44) | def needs_restart(win):
function test_notifications (line 51) | def test_notifications(win):
function configure_notifications (line 72) | def configure_notifications(win):
function cmd_spin_clicked (line 85) | def cmd_spin_clicked(win, widget, operation):
function config_server_auth_type (line 98) | def config_server_auth_type(win, idx):
function show_help (line 108) | def show_help():
function hide_status_label (line 116) | def hide_status_label(win):
function show_status_label (line 119) | def show_status_label(win):
function set_status_error (line 122) | def set_status_error(win, msg):
function set_status_successful (line 128) | def set_status_successful(win, msg):
function set_status_message (line 134) | def set_status_message(win, msg):
function reset_status_message (line 140) | def reset_status_message(win):
FILE: ui/opensnitch/dialogs/processdetails.py
class ProcessDetailsDialog (line 19) | class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_P...
method __init__ (line 61) | def __init__(self, parent=None, appicon=None):
method _configure_plugins (line 104) | def _configure_plugins(self):
method _cb_notification_callback (line 114) | def _cb_notification_callback(self, addr, reply):
method closeEvent (line 157) | def closeEvent(self, e):
method _cb_close_clicked (line 160) | def _cb_close_clicked(self):
method _cb_combo_pids_changed (line 163) | def _cb_combo_pids_changed(self, idx):
method _cb_action_clicked (line 172) | def _cb_action_clicked(self):
method _show_message (line 178) | def _show_message(self, text):
method _delete_notification (line 181) | def _delete_notification(self, nid):
method _reset (line 185) | def _reset(self):
method _set_button_running (line 200) | def _set_button_running(self, yes):
method _close (line 208) | def _close(self):
method monitor (line 214) | def monitor(self, pids):
method _set_tab_text (line 228) | def _set_tab_text(self, tab_idx, text):
method _start_monitoring (line 233) | def _start_monitoring(self):
method _stop_monitoring (line 255) | def _stop_monitoring(self):
method _load_data (line 271) | def _load_data(self, data):
method _load_app_icon (line 340) | def _load_app_icon(self, proc_path):
method _load_iostats (line 351) | def _load_iostats(self, iostats):
method _load_mem_data (line 370) | def _load_mem_data(self, mem):
method _load_descriptors (line 380) | def _load_descriptors(self, descriptors):
method _load_env_vars (line 401) | def _load_env_vars(self, envs):
method _build_notification_message (line 412) | def _build_notification_message(self, pid):
FILE: ui/opensnitch/dialogs/prompt/checksums.py
function verify (line 5) | def verify(checksums, rule):
function update_rule (line 28) | def update_rule(node, rules, rule_name, con):
FILE: ui/opensnitch/dialogs/prompt/details.py
function render (line 4) | def render(node, detailsWidget, con):
FILE: ui/opensnitch/dialogs/prompt/dialog.py
class PromptDialog (line 36) | class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
method __init__ (line 43) | def __init__(self, parent=None, appicon=None):
method _cb_label_clicked (line 150) | def _cb_label_clicked(self, what):
method _configure_plugins (line 163) | def _configure_plugins(self):
method _pre_popup_plugins (line 176) | def _pre_popup_plugins(self, con):
method _post_popup_plugins (line 179) | def _post_popup_plugins(self, conn):
method get_main_widget (line 194) | def get_main_widget(self):
method get_connection (line 198) | def get_connection(self):
method get_peer (line 202) | def get_peer(self):
method get_message_text (line 206) | def get_message_text(self):
method set_app_name (line 209) | def set_app_name(self, text):
method set_app_description (line 212) | def set_app_description(self, text):
method set_app_path (line 215) | def set_app_path(self, text):
method set_app_args (line 218) | def set_app_args(self, text):
method set_message_text (line 221) | def set_message_text(self, text):
method set_message_style (line 225) | def set_message_style(self, style):
method set_icon_pixmap (line 228) | def set_icon_pixmap(self, pixmap):
method eventFilter (line 232) | def eventFilter(self, obj, event):
method showEvent (line 238) | def showEvent(self, event):
method adjust_size (line 244) | def adjust_size(self):
method move_popup (line 251) | def move_popup(self):
method stop_countdown (line 266) | def stop_countdown(self):
method _check_advanced_toggled (line 277) | def _check_advanced_toggled(self, state):
method _button_clicked (line 292) | def _button_clicked(self):
method _cb_warninglbl_clicked (line 295) | def _cb_warninglbl_clicked(self, link):
method _cb_cmdinfo_clicked (line 300) | def _cb_cmdinfo_clicked(self):
method _cb_update_rule_clicked (line 304) | def _cb_update_rule_clicked(self, updateAll=False):
method _cb_cmdback_clicked (line 334) | def _cb_cmdback_clicked(self):
method promptUser (line 338) | def promptUser(self, connection, is_local, peer):
method _timeout_worker (line 371) | def _timeout_worker(self):
method on_connection_prompt_triggered (line 392) | def on_connection_prompt_triggered(self):
method on_tick_triggered (line 404) | def on_tick_triggered(self):
method on_timeout_triggered (line 408) | def on_timeout_triggered(self):
method reset_widgets (line 412) | def reset_widgets(self):
method _hide_widget (line 426) | def _hide_widget(self, widget, hide):
method _set_cmd_action_text (line 429) | def _set_cmd_action_text(self):
method _display_checksums_warning (line 440) | def _display_checksums_warning(self, peer, con):
method _render_connection (line 493) | def _render_connection(self, con):
method keyPressEvent (line 585) | def keyPressEvent(self, event):
method closeEvent (line 591) | def closeEvent(self, e):
method close (line 595) | def close(self):
method _on_action_clicked (line 600) | def _on_action_clicked(self, action):
method _on_deny_btn_clicked (line 604) | def _on_deny_btn_clicked(self, action):
method _is_list_rule (line 610) | def _is_list_rule(self):
method _send_rule (line 616) | def _send_rule(self):
FILE: ui/opensnitch/dialogs/prompt/utils.py
function truncate_text (line 11) | def truncate_text(text, max_size=64):
function set_elide_text (line 16) | def set_elide_text(widget, text, max_size=64):
function get_rule_name (line 20) | def get_rule_name(rule, is_list):
function get_popup_message (line 30) | def get_popup_message(is_local, node, hostname, app_name, con):
function set_app_path (line 69) | def set_app_path(appPathLabel, app_name, app_args, con):
function set_app_args (line 93) | def set_app_args(argsLabel, app_name, app_args):
function set_app_description (line 110) | def set_app_description(appDescriptionLabel, description):
function add_fixed_options_to_combo (line 127) | def add_fixed_options_to_combo(combo, con, uid):
function add_ip_regexp_to_combo (line 145) | def add_ip_regexp_to_combo(combo, IPcombo, con):
function add_appimage_pattern_to_combo (line 154) | def add_appimage_pattern_to_combo(combo, con):
function add_snap_pattern_to_combo (line 165) | def add_snap_pattern_to_combo(combo, con):
function add_dst_networks_to_combo (line 181) | def add_dst_networks_to_combo(combo, dst_ip):
function add_dsthost_to_combo (line 193) | def add_dsthost_to_combo(popup, dst_host):
function get_duration (line 203) | def get_duration(duration_idx):
function set_default_duration (line 223) | def set_default_duration(cfg, durationCombo):
function set_default_target (line 230) | def set_default_target(combo, con, cfg, app_name, app_args):
function get_combo_operator (line 266) | def get_combo_operator(data, comboText, con):
FILE: ui/opensnitch/dialogs/ruleseditor/dialog.py
class RulesEditorDialog (line 38) | class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH...
method __init__ (line 42) | def __init__(self, parent=None, modal=True, appicon=None):
method showEvent (line 71) | def showEvent(self, event):
method init (line 75) | def init(self):
method add_section (line 104) | def add_section(self, widget, icon, lbl):
method insert_section (line 108) | def insert_section(self, idx, widget, lbl):
method remove_section (line 112) | def remove_section(self, idx):
method enable_section (line 116) | def enable_section(self, idx, enable):
method set_section_title (line 120) | def set_section_title(self, idx, text):
method set_section_visible (line 124) | def set_section_visible(self, idx, visible):
method get_section (line 128) | def get_section(self, idx):
method cb_rule_name_validator_result (line 132) | def cb_rule_name_validator_result(self, result):
method cb_accept_clicked (line 143) | def cb_accept_clicked(self):
method cb_close_clicked (line 146) | def cb_close_clicked(self):
method cb_reset_clicked (line 149) | def cb_reset_clicked(self):
method cb_help_clicked (line 152) | def cb_help_clicked(self):
method cb_select_list_button_clicked (line 155) | def cb_select_list_button_clicked(self):
method cb_select_nets_list_button_clicked (line 160) | def cb_select_nets_list_button_clicked(self):
method cb_select_ips_list_button_clicked (line 165) | def cb_select_ips_list_button_clicked(self):
method cb_select_regexp_list_button_clicked (line 170) | def cb_select_regexp_list_button_clicked(self):
method cb_proto_check_toggled (line 175) | def cb_proto_check_toggled(self, state):
method cb_proc_check_toggled (line 178) | def cb_proc_check_toggled(self, state):
method cb_cmdline_check_toggled (line 183) | def cb_cmdline_check_toggled(self, state):
method cb_iface_check_toggled (line 188) | def cb_iface_check_toggled(self, state):
method cb_dstport_check_toggled (line 191) | def cb_dstport_check_toggled(self, state):
method cb_srcport_check_toggled (line 194) | def cb_srcport_check_toggled(self, state):
method cb_uid_check_toggled (line 197) | def cb_uid_check_toggled(self, state):
method cb_pid_check_toggled (line 200) | def cb_pid_check_toggled(self, state):
method cb_srcip_check_toggled (line 203) | def cb_srcip_check_toggled(self, state):
method cb_dstip_check_toggled (line 206) | def cb_dstip_check_toggled(self, state):
method cb_dsthost_check_toggled (line 209) | def cb_dsthost_check_toggled(self, state):
method cb_dstlists_check_toggled (line 212) | def cb_dstlists_check_toggled(self, state):
method cb_dstregexplists_check_toggled (line 216) | def cb_dstregexplists_check_toggled(self, state):
method cb_dstiplists_check_toggled (line 220) | def cb_dstiplists_check_toggled(self, state):
method cb_dstnetlists_check_toggled (line 224) | def cb_dstnetlists_check_toggled(self, state):
method cb_uid_combo_changed (line
Condensed preview — 441 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,661K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 654,
"preview": "# These are supported funding model platforms\n\ngithub: gustavo-iniguez-goya\npatreon: # Replace with a single patreon use"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 2086,
"preview": "---\nname: 🐞 Bug report\nabout: Create a report to help us improve\ntitle: '[Bug Report] <title>'\nlabels: 'bug'\nassignees: "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 136,
"preview": "contact_links:\n - name: 🙋 Question\n url: https://github.com/evilsocket/opensnitch/discussions/new\n about: Ask you"
},
{
"path": ".github/ISSUE_TEMPLATE/feature-request.md",
"chars": 281,
"preview": "---\nname: 💡 Feature request\nabout: Suggest an idea \ntitle: '[Feature Request] <title>'\nlabels: feature\nassignees: ''\n\n--"
},
{
"path": ".github/workflows/build_ebpf_modules.yml",
"chars": 2437,
"preview": "# This is a basic workflow to help you get started with Actions\n\nname: CI - build eBPF modules\n\n# Controls when the work"
},
{
"path": ".github/workflows/generic_validations.yml",
"chars": 862,
"preview": "name: Test resources validation\non:\n\n # Trigger this workflow only when ebpf modules changes.\n push:\n paths:\n "
},
{
"path": ".github/workflows/go.yml",
"chars": 1308,
"preview": "name: Build status\non:\n push:\n paths:\n - 'daemon/**'\n - '.github/workflows/go.yml'\n pull_request:\n pat"
},
{
"path": ".gitignore",
"chars": 49,
"preview": "*.sock\n*.pyc\n*.profile\n\n.vscode/\n.idea/\n.DS_Store"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "Makefile",
"chars": 855,
"preview": "all: protocol opensnitch_daemon gui\n\ninstall:\n\t@cd daemon && make install\t\n\t@cd ui && make install\n\nprotocol:\n\t@cd proto"
},
{
"path": "README.md",
"chars": 4366,
"preview": "<p align=\"center\">\n <small>Join the project community on our server!</small>\n <br/><br/>\n <a href=\"https://discord.gg"
},
{
"path": "daemon/.gitignore",
"chars": 19,
"preview": "opensnitchd\nvendor\n"
},
{
"path": "daemon/Gopkg.toml",
"chars": 352,
"preview": "[[constraint]]\n name = \"github.com/fsnotify/fsnotify\"\n version = \"1.4.7\"\n\n[[constraint]]\n name = \"github.com/google/g"
},
{
"path": "daemon/Makefile",
"chars": 903,
"preview": "#SRC contains all *.go *.c *.h files in daemon/ and its subfolders \nSRC := $(shell find . -type f -name '*.go' -o -name "
},
{
"path": "daemon/conman/connection.go",
"chars": 9771,
"preview": "package conman\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evi"
},
{
"path": "daemon/conman/connection_test.go",
"chars": 3618,
"preview": "package conman\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\n\t"
},
{
"path": "daemon/core/core.go",
"chars": 1663,
"preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n)\n\nconst (\n\tdefaultTrimSet"
},
{
"path": "daemon/core/ebpf.go",
"chars": 1839,
"preview": "package core\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/cilium/ebpf\"\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\n// LoadEbpfMo"
},
{
"path": "daemon/core/gzip.go",
"chars": 413,
"preview": "package core\n\nimport (\n\t\"compress/gzip\"\n\t\"io/ioutil\"\n\t\"os\"\n)\n\n// ReadGzipFile reads a gzip to text.\nfunc ReadGzipFile(fi"
},
{
"path": "daemon/core/system.go",
"chars": 6528,
"preview": "package core\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnit"
},
{
"path": "daemon/core/version.go",
"chars": 200,
"preview": "package core\n\n// version related consts\nconst (\n\tName = \"opensnitch-daemon\"\n\tVersion = \"1.9.0\"\n\tAuthor = \"Simone 'ev"
},
{
"path": "daemon/data/default-config.json",
"chars": 1162,
"preview": "{\n \"Server\":\n {\n \"Address\":\"unix:///tmp/osui.sock\",\n \"Authentication\": {\n \"Type\": \"simple"
},
{
"path": "daemon/data/init/opensnitchd-dinit",
"chars": 178,
"preview": "# Application firewall OpenSnitch\ntype = process\ncommand = /usr/bin/opensnitchd\nrestart = true\nsmooth-recovery = yes\nres"
},
{
"path": "daemon/data/init/opensnitchd-openrc",
"chars": 888,
"preview": "#!/sbin/openrc-run\n# OpenSnitch firewall service\n\ndepend() {\n before net\n after iptables ip6tables \n use logger"
},
{
"path": "daemon/data/init/opensnitchd.service",
"chars": 256,
"preview": "[Unit]\nDescription=Application firewall OpenSnitch\nDocumentation=https://github.com/evilsocket/opensnitch/wiki\n\n[Service"
},
{
"path": "daemon/data/network_aliases.json",
"chars": 221,
"preview": "{\n \"LAN\": [\n \"10.0.0.0/8\",\n \"172.16.0.0/12\",\n \"192.168.0.0/16\",\n \"127.0.0.0/8\",\n \""
},
{
"path": "daemon/data/rules/000-allow-localhost.json",
"chars": 503,
"preview": "{\n \"created\": \"2025-04-09T23:21:35-06:00\",\n \"updated\": \"2025-04-09T23:21:35-06:00\",\n \"name\": \"000-allow-localhost\",\n "
},
{
"path": "daemon/data/rules/000-allow-localhost6.json",
"chars": 498,
"preview": "{\n \"created\": \"2025-04-09T23:17:39-06:00\",\n \"updated\": \"2025-04-09T23:17:39-06:00\",\n \"name\": \"000-allow-localhost6\",\n"
},
{
"path": "daemon/data/system-fw.json",
"chars": 7439,
"preview": "{\n \"Enabled\": true,\n \"Version\": 1,\n \"SystemRules\": [\n {\n \"Rule\": {\n \"Table\": \"mangle\",\n \"Chain\""
},
{
"path": "daemon/data/tasks/tasks.json",
"chars": 20,
"preview": "{\n \"tasks\": []\n}\n"
},
{
"path": "daemon/dns/ebpfhook.go",
"chars": 6697,
"preview": "package dns\n\nimport (\n\t\"bytes\"\n\t\"debug/elf\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\t\""
},
{
"path": "daemon/dns/parse.go",
"chars": 511,
"preview": "package dns\n\nimport (\n\t\"github.com/evilsocket/opensnitch/daemon/netfilter\"\n\t\"github.com/google/gopacket/layers\"\n)\n\n// Ge"
},
{
"path": "daemon/dns/systemd/monitor.go",
"chars": 6557,
"preview": "// Package systemd defines several utilities to interact with systemd.\n//\n// ResolvedMonitor:\n// * To debug systemd-res"
},
{
"path": "daemon/dns/track.go",
"chars": 2139,
"preview": "package dns\n\nimport (\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\n\t\"github.com/google/gopacket\"\n\t\"gi"
},
{
"path": "daemon/firewall/common/common.go",
"chars": 4436,
"preview": "package common\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\n// default arguments for var"
},
{
"path": "daemon/firewall/config/config.go",
"chars": 6850,
"preview": "// Package config provides functionality to load and monitor the system\n// firewall rules.\n// It's inherited by the diff"
},
{
"path": "daemon/firewall/config/config_test.go",
"chars": 526,
"preview": "package config\n\nimport (\n\t\"testing\"\n)\n\nfunc preloadConfCallback() {\n}\n\nfunc reloadConfCallback() {\n}\n\nfunc TestNftLoadFr"
},
{
"path": "daemon/firewall/iptables/iptables.go",
"chars": 5567,
"preview": "package iptables\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evilsocket/op"
},
{
"path": "daemon/firewall/iptables/monitor.go",
"chars": 2060,
"preview": "package iptables\n\nimport (\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evilsocket/opensnitch/daemon/fir"
},
{
"path": "daemon/firewall/iptables/rules.go",
"chars": 3160,
"preview": "package iptables\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evilsocket/opensnitch/da"
},
{
"path": "daemon/firewall/iptables/system.go",
"chars": 4873,
"preview": "package iptables\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/common\"\n\t\"github.com/evilsocke"
},
{
"path": "daemon/firewall/nftables/chains.go",
"chars": 6108,
"preview": "package nftables\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"githu"
},
{
"path": "daemon/firewall/nftables/chains_test.go",
"chars": 2444,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github."
},
{
"path": "daemon/firewall/nftables/exprs/counter.go",
"chars": 255,
"preview": "package exprs\n\nimport (\n\t\"github.com/google/nftables/expr\"\n)\n\n// NewExprCounter returns a counter for packets or bytes.\n"
},
{
"path": "daemon/firewall/nftables/exprs/counter_test.go",
"chars": 1307,
"preview": "package exprs_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github.com"
},
{
"path": "daemon/firewall/nftables/exprs/ct.go",
"chars": 2912,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"githu"
},
{
"path": "daemon/firewall/nftables/exprs/ct_test.go",
"chars": 5101,
"preview": "package exprs_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/"
},
{
"path": "daemon/firewall/nftables/exprs/enums.go",
"chars": 5734,
"preview": "package exprs\n\n// keywords used in the configuration to define rules.\nconst (\n\tTABLE_OPENSNITCH = \"opensnitch\"\n\tCHAI"
},
{
"path": "daemon/firewall/nftables/exprs/ether.go",
"chars": 1423,
"preview": "package exprs\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\""
},
{
"path": "daemon/firewall/nftables/exprs/ether_test.go",
"chars": 2747,
"preview": "package exprs_test\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n"
},
{
"path": "daemon/firewall/nftables/exprs/iface.go",
"chars": 690,
"preview": "package exprs\n\nimport (\n\t\"github.com/google/nftables/expr\"\n)\n\n// NewExprIface returns a new network interface expression"
},
{
"path": "daemon/firewall/nftables/exprs/iface_test.go",
"chars": 2274,
"preview": "package exprs_test\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables"
},
{
"path": "daemon/firewall/nftables/exprs/ip.go",
"chars": 3903,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.co"
},
{
"path": "daemon/firewall/nftables/exprs/ip_test.go",
"chars": 6427,
"preview": "package exprs_test\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/"
},
{
"path": "daemon/firewall/nftables/exprs/limit.go",
"chars": 2060,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/googl"
},
{
"path": "daemon/firewall/nftables/exprs/log.go",
"chars": 1810,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/evilsocket/opens"
},
{
"path": "daemon/firewall/nftables/exprs/log_test.go",
"chars": 3277,
"preview": "package exprs_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\texprs \"github.com/e"
},
{
"path": "daemon/firewall/nftables/exprs/meta.go",
"chars": 3491,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/googl"
},
{
"path": "daemon/firewall/nftables/exprs/meta_test.go",
"chars": 4095,
"preview": "package exprs_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/evilsoc"
},
{
"path": "daemon/firewall/nftables/exprs/nat.go",
"chars": 4151,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/google/nftables\"\n\t\"github.com/google/nftables/"
},
{
"path": "daemon/firewall/nftables/exprs/nat_test.go",
"chars": 12322,
"preview": "package exprs_test\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"git"
},
{
"path": "daemon/firewall/nftables/exprs/notrack.go",
"chars": 196,
"preview": "package exprs\n\nimport \"github.com/google/nftables/expr\"\n\n// NewNoTrack adds a new expression not to track connections.\nf"
},
{
"path": "daemon/firewall/nftables/exprs/operator.go",
"chars": 583,
"preview": "package exprs\n\nimport (\n\t\"github.com/google/nftables/expr\"\n)\n\n// NewOperator translates a string comparator operator to "
},
{
"path": "daemon/firewall/nftables/exprs/port.go",
"chars": 2257,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/google/nftables\"\n\t\"github.com/google/nftables/binaryu"
},
{
"path": "daemon/firewall/nftables/exprs/port_test.go",
"chars": 3302,
"preview": "package exprs_test\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\texprs \"github.com/evilsocket/opensnitch/daemon/fire"
},
{
"path": "daemon/firewall/nftables/exprs/protocol.go",
"chars": 2801,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/nftables\"\n\t\"github.com/google/nftables/expr\"\n\t\"golang.org"
},
{
"path": "daemon/firewall/nftables/exprs/protocol_test.go",
"chars": 2372,
"preview": "package exprs_test\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\texprs \"github.com/evilsocket/opensnitch/daemon/firewall/nfta"
},
{
"path": "daemon/firewall/nftables/exprs/quota.go",
"chars": 1672,
"preview": "package exprs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/googl"
},
{
"path": "daemon/firewall/nftables/exprs/quota_test.go",
"chars": 4360,
"preview": "package exprs_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/evilsoc"
},
{
"path": "daemon/firewall/nftables/exprs/utils.go",
"chars": 5520,
"preview": "package exprs\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/google/gopacket/layers\"\n\t\"golang.org/x/sys/unix\"\n)\n\n// GetICMPRejectCod"
},
{
"path": "daemon/firewall/nftables/exprs/verdict.go",
"chars": 4939,
"preview": "package exprs\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/google/nftabl"
},
{
"path": "daemon/firewall/nftables/exprs/verdict_test.go",
"chars": 8883,
"preview": "package exprs_test\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/e"
},
{
"path": "daemon/firewall/nftables/monitor.go",
"chars": 2299,
"preview": "package nftables\n\nimport (\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/common\"\n\t\"github.com/evilsocket/o"
},
{
"path": "daemon/firewall/nftables/monitor_test.go",
"chars": 2985,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/common\"\n\tnftb \"gi"
},
{
"path": "daemon/firewall/nftables/nftables.go",
"chars": 5264,
"preview": "package nftables\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firew"
},
{
"path": "daemon/firewall/nftables/nftest/nftest.go",
"chars": 1772,
"preview": "package nftest\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"testing\"\n\n\tnftb \"github.com/evilsocket/opensnitch/daemon/firewall/nftables\"\n"
},
{
"path": "daemon/firewall/nftables/nftest/test_utils.go",
"chars": 6854,
"preview": "package nftest\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"gi"
},
{
"path": "daemon/firewall/nftables/nftest/utils.go",
"chars": 2819,
"preview": "package nftest\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github.com/goo"
},
{
"path": "daemon/firewall/nftables/parser.go",
"chars": 6672,
"preview": "package nftables\n\nimport (\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/evilsocket/opensnitch"
},
{
"path": "daemon/firewall/nftables/rule_helpers.go",
"chars": 6203,
"preview": "package nftables\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"github.com/ev"
},
{
"path": "daemon/firewall/nftables/rules.go",
"chars": 7813,
"preview": "package nftables\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github.com/evils"
},
{
"path": "daemon/firewall/nftables/rules_test.go",
"chars": 6254,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\n\tnftb \"github.com/evilsocket/opensnitch/daemon/firewall/nftables\"\n\t\"github.c"
},
{
"path": "daemon/firewall/nftables/system.go",
"chars": 4948,
"preview": "package nftables\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/config\"\n\t\"githu"
},
{
"path": "daemon/firewall/nftables/system_test.go",
"chars": 4679,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github."
},
{
"path": "daemon/firewall/nftables/tables.go",
"chars": 1867,
"preview": "package nftables\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github.com/evils"
},
{
"path": "daemon/firewall/nftables/tables_test.go",
"chars": 3040,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\n\tnftb \"github.com/evilsocket/opensnitch/daemon/firewall/nftables\"\n\t\"github.c"
},
{
"path": "daemon/firewall/nftables/testdata/test-sysfw-conf.json",
"chars": 4356,
"preview": "{\n \"Enabled\": true,\n \"Version\": 1,\n \"SystemRules\": [\n {\n \"Chains\": [\n {\n \"Name\": \"filter_inpu"
},
{
"path": "daemon/firewall/nftables/utils.go",
"chars": 6193,
"preview": "package nftables\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/nftables/exprs\"\n\t\"github.com/e"
},
{
"path": "daemon/firewall/nftables/utils_test.go",
"chars": 7659,
"preview": "package nftables_test\n\nimport (\n\t\"testing\"\n\n\tnftb \"github.com/evilsocket/opensnitch/daemon/firewall/nftables\"\n\t\"github.c"
},
{
"path": "daemon/firewall/rules.go",
"chars": 4745,
"preview": "package firewall\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/firewall/common\"\n\t\"github.com/evilsocket/op"
},
{
"path": "daemon/go.mod",
"chars": 879,
"preview": "module github.com/evilsocket/opensnitch/daemon\n\ngo 1.23.0\n\n//toolchain go1.24.4\n\nrequire (\n\tgithub.com/cilium/ebpf v0.19"
},
{
"path": "daemon/go.sum",
"chars": 10102,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1/go."
},
{
"path": "daemon/internal/testutil/network.go",
"chars": 7688,
"preview": "//go:build linux\n\n/*\nPackage testutil provides test infrastructure for OpenSnitch integration tests.\n\nNetwork Test Harne"
},
{
"path": "daemon/log/formats/csv.go",
"chars": 966,
"preview": "package formats\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/ui/protocol\"\n)\n\n// CSV name of the output fo"
},
{
"path": "daemon/log/formats/formats.go",
"chars": 1773,
"preview": "package formats\n\nimport (\n\t\"log/syslog\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"g"
},
{
"path": "daemon/log/formats/json.go",
"chars": 1796,
"preview": "package formats\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\ttaskBase \"github.com/evilso"
},
{
"path": "daemon/log/formats/rfc3164.go",
"chars": 1271,
"preview": "package formats\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\ttaskBase \"github.com/evilsocket/opensnitch/daemon/tasks/base\"\n\t\"github.com/ev"
},
{
"path": "daemon/log/formats/rfc5424.go",
"chars": 1363,
"preview": "package formats\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\ttaskBase \"github.com/evilsocket/opensnitch/daemon/tasks/base\"\n\t\"github.com/ev"
},
{
"path": "daemon/log/log.go",
"chars": 5088,
"preview": "package log\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype Handler func(format string, args ...interface{})\n\n"
},
{
"path": "daemon/log/loggers/logger.go",
"chars": 4568,
"preview": "package loggers\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\nconst log"
},
{
"path": "daemon/log/loggers/remote.go",
"chars": 6292,
"preview": "package loggers\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/syslog\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"gith"
},
{
"path": "daemon/log/loggers/remote_syslog.go",
"chars": 772,
"preview": "package loggers\n\nimport (\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\nconst (\n\tLOGGER_REMOTE_SYSLOG = \"remote_sysl"
},
{
"path": "daemon/log/loggers/syslog.go",
"chars": 1733,
"preview": "package loggers\n\nimport (\n\t\"log/syslog\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/evilsocket/opensnit"
},
{
"path": "daemon/main.go",
"chars": 20375,
"preview": "/* Copyright (C) 2018 Simone Margaritelli\n// 2021 themighty1\n// 2022 ca"
},
{
"path": "daemon/netfilter/netfilter_test.go",
"chars": 21229,
"preview": "//go:build linux\n\n/*\nNetfilter/NFQueue Tests\n\nIntegration tests for OpenSnitch's netfilter queue packet interception.\n\nR"
},
{
"path": "daemon/netfilter/packet.go",
"chars": 1553,
"preview": "package netfilter\n\nimport \"C\"\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\n// packet consts\nconst (\n\tIPv4 = 4\n)\n\n// Verdic"
},
{
"path": "daemon/netfilter/queue.c",
"chars": 20,
"preview": "#include \"queue.h\"\n\n"
},
{
"path": "daemon/netfilter/queue.go",
"chars": 6810,
"preview": "package netfilter\n\n/*\n#cgo pkg-config: libnetfilter_queue\n#cgo CFLAGS: -I/usr/include\n#cgo LDFLAGS: -L/usr/lib64/ -ldl\n\n"
},
{
"path": "daemon/netfilter/queue.h",
"chars": 3280,
"preview": "#ifndef _NETFILTER_QUEUE_H\n#define _NETFILTER_QUEUE_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#inclu"
},
{
"path": "daemon/netlink/ifaces.go",
"chars": 1234,
"preview": "package netlink\n\nimport (\n\t\"net\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/vishvananda/netlink\"\n)\n\n//"
},
{
"path": "daemon/netlink/procmon/procmon.go",
"chars": 3688,
"preview": "package procmon\n\nimport (\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/vishvananda/ne"
},
{
"path": "daemon/netlink/socket.go",
"chars": 8488,
"preview": "package netlink\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"syscall\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.c"
},
{
"path": "daemon/netlink/socket_linux.go",
"chars": 6843,
"preview": "package netlink\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"syscall\"\n\n\t\"github.com/evilsocket/opensnitch/daem"
},
{
"path": "daemon/netlink/socket_packet.go",
"chars": 5447,
"preview": "package netlink\n\nimport (\n\t\"encoding/binary\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"gith"
},
{
"path": "daemon/netlink/socket_test.go",
"chars": 2982,
"preview": "package netlink\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n)\n\ntype Connection struct {\n\tSrcIP net"
},
{
"path": "daemon/netlink/socket_xdp.go",
"chars": 239,
"preview": "package netlink\n\nimport (\n\tvnl \"github.com/vishvananda/netlink\"\n)\n\n// SocketGetXDP dumps all the opened XDP sockets from"
},
{
"path": "daemon/netstat/entry.go",
"chars": 785,
"preview": "package netstat\n\nimport (\n\t\"net\"\n)\n\n// Entry holds the information of a /proc/net/* entry.\n// For example, /proc/net/tcp"
},
{
"path": "daemon/netstat/find.go",
"chars": 1330,
"preview": "package netstat\n\nimport (\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evilsocket/ope"
},
{
"path": "daemon/netstat/parse.go",
"chars": 2730,
"preview": "package netstat\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"net\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensni"
},
{
"path": "daemon/netstat/parse_packet.go",
"chars": 1371,
"preview": "package netstat\n\nimport (\n\t\"bufio\"\n\t\"os\"\n\t\"regexp\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evilsoc"
},
{
"path": "daemon/procmon/activepids.go",
"chars": 1631,
"preview": "package procmon\n\nimport (\n\t\"sync\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/evilsocket/opensnitch/dae"
},
{
"path": "daemon/procmon/audit/client.go",
"chars": 9305,
"preview": "// Package audit reads auditd events from the builtin af_unix plugin, and parses\n// the messages in order to proactively"
},
{
"path": "daemon/procmon/audit/config.go",
"chars": 325,
"preview": "package audit\n\nimport \"github.com/evilsocket/opensnitch/daemon/log\"\n\n// Config holds the configuration to customize ebpf"
},
{
"path": "daemon/procmon/audit/parse.go",
"chars": 7846,
"preview": "package audit\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"net\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\tnewEvent = false\n\tnetEve"
},
{
"path": "daemon/procmon/cache.go",
"chars": 7473,
"preview": "package procmon\n\nimport (\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n)\n\n/"
},
{
"path": "daemon/procmon/cache_events.go",
"chars": 10125,
"preview": "package procmon\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\nvar (\n\t// EventsCache is th"
},
{
"path": "daemon/procmon/cache_events_test.go",
"chars": 5297,
"preview": "package procmon\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar (\n\tourPid = os.Getpid()\n)\n\nfunc createNewProc(pid int) *Proces"
},
{
"path": "daemon/procmon/cache_test.go",
"chars": 3461,
"preview": "package procmon\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCacheProcs(t *testing.T) {\n\tfdList := []string{\"0\", \"1\","
},
{
"path": "daemon/procmon/details.go",
"chars": 18560,
"preview": "package procmon\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/md5\"\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"io/iouti"
},
{
"path": "daemon/procmon/ebpf/cache.go",
"chars": 2330,
"preview": "package ebpf\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype ebpfCacheItem struct {\n\tKey []byte\n\tLastSeen int64\n\tPid int\n\tUI"
},
{
"path": "daemon/procmon/ebpf/config.go",
"chars": 1321,
"preview": "package ebpf\n\nimport \"github.com/evilsocket/opensnitch/daemon/log\"\n\n// Config holds the configuration to customize ebpf "
},
{
"path": "daemon/procmon/ebpf/debug.go",
"chars": 1775,
"preview": "package ebpf\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"syscall\"\n\n\tdaemonNetlink \"github.com/evilsocket/opensnitch/daemon/"
},
{
"path": "daemon/procmon/ebpf/ebpf.go",
"chars": 9034,
"preview": "package ebpf\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/cilium/ebpf\"\n\t\"gi"
},
{
"path": "daemon/procmon/ebpf/ebpf_test.go",
"chars": 44915,
"preview": "//go:build linux\n\n/*\neBPF Tests\n\nIntegration tests for OpenSnitch's eBPF programs.\n\nRunning Tests:\n\n\tsudo go test -v ./d"
},
{
"path": "daemon/procmon/ebpf/events.go",
"chars": 9700,
"preview": "package ebpf\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/cilium/ebpf\"\n\t\"github.com/cilium/ebpf/"
},
{
"path": "daemon/procmon/ebpf/find.go",
"chars": 7788,
"preview": "package ebpf\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"gi"
},
{
"path": "daemon/procmon/ebpf/monitor.go",
"chars": 4011,
"preview": "package ebpf\n\nimport (\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"github.com/evilsocket/opens"
},
{
"path": "daemon/procmon/ebpf/utils.go",
"chars": 3684,
"preview": "package ebpf\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"unsafe\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"g"
},
{
"path": "daemon/procmon/find.go",
"chars": 2836,
"preview": "package procmon\n\nimport (\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n)\n\nfunc sortPidsByTi"
},
{
"path": "daemon/procmon/find_test.go",
"chars": 892,
"preview": "package procmon\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestGetProcPids(t *testing.T) {\n\tpids := getProcPids(\"/proc\")\n\n\tif l"
},
{
"path": "daemon/procmon/monitor/init.go",
"chars": 3600,
"preview": "package monitor\n\nimport (\n\t\"context\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\tnetlinkProcmon \"github.com/evilsoc"
},
{
"path": "daemon/procmon/parse.go",
"chars": 3514,
"preview": "package procmon\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/evilsocket/"
},
{
"path": "daemon/procmon/process.go",
"chars": 6236,
"preview": "package procmon\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n\t\"githu"
},
{
"path": "daemon/procmon/process_test.go",
"chars": 4323,
"preview": "package procmon\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/core\"\n)\n\nvar (\n\t"
},
{
"path": "daemon/rule/loader.go",
"chars": 13333,
"preview": "package rule\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\""
},
{
"path": "daemon/rule/loader_test.go",
"chars": 10011,
"preview": "package rule\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar tmpDir string\n\nfunc TestMain(m *testing"
},
{
"path": "daemon/rule/operator.go",
"chars": 12096,
"preview": "package rule\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os/user\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evilsocket/opensni"
},
{
"path": "daemon/rule/operator_aliases.go",
"chars": 1361,
"preview": "package rule\n\nimport (\n\t\"encoding/json\"\n\t\"net\"\n\t\"os\"\n)\n\nvar NetworkAliases = make(map[string][]string)\nvar AliasIPCache "
},
{
"path": "daemon/rule/operator_lists.go",
"chars": 7377,
"preview": "package rule\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gith"
},
{
"path": "daemon/rule/operator_test.go",
"chars": 24532,
"preview": "package rule\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/conm"
},
{
"path": "daemon/rule/rule.go",
"chars": 4689,
"preview": "package rule\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/conman\"\n\t\"github.com/evilsocket/opensni"
},
{
"path": "daemon/rule/rule_test.go",
"chars": 3219,
"preview": "package rule\n\nimport (\n\t\"testing\"\n)\n\nfunc TestCreate(t *testing.T) {\n\tt.Log(\"Test: Create rule\")\n\n\tvar list []Operator\n\t"
},
{
"path": "daemon/rule/testdata/000-allow-chrome.json",
"chars": 376,
"preview": "{\n \"created\": \"2020-12-13T18:06:52.209804547+01:00\",\n \"updated\": \"2020-12-13T18:06:52.209857713+01:00\",\n \"name\": \"000"
},
{
"path": "daemon/rule/testdata/001-deny-chrome.json",
"chars": 375,
"preview": "{\n \"created\": \"2020-12-13T17:54:49.067148304+01:00\",\n \"updated\": \"2020-12-13T17:54:49.067213602+01:00\",\n \"name\": \"001"
},
{
"path": "daemon/rule/testdata/invalid-regexp-list.json",
"chars": 854,
"preview": "{\n \"created\": \"2020-12-13T18:06:52.209804547+01:00\",\n \"updated\": \"2020-12-13T18:06:52.209857713+01:00\",\n \"name\": \"inv"
},
{
"path": "daemon/rule/testdata/invalid-regexp.json",
"chars": 380,
"preview": "{\n \"created\": \"2020-12-13T18:06:52.209804547+01:00\",\n \"updated\": \"2020-12-13T18:06:52.209857713+01:00\",\n \"name\": \"inv"
},
{
"path": "daemon/rule/testdata/lists/domains/domainlists.txt",
"chars": 116,
"preview": "# this line must be ignored, 0.0.0.0 www.test.org\n0.0.0.0 www.test.org\n127.0.0.1 www.test.org\n0.0.0.0 opensnitch.io\n"
},
{
"path": "daemon/rule/testdata/lists/ips/ips.txt",
"chars": 151,
"preview": "# this line must be ignored, 0.0.0.0 www.test.org\n\n# empty lines are also ignored\n1.1.1.1\n185.53.178.14\n# duplicated ent"
},
{
"path": "daemon/rule/testdata/lists/nets/nets.txt",
"chars": 160,
"preview": "# this line must be ignored, 0.0.0.0 www.test.org\n\n# empty lines are also ignored\n1.1.1.0/24\n185.53.178.0/24\n# duplicate"
},
{
"path": "daemon/rule/testdata/lists/regexp/domainsregexp.txt",
"chars": 90,
"preview": "# this line must be ignored, 0.0.0.0 www.test.org\nwww.test.org\nwww.test.org\nopensnitch.io\n"
},
{
"path": "daemon/rule/testdata/live_reload/test-live-reload-delete.json",
"chars": 400,
"preview": "{\n \"created\": \"2020-12-13T18:06:52.209804547+01:00\",\n \"updated\": \"2020-12-13T18:06:52.209857713+01:00\",\n \"name\""
},
{
"path": "daemon/rule/testdata/live_reload/test-live-reload-remove.json",
"chars": 400,
"preview": "{\n \"created\": \"2020-12-13T18:06:52.209804547+01:00\",\n \"updated\": \"2020-12-13T18:06:52.209857713+01:00\",\n \"name\""
},
{
"path": "daemon/rule/testdata/rule-disabled-operator-list-expanded.json",
"chars": 683,
"preview": "{\n \"created\": \"2023-10-03T18:06:52.209804547+01:00\",\n \"updated\": \"2023-10-03T18:06:52.209857713+01:00\",\n \"name\": \"rul"
},
{
"path": "daemon/rule/testdata/rule-disabled-operator-list.json",
"chars": 580,
"preview": "{\n \"created\": \"2023-10-03T18:06:52.209804547+01:00\",\n \"updated\": \"2023-10-03T18:06:52.209857713+01:00\",\n \"name\": \"rul"
},
{
"path": "daemon/rule/testdata/rule-operator-list-data-empty.json",
"chars": 675,
"preview": "{\n \"created\": \"2023-10-03T18:06:52.209804547+01:00\",\n \"updated\": \"2023-10-03T18:06:52.209857713+01:00\",\n \"name\": \"rul"
},
{
"path": "daemon/rule/testdata/rule-operator-list.json",
"chars": 863,
"preview": "{\n \"created\": \"2023-10-03T18:06:52.209804547+01:00\",\n \"updated\": \"2023-10-03T18:06:52.209857713+01:00\",\n \"name\": \"rul"
},
{
"path": "daemon/statistics/event.go",
"chars": 681,
"preview": "package statistics\n\nimport (\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/conman\"\n\t\"github.com/evilsocket/opensnit"
},
{
"path": "daemon/statistics/stats.go",
"chars": 6985,
"preview": "package statistics\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/conman\"\n\t\""
},
{
"path": "daemon/tasks/base/main.go",
"chars": 2453,
"preview": "package base\n\nimport (\n\t\"context\"\n)\n\nconst (\n\tPID_MON = 9000\n\tNODE_MON = 9001\n\tSOCKETS_MON = 9002\n\tDOWNLOADER "
},
{
"path": "daemon/tasks/config/main.go",
"chars": 2680,
"preview": "package config\n\n// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by"
},
{
"path": "daemon/tasks/config/monitor.go",
"chars": 2596,
"preview": "package config\n\nimport (\n\t//\"path\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/fsnot"
},
{
"path": "daemon/tasks/config/utils.go",
"chars": 542,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\nfunc Lo"
},
{
"path": "daemon/tasks/doc.go",
"chars": 1008,
"preview": "package tasks\n\n// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by "
},
{
"path": "daemon/tasks/downloader/README.md",
"chars": 2310,
"preview": "### Download task\n\nA simple task to download files in background, at regular intervals.\n\nThis task can be used for examp"
},
{
"path": "daemon/tasks/downloader/config.go",
"chars": 1053,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/downloader/downloader.go",
"chars": 2547,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/downloader/main.go",
"chars": 4618,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/downloader/utils.go",
"chars": 1693,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/README.md",
"chars": 6344,
"preview": "\n### IOC scanner task\n\nThis task is meant to scan for Indicators Of Compromise in the system, periodically, and in backg"
},
{
"path": "daemon/tasks/iocscanner/config/config.go",
"chars": 4569,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/main.go",
"chars": 4998,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/run_tools.go",
"chars": 1664,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/tools/base/base.go",
"chars": 1618,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/tools/dpkg/dpkg.go",
"chars": 4089,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/tools/executer/executer.go",
"chars": 2356,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/tools/generic/generic.go",
"chars": 3465,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/iocscanner/tools/yara/yara.go",
"chars": 6049,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/load.go",
"chars": 4235,
"preview": "package tasks\n\nimport (\n\t//\"fmt\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n\t\"github.com/evilsocket/opensnitch/daem"
},
{
"path": "daemon/tasks/looptask/main.go",
"chars": 2243,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/main.go",
"chars": 4768,
"preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t//\"io/ioutil\"\n\t//\"strconv\"\n\t//\"encoding/json\"\n\t\"sync\"\n\n\t\"github.com/evilsocke"
},
{
"path": "daemon/tasks/main_test.go",
"chars": 1575,
"preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/tasks/base\"\n)\n\ntype BasicTask s"
},
{
"path": "daemon/tasks/nodemonitor/main.go",
"chars": 2639,
"preview": "package nodemonitor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/evil"
},
{
"path": "daemon/tasks/nodemonitor/main_test.go",
"chars": 1840,
"preview": "package nodemonitor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensni"
},
{
"path": "daemon/tasks/pidmonitor/main.go",
"chars": 2821,
"preview": "package pidmonitor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/evilsocket/opens"
},
{
"path": "daemon/tasks/pidmonitor/main_test.go",
"chars": 1966,
"preview": "package pidmonitor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/da"
},
{
"path": "daemon/tasks/scheduler/daily.go",
"chars": 5209,
"preview": "package scheduler\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/log\"\n)\n\n// if the comp"
},
{
"path": "daemon/tasks/scheduler/scheduler.go",
"chars": 4096,
"preview": "// Copyright 2025 The OpenSnitch Authors. All rights reserved.\n// Use of this source code is governed by the GPLv3\n// li"
},
{
"path": "daemon/tasks/socketsmonitor/dump.go",
"chars": 5014,
"preview": "package socketsmonitor\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\t\"syscall\"\n\n\t\"github.com/evilsocket/opensnitch/daemon/"
},
{
"path": "daemon/tasks/socketsmonitor/main.go",
"chars": 3320,
"preview": "package socketsmonitor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/evilsocket/o"
},
{
"path": "daemon/tasks/socketsmonitor/options.go",
"chars": 1211,
"preview": "package socketsmonitor\n\nimport (\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// Protos holds valid combinations of protocols"
}
]
// ... and 241 more files (download for full content)
About this extraction
This page contains the full source code of the evilsocket/opensnitch GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 441 files (6.9 MB), approximately 1.8M tokens, and a symbol index with 3167 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.