Skip to content

Commit 8d71e85

Browse files
authored
Merge branch 'develop' into amgp_timeout
2 parents 0622a55 + 1a92ae8 commit 8d71e85

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+945
-642
lines changed

.github/workflows/debian-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434

3535
- name: Upload artifact
3636
if: ${{ github.event_name == 'push' }}
37-
uses: actions/upload-artifact@v3
37+
uses: actions/upload-artifact@v4
3838
with:
3939
name: debian-package-${{ matrix.codename }}-${{ github.sha }}
4040
path: '~/artifacts'

.github/workflows/python/github.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@ def __init__(self):
3131

3232
def get_reviews(self):
3333
""" Get a list of reviews on a Github pull request as json object """
34-
reviews = self.session.get(self.api + 'repos/{}/pulls/{}/reviews'.format(self.github_repository, self.pr_id))
34+
reviews = self.session.get(self.api + f'repos/{self.github_repository}/pulls/{self.pr_id}/reviews')
3535
reviews.raise_for_status()
3636
return reviews.json()
3737

3838
def update_review(self, review_id, body):
3939
""" Update a review given by `review_id` and set its body to `body` """
4040
payload = {'body': body}
41-
resp = self.session.put(self.api + 'repos/{}/pulls/{}/reviews/{}'.format(self.github_repository, self.pr_id, review_id), json=payload)
41+
resp = self.session.put(self.api + f'repos/{self.github_repository}/pulls/{self.pr_id}/reviews/{review_id}', json=payload)
4242
resp.raise_for_status()
4343
return resp.json()
4444

4545
def post_review(self, body):
4646
""" Post a pull request review containing `body` and requesting changes """
4747
payload = {'body': body, 'event': "REQUEST_CHANGES"}
48-
resp = self.session.post(self.api + 'repos/{}/pulls/{}/reviews'.format(self.github_repository, self.pr_id), json=payload)
48+
resp = self.session.post(self.api + f'repos/{self.github_repository}/pulls/{self.pr_id}/reviews', json=payload)
4949
resp.raise_for_status()
5050
return resp.json()

.github/workflows/python/pycodestyle_comment.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def style_error_format(style_error_list) -> str:
3434
""" Format the list of pycodestyle errors and return them a one string. """
3535
ret = ''
3636
for error in style_error_list:
37-
ret += '* {}\n'.format(error)
37+
ret += f'* {error}\n'
3838
return ret
3939

4040

@@ -45,7 +45,7 @@ def style_error_format(style_error_list) -> str:
4545
style_errors = list_style_errors()
4646

4747
if style_errors:
48-
print("Found {} errors.".format(len(style_errors)))
48+
print(f"Found {len(style_errors)} errors.")
4949

5050
gh = github.Github()
5151

.github/workflows/scripts/setup-full.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
# SPDX-FileCopyrightText: 2020 Birger Schacht
2+
# SPDX-FileCopyrightText: 2020 Birger Schacht, 2024 Institute for Common Good Technology
33
# SPDX-License-Identifier: AGPL-3.0-or-later
44

55
set -x
@@ -14,6 +14,14 @@ echo -e '-XX:+DisableExplicitGC\n-Djdk.io.permissionsUseCanonicalPath=true\n-Dlo
1414
sudo chown -R elasticsearch:elasticsearch /etc/default/elasticsearch
1515
sudo systemctl start elasticsearch
1616

17+
sudo apt update
18+
if [ $python_version == '3.8' ]; then
19+
# for pymssql there are no wheels for 3.8 https://github.com/certtools/intelmq/issues/2539
20+
DEBIAN_FRONTEND="noninteractive" sudo -E apt install -y build-essential freetds-dev libssl-dev libkrb5-dev
21+
fi
22+
# for psql (used below)
23+
DEBIAN_FRONTEND="noninteractive" sudo -E apt install -y postgresql-client
24+
1725
# Install the dependencies of all the bots
1826
pip install wheel
1927
for file in intelmq/bots/*/*/REQUIREMENTS.txt; do
@@ -30,7 +38,16 @@ done
3038
# Setup sudo and install intelmq
3139
sudo sed -i '/^Defaults\tsecure_path.*$/ d' /etc/sudoers
3240
sudo pip install .
33-
sudo intelmqsetup --skip-ownership
41+
42+
intelmq_user_exists=$(getent passwd intelmq ||:)
43+
if [[ "$UID" -eq '0' && -z "$intelmq_user_exists" ]]; then
44+
# create an unprivileged user, if currently running as root. Otherwise dropping privileges won't work
45+
groupadd -r intelmq
46+
useradd -r -d /var/lib/intelmq/ -c "user running intelmq" -g intelmq -s /bin/bash intelmq
47+
sudo intelmqsetup
48+
else
49+
sudo intelmqsetup --skip-ownership
50+
fi
3451

