goshred

goshred is a robust, cross-platform Go library for securely deleting files and directories. It goes beyond simple deletion by overwriting data with cryptographically secure random patterns, bypassing operating system caches, obfuscating file metadata, and inspecting the underlying storage medium to warn about limitations (such as SSDs or Copy-on-Write filesystems).
Features
- Cryptographically Secure Wiping: Uses AES-CTR based PRNG to generate random noise for overwriting data.
- Direct I/O: Bypasses OS page caches (
O_DIRECT on Linux/FreeBSD, O_SYNC on Windows) to ensure data is flushed to the physical disk.
- Smart Storage Inspection: Automatically detects the filesystem and device type (Rotational HDD vs. SSD/NVMe) to determine if secure deletion is physically possible.
- Copy-on-Write (CoW) Awareness: Detects filesystems like ZFS, Btrfs, and APFS where standard overwriting is ineffective, requiring a forced override.
- Metadata Shredding: Renames files multiple times with random characters and shortening lengths before unlinking to hide original filenames.
- Timestamp Reset: Resets file timestamps to the Unix epoch.
- Recursive Deletion: Supports shredding entire directories recursively.
- Verification: Optional read-back verification to ensure data was actually overwritten.
- SSD TRIM Support: Attempts to punch holes (TRIM) in the file on Linux/SSDs after wiping to aid in data unreachability.
Requirements
Installation
go get github.com/OpexDevelop/goshred
Usage
Basic Usage
The simplest way to shred a file with default settings (1 pass of random data, metadata obfuscation):
package main
import (
"log"
"github.com/OpexDevelop/goshred"
)
func main() {
err := goshred.File("secret_document.pdf")
if err != nil {
log.Fatalf("Failed to shred file: %v", err)
}
log.Println("File securely deleted")
}
Advanced Configuration
You can customize the shredding process using functional options:
package main
import (
"context"
"log"
"time"
"github.com/OpexDevelop/goshred"
)
func main() {
// Configure shredding options
err := goshred.File("sensitive_data.db",
goshred.WithPasses(3), // Overwrite 3 times
goshred.WithZeroFill(true), // Final pass writes all zeros
goshred.WithVerify(true), // Read back to verify overwrite
goshred.WithForce(true), // Force operation even on CoW/SSD
goshred.WithBufferSize(4*1024), // 4KB buffer
)
if err != nil {
log.Fatal(err)
}
}
Using Context
You can cancel a long-running shred operation (e.g., large files or many passes) using FileWithContext:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err := goshred.FileWithContext(ctx, "large_file.iso", goshred.WithPasses(3))
Testing
go test -v ./...
Storage Inspection & Safety Levels
goshred attempts to protect you from a false sense of security. Modern storage technologies often make "overwriting" a specific physical block impossible.
Before wiping, goshred inspects the file path:
- High Security (Supported): Standard filesystems on rotational drives (ext4, xfs, ntfs on HDD).
- Medium Security (SSD/Flash): Flash storage uses wear-leveling. Overwriting logical block X does not guarantee physical block Y is overwritten.
goshred will warn or require Force depending on configuration.
- Low Security (CoW/Network): Filesystems like ZFS, Btrfs, APFS, ReiserFS, or Network shares. On these systems, overwriting a file simply allocates new blocks and unlinks the old ones, leaving the original data intact on disk.
Behavior:
If goshred detects a Low Security environment (e.g., a file on ZFS), it will return ErrNotSupported to prevent a false sense of security. You must use WithForce(true) to proceed anyway.
How It Works
- Inspection: Checks filesystem magic numbers and device properties (rotational vs non-rotational).
- Permissions: Ensures the file is writable (chmod) if
Force is enabled.
- Wiping:
- Opens file with
O_DIRECT/O_SYNC.
- Generates a random AES key and IV.
- Writes random streams to the file for $N passes.
- Optionally writes zeros on the final pass.
- Verification: Reads the file back to ensure the data on disk matches the pattern (if enabled).
- Cleanup:
- TRIM: On Linux/SSD, calls
FALLOC_FL_PUNCH_HOLE.
- Timestamps: Sets Access/Modify times to 1970-01-01.
- Obfuscation: Renames
secret.txt -> a8f3.txt -> x9.txt -> z (example) to scrub directory entries.
- Removal: Unlinks the file.
Limitations & Disclaimer
WARNING: Data recovery is a complex field.
- SSDs/NVMe/Flash: Due to wear leveling and over-provisioning, software-based wiping cannot guarantee 100% data destruction on flash media. The firmware may remap blocks transparently.
- Journaling/CoW: Metadata journals or snapshots might retain copies of the file metadata or content.
- Bad Sectors: Hard drives reallocate bad sectors; data in damaged sectors may remain readable by specialized hardware.
For strictly confidential data on modern hardware, physical destruction of the drive is the only method guaranteed to be 100% effective. goshred provides the best effort possible via software.
License
This project is licensed under the MIT License.