TrueNAS (formerly FreeNAS) is the most widely deployed self-hosted NAS operating system, managing petabytes of storage in home labs, small businesses, and enterprises. Its security profile centers on the fact that TrueNAS runs as root and its API provides direct access to the filesystem, user accounts, and all storage services. Key assessment areas: TrueNAS API keys created in the web UI provide full root-level system access equivalent to the root password; GET /api/v2.0/sharing/smb returns all SMB share paths and their guest access settings; GET /api/v2.0/iscsi/auth returns iSCSI CHAP authentication usernames and secrets in plaintext; GET /api/v2.0/keychaincredential returns SSH private keys stored for replication tasks; and TrueNAS allows executing shell commands via the API using the core.bulk method when authenticated as root. This guide covers systematic TrueNAS security assessment.
# TrueNAS REST API v2.0 — API key authentication
TRUENAS_URL="https://truenas.example.com"
API_KEY="your-truenas-api-key"
# Verify API key and get system info
curl -s "${TRUENAS_URL}/api/v2.0/system/info" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Hostname: {d.get(\"hostname\")}')
print(f'TrueNAS version: {d.get(\"version\")}')
print(f'System product: {d.get(\"system_product\")}')
print(f'Uptime seconds: {d.get(\"uptime_seconds\")}')
print(f'Cores: {d.get(\"cores\")}')
" 2>/dev/null
# List all API keys — only root can see all keys
curl -s "${TRUENAS_URL}/api/v2.0/api_key" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
keys = json.load(sys.stdin)
print(f'API keys configured: {len(keys)}')
for k in keys:
print(f' [{k.get(\"id\")}] {k.get(\"name\")} created={k.get(\"created_at\")} user={k.get(\"username\")}')
" 2>/dev/null
# List all local users — includes shell access configuration
curl -s "${TRUENAS_URL}/api/v2.0/user" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
users = json.load(sys.stdin)
print(f'Users: {len(users)}')
for u in users:
if not u.get('builtin'):
print(f' [{u.get(\"uid\")}] {u.get(\"username\")} shell={u.get(\"shell\")} sudo={u.get(\"sudo\")} email={u.get(\"email\")}')
" 2>/dev/null
# TrueNAS storage shares — reveals all shared paths and access controls
TRUENAS_URL="https://truenas.example.com"
API_KEY="your-truenas-api-key"
# Get all SMB shares — includes guest access settings and dataset paths
curl -s "${TRUENAS_URL}/api/v2.0/sharing/smb" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
shares = json.load(sys.stdin)
print(f'SMB shares: {len(shares)}')
for s in shares:
print(f' {s.get(\"name\")}: {s.get(\"path\")} guest={s.get(\"guestok\")} enabled={s.get(\"enabled\")}')
if s.get('comment'):
print(f' Comment: {s.get(\"comment\")}')
" 2>/dev/null
# Get all NFS shares — includes allowed hosts and network restrictions
curl -s "${TRUENAS_URL}/api/v2.0/sharing/nfs" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
shares = json.load(sys.stdin)
print(f'NFS shares: {len(shares)}')
for s in shares:
print(f' {s.get(\"path\")} networks={s.get(\"networks\")} hosts={s.get(\"hosts\")} ro={s.get(\"ro\")}')
" 2>/dev/null
# Get iSCSI configuration — CHAP secrets are stored in plaintext
curl -s "${TRUENAS_URL}/api/v2.0/iscsi/auth" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
auth = json.load(sys.stdin)
print(f'iSCSI auth groups: {len(auth)}')
for a in auth:
print(f' Tag {a.get(\"tag\")}: user={a.get(\"user\")} secret={a.get(\"secret\")} peeruser={a.get(\"peeruser\")}')
" 2>/dev/null
# Get iSCSI extents — reveals underlying disk/zvol paths
curl -s "${TRUENAS_URL}/api/v2.0/iscsi/extent" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
extents = json.load(sys.stdin)
print(f'iSCSI extents: {len(extents)}')
for e in extents:
print(f' {e.get(\"name\")}: {e.get(\"path\")} size={e.get(\"filesize\")} type={e.get(\"type\")}')
" 2>/dev/null
# TrueNAS keychain credentials — stores SSH keys for replication tasks
TRUENAS_URL="https://truenas.example.com"
API_KEY="your-truenas-api-key"
# Get all keychain credentials — contains SSH private keys
curl -s "${TRUENAS_URL}/api/v2.0/keychaincredential" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
creds = json.load(sys.stdin)
print(f'Keychain credentials: {len(creds)}')
for c in creds:
print(f' [{c.get(\"id\")}] {c.get(\"name\")} type={c.get(\"type\")}')
attrs = c.get('attributes',{})
if c.get('type') == 'SSH_KEY_PAIR':
print(f' Private key: {str(attrs.get(\"private_key\",\"\"))[:60]}...')
print(f' Public key: {str(attrs.get(\"public_key\",\"\"))[:60]}...')
elif c.get('type') == 'SSH_CREDENTIALS':
print(f' Host: {attrs.get(\"host\")}:{attrs.get(\"port\")}')
print(f' Username: {attrs.get(\"username\")}')
" 2>/dev/null
# Get cloud credentials (S3, B2, Dropbox, etc.) used for cloud sync tasks
curl -s "${TRUENAS_URL}/api/v2.0/cloudsync/credentials" \
-H "Authorization: Bearer ${API_KEY}" 2>/dev/null | python3 -c "
import json,sys
creds = json.load(sys.stdin)
print(f'Cloud sync credentials: {len(creds)}')
for c in creds:
attrs = c.get('attributes',{})
print(f' [{c.get(\"id\")}] {c.get(\"name\")} provider={c.get(\"provider\")}')
# AWS S3, Backblaze B2, etc.
for key in ['access_key_id','secret_access_key','account','key','token']:
if attrs.get(key):
print(f' {key}: {attrs.get(key)}')
" 2>/dev/null
| Security Test | Method | Risk |
|---|---|---|
| API key root-level access | GET /api/v2.0/system/info — confirms API key gives root system access; TrueNAS API keys have full root privileges including filesystem access, user management, and service configuration | Critical |
| SMB share guest access enumeration | GET /api/v2.0/sharing/smb — returns all share names, filesystem paths, and guestok settings; shares with guestok=true accessible without credentials from the network | High |
| iSCSI CHAP credential extraction | GET /api/v2.0/iscsi/auth — returns iSCSI authentication groups with CHAP username, secret, peer username, and peer secret in plaintext | High |
| SSH private key extraction from keychain | GET /api/v2.0/keychaincredential — returns SSH key pairs and SSH credential entries including private keys in plaintext; keys used for replication provide access to remote systems | Critical |
| Cloud provider credential exposure | GET /api/v2.0/cloudsync/credentials — returns AWS S3 access key ID and secret, Backblaze B2 account and key, and credentials for all configured cloud sync providers | High |
Ironimo tests TrueNAS deployments for API key root access scope assessment, SMB share guest access configuration, iSCSI CHAP secret extraction, SSH private key retrieval from keychain credentials, cloud sync provider credential exposure (AWS S3, Backblaze B2), user enumeration with shell access, NFS share network restriction audit, and two-factor authentication configuration.
Start free scan