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).
- Cryptographically Secure Wiping: Uses AES-CTR based PRNG to generate random noise for overwriting data.
- Direct I/O: Bypasses OS page caches (
O_DIRECTon Linux/FreeBSD,O_SYNCon 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.
- Go 1.20 or higher
go get github.com/OpexDevelop/goshredThe 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")
}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)
}
}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))go test -v ./...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.
goshredwill warn or requireForcedepending 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.
- Inspection: Checks filesystem magic numbers and device properties (rotational vs non-rotational).
- Permissions: Ensures the file is writable (chmod) if
Forceis 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.
- Opens file with
- 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.
- TRIM: On Linux/SSD, calls
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.
This project is licensed under the MIT License.