devshield-scanner 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devshield_scanner-0.1.0/devshield_scanner.egg-info → devshield_scanner-0.1.1}/PKG-INFO +4 -2
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/README.md +3 -1
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_linux.py +36 -3
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1/devshield_scanner.egg-info}/PKG-INFO +4 -2
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/pyproject.toml +1 -1
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/LICENSE +0 -0
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/SOURCES.txt +0 -0
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/dependency_links.txt +0 -0
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/entry_points.txt +0 -0
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/top_level.txt +0 -0
- {devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devshield-scanner
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Read-only Linux host and Docker filesystem inspection using ClamAV
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -14,7 +14,9 @@ Dynamic: license-file
|
|
|
14
14
|
|
|
15
15
|
# DevShield for Linux
|
|
16
16
|
|
|
17
|
-
An installable Python CLI package is included.
|
|
17
|
+
An installable Python CLI package is included. The Python distribution is `devshield-scanner`; the command is `devshield`. See **INSTALL.md** for isolated installation under `/opt/devshield`. `devshield --version` displays the CLI version.
|
|
18
|
+
|
|
19
|
+
Version 0.1.1 enables ClamAV scan-limit alerts and marks zero-data scans, missing summaries and logged warnings/errors as incomplete coverage (exit 2), even when ClamAV returns 0. Limit alerts are not proof of malware. Optional `--max-filesize-mb` and `--max-scansize-mb` override engine limits in MB. Increasing limits can increase memory, CPU and runtime; engine hard limits still apply. A positive data count alone does not prove every archive entry was inspected.
|
|
18
20
|
|
|
19
21
|
Read-only host and Docker filesystem malware scanning using the locally installed ClamAV signature engine. Requires Linux, Python 3.8+, `clamscan`, updated ClamAV databases, and the Docker CLI for container scanning. Run on the Docker host with a local Unix socket context. Root access normally provides the required file/socket access.
|
|
20
22
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# DevShield for Linux
|
|
2
2
|
|
|
3
|
-
An installable Python CLI package is included.
|
|
3
|
+
An installable Python CLI package is included. The Python distribution is `devshield-scanner`; the command is `devshield`. See **INSTALL.md** for isolated installation under `/opt/devshield`. `devshield --version` displays the CLI version.
|
|
4
|
+
|
|
5
|
+
Version 0.1.1 enables ClamAV scan-limit alerts and marks zero-data scans, missing summaries and logged warnings/errors as incomplete coverage (exit 2), even when ClamAV returns 0. Limit alerts are not proof of malware. Optional `--max-filesize-mb` and `--max-scansize-mb` override engine limits in MB. Increasing limits can increase memory, CPU and runtime; engine hard limits still apply. A positive data count alone does not prove every archive entry was inspected.
|
|
4
6
|
|
|
5
7
|
Read-only host and Docker filesystem malware scanning using the locally installed ClamAV signature engine. Requires Linux, Python 3.8+, `clamscan`, updated ClamAV databases, and the Docker CLI for container scanning. Run on the Docker host with a local Unix socket context. Root access normally provides the required file/socket access.
|
|
6
8
|
|
|
@@ -14,9 +14,30 @@ import tempfile
|
|
|
14
14
|
import time
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def coverage_warnings(log_path):
|
|
18
|
+
"""Read logs incrementally; a zero exit code alone does not establish coverage."""
|
|
19
|
+
warnings = set()
|
|
20
|
+
summary = False
|
|
21
|
+
with open(log_path, encoding='utf-8', errors='replace') as log:
|
|
22
|
+
for line in log:
|
|
23
|
+
if 'Data scanned:' in line:
|
|
24
|
+
summary = True
|
|
25
|
+
if re.search(r'Data scanned:\s*0(?:[.,]0+)?\s', line):
|
|
26
|
+
warnings.add('ClamAV reported zero data scanned; coverage is unverified.')
|
|
27
|
+
if 'Heuristics.Limits.Exceeded' in line or 'Heuristics.Encrypted.' in line:
|
|
28
|
+
warnings.add('Scan limit or encrypted-content alert; some content was not inspected.')
|
|
29
|
+
if re.search(r'\b(?:WARNING|ERROR):', line) or re.search(r'Total errors:\s*[1-9]', line):
|
|
30
|
+
warnings.add('ClamAV reported warnings/errors; inspect the stage log.')
|
|
31
|
+
if not summary:
|
|
32
|
+
warnings.add('ClamAV scan summary missing; coverage is unverified.')
|
|
33
|
+
return sorted(warnings)
|
|
34
|
+
|
|
35
|
+
|
|
17
36
|
def main():
|
|
18
37
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
19
|
-
parser.add_argument('--version', action='version', version='DevShield 0.1.
|
|
38
|
+
parser.add_argument('--version', action='version', version='DevShield 0.1.1')
|
|
39
|
+
parser.add_argument('--max-filesize-mb', type=int, help='ClamAV per-file limit in MB (default: engine setting)')
|
|
40
|
+
parser.add_argument('--max-scansize-mb', type=int, help='ClamAV archive scan limit in MB (default: engine setting)')
|
|
20
41
|
parser.add_argument('--host-root', default='/', help='Host directory to scan (default /)')
|
|
21
42
|
parser.add_argument('--skip-host', action='store_true')
|
|
22
43
|
parser.add_argument('--skip-docker', action='store_true')
|
|
@@ -28,6 +49,9 @@ def main():
|
|
|
28
49
|
parser.error('Run this script on Linux.')
|
|
29
50
|
if args.heartbeat < 1:
|
|
30
51
|
parser.error('--heartbeat must be positive')
|
|
52
|
+
for value in (args.max_filesize_mb, args.max_scansize_mb):
|
|
53
|
+
if value is not None and value < 1:
|
|
54
|
+
parser.error('Scan size limits must be positive MB values')
|
|
31
55
|
if not shutil.which('clamscan'):
|
|
32
56
|
parser.error('clamscan is missing. Install ClamAV and update its databases first; see README.md.')
|
|
33
57
|
report_dir = Path(args.reports).resolve() / (dt.datetime.now(dt.timezone.utc).strftime('%Y%m%dT%H%M%SZ') + '-' + str(os.getpid()))
|
|
@@ -81,12 +105,21 @@ def main():
|
|
|
81
105
|
scratch = tempfile.TemporaryDirectory(prefix='devshield-', dir=args.temp_dir)
|
|
82
106
|
def scan(path, label, excludes=()):
|
|
83
107
|
command = ['clamscan', '--recursive=yes', '--infected', '--verbose', '--scan-archive=yes',
|
|
84
|
-
'--cross-fs=yes', '--follow-dir-symlinks=0', '--follow-file-symlinks=0']
|
|
108
|
+
'--cross-fs=yes', '--follow-dir-symlinks=0', '--follow-file-symlinks=0', '--alert-exceeds-max=yes']
|
|
109
|
+
if args.max_filesize_mb is not None:
|
|
110
|
+
command.append(f'--max-filesize={args.max_filesize_mb}M')
|
|
111
|
+
if args.max_scansize_mb is not None:
|
|
112
|
+
command.append(f'--max-scansize={args.max_scansize_mb}M')
|
|
85
113
|
command.extend('--exclude-dir=^' + re.escape(str(Path(p).resolve())) + r'(/|$)' for p in excludes)
|
|
86
114
|
rc, log = run([*command, '--', str(path)], label)
|
|
115
|
+
warnings = coverage_warnings(log)
|
|
87
116
|
report['scans'].append({'target': str(path), 'label': label, 'exit_code': rc, 'log': log,
|
|
88
|
-
'
|
|
117
|
+
'coverage_warnings': warnings,
|
|
118
|
+
'result': ('Incomplete coverage; review log' if warnings else
|
|
119
|
+
{0: 'No signature detections reported', 1: 'Detection reported'}.get(rc, 'Scan error'))})
|
|
89
120
|
save()
|
|
121
|
+
for warning in warnings:
|
|
122
|
+
issue(f'{label}: {warning} See {log}')
|
|
90
123
|
if rc not in (0, 1):
|
|
91
124
|
issue(f'{label}: ClamAV failed; see {log}')
|
|
92
125
|
save()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devshield-scanner
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Read-only Linux host and Docker filesystem inspection using ClamAV
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -14,7 +14,9 @@ Dynamic: license-file
|
|
|
14
14
|
|
|
15
15
|
# DevShield for Linux
|
|
16
16
|
|
|
17
|
-
An installable Python CLI package is included.
|
|
17
|
+
An installable Python CLI package is included. The Python distribution is `devshield-scanner`; the command is `devshield`. See **INSTALL.md** for isolated installation under `/opt/devshield`. `devshield --version` displays the CLI version.
|
|
18
|
+
|
|
19
|
+
Version 0.1.1 enables ClamAV scan-limit alerts and marks zero-data scans, missing summaries and logged warnings/errors as incomplete coverage (exit 2), even when ClamAV returns 0. Limit alerts are not proof of malware. Optional `--max-filesize-mb` and `--max-scansize-mb` override engine limits in MB. Increasing limits can increase memory, CPU and runtime; engine hard limits still apply. A positive data count alone does not prove every archive entry was inspected.
|
|
18
20
|
|
|
19
21
|
Read-only host and Docker filesystem malware scanning using the locally installed ClamAV signature engine. Requires Linux, Python 3.8+, `clamscan`, updated ClamAV databases, and the Docker CLI for container scanning. Run on the Docker host with a local Unix socket context. Root access normally provides the required file/socket access.
|
|
20
22
|
|
|
File without changes
|
|
File without changes
|
{devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{devshield_scanner-0.1.0 → devshield_scanner-0.1.1}/devshield_scanner.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|