Skip to content

Commit e5765c1

Browse files
committed
add root path option and update triage mode support; update README and Docker helper scripts for clarity
1 parent 4c635f1 commit e5765c1

File tree

5 files changed

+221
-27
lines changed

5 files changed

+221
-27
lines changed

README.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,9 @@ fastfinder [OPTIONS]
104104
| `-h, --help` | Print help information | |
105105
| `-c, --configuration` | Configuration file path | |
106106
| `-b, --build` | Create standalone binary with embedded config | |
107-
| `-o, --output` | Output log file path | |
108-
| `-n, --no-window` | Hide application window | `false` |
109-
| `-u, --no-userinterface` | Disable advanced UI | `false` |
110-
| `-v, --verbosity` | Log verbosity level (1-4) | `3` |
107+
| `-r, --root` | Scan root path (override drive enumeration) | |
108+
| `-s, --silent` | Silent mode - run without any visible window or console | |
109+
| `-v, --verbosity` | Log verbosity level (1-5) | `3` |
111110
| `-t, --triage` | Continuous monitoring mode | `false` |
112111

113112
### Verbosity Levels
@@ -127,11 +126,8 @@ fastfinder [OPTIONS]
127126
# Continuous monitoring mode
128127
./fastfinder -c config.yaml -t
129128

