<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Servers and infrastructure on errno</title><link>https://errno.jofrey.eu/categories/servers-and-infrastructure/</link><description>Recent content in Servers and infrastructure on errno</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 22 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://errno.jofrey.eu/categories/servers-and-infrastructure/index.xml" rel="self" type="application/rss+xml"/><item><title>Synology NAS: scp fails with "subsystem request failed on channel 0"</title><link>https://errno.jofrey.eu/posts/synology-scp-subsystem-request-failed-on-channel-0/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://errno.jofrey.eu/posts/synology-scp-subsystem-request-failed-on-channel-0/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;&#10;&lt;p&gt;SSH into the NAS works. Copying a file off it does not:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ssh nasuser@nas.example.lan &amp;#39;echo login ok&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;login ok&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ scp nasuser@nas.example.lan:/volume1/media/clip.mp4 .&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;subsystem request failed on channel 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp: Connection closed&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;sftp&lt;/code&gt; fails the same way:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sftp nasuser@nas.example.lan&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Connection closed.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;subsystem request failed on channel 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="diagnosis"&gt;Diagnosis&lt;/h2&gt;&#10;&lt;p&gt;Modern &lt;code&gt;scp&lt;/code&gt; no longer uses the legacy remote-copy protocol; it speaks &lt;strong&gt;SFTP&lt;/strong&gt;, which requires the server&#10;to offer an &lt;code&gt;sftp&lt;/code&gt; subsystem. On this DSM installation, that subsystem is not exposed, so the channel&#10;request is rejected before any transfer starts. The interactive shell is unaffected, which is exactly why&#10;the failure looks so confusing: authentication, host key and network are all fine.&lt;/p&gt;</description></item><item><title>docker manifest inspect fails with "permission denied" on /etc/docker/certs.d</title><link>https://errno.jofrey.eu/posts/docker-manifest-inspect-permission-denied-certs-d/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate><guid>https://errno.jofrey.eu/posts/docker-manifest-inspect-permission-denied-certs-d/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;&#10;&lt;p&gt;A deployment script verifies that the requested tag exists before it touches a running stack. Under the&#10;deploy user it fails:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-zed" data-lang="zed"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;com/&lt;/span&gt;&lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;42&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nn"&gt;etc/docker/&lt;/span&gt;&lt;span class="n"&gt;certs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;d/&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;com/&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;permission&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;denied&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Under &lt;code&gt;root&lt;/code&gt; on the same node the identical command returns the manifest. Pulling images works for the&#10;deploy user too, which makes the failure look arbitrary.&lt;/p&gt;&#10;&lt;h2 id="why-root-works-and-your-user-does-not"&gt;Why root works and your user does not&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;docker manifest inspect&lt;/code&gt; is one of the CLI commands that talks to the registry &lt;strong&gt;from the client&#10;process&lt;/strong&gt;, not through the daemon. So it needs to read the registry CA itself — and&#10;&lt;code&gt;/etc/docker/certs.d/...&lt;/code&gt; is intentionally readable only by root and the daemon.&lt;/p&gt;</description></item><item><title>Editing a Subversion repository without a working copy: svnmucc</title><link>https://errno.jofrey.eu/posts/svnmucc-commit-without-working-copy/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate><guid>https://errno.jofrey.eu/posts/svnmucc-commit-without-working-copy/</guid><description>&lt;h2 id="the-problem-with-a-checkout"&gt;The problem with a checkout&lt;/h2&gt;&#10;&lt;p&gt;Release repositories tend to be large and deeply nested. Changing one deploy script means a checkout of a&#10;tree you do not care about, a build-up of stale working copies on a jump host, and a real risk of&#10;committing something you did not intend because the working copy had other local modifications.&lt;/p&gt;&#10;&lt;p&gt;For scripted or one-off edits, skip the working copy entirely.&lt;/p&gt;&#10;&lt;h2 id="svnmucc-multiple-url-commands-one-commit"&gt;svnmucc: multiple URL commands, one commit&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;svnmucc &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; put local/stack-deploy-or-update.sh &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; svn://svn.example.com/svn/release/trunk/projects/app/test/docker/stack-deploy-or-update.sh &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rm svn://svn.example.com/svn/release/trunk/projects/app/test/docker/portainer-compose.yml &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -m &lt;span class="s2"&gt;&amp;#34;APP: unify deploy script, drop portainer compose&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --username builder --non-interactive --no-auth-cache&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Everything on that command line lands as &lt;strong&gt;one atomic revision&lt;/strong&gt; — which is the property you want when a&#10;change spans several files and half of it applied would leave the environment broken. The available&#10;operations are &lt;code&gt;put&lt;/code&gt;, &lt;code&gt;rm&lt;/code&gt;, &lt;code&gt;mkdir&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt; and &lt;code&gt;propset&lt;/code&gt;, all addressed by URL.&lt;/p&gt;</description></item></channel></rss>