158 lines
5.1 KiB
Markdown
158 lines
5.1 KiB
Markdown
# Setillo
|
|
|
|
Synology DS223j NAS running DSM 7.3.2. Secondary Synology used for monitoring exporters and AdGuard secondary DNS.
|
|
|
|
## Specs
|
|
|
|
| | |
|
|
|---|---|
|
|
| Model | DS223j |
|
|
| Platform | rtd1619b (aarch64) |
|
|
| DSM | 7.3.2 (build 86009) |
|
|
| Storage | `/volume1` — 8.8 TB btrfs |
|
|
| Tailscale | 1.96.4 (as of 2026-04-11) |
|
|
|
|
## Running services
|
|
|
|
Containers under DSM Container Manager:
|
|
|
|
| Name | Image | Purpose |
|
|
|---|---|---|
|
|
| `node_exporter` | `quay.io/prometheus/node-exporter` | Prometheus host metrics |
|
|
| `snmp_exporter` | `quay.io/prometheus/snmp-exporter` | SNMP metrics for network gear |
|
|
| `adguard` | `adguard/adguardhome` | Secondary AdGuard DNS resolver |
|
|
| `dozzle-agent` | `amir20/dozzle` | Remote log agent for the main Dozzle instance |
|
|
|
|
## Sudoers restriction (important)
|
|
|
|
The `vish` user has passwordless sudo but **cannot invoke shells via sudo**:
|
|
|
|
```
|
|
(ALL) NOPASSWD: "REDACTED_PASSWORD" !/bin/ash, !/bin/sh, !/bin/bash, !/usr/bin/su
|
|
```
|
|
|
|
Practical implications:
|
|
|
|
- ✅ Works: `sudo mkdir`, `sudo mount`, `sudo wget`, `sudo /opt/bin/opkg install foo`, `sudo tee /etc/file`, `sudo systemctl enable foo`
|
|
- ❌ Blocked: `sudo sh script.sh`, `sudo bash -c '...'`, `sudo -i`, `sudo ./script.sh` (even with a `#!/bin/sh` shebang — the kernel exec of `#!/bin/sh script.sh` is blocked)
|
|
|
|
To run shell scripts as root, translate them into a series of individual `sudo` invocations of non-shell binaries. Use `sudo tee file <<EOF` heredocs to write files (tee is not a shell, so it's allowed).
|
|
|
|
## Entware (opkg package manager)
|
|
|
|
Installed 2026-04-11 to work around DSM's minimal busybox toolset.
|
|
|
|
### Layout
|
|
|
|
| | |
|
|
|---|---|
|
|
| Distro | `aarch64-k3.10`, GLIBC 2.27 |
|
|
| Home | `/volume1/@entware` |
|
|
| Mount point | `/opt` (bind mount) |
|
|
| Persistence | `/etc/systemd/system/opt.mount` (enabled, `After=syno-volume.target`, `WantedBy=local-fs.target`) |
|
|
| Installed size | ~260 MB (153 packages) |
|
|
|
|
### Persistence unit
|
|
|
|
`/etc/systemd/system/opt.mount`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Entware bind mount for /opt
|
|
DefaultDependencies=no
|
|
After=syno-volume.target
|
|
Requires=syno-volume.target
|
|
Before=local-fs.target
|
|
Conflicts=umount.target
|
|
|
|
[Mount]
|
|
What=/volume1/@entware
|
|
Where=/opt
|
|
Type=none
|
|
Options=bind
|
|
|
|
[Install]
|
|
WantedBy=local-fs.target
|
|
```
|
|
|
|
### PATH setup
|
|
|
|
`/opt` uses three binary directories. `~/.profile` sets:
|
|
|
|
```sh
|
|
export PATH=/opt/bin:/opt/sbin:/opt/usr/bin:$PATH
|
|
```
|
|
|
|
Some binaries live at `/opt/bin`, some at `/opt/sbin` (e.g. `iotop`, `fzf`), some at `/opt/usr/bin` (e.g. `fd`, `eza`). Keep all three in PATH.
|
|
|
|
### /opt/containerd preservation
|
|
|
|
DSM pre-creates empty stub dirs `/opt/containerd/{bin,lib}` (cosmetic — real containerd lives at `/var/packages/REDACTED_APP_PASSWORD/`). The Entware install recreated these stubs inside the bind-mounted tree so Synology's view of `/opt/containerd` is preserved whether `/opt` is bind-mounted or not. If you ever rebuild Entware, recreate them:
|
|
|
|
```sh
|
|
sudo mkdir -p /opt/containerd/bin /opt/containerd/lib
|
|
sudo chmod 711 /opt/containerd
|
|
```
|
|
|
|
### Installing packages
|
|
|
|
Entware's `opkg` is not in the default sudo PATH (and sudoers blocks shells, so you can't `sudo bash -c`). Always invoke opkg by full path:
|
|
|
|
```sh
|
|
sudo /opt/bin/opkg update
|
|
sudo /opt/bin/opkg install <pkg>
|
|
```
|
|
|
|
For Python packages not in the Entware repo, use `/opt/bin/pip3`:
|
|
|
|
```sh
|
|
sudo /opt/bin/pip3 install --break-system-packages <pkg>
|
|
```
|
|
|
|
### Currently installed (high-value tools)
|
|
|
|
| Category | Packages |
|
|
|---|---|
|
|
| Shell | `bash`, `tmux`, `screen`, `htop`, `vim-full`, `nano`, `less`, `fzf` |
|
|
| Network | `iperf3`, `mtr-json`, `bind-dig`, `tcpdump`, `nmap`, `socat`, `curl`, `wget-ssl`, `nethogs`, `iftop`, `whois`, `mosh-full`, `openssh-client`, `openssh-sftp-server` |
|
|
| Filesystem | `rsync`, `rclone`, `ncdu`, `pv`, `file`, `tree`, `lsof`, `jq`, `yq` (pip) |
|
|
| Observability | `sysstat`, `dstat`, `strace`, `procps-ng`, `python3-iotop`, `glances` (pip), `fail2ban` |
|
|
| Dev | `git`, `python3`, `python3-pip`, `node`, `gnupg2` |
|
|
| Modern unix | `ripgrep`, `fd`, `eza`, `zoxide` |
|
|
|
|
### Not available in the Entware aarch64-k3.10 repo
|
|
|
|
- `bat` — install via `cargo install bat` if needed
|
|
- `duf` — use `df` / `ncdu` instead
|
|
- `bash-completion` — individual tools (git, fzf) provide their own
|
|
- `yq`, `glances` — installed via `pip3` instead
|
|
|
|
### Uninstall (full reversal)
|
|
|
|
```sh
|
|
sudo systemctl disable --now opt.mount
|
|
sudo rm /etc/systemd/system/opt.mount
|
|
sudo systemctl daemon-reload
|
|
sudo rm -rf /volume1/@entware
|
|
```
|
|
|
|
### DSM upgrade caveat
|
|
|
|
DSM major version bumps (e.g. 7.3 → 8) can clobber `/etc/systemd/system/`. After any DSM upgrade, re-check:
|
|
|
|
```sh
|
|
systemctl is-enabled opt.mount
|
|
```
|
|
|
|
If missing, recreate the unit file (content above), then `sudo systemctl daemon-reload && sudo systemctl enable --now opt.mount`. The Entware tree itself survives on `/volume1/@entware` — only the mount unit needs recreating.
|
|
|
|
## Tailscale upgrades
|
|
|
|
Tailscale's Synology package ships a built-in self-updater. Don't hunt for SPK URLs — just:
|
|
|
|
```sh
|
|
sudo tailscale update --yes
|
|
```
|
|
|
|
It downloads the right `.spk` from `pkgs.tailscale.com` and installs it in place. Confirmed working 2026-04-11 (upgraded 1.92.3 → 1.96.4).
|