130-
# Silent mode with file output
131-
./fastfinder -c config.yaml -n -o scan_results.log
132-
133129
# Create standalone executable
134-
./fastfinder -b standalone_scanner.exe
130+
./fastfinder -c config.yaml -b standalone_scanner.exe
135131
```
136132

137133
> 💡 **Tip**: FastFinder can run with standard user privileges, but administrative rights provide access to all system files.

docker/docker-helper.ps1

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Commands:
4141
build-runtime Build the runtime image (FastFinder inside container)
4242
run-runtime Run FastFinder inside a container named "runtime"
4343
(add -Interactive to drop into shell instead of running the scan)
44+
(add -Triage for continuous monitoring mode)
4445
clean Remove Docker build cache
4546
help Show this help message
4647
@@ -60,9 +61,15 @@ Examples:
6061
# Run FastFinder inside a privileged container named "runtime"
6162
.\docker-helper.ps1 run-runtime -ConfigPath ./examples/ -ScanPath /your/root/path
6263
64+
# Run with specific config file (YARA rules must be in same directory)
65+
.\docker-helper.ps1 run-runtime -ConfigPath "C:\scans\my_config.yaml" -ScanPath "C:\target"
66+
6367
# Start runtime container in interactive shell (no scan)
6468
.\docker-helper.ps1 run-runtime -Interactive
6569
70+
# Run in triage mode (continuous monitoring)
71+
.\docker-helper.ps1 run-runtime -ConfigPath "C:\scans\my_config.yaml" -ScanPath "C:\target" -Triage
72+
6673
# Clean up Docker build cache
6774
.\docker-helper.ps1 clean
6875
@@ -188,7 +195,8 @@ function Run-Runtime {
188195
param(
189196
[string]$ConfigPath = "$ProjectRoot/examples",
190197
[string]$ScanPath = "$ProjectRoot",
191-
[switch]$Interactive
198+
[switch]$Interactive,
199+
[switch]$Triage
192200
)
193201

194202
# Ensure runtime image exists; build if missing
@@ -216,10 +224,12 @@ function Run-Runtime {
216224
if ($configIsDir) {
217225
# Mount directory; expect config.yml inside
218226
$HostConfigDir = $ResolvedConfig
227+
Write-Info "Config mode: directory mounting - looking for config.yml in $ResolvedConfig"
219228
} else {
220229
# Mount parent dir; keep config filename
221230
$HostConfigDir = Split-Path $ResolvedConfig
222231
$configFileInContainer = "/config/" + (Split-Path $ResolvedConfig -Leaf)
232+
Write-Info "Config mode: file mounting - using $(Split-Path $ResolvedConfig -Leaf) from $HostConfigDir"
223233
}
224234

225235
# Allow Linux-style scan paths (e.g. /host) without Windows Test-Path check
@@ -246,6 +256,10 @@ function Run-Runtime {
246256
$commandArgs = @()
247257
} else {
248258
$commandArgs = @("-c", $configFileInContainer)
259+
if ($Triage) {
260+
$commandArgs += "-t"
261+
Write-Info "Triage mode enabled - continuous monitoring active"
262+
}
249263
}
250264

251265
docker run `
@@ -266,13 +280,32 @@ function Run-Runtime {
266280

267281
# Clean up Docker build cache
268282
function Clean-Docker {
269-
Write-Warning "Cleaning up Docker build cache..."
283+
Write-Warning "Cleaning up FastFinder Docker resources..."
284+
285+
# Remove FastFinder runtime containers
286+
Write-Info "Removing FastFinder containers..."
287+
$containers = docker ps -a --filter "name=runtime" --format "{{.ID}}"
288+
if ($containers) {
289+
docker rm -f $containers 2>$null | Out-Null
290+
Write-Success "Removed FastFinder containers"
291+
} else {
292+
Write-Info "No FastFinder containers found"
293+
}
294+
295+
# Remove FastFinder images
296+
Write-Info "Removing FastFinder images..."
297+
$images = docker images --filter "reference=fastfinder:*" --format "{{.ID}}"
298+
if ($images) {
299+
docker rmi -f $images 2>$null | Out-Null
300+
Write-Success "Removed FastFinder images"
301+
} else {
302+
Write-Info "No FastFinder images found"
303+
}
270304

271-
# Prune build cache
272-
Write-Info "Pruning Docker build cache..."
273-
docker builder prune -f
305+
# Optional: prune all build cache (affects all projects!)
306+
Write-Warning "To clean ALL Docker build cache (all projects), run: docker builder prune -f"
274307

275-
Write-Success "Cleanup complete!"
308+
Write-Success "FastFinder cleanup complete!"
276309
}
277310

278311
# Main logic

docker/docker-helper.sh

Lines changed: 158 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ Commands:
4343
build-binaries Build Linux and Windows binaries with YARA
4444
build-linux Build Linux binary with YARA support
4545
build-windows Build Windows binary with YARA support
46-
clean Remove Docker build cache
46+
build-runtime Build the runtime image (FastFinder inside container)
47+
run-runtime Run FastFinder inside a container named "runtime"
48+
Options: --config=PATH --scan=PATH --interactive --triage
49+
clean Remove FastFinder Docker resources
4750
help Show this help message
4851
4952
Examples:
@@ -56,7 +59,22 @@ Examples:
5659
# Build only Windows binary
5760
$0 build-windows
5861
59-
# Clean up Docker build cache
62+
# Build runtime image
63+
$0 build-runtime
64+
65+
# Run FastFinder in container with config directory
66+
$0 run-runtime --config=/path/to/config --scan=/data
67+
68+
# Run with specific config file
69+
$0 run-runtime --config=/path/to/config.yaml --scan=/data
70+
71+
# Interactive shell mode
72+
$0 run-runtime --interactive
73+
74+
# Triage mode (continuous monitoring)
75+
$0 run-runtime --config=/path/to/config --scan=/data --triage
76+
77+
# Clean up FastFinder Docker resources
6078
$0 clean
6179
6280
For more details, see docker/README.md
@@ -149,15 +167,141 @@ build_windows() {
149167
fi
150168
}
151169

170+
# Build runtime image
171+
build_runtime() {
172+
print_info "Building FastFinder runtime image..."
173+
174+
cd "$PROJECT_ROOT"
175+
176+
docker build \
177+
-f docker/Dockerfile.runtime \
178+
-t fastfinder:runtime \
179+
.
180+
181+
print_success "Runtime image built as fastfinder:runtime"
182+
}
183+
184+
# Run FastFinder in runtime container
185+
run_runtime() {
186+
local config_path="$PROJECT_ROOT/examples"
187+
local scan_path="$PROJECT_ROOT"
188+
local interactive=false
189+
local triage=false
190+
191+
# Parse arguments
192+
while [[ $# -gt 0 ]]; do
193+
case $1 in
194+
--config=*)
195+
config_path="${1#*=}"
196+
shift
197+
;;
198+
--scan=*)
199+
scan_path="${1#*=}"
200+
shift
201+
;;
202+
--interactive)
203+
interactive=true
204+
shift
205+
;;
206+
--triage)
207+
triage=true
208+
shift
209+
;;
210+
*)
211+
print_error "Unknown option: $1"
212+
return 1
213+
;;
214+
esac
215+
done
216+
217+
# Ensure runtime image exists
218+
if ! docker image inspect fastfinder:runtime >/dev/null 2>&1; then
219+
build_runtime
220+
fi
221+
222+
# Check config path exists
223+
if [ ! -e "$config_path" ]; then
224+
print_error "Config path not found: $config_path"
225+
return 1
226+
fi
227+
228+
# Resolve paths
229+
config_path=$(realpath "$config_path")
230+
231+
local config_file_in_container="/config/config.yml"
232+
local host_config_dir
233+
234+
if [ -d "$config_path" ]; then
235+
host_config_dir="$config_path"
236+
print_info "Config mode: directory mounting - looking for config.yml in $config_path"
237+
else
238+
host_config_dir=$(dirname "$config_path")
239+
config_file_in_container="/config/$(basename "$config_path")"
240+
print_info "Config mode: file mounting - using $(basename "$config_path") from $host_config_dir"
241+
fi
242+
243+
# Resolve scan path if not Linux-style
244+
if [[ ! "$scan_path" =~ ^/ ]]; then
245+
if [ ! -e "$scan_path" ]; then
246+
print_error "Scan path not found: $scan_path"
247+
return 1
248+
fi
249+
scan_path=$(realpath "$scan_path")
250+
fi
251+
252+
print_info "Running FastFinder in container 'runtime' (privileged for drive discovery)..."
253+
254+
# Remove existing container if present
255+
docker rm -f runtime >/dev/null 2>&1 || true
256+
257+
# Build docker run command
258+
local docker_cmd=(docker run --rm -it --name runtime --privileged --pid=host)
259+
docker_cmd+=(--cap-add SYS_ADMIN --cap-add SYS_RAWIO)
260+
docker_cmd+=(-e "FASTFINDER_DISABLE_MUTEX=1")
261+
docker_cmd+=(-v "${host_config_dir}:/config")
262+
docker_cmd+=(-v "${scan_path}:/scan:ro")
263+
264+
if [ "$interactive" = true ]; then
265+
docker_cmd+=(--entrypoint /bin/bash fastfinder:runtime)
266+
else
267+
docker_cmd+=(fastfinder:runtime -c "$config_file_in_container")
268+
if [ "$triage" = true ]; then
269+
docker_cmd+=(-t)
270+
print_info "Triage mode enabled - continuous monitoring active"
271+
fi
272+
fi
273+
274+
"${docker_cmd[@]}"
275+
}
276+
152277
# Clean up Docker build cache
153278
clean_docker() {
154-
print_warning "Cleaning up Docker build cache..."
279+
print_warning "Cleaning up FastFinder Docker resources..."
280+
281+
# Remove FastFinder runtime containers
282+
print_info "Removing FastFinder containers..."
283+
local containers=$(docker ps -a --filter "name=runtime" --format "{{.ID}}" 2>/dev/null || true)
284+
if [ -n "$containers" ]; then
285+
docker rm -f $containers >/dev/null 2>&1 || true
286+
print_success "Removed FastFinder containers"
287+
else
288+
print_info "No FastFinder containers found"
289+
fi
155290

156-
# Prune build cache
157-
print_info "Pruning Docker build cache..."
158-
docker builder prune -f
291+
# Remove FastFinder images
292+
print_info "Removing FastFinder images..."
293+
local images=$(docker images --filter "reference=fastfinder:*" --format "{{.ID}}" 2>/dev/null || true)
294+
if [ -n "$images" ]; then
295+
docker rmi -f $images >/dev/null 2>&1 || true
296+
print_success "Removed FastFinder images"
297+
else
298+
print_info "No FastFinder images found"
299+
fi
300+
301+
# Optional: prune all build cache (affects all projects!)
302+
print_warning "To clean ALL Docker build cache (all projects), run: docker builder prune -f"
159303

160-
print_success "Cleanup complete!"
304+
print_success "FastFinder cleanup complete!"
161305
}
162306