3552
# Initialize the postgres database
3653
intelmq_psql_initdb

.github/workflows/unittests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
strategy:
1919
fail-fast: false
2020
matrix:
21-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
21+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
2222
type: ['full', 'basic']
2323

2424
services:
@@ -59,6 +59,7 @@ jobs:
5959
PGPORT: 5432
6060
PGUSER: intelmq
6161
PGPASSWORD: intelmq
62+
python_version: ${{ matrix.python-version }}
6263
run: bash .github/workflows/scripts/setup-full.sh
6364

6465
- name: Install test dependencies

CHANGELOG.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- comment
2-
SPDX-FileCopyrightText: 2015-2024 Sebastian Wagner
2+
SPDX-FileCopyrightText: 2015-2025 Sebastian Wagner
33
SPDX-License-Identifier: AGPL-3.0-or-later
44
-->
55

@@ -13,27 +13,59 @@
1313

1414
### Core
1515
- AMQP: Fix maintaining pipeline connection when during interrupted connections (PR#2533 by Kamil Mankowski).
16+
- Python 3.8 or newer is required (PR#2541 by Sebastian Wagner).
17+
- `intelmq.lib.utils.list_all_bots`/`intelmqctl check`: Fix check for bot executable in $PATH by using the bot name instead of the import path (fixes #2559, PR#2564 by Sebastian Wagner).
1618

1719
### Development
1820

1921
### Data Format
2022

2123
### Bots
2224
#### Collectors
25+
- `intelmq.bots.collectors.shadowserver.collector_reports_api.py`:
26+
- Fixed behaviour if parameter `types` value is empty string, behave the same way as not set, not like no type.
27+
- `intelmq.bots.collectors.misp`: Use `PyMISP` class instead of deprecated `ExpandedPyMISP` (PR#2532 by Radek Vyhnal)
28+
- `intelmq.bots.collectors.http.collector_http`: Log the downloaded size in bytes to ease troubleshooting (PR#2554 by Sebastian Wagner).
29+
- `intelmq.bots.collectors.mail.collector_mail_url`:
30+
- Log the downloaded size in bytes to ease troubleshooting (PR#2554 by Sebastian Wagner).
31+
- Fix import for Timeout exception preventing another exception (fixes #2555, PR#2556 by Sebastian Wagner).
32+
- Remove `intelmq.bots.collectors.twitter` as it uses an unmaintained library and does not work any more (fixes #2346, #2441, PR#2568 by Sebastian Wagner).
33+
- Renamed `intelmq.bots.parser.twitter` to `intelmq.bots.parser.ioc_extractor` (PR#2568 by Sebastian Wagner).
34+
- Added `intelmq.bots.parser.twitter` as a stub to load the IoC Extractor parser.
2335

2436
#### Parsers
2537
- `intelmq.bots.parsers.shadowserver._config`:
2638
- fix error message formatting if schema file is absent (PR#2528 by Sebastian Wagner).
39+
- `intelmq.bots.parsers.shadowserver.parser`:
40+
- Fix to avoid schema download if not configured #2530.
2741

2842
#### Experts
43+
- `intelmq.bots.experts.securitytxt`:
44+
- Added new bot (PR#2538 by Frank Westers and Sebastian Wagner)
45+
- `intelmq.bots.experts.misp`: Use `PyMISP` class instead of deprecated `ExpandedPyMISP` (PR#2532 by Radek Vyhnal)
2946

3047
#### Outputs
48+
- `intelmq.bots.outputs.cif3.output`:
49+
- The requirement can only be installed on Python version < 3.12.
50+
- Add a check on the Python version and exit if incompatible.
51+
- Add a deprecation warning (PR#2544 by Sebastian Wagner)
52+
- `intelmq.bots.outputs.sql.output`:
53+
- Treat an empty string `fields` parameter as unset parameter, fixing a crash in default configuration (PR#2548 by Sebastian Wagner, fixes #2548).
3154

3255
### Documentation
56+
- `docs/admin/installation/linux-packages`: Add `[signed-by=]` options, add wget command as alternative to curl (PR#2547 by Sebastian Wagner).
57+
- Add documentation on the Redis pipeline (databases, configuration), fix generic pipeline documentation and add missing information on parameters, add unlinked intelmqctl docs to the index and TOC (PR#2560 by Sebastian Wagner).
58+
- Remove empty page tutorials/intelmq-manager (PR#2562 by Sebastian Wagner).
3359

3460
### Packaging
3561

3662
### Tests
63+
- Install build dependencies for `pymssql` on Python 3.8 as there are no wheels available for this Python version (PR#2542 by Sebastian Wagner).
64+
- Install `psql` explicitly for workflow support on other platforms such as act (PR#2542 by Sebastian Wagner).
65+
- Create intelmq user & group if running privileged to allow dropping privileges (PR#2542 by Sebastian Wagner).
66+
- `intelmq.tests.lib.test_pipeline.TestAmqp.test_acknowledge`: Also skip on Python 3.11 and 3.12 besides on 3.8 when running on CI (PR#2542 by Sebastian Wagner).
67+
- Full pytest workflow: Version-independent install of postgres client, for Ubuntu 24.04 (default on GitHub now) test environment compatibility (PR#2557 by Sebastian Wagner).
68+
- Debian package build workflow: Use artifact upload v4 instead of v3 (PR#2565 by Sebastian Wagner).
3769

3870
### Tools
3971

@@ -340,7 +372,7 @@ This is short list of the most important known issues. The full list can be retr
340372
- Added an ExpertBot class - it should be used by all expert bots as a parent class
341373
- Introduced a module for IntelMQ related datatypes `intelmq.lib.datatypes` which for now only contains an Enum listing the four bot types
342374
- Added a `bottype` attribute to CollectorBot, ParserBot, ExpertBot, OutputBot
343-
- Introduces a module for IntelMQ processmanagers. The processmanagers were up until now part of the intelmqct script.
375+
- Introduces a module for IntelMQ processmanagers. The processmanagers were up until now part of the intelmqctl script.
344376
They now reside in `intelmq.lib.processmanager` which also contains an interface definition the processmanager implementations must adhere to.
345377
Both the processmanagers and the `intelmqctl` script were cleaned up a bit.
346378
The `LogLevel` and `ReturnType` Enums were added to `intelmq.lib.datatypes`.

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ codespell:
1919

2020
test:
2121
pytest --no-cov -v intelmq/tests/ && echo "Success!"
22+
23+
codestyle:
24+
pycodestyle intelmq/{bots,lib,bin}

NEWS.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ Please refer to the change log for a full list of changes.
1414
---------------------------------
1515

1616
### Requirements
17+
Python 3.8 or newer is required.
18+
19+
## Bots
20+
#### CIF 3 API
21+
The CIF 3 API Output bot is not compatible with Python version greater or equal to 3.12 and will be removed in the future due to lack of maintenance.
22+
See https://lists.cert.at/pipermail/intelmq-users/2024-December/000474.html for more information.
1723

1824
### Tools
1925

@@ -36,7 +42,7 @@ No changes are required by administrators.
3642
----------------------------------
3743

3844
### Documentation
39-
The documentation is now available at [docs.intelmq.org](https://docs.intelmq.org/). Documentation has been updated and restructured into User, Administrator and Developer Guide. It provides modern look with various quality of life improvements. Big thanks to to @gethvi.
45+
The documentation is now available at [docs.intelmq.org](https://docs.intelmq.org/). Documentation has been updated and restructured into User, Administrator and Developer Guide. It provides modern look with various quality of life improvements. Big thanks to to @gethvi.
4046
We now have a slick, modern mkdocs based documentation. Please do check it out!
4147

4248

@@ -55,7 +61,7 @@ Shadowserver adds new scans on a nearly weekly basis. IntelMQ's release cycle an
5561
We therefore (thanks to @eslif2) move the shadowserver reports collector and parser to a new, dynamic system. It can:
5662

5763
- fetch the shadowserver schema from shadowserver (https://interchange.shadowserver.org/intelmq/v1/schema)
58-
- dynamically collect new reports (see also https://docs.intelmq.org/latest/user/bots/?h=shadow#shadowserver-reports-api)
64+
- dynamically collect new reports (see also https://docs.intelmq.org/latest/user/bots/?h=shadow#shadowserver-reports-api)
5965
- parse the new reports
6066

6167
**Note well**: if your IntelMQ system runs in an airgapped environment or if it may only reach out to specific IPs/sites, you should read the notes here:
@@ -86,7 +92,7 @@ Quite a few changes (thanks to Kamil, @gethvi) on AMQP
8692
### General changes and bug fixes
8793

8894
Digital Trust Center fixed a bug where the config was loaded twice in intelmqctl which created quite some speedups. Thanks!
89-
This speeds up IntelMQ API calls.
95+
This speeds up IntelMQ API calls.
9096

9197
### Data Format
9298

contrib/eventdb/README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ EventDB Utilities
1010
- Apply Malware Name Mapping: Applies the malware name mapping to the eventdb. Source and destination columns can be given, also a local file. If no local file is present, the mapping can be downloaded on demand.
1111
It queries the database for all distinct malware names with the taxonomy "malicious-code" and sets another column to the malware family name.
1212
- Apply Domain Suffix: Writes the public domain suffix to the `source.domain_suffix` / `destination.domain_suffix` columns, extracted from `source.fqdn` / `destination.fqdn`.
13-
- PostgreSQL trigger keeping track of the oldest inserted/updated "time.source" data. This can be useful to (re-)generate statistics or aggregation data.
14-
- SQL queries to set up a separate `raws` table, described in https://docs.intelmq.org/latest/admin/database/postgresql/#separating-raw-values-in-postgresql-using-view-and-trigger
13+
- `trigger_oldest_time.source.sql`: PostgreSQL trigger keeping track of the oldest inserted/updated "time.source" data. This can be useful to (re-)generate statistics or aggregation data.
14+
- `to_json.py`: Export EventDB data to JSON, to use it in IntelMQ again.
1515

1616
Usage
1717
-----
@@ -22,6 +22,16 @@ See `--help` for more information:
2222
```
2323
apply_mapping_eventdb.py -h
2424
apply_domain_suffix.py -h
25+
to_json.py -h
2526
```
2627

2728
The SQL script can be executed in the database directly.
29+
30+
### `to_json.py`
31+
32+
33+
- Get an event by ID: `~intevation/to_json.py --id $id`
34+
- You can give multiple IDs
35+
- Pretty printed: Add `--pretty`
36+
- Inject the data into an IntelMQ bot (dry run):
37+
- `intelmqctl run $botid process --dry-run --show-sent --msg '$jsondata'`

contrib/eventdb/to_json.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/python3
2+
3+
# SPDX-FileCopyrightText: 2025 Institute for Common Good Technology
4+
#
5+
# SPDX-License-Identifier: AGPL-3.0-or-later
6+
7+
from argparse import ArgumentParser
8+
from datetime import datetime
9+
import json
10+
from sys import exit, stderr
11+
from pprint import pprint
12+
13+
from psycopg2 import connect
14+
from psycopg2.extras import RealDictCursor
15+
16+
parser = ArgumentParser(
17+
prog='EventDB to JSON',
18+
description='Extract data from the IntelMQ EventDB')
19+
parser.add_argument('-v', '--verbose', action='store_true')
20+
parser.add_argument('-i', '--id', help='Get events by ID')
21+
parser.add_argument('-p', '--pretty', action='store_true', help='Pretty print JSON output')
22+
parser.add_argument('--dsn', help='A complete libpg conninfo string. If not given, it will be loaded from /etc/intelmq/eventdb-serve.conf')
23+
args = parser.parse_args()
24+
25+
if args.dsn:
26+
conninfo = args.dsn
27+
else:
28+
try:
29+
with open('/etc/intelmq/eventdb-serve.conf') as fody_config:
30+
conninfo = json.load(fody_config)['libpg conninfo']
31+
except FileNotFoundError as exc:
32+
print(f'Could not load database configuration. {exc}', file=stderr)
33+
exit(2)
34+
35+
if args.verbose:
36+
print(f'Using DSN {conninfo!r}.')
37+
db = connect(dsn=conninfo)
38+
cur = db.cursor(cursor_factory=RealDictCursor)
39+
cur.execute ('SELECT * FROM events WHERE id = %s', (args.id, ))
40+
41+
for row in cur.fetchall():
42+
del row['id']
43+
for key in list(row.keys()):
44+
if isinstance(row[key], datetime):
45+
# data from the database has TZ information already included
46+
row[key] = row[key].isoformat()
47+
elif row[key] is None:
48+
del row[key]
49+
if args.pretty:
50+
print(json.dumps(row, indent=2))
51+
else:
52+
print(json.dumps(row))

0 commit comments

Comments
 (0)