owned this note
owned this note
Published
Linked with GitHub
# Setting up the Synology DS920+
```
0:11:32:e1:21:5c
```
## Where is strace in DSM 7.0??
https://community.synology.com/enu/forum/1/create
```console
$ sudo synogear install
(synogear) # synogear list | tail -1 |sed 's/ /\n/g'
autojump
autojump_match.py
cifsiostat
domain_test.sh
file
fio
fix_idmap.sh
free
iftop
iostat
iotop
iperf3
kill
log-analyzer.sh
lsof
mpstat
ncat
nethogs
nmap
nping
nslookup
nsupdate
perf-check.py
pgrep
pidof
pidstat
pkill
pmap
ps
pwdx
sa1
sa2
sadc
sadf
sar
sid2ugid.sh
slabtop
sockstat
speedtest-cli.py
sysctl
sysstat
tcpdump
tcpdump_wrapper
telnet
tload
tmux
top
uptime
vmstat
w
watch
zblacklist
zmap
ztee
```
## Setting up Homebrew
As per https://community.synology.com/enu/forum/1/post/153781, we start by pretending that we have GCC installed.
```shell=sh
sudo tee /usr/bin/ldd <<EOF
#!/bin/sh
echo "ldd 2.20"
EOF
sudo chmod ugo+rx /usr/bin/ldd
```
```shell=sh
sudo mkdir /home
sudo chmod ugo+rx /home
sudo mkdir -p /home/linuxbrew/.linuxbrew
sudo chown -R mael.valais:users /home/linuxbrew
# The volume2 disk is an SSD I use for installing software
# from the Synology Package Center, and that I also use for
# Docker. So I might as well use it for Homebrew.
sudo mount -o bind /volume2/linuxbrew/ /home/linuxbrew/.linuxbrew
```
In bashrc:
```shell=sh
if test -d /home/linuxbrew/.linuxbrew/bin; then
export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
fi
export HOMEBREW_GIT_PATH=/usr/local/bin/git
```
The line `HOMEBREW_GIT_PATH` is required because git was installed in /usr/local/bin (Syno Community package). It has the version 2.37 which is totally fine, but Homebrew does not seem to look at /usr/local/bin:
```
$ brew
Error: Please update your system Git or set HOMEBREW_GIT_PATH to a newer version.
Minimum required version: 2.7.0
```
## Permission denied and noexec mounted disk
> ```
> $ ldd
> /bin/sh: /bin/ldd: Permission denied
> ```
>
> Looking at the permissions, everything look OK:
>
> ```
> $ ls -al /usr/bin/ldd
> -rwxr-x--x 1 root root 26 Jul 11 10:35 /usr/bin/ldd
> $ synoacltool -get /usr/bin/ldd
> (synoacltool.c, 489)It's Linux mode
> ```
It is not possible to execute a binary from a mounted filesystem when it was automatically mounted (e.g. flash drive) because it is mounted with noexec.
## Debugging "Permission denied" with `strace`:
```shell=sh
# Install strace.
sudo synogear install
# strace isn't installed with DSM 7!
```
## Setting up SSH agent forwarding
([source](https://community.synology.com/enu/forum/1/post/125198))
```sh
sudo synogroup --add docker $USER
sudo chown root:docker /var/run/docker.sock
sudo synoservice --restart pkgctl-Docker
```
Enable using RSA keys in order to SSH ([source](https://bbrks.me/synology-nas-tips/#sudolessdocker)):
```sh
ssh-copy-id -i ~/.ssh/id_rsa mael.valais@192.168.1.201
```
```sh
% sudo vim /etc/ssh/sshd_config
#RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
```
```sh
# In DSM 6:
sudo synoservice --restart ssh-shell
# In DSM 7:
sudo systemctl restart sshd
```
and finally:
```sh
chmod g-w,o-w ~/
chmod 700 ~/.ssh
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
```
## Run a devcontainer
```sh
docker volume create --driver local workspace
docker run -d -v workspace:/home/vscode -v /var/run/docker.sock:/var/run/docker.sock --name=devcontainer docker.pkg.github.com/maelvls/dotfiles/devcontainer sleep infinity
docker exec -it devcontainer sh -c "(cd dotfiles && git pull) || git clone https://github.com/maelvls/dotfiles"
docker exec -it devcontainer dotfiles/install.sh
docker exec -it devcontainer /bin/zsh
```
⚠️ publickey authentication ONLY works with local addresses
(192.168.0.0/16, 10.0.0.0/8). See [this
Reddit](https://www.reddit.com/r/synology/comments/im6k1b/ssh_permission_denied_but_only_externally/)
thread about that. The workaround is to use Tailscale!
# Using inlets-pro
I followed the "quest" [from
Ellis](https://gist.github.com/alexellis/cb2653a56d666871955e4ac180355168).
```
# Install inlets-pro:
curl -OL https://github.com/inlets/inlets-pro/releases/download/0.8.0-rc4/inlets-pro && install inlets-pro ~/bin
```
```sh
# Create free-tier VM:
gcloud compute instances create hit-me --machine-type f1-micro --zone europe-west1-c
gcloud compute firewall-rules create inlets --allow tcp:80,tcp:443,tcp:8123 --source-ranges=0.0.0.0/0
gcloud compute ssh hit-me
```
```sh
# To generate the token
head -c 16 /dev/urandom | shasum | cut -d" " -f1
```
```sh
# The "server side is the external VM that serves as the ingress point
# available from the internet.
export TOKEN=74917812e4cf996f7d31ce715509be582ac62842
printf "Token: %s" "$TOKEN"
sudo inlets-pro http server \
--letsencrypt-domain hit-me.vls.dev \
--letsencrypt-email mael.valais@gmail.com \
--letsencrypt-issuer prod \
--token $TOKEN \
--auto-tls \
--tls-san $(curl myip.ninja | tee /dev/stderr)
```
```sh
# The "client" side running on my Synology.
#
# 7-day trial license for the inlets PRO client
export TOKEN=74917812e4cf996f7d31ce715509be582ac62842
echo "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiaW5sZXRzIFJDIHRyaWFsIiwiZW1haWxfYWRkcmVzcyI6ImNvbnRhY3RAb3BlbmZhYXMuY29tIiwicHJvZHVjdHMiOlsiaW5sZX
RzLXBybyJdLCJhdWQiOiJqd3QtbGljZW5zZSIsImV4cCI6MTYxMzIxNjI4MiwianRpIjoiODA4MSIsImlhdCI6MTYxMjYxMTQ4MiwiaXNzIjoiand0LWxpY2Vuc2UiLCJzdWIiOiJpbmxldHMgUkMgdHJ
pYWwifQ.dXYMO6guxldF5aQwJFNSW01EDhRxdP2kjoEnZi0hnwL53xAAiWqWtqsCNBz0cLfQtNUROKCbUBL5y8vj8AQJXA" > LICENSE.txt
export PUBLIC_IP_OF_SERVER=35.205.124.213
inlets-pro http client \
--url wss://$PUBLIC_IP_OF_SERVER:8123 \
--token $TOKEN \
--license-file ./LICENSE.txt \
--upstream http://127.0.0.1:8989
```
# Using Docker remotely
About
```
% docker-machine create --driver generic --generic-ip-address=synology --generic-ssh-port=9922 --generic-ssh-key ~/.ssh/id_rsa --generic-ssh-user=mael.valais synology
Running pre-create checks...
Creating machine...
(synology) Importing SSH key...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Error creating machine: Error detecting OS: Error getting SSH command: ssh command error:
command : cat /etc/os-release
err : exit status 1
output : cat: /etc/os-release: No such file or directory
```
As explained
[here](https://community.synology.com/enu/forum/17/post/103526?reply=346909),
cat <<EOF | sudo tee /etc/os-release
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
EOF
Then I hit [this issue](https://github.com/docker/machine/issues/3554):
```sh
% docker-machine create --driver generic --generic-ip-address=synology --generic-ssh-port=9922 --generic-ssh-key ~/.ssh/id_rsa --generic-ssh-user=mael.valais synology
Running pre-create checks...
Creating machine...
(synology) Importing SSH key...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with debian...
Error creating machine: Error running provisioning: ssh command error:
command : sudo hostname synology && echo "synology" | sudo tee /etc/hostname
err : exit status 1
output : sudo: no tty present and no askpass program specified
```
so I added myself to the sudoers:
```sh
%sudo vim /etc/sudoers
# Add this line:
mael.valais ALL=(ALL) NOPASSWD: ALL
```
# Using another sshd
```sh
docker run -d --restart=always --name socat -p 127.0.0.1:2376:2375 -v /var/run/docker.sock:/var/run/docker.sock alpine/socat tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
# https://github.com/panubo/docker-sshd
docker run -d --restart=always --name=ssh -p 9022:22 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.ssh/authorized_keys:/root/.ssh/authorized_keys \
-v ~/.ssh/keys/:/etc/ssh/keys \
-e SSH_ENABLE_ROOT=true \
docker.io/panubo/sshd:1.3.0
```
> IMPORTANT: I had a wrong mode error with /root/.ssh/authorized_keys,
> fixed it by removing `:ro` from the command that the panubo/sshd's readme
> shows, see [this issue](https://github.com/panubo/docker-sshd/issues/5).
Of course, Alpine isn't supported... meh
https://medium.com/@rhrn/add-alpine-server-to-as-docker-machine-acb53e112ba1
## Using Caddy + tailscale instead of inlets-pro
Note that I use the Tailscale MagicDNS feature in order to use the DNS
names `hit-me` and `synology`.
First, install Tailscale on the internet-facing VM:
```sh
gcloud compute ssh hit-me
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.gpg | sudo apt-key add -
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt update && sudo apt install -y tailscale
sudo tailscale up
```
Then, run Caddy as a Docker container on the internet-facing VM:
```sh
gcloud compute ssh hit-me
curl -fsSL https://download.docker.com/linux/$(lsb_release --id -s | tr '[:upper:]' '[:lower:]')/gpg | sudo apt-key add -
echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release --id -s | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list
sudo apt install -y docker-ce docker-ce-cli containerd.io
sudo docker run -d --restart=always --name=caddy -p 80:80 -p 443:443 caddy:latest caddy reverse-proxy --from=hit-me.vls.dev --to=synology:8989
```
Now, let's have the speedtest running on the behind-NAT Synology DS920+
running at home.
First, install Docker (DSM UI > Package Manager).
Then, install tailscaled on the Synology NAS using
[nirev/synology-tailscale](https://github.com/nirev/synology-tailscale):
```sh
curl -LO https://github.com/tailscale/tailscale-synology/releases/download/v1.16.0/tailscale-x86_64-1.16.0-011-dsm6.spk
sudo synopkg install ./tailscale-x86_64-1.16.0-011-dsm6.spk
sudo tailscale up
```
Finally, run the behind-NAT speedtest:
```sh
docker run -d --restart=always -p 8989:80 --name=hit-me adolfintel/speedtest:latest
```
## Grafana Cloud
```sh
curl -O -L https://github.com/grafana/agent/releases/latest/download/agent-linux-amd64.zip
7z x agent-linux-amd64.zip
install agent-linux-amd64 ~/bin
```
For some reason, the grafana/agent does not have any documentation; where
should config.yml be mounted to?
```sh
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest grafana/agent
# Seems to be at /etc/agent/agent.yaml!
```
```sh
cat <<EOF > ~/.grafana-agent.yml
integrations:
node_exporter:
enabled: true
prometheus_remote_write:
- basic_auth:
password: ...
username: ...
url: https://prometheus-us-central1.grafana.net/api/prom/push
prometheus:
configs:
- name: integrations
remote_write:
- basic_auth:
password: ...
username: ...
url: https://prometheus-us-central1.grafana.net/api/prom/push
global:
scrape_interval: 15s
wal_directory: /tmp/grafana-agent-wal
server:
http_listen_port: 12345
EOF
docker run -d --rm -v ~/.grafana-agent.yml:/etc/agent/agent.yaml grafana/agent
```
## Install and upgrade tailscale from the terminal
First, disable codesign check. Otherwise, you will see `pkginstall.cpp:166 Check codesign failed` in `/var/log/messages`. In the UI, go to Package
Manager > Settings > Any publisher.
Synology packages are now officially supported by Tailscale, see https://pkgs.tailscale.com/stable/#spks.
```sh
curl -sL https://pkgs.tailscale.com/stable/tailscale_1.20.4_amd64.tgz --fail --show-error -o tailscale.spk
sudo synopkg install tailscale.spk
sudo synopkg restart tailscale
```
> Note The `>|` disables the noclobber bash feature that avoid mistankenly
> overriding an existing file.
## Run the Grafana agent as a service
```sh
curl -sOL https://github.com/grafana/agent/releases/latest/download/agent-linux-amd64.zip
7z e agent-linux-amd64.zip
sudo install agent-linux-amd64 /usr/local/bin/grafana-agent
```
Apparently no way to create a "service" from the command line on Synology
OS. Go to Control Panel > Task Scheduler > Create > Scheduled Task >
Service:
```plain
Task: grafana-agent
User: mael.valais
Event: Boot-up
Enabled: true
User-defined script:
grafana-agent -config.file ~/.grafana-agent.yml
Save logs to: docker
```
To see the logs:
```sh
tail -F /volume1/docker/grafana-agent/*/output.log
```
Unfortunately, I did nopt find any way of starting the task it without
having to reboot or to go into the UI. I first thought `sudo synoschedtask --get` would show my user-defined tasks but no, it does not.
## Make sure the Plex icon in DSM 7 leads to the correct URL
In DSM 7:
```sh
# sudo vim /var/packages/PlexMediaServer/target/ui/config
{
".url": {
"com.plexapp.plexmediaserver": {
"title": "Plex Media Server",
"desc": "Plex Media Server Web App",
"icon": "images/plexmediaserver_{0}.png",
"type": "url",
"url": "https://plex.famille.vls.dev",
"allUsers": true
}
}
}
```
then, restart the DSM UI so that the icon links to the above URL:
```sh
# In DSM 7:
sudo systemctl restart nginx
```
## Make sure the Photos app icon in DSM leads to the correct URL
In DSM 7, you can set a custom domain for the Photos app. But when clicking the Photos icon, the old URL is used:
```sh
https://famille.vls.dev/?launchApp=SYNO.Foto.AppInstance#/shared_space/timeline
```
To fix that:
```sh
sudo vim /volume1/@appstore/SynologyPhotos/ui/config
```
Then, make the following change:
```diff
{
"pkg_index.min.js": {
"SYNO.Foto.AppInstance": {
- "type": "standalone",
+ "type": "url",
+ "url":"https://photos.famille.vls.dev",
"pkgId": "SynologyPhotos",
"version": "1.1.0-0224",
"hidden": false,
"title": "app:pkg_displayname",
"texts": "texts",
"icon": "images/icon/photos_{0}.png",
"loginIcon": "images/icon/photos_{0}.png",
"allUsers": true,
"allowMultiInstance": false,
"allowAltPort": true,
"grantPrivilege": "all",
"advanceGrantPrivilege": true,
"usePrototypeJS": false,
"appWindow": "SYNO.Foto.MainWindow",
"buildTime": "2021-11-04",
"allowSharing": true,
"publicAccess": true,
"waterfallLoadTexts": true,
```
then, restart the DSM UI so that the icon links to the above URL:
```sh
# In DSM 7:
sudo systemctl restart nginx
```
## Use an nvme drive to store Docker
From https://www.reddit.com/r/synology/comments/pwrch3/how_to_create_a_usable_poolvolume_to_use_as/:
```sh
1. ls /dev/nvme* (Lists your NVMe drives)
3. sudo -i fdisk -l /dev/nvme0n1 (Lists the partitions on NVMe1)
4. sudo -i fdisk -l /dev/nvme1n1 (Lists the partitions on NVMe2)
5. sudo -i synopartition --part /dev/nvme0n1 12 (Creates the Syno partitions on NVMe1)
6. sudo -i synopartition --part /dev/nvme1n1 12 (Creates the Syno partitions on NVMe2)
7. sudo -i fdisk -l /dev/nvme0n1 (Lists the partitions on NVMe1)
8. sudo -i fdisk -l /dev/nvme1n1 (Lists the partitions on NVMe2)
9. sudo -i cat /proc/mdstat (Lists your RAID arrays/logical drives)
10. sudo -i mdadm --create /dev/md3 --level=0 --raid-devices=1 --force /dev/nvme0n1p3 (Creates the RAID array in RAID 0)
11. sudo -i cat /proc/mdstat (Shows the progress of the RAID resync for md3)
12. sudo -i mkfs.btrfs -f /dev/md3 (Formats the array as btrfs)
13. sudo -i reboot (Reboots the DS)
```
## Internet speed
```sh
docker run -it --rm --net=host pschmitt/speedtest:latest
```
Note that it is important to use the host namespace, since using other
namespaces lowers the bandwith. For example, I could get 280 Mbps with
the host namespace but only 80 Mbps in the container's namespace.
## git push to synology does not work
I was getting:
```console
$ git push
sh: git-receive-pack: command not found
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```
Sure enough, the non-login session was the cause:
```console
$ ssh synology env | grep PATH
PATH=/usr/bin:/bin:/usr/sbin:/sbin
```
But when the commands are passed to stdin, it is a login session:
```console
$ ssh synology <<<env | grep PATH
Pseudo-terminal will not be allocated because stdin is not a terminal.
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin
```
The difference between giving a command to the ssh incantation, and
piping commands to ssh are described in
https://unix.stackexchange.com/questions/349425/ssh-command-and-non-interactive-non-login-shell.
From https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell/46856:
> When a shell runs a script or a command passed on its command line, it's a **non-interactive, non-login shell**. Such shells run all the time: it's very common that when a program calls another program, it really runs a tiny script in a shell to invoke that other program. Some shells read a startup file in this case (bash runs the file indicated by the `BASH_ENV` variable, zsh runs `/etc/zshenv` and `~/.zshenv`), but this is risky: the shell can be invoked in all sorts of contexts, and there's hardly anything you can do that might not break something.
## rsync doesn't work
```
$ rsync --compress . mael.valais@synology:foo
Permission denied, please try again.
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(228) [sender=3.2.3]
```
```
$ ssh synology rsync
Permission denied, please try again.
```
```console
$ which -a rsync
/usr/local/bin/rsync
/bin/rsync
/usr/bin/rsync
/usr/local/bin/rsync
$ readlink $(which rsync)
/var/packages/synocli-net/target/bin/rsync
```
## google-photos-metadata-fixer
```
Processed JSON for /volume3/temp/Takeout/Google Photos/à la Ciotat/DSC00092.JPG with last timezone offset -1 and no geoData
Processed JSON for /volume3/temp/Takeout/Google Photos/à la Ciotat/DSC00094.JPG with last timezone offset -1 and no geoData
Processed JSON for /volume3/temp/Takeout/Google Photos/à la Ciotat/DSC00095.JPG with last timezone offset -1 and no geoData
Processed JSON for /volume3/temp/Takeout/Google Photos/à la Ciotat/DSC00096.JPG with last timezone offset -1 and no geoData
applying timezones
[Error: EACCES: permission denied, rename '/volume3/temp/Takeout/Google Photos/Amis et proches/IMG_2054.HEIC' -> '/volume3/temp/Takeout/.cache/7e1a4816-8dfb-44f7-b086-6654c8b4164f.HEIC'] {
errno: -13,
code: 'EACCES',
syscall: 'rename',
path: '/volume3/temp/Takeout/Google Photos/Amis et proches/IMG_2054.HEIC',
dest: '/volume3/temp/Takeout/.cache/7e1a4816-8dfb-44f7-b086-6654c8b4164f.HEIC'
}
```