163307
# Main logic
@@ -171,6 +315,13 @@ case "${1:-help}" in
171315
build-windows)
172316
build_windows
173317
;;
318+
build-runtime)
319+
build_runtime
320+
;;
321+
run-runtime)
322+
shift
323+
run_runtime "$@"
324+
;;
174325
clean)
175326
clean_docker
176327
;;

finder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,15 @@ func CheckFileChecksumAndContent(path string, content []byte, hashList []string,
166166

167167
// checkForChecksum calculate content checksum and check if it is in hashlist
168168
func checkForChecksum(path string, content []byte, hashList []string) (matchingFiles []string) {
169+
LogMessage(LOG_VERBOSE, "(SCAN)", "Calculating checksums for", path)
169170
var hashs []string
170171
hashs = append(hashs, fmt.Sprintf("%x", md5.Sum(content)))
171172
hashs = append(hashs, fmt.Sprintf("%x", sha1.Sum(content)))
172173
hashs = append(hashs, fmt.Sprintf("%x", sha256.Sum256(content)))
173174

174175
for _, c := range hashs {
175176
if Contains(hashList, c) && !Contains(matchingFiles, path) {
177+
LogMessage(LOG_ALERT, "(ALERT)", "Checksum match:", c, "in", path)
176178
matchingFiles = append(matchingFiles, path)
177179
}
178180
}
@@ -182,8 +184,10 @@ func checkForChecksum(path string, content []byte, hashList []string) (matchingF
182184

183185
// checkForStringPattern check if file content matches any specified pattern
184186
func checkForStringPattern(path string, content []byte, patterns []string) (matchingFiles []string) {
187+
LogMessage(LOG_VERBOSE, "(SCAN)", "Checking grep patterns in", path)
185188
for _, expression := range patterns {
186189
if strings.Contains(string(content), expression) {
190+
LogMessage(LOG_ALERT, "(ALERT)", "Grep match:", expression, "in", path)
187191
matchingFiles = append(matchingFiles, path)
188192
}
189193
}

0 commit comments

Comments
 (0)