Synology Commands

Overview

The netapi synology command group provides CLI access to Synology NAS devices via DSM API.

Prerequisites

Load secrets before using Synology commands:

dsource d000 dev/storage

Required environment variables:

Variable Description

SYNOLOGY_IP

Synology NAS IP

SYNOLOGY_USER

DSM username

SYNOLOGY_PASS

DSM password

Global Options

Option Short Description

--host

-H

Override NAS IP (overrides env)

Example:

# Target specific NAS (nas-02)
netapi synology -H 10.50.1.71 info
The -H flag overrides SYNOLOGY_IP. Ensure the target NAS has the same credentials as configured in dev/storage.

System Information

info

Show Synology system information:

netapi synology info
Example Output
Synology System Information
----------------------------------------
Model:       DS3018xs
Serial:      2020PXN129100
DSM:         DSM 7.1.1-42962 Update 8
Hostname:    nas-01
RAM:         8192 MB
Temperature: 68°C
Uptime:      76d 18h 15m

volumes

List storage volumes:

netapi synology volumes
Example Output
Volume       Status     Used       Total      %Used
-------------------------------------------------------
volume_1     normal      2146.1GB 21449.1GB  10.0%

disks

List physical disks:

netapi synology disks

Returns:

  • Disk name (e.g., disk1, disk2)

  • Model

  • Serial number

  • Status

  • Temperature

shares

List shared folders:

netapi synology shares

Returns:

  • Share name

  • Path

  • Description

network

Show network configuration:

netapi synology network

Returns:

  • Hostname

  • Domain/workgroup

  • DNS server

  • Gateway

  • Network interfaces with IP, netmask, MAC

utilization

Show real-time system utilization:

netapi synology utilization
Example Output
                System Utilization
┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric        ┃  Value ┃ Details                         ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ CPU           │  12.3% │ user: 8.1% / sys: 4.2%          │
│ Memory        │  45.2% │ 4320 MB available of 8192 MB    │
│ Disk I/O      │   5.1% │                                 │
│ Network (eth0)│        │ RX: 125.3 KB/s / TX: 45.2 KB/s  │
└───────────────┴────────┴─────────────────────────────────┘

Values are color-coded:

  • Green: < 50%

  • Yellow: 50-80%

  • Red: > 80%

connections

Show active connections/sessions:

netapi synology connections
Example Output
        Active Connections (3)
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━┓
┃ User         ┃ IP Address   ┃ Type   ┃ Time        ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━┩
│ admin        │ 10.50.1.225  │ DSM    │ 2026-02-21  │
│ adminerosado │ 10.50.1.10   │ SMB    │ 2026-02-21  │
│ netapi       │ 10.50.1.225  │ API    │ 2026-02-21  │
└──────────────┴──────────────┴────────┴─────────────┘

Docker Operations

The docker subcommand manages Docker containers on Container Manager (formerly Docker package).

docker list

List all Docker containers:

netapi synology docker list
Example Output
               Docker Containers (5)
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Name            ┃ Image                ┃   Status    ┃ Ports        ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ pihole          │ pihole/pihole:latest │ ● running   │ 53→53, 80→80 │
│ portainer       │ portainer/portainer  │ ● running   │ 9000→9000    │
│ homeassistant   │ homeassistant/home   │ ○ stopped   │ 8123→8123    │
│ watchtower      │ containrrr/watchtower│ ● running   │ -            │
│ nginx-proxy     │ jwilder/nginx-proxy  │ ● running   │ 443→443      │
└─────────────────┴──────────────────────┴─────────────┴──────────────┘

docker status

Show detailed container status:

netapi synology docker status pihole
Example Output
pihole ● RUNNING
Image: pihole/pihole:latest

Port Mappings:
  53 → 53/tcp
  53 → 53/udp
  80 → 80/tcp

Environment (12 vars)

Volumes:
  /volume1/docker/pihole/etc → /etc/pihole
  /volume1/docker/pihole/dnsmasq → /etc/dnsmasq.d

docker start

Start a stopped container:

netapi synology docker start homeassistant

docker stop

Stop a running container:

netapi synology docker stop pihole

docker restart

Restart a container:

netapi synology docker restart nginx-proxy

Certificate Operations

The cert subcommand manages SSL/TLS certificates on the Synology NAS.

cert list

List installed certificates:

netapi synology cert list

Returns:

  • Certificate ID

  • Description

  • Subject/CN

  • Expiration date

  • Is default

cert import

Import certificate from local files:

# Import cert and key
netapi synology cert import -c /path/to/cert.pem -k /path/to/key.pem

# With chain and description
netapi synology cert import \
    -c /path/to/cert.pem \
    -k /path/to/key.pem \
    --chain /path/to/chain.pem \
    -d "LetsEncrypt Wildcard"

# Set as default certificate
netapi synology cert import -c cert.pem -k key.pem --default

Options:

Option Required Description

-c, --cert

Yes

Path to certificate PEM file

-k, --key

Yes

Path to private key PEM file

--chain

No

Path to intermediate/chain PEM

-d, --descr

No

Certificate description

--default

No

Set as default certificate

cert import-from-vault

Import certificate from vault-01 to Synology via direct file copy:

# Import default domain certificate
netapi synology cert import-from-vault

# Import specific domain
netapi synology cert import-from-vault -D guest.domusdigitalis.dev

# Dry run to see commands
netapi synology cert import-from-vault --dry-run

# Specify cert ID (auto-detected if not set)
netapi synology cert import-from-vault --cert-id abc123

This command bypasses the buggy DSM API (which fails with ECDSA certs) by:

  1. Copying PEM files to NAS /tmp

  2. Installing to /usr/syno/etc/certificate/_archive/<cert_id>/

  3. Running synow3tool --gen-all to propagate to all services

  4. Restarting nginx

Requires passwordless sudo configured on NAS for cert commands.

Options:

Option Required Description

-v, --vault

No

Vault host (default: 10.50.1.60)

--vault-user

No

Vault SSH user (default: ansible)

-D, --domain

No

Certificate domain (default: guest.domusdigitalis.dev)

--cert-id

No

DSM cert ID (auto-detect if not set)

--dry-run

No

Show commands without executing

Backup Validation

Monitor and validate infrastructure backups stored on the NAS.

backup-status

Dashboard view of all backup folders with age, size, and file count:

netapi synology backup-status
Sample Output
                                     Backup Status
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━┳━━━━━━━━━┓
┃ System   ┃ Folder            ┃ Files ┃ Devices ┃     Size   ┃  Age ┃ Status ┃ Latest  ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━╇━━━━━━━━━┩
│ ISE      │ /ise_backups      │    12 │      11 │    5.0 GB  │ 7.0d │  ✓ OK  │ 02-14   │
│ WLC      │ /wlc_backups      │     5 │       2 │   79.0 KB  │ 12.8d│⚠ STALE │ 02-08   │
│ pfSense  │ /firewall_backups │     4 │       2 │  171.7 KB  │ 12.8d│⚠ STALE │ 02-08   │
│ Switches │ /switch_backups   │     4 │       2 │   35.4 KB  │ 12.8d│⚠ STALE │ 02-08   │
│ KVM VMs  │ /kvm_backups      │    23 │      12 │  166.5 KB  │ 12.8d│⚠ STALE │ 02-08   │
│ Keycloak │ /Backups/keycloak │     4 │       2 │   19.3 KB  │ 12.8d│⚠ STALE │ 02-08   │
│ Vault    │ /vault_backups    │     3 │       1 │   45.2 KB  │ 1.2d │  ✓ OK  │ 02-20   │
│ Workstation│ /Backups/borg   │    42 │       1 │   85.3 GB  │ 0.5d │  ✓ OK  │ 02-21   │
└──────────┴───────────────────┴───────┴─────────┴────────────┴──────┴────────┴─────────┘

⚠ 5 stale, 0 errors

Detailed Device View

Show individual devices with their backup ages:

netapi synology backup-status --detailed
Sample Output (Detailed)
                                    Backup Status
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━┳━━━━━━━━┳━━━━━━━━━┓
┃ System   ┃ Folder            ┃ Files ┃ Devices ┃     Size   ┃ Age ┃ Status ┃ Latest  ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━╇━━━━━━━━╇━━━━━━━━━┩
│ KVM VMs  │ /kvm_backups      │    16 │       8 │  113.3 KB  │  0m │  ✓ OK  │ 01-24   │
│          │   9800-CL-WLC     │       │         │            │  0m │        │         │
│          │   vault-01        │       │         │            │  0m │        │         │
│          │   home-dc01       │       │         │            │  0m │        │         │
│          │   ipsk-manager    │       │         │            │  0m │        │         │
│          │   ise-01          │       │         │            │  0m │        │         │
│          │   keycloak-01     │       │         │            │  0m │        │         │
│          │   P50             │       │         │            │  0m │        │         │
│          │   pfsense-01      │       │         │            │  0m │        │         │
└──────────┴───────────────────┴───────┴─────────┴────────────┴─────┴────────┴─────────┘

Device ages are color-coded:

  • Green: < 24 hours old

  • Yellow: > 7 days old

  • Red: Missing or very stale

Options:

Option Short Description

--format

-f

Output format: table or json

--detailed

-d

Show individual device names with ages

JSON output for scripting:

netapi synology backup-status -f json

backup-check

Check backup freshness and alert if stale. Returns exit code 1 on failure - useful for cron/monitoring:

# Default 7-day (168h) threshold
netapi synology backup-check

# Custom threshold (24 hours)
netapi synology backup-check --max-age 24

# Quiet mode - only output on failure
netapi synology backup-check --max-age 24 --quiet
Sample Output (Success)
✓ BACKUP CHECK PASSED
  All 6 backup sets within 168h threshold
Sample Output (Failure)
BACKUP CHECK FAILED
  4 OK, 2 ISSUES

  ✗ ISE: 180.5h old (max: 168h)
  ✗ Keycloak: NO BACKUPS in /Backups/keycloak

Options:

Option Short Description

--max-age

-m

Max age in hours before alert (default: 168)

--quiet

-q

Only output on failure

backup-list

List recent backups for a specific system:

netapi synology backup-list kvm
netapi synology backup-list ise --limit 5
Sample Output
           Recent KVM Backups (/kvm_backups)
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃ Filename                         ┃   Size ┃             Date ┃    Age ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│ 9800-CL-WLC-20260124-191735.xml  │ 4.0 KB │ 2026-01-24 19:18 │ 1m ago │
│ vault-01-20260124-191736.xml     │ 8.1 KB │ 2026-01-24 19:18 │ 1m ago │
│ home-dc01-20260124-191736.xml    │ 8.0 KB │ 2026-01-24 19:18 │ 1m ago │
│ ipsk-manager-20260124-191735.xml │ 8.7 KB │ 2026-01-24 19:18 │ 1m ago │
│ ise-01-20260124-191736.xml       │ 6.8 KB │ 2026-01-24 19:18 │ 1m ago │
└──────────────────────────────────┴────────┴──────────────────┴────────┘

Showing 5 of 16 total backups

Valid system names: ise, wlc, pfsense, switch, kvm, keycloak, vault, borg, workstation

Options:

Option Short Description

--limit

-n

Number of recent backups to show (default: 10)

Monitoring Integration

Cron Job for Daily Check

# /etc/cron.d/backup-check
0 8 * * * user dsource d000 dev/storage && \
    netapi synology backup-check --max-age 24 --quiet || \
    mail -s "Backup Alert" admin@example.com

Prometheus/Alertmanager

Export JSON for Prometheus node_exporter textfile collector:

#!/bin/bash
# /opt/scripts/backup-metrics.sh
dsource d000 dev/storage
netapi synology backup-status -f json | python3 -c "
import sys, json
data = json.load(sys.stdin)
for r in data:
    label = r['label'].lower().replace(' ', '_')
    age = r['age_hours'] or 999
    print(f'backup_age_hours{{system=\"{label}\"}} {age}')
    print(f'backup_file_count{{system=\"{label}\"}} {r[\"count\"]}')
" > /var/lib/node_exporter/textfile/backups.prom

Share and Folder Management

Administrative operations for creating shares and folders on the NAS.

2FA/OTP Requirement

Share creation requires DSM admin 2FA. If your account has 2-step verification enabled, pass the OTP code:

netapi synology --otp 123456 share-create k3s

Get your OTP from your authenticator app (Google Authenticator, Authy, 1Password, etc.) - the same 6-digit code you use when logging into DSM web UI.

DSM web UI may skip OTP if your browser is "trusted", but the API always requires OTP when 2FA is enabled on the account. If you get 403: 2-step verification code required, use --otp.

share-create

Create a new shared folder:

# Basic share creation
netapi synology --otp 123456 share-create k3s

# With description
netapi synology --otp 123456 share-create k3s --descr "k3s persistent volumes"

Options:

Option Required Description

NAME

Yes

Share name (positional argument)

--descr, -d

No

Share description

mkdir

Create a folder within an existing share:

# Single folder
netapi synology mkdir /k3s/manifests

# Multiple folders
netapi synology mkdir /k3s/prometheus
netapi synology mkdir /k3s/grafana
netapi synology mkdir /k3s/loki
mkdir does not require OTP - only share creation does.

setup-k3s-storage

One-command setup for all k3s storage directories:

# Full setup (creates share + folders)
netapi synology --otp 123456 setup-k3s-storage

# Folders only (if share already exists via DSM)
netapi synology setup-k3s-storage --folders-only

Creates:

Path Purpose

/k3s

Root share for k3s PVs

/k3s/manifests

YAML manifests backup

/k3s/prometheus

Prometheus data

/k3s/grafana

Grafana dashboards/data

/k3s/loki

Loki log storage

/k3s/alertmanager

Alertmanager config

Options:

Option Required Description

--folders-only

No

Skip share creation, only create folders

Alternative: Create via SSH (No OTP Required)

If 2FA blocks API access, SSH to the NAS and use synoshare CLI:

ssh nas-01

CRITICAL: Do NOT create directories first. synoshare --add creates the directory automatically. If directory exists, synoshare fails with 0xE700.

# Create DSM share (synoshare creates /volume1/k3s automatically)
sudo synoshare --add k3s "k3s persistent volumes" /volume1/k3s "" administrators "" 1 1

# Create subdirectories AFTER share exists
sudo mkdir -p /volume1/k3s/{manifests,prometheus,grafana,loki,alertmanager}

# Verify
sudo synoshare --enum ALL | grep k3s
synoshare --add syntax
synoshare --add <name> <desc> <path> <na> <rw> <ro> <browsable 0|1> <adv_privilege 0-7>
Table 1. Positional arguments
Position Value Description

1

k3s

Share name

2

"k3s persistent volumes"

Description (quote if spaces)

3

/volume1/k3s

Filesystem path (synoshare creates this)

4

""

No access users (empty = none)

5

administrators

Read-write users (no @ prefix)

6

""

Read-only users (empty = none)

7

1

Browseable (1=yes, 0=no)

8

1

Advanced privileges (0-7)

If directory already exists, delete it first: sudo rm -rf /volume1/<sharename> then run synoshare.

Standard Naming Convention

Infrastructure backup shares follow the pattern _backups:

Share System

/ise_backups

ISE configuration exports

/wlc_backups

WLC configuration

/firewall_backups

pfSense XML configs

/switch_backups

IOS switch configs

/kvm_backups

VM XML definitions

/k3s_backups

etcd snapshots, manifests

/Backups/vault

Vault snapshots

/Backups/keycloak

Realm exports

/Backups/borg

Workstation Borg repos

File Operations

list-files

List files in a folder:

netapi synology list-files /firewall_backups

upload

Upload a file to NAS:

netapi synology upload /tmp/backup.xml /firewall_backups

Integration with Vault PKI

Both pfSense and Synology certificate commands integrate with HashiCorp Vault on vault-01 for centralized PKI.

Typical workflow:

# 1. Vault issues/renews certificates via PKI secrets engine
# 2. Deploy to pfSense
netapi pfsense cert import-from-vault -D guest.domusdigitalis.dev

# 3. Deploy to Synology
netapi synology cert import-from-vault -D guest.domusdigitalis.dev