<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://cli.pignat.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://cli.pignat.org/" rel="alternate" type="text/html" /><updated>2026-07-08T08:30:36+02:00</updated><id>https://cli.pignat.org/feed.xml</id><title type="html">cli.pignat.org - my tips and tricks</title><subtitle>my tips and tricks</subtitle><author><name>RandomReaper</name></author><entry><title type="html">DNS tips and tricks</title><link href="https://cli.pignat.org/pages/dns.html" rel="alternate" type="text/html" title="DNS tips and tricks" /><published>2026-03-30T00:00:00+02:00</published><updated>2026-03-30T00:00:00+02:00</updated><id>https://cli.pignat.org/pages/dns</id><content type="html" xml:base="https://cli.pignat.org/pages/dns.html"><![CDATA[<p><code class="language-plaintext highlighter-rouge">ping</code>, <code class="language-plaintext highlighter-rouge">ssh</code> or your favorite web browser may not resolve host names in the
same way, sometimes producing strange results.</p>

<p>Standard tools (ping, telnet, wget, curl, …) obey “Name Service Switch” configured in (<code class="language-plaintext highlighter-rouge">/etc/nsswitch.conf</code>). On my machine, the line about hosts reads:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /etc/nsswitch.conf | <span class="nb">grep </span>hosts
hosts:          files mdns4_minimal <span class="o">[</span><span class="nv">NOTFOUND</span><span class="o">=</span><span class="k">return</span><span class="o">]</span> dns
</code></pre></div></div>

<p>So host name resolution will be:</p>
<ul>
  <li>Use local files (<code class="language-plaintext highlighter-rouge">/etc/hotsts</code>)</li>
  <li>Then <a href="https://en.wikipedia.org/wiki/Multicast_DNS" class="external">mDNS</a> but only for  host names ending in <code class="language-plaintext highlighter-rouge">.local</code>.</li>
  <li>Then DNS server (from <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code>) (only for host names not ending in <code class="language-plaintext highlighter-rouge">.local</code>)</li>
</ul>

<p>This file may also use LDAP or NIS for host name resolution.</p>

<h2 id="etchosts"><code class="language-plaintext highlighter-rouge">/etc/hosts</code></h2>

<p>Here is the <a href="https://linux.die.net/man/5/hosts" class="external">/etc/hosts documentation</a>.</p>

<p>:point_up: You may experience problems if <code class="language-plaintext highlighter-rouge">localhost</code> and the local machine host name is not defined in that file.</p>

<h2 id="mdns">mDNS</h2>
<p>mDNS, (Linux: Avahi, Apple: Bonjour) is used by local machine to announce there
services. You may have to install <code class="language-plaintext highlighter-rouge">umdns</code> on OpenWRT.</p>

<h2 id="dns-and-etcresolvconf">DNS (and <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code>)</h2>
<ul>
  <li>
    <p>Most modern Linux distributions uses systemd-resolve and/or NetworkManager, so
/etc/resolve.conf contains <code class="language-plaintext highlighter-rouge">127.0.0.1</code> as nameserver.</p>

    <p><code class="language-plaintext highlighter-rouge">resolvectl status</code> will show how host name are resolved.</p>
  </li>
</ul>

<h2 id="web-browsers">Web browsers</h2>
<p>Web browsers uses DNS caching and modifying <code class="language-plaintext highlighter-rouge">/etc/hosts</code> won’t affect name resolution unless the cache is cleared by a restart or an action.</p>
<ul>
  <li>Firefox : Open <a href="about:networking#dns">about:networking#dns</a> and click on “Clear DNS cache”.</li>
  <li>Chrome : Open <a href="chrome://net-internals/#dns">chrome://net-internals/#dns</a> and click on “Clear host cache”</li>
</ul>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="24.04" /><category term="openwrt" /><summary type="html"><![CDATA[ping, ssh or your favorite web browser may not resolve host names in the same way, sometimes producing strange results.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/tab.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/tab.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ubuntu server and desktop with network bridge (for kvm)</title><link href="https://cli.pignat.org/pages/ubuntu-bridge-kvm.html" rel="alternate" type="text/html" title="Ubuntu server and desktop with network bridge (for kvm)" /><published>2026-03-10T00:00:00+01:00</published><updated>2026-03-10T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/ubuntu-bridge-kvm</id><content type="html" xml:base="https://cli.pignat.org/pages/ubuntu-bridge-kvm.html"><![CDATA[<p>Ubuntu server uses <code class="language-plaintext highlighter-rouge">networkd</code> for network rendering and Ubuntu desktop uses
<code class="language-plaintext highlighter-rouge">NetworkManager</code>.</p>

<p>While you can find many places on the Internet explaining how to do a network
bridge using <code class="language-plaintext highlighter-rouge">NetworkManager</code>, I’ve never seen it work.</p>

<p>You can switch your entire desktop workstation to <code class="language-plaintext highlighter-rouge">networkd</code> but you will
lose the adantages of <code class="language-plaintext highlighter-rouge">NetworkManager</code> (WiFi, GUI support, …).</p>

<p>But you may have missed that both <code class="language-plaintext highlighter-rouge">networkd</code> <strong>and</strong> <code class="language-plaintext highlighter-rouge">NetworkManager</code> can be
used together.</p>

<h2 id="network-bridge-on-the-server-etcnetplan01-configyaml">Network bridge on the server (<code class="language-plaintext highlighter-rouge">/etc/netplan/01-config.yaml</code>)</h2>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">network</span><span class="pi">:</span>
  <span class="na">version</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">renderer</span><span class="pi">:</span> <span class="s">networkd</span>
  <span class="na">ethernets</span><span class="pi">:</span>
    <span class="na">enp3s0</span><span class="pi">:</span>
      <span class="na">dhcp4</span><span class="pi">:</span> <span class="kc">false</span>
  <span class="na">bridges</span><span class="pi">:</span>
    <span class="na">br0</span><span class="pi">:</span>
      <span class="na">macaddress</span><span class="pi">:</span> <span class="s">XX:XX:XX:XX:XX:XX</span>
      <span class="na">dhcp4</span><span class="pi">:</span> <span class="kc">false</span>
      <span class="na">interfaces</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="s">enp3s0</span>
      <span class="na">addresses</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="s">XXX.YYY.ZZZ.10/16</span>
      <span class="na">routes</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">to</span><span class="pi">:</span> <span class="s">default</span>
          <span class="na">via</span><span class="pi">:</span> <span class="s">XXX.YYY.ZZZ.1</span>
      <span class="na">nameservers</span><span class="pi">:</span>
        <span class="na">search</span><span class="pi">:</span>
          <span class="pi">-</span> <span class="s2">"</span><span class="s">lan"</span>
        <span class="na">addresses</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">XXX.YYY.ZZZ.1</span><span class="pi">]</span>
</code></pre></div></div>

<h2 id="network-bridge-on-the-desktop-etcnetplan01-configyaml">Network bridge on the desktop (<code class="language-plaintext highlighter-rouge">/etc/netplan/01-config.yaml</code>)</h2>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">network</span><span class="pi">:</span>
  <span class="na">version</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">ethernets</span><span class="pi">:</span>
    <span class="na">eno1</span><span class="pi">:</span>
      <span class="na">renderer</span><span class="pi">:</span> <span class="s">networkd</span>
      <span class="na">dhcp4</span><span class="pi">:</span> <span class="kc">false</span>
  <span class="na">bridges</span><span class="pi">:</span>
    <span class="na">br0</span><span class="pi">:</span>
      <span class="na">renderer</span><span class="pi">:</span> <span class="s">networkd</span>
      <span class="na">macaddress</span><span class="pi">:</span> <span class="s">YY:YY:YY:YY:YY:YY</span>
      <span class="na">dhcp4</span><span class="pi">:</span> <span class="kc">false</span>
      <span class="na">addresses</span><span class="pi">:</span> <span class="pi">[</span> <span class="s2">"</span><span class="s">XXX.YYY.ZZZ.20/24"</span> <span class="pi">]</span>
      <span class="na">nameservers</span><span class="pi">:</span>
        <span class="na">addresses</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">XXX.YYY.ZZZ.1</span><span class="pi">]</span>
        <span class="na">search</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">lan</span><span class="pi">]</span>
      <span class="na">routes</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">to</span><span class="pi">:</span> <span class="s">default</span>
          <span class="na">via</span><span class="pi">:</span> <span class="s">XXX.YYY.ZZZ.1</span>
      <span class="na">interfaces</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="s">eno1</span>
      <span class="na">parameters</span><span class="pi">:</span>
        <span class="na">forward-delay</span><span class="pi">:</span> <span class="m">0</span>
        <span class="na">stp</span><span class="pi">:</span> <span class="kc">false</span>
</code></pre></div></div>

<p>You may need to reboot to force <code class="language-plaintext highlighter-rouge">NetworkManager</code> to ignore <code class="language-plaintext highlighter-rouge">br0</code> and <code class="language-plaintext highlighter-rouge">eno1</code>.</p>

<h2 id="install-libvirt-on-all-machines">Install libvirt on all machines</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>libvirt-daemon-system libvirt-clients
<span class="nb">sudo </span>usermod <span class="nt">-aG</span> kvm,libvirt <span class="nv">$USER</span>
<span class="nb">sudo</span> <span class="nt">-i</span> <span class="nt">-u</span> <span class="nv">$user</span> <span class="c"># or logout+login to enable groups</span>

<span class="c"># remove the default (NAT network)</span>
virsh net-undefine default
virsh net-define /dev/stdin <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh">
&lt;network&gt;
  &lt;name&gt;host-br0&lt;/name&gt;
  &lt;bridge name='br0'/&gt;
  &lt;forward mode="bridge"/&gt;
&lt;/network&gt;
</span><span class="no">EOF

</span>virsh net-autostart host-br0
virsh net-start host-br0

<span class="c"># define a boot pool</span>
<span class="nb">sudo mkdir</span> <span class="nt">-p</span> /var/lib/libvirt/boot
<span class="nb">sudo </span>wget <span class="nt">-P</span> /var/lib/libvirt/boot https://cdimage.ubuntu.com/ubuntu-mini-iso/noble/daily-live/current/noble-mini-iso-amd64.iso
<span class="nb">sudo chown </span>libvirt-qemu:kvm /var/lib/libvirt/boot <span class="nt">-R</span>

virsh pool-define /dev/stdin <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh">
&lt;pool type='dir'&gt;
  &lt;name&gt;boot&lt;/name&gt;
  &lt;target&gt;
    &lt;path&gt;/var/lib/libvirt/boot&lt;/path&gt;
  &lt;/target&gt;
&lt;/pool&gt;
</span><span class="no">EOF

</span>virsh pool-autostart boot
virsh pool-start boot
</code></pre></div></div>

<h3 id="on-the-desktop">On the desktop:</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>virt-manager
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">virt-manager</code> will automatically connect to the local libvirt, but can be used to connect to a remote libvirt over ssh: `File -&gt; Add Connection.. -&gt; Connect</p>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="kvm" /><summary type="html"><![CDATA[Ubuntu server uses networkd for network rendering and Ubuntu desktop uses NetworkManager.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Raspberry Pi stratum 0 NTP server + PTP server</title><link href="https://cli.pignat.org/pages/cm5-openwrt-chronyd-pps-ptp.html" rel="alternate" type="text/html" title="Raspberry Pi stratum 0 NTP server + PTP server" /><published>2026-03-04T00:00:00+01:00</published><updated>2026-03-04T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/cm5-openwrt-chronyd-pps-ptp</id><content type="html" xml:base="https://cli.pignat.org/pages/cm5-openwrt-chronyd-pps-ptp.html"><![CDATA[<p>If you think having your own stratum 0 <a href="/tag/ntp.html">NTP</a> server is not cool enough, why not have a <a href="/tag/ptp.html"><code class="language-plaintext highlighter-rouge">PTP</code></a> server at home?</p>

<p>:x: Well, it looks cool, but the PTP part is currently not working!</p>

<h2 id="tl--dr">TL ; DR</h2>
<asciinema-player src="../data/a/chronyc.jsonl" preload="" autoplay="" loop="" cols="80" rows="23" poster="npt:5.1" font-size="small"></asciinema-player>

<h2 id="hw">HW</h2>
<ul>
  <li>Raspberry Pi CM5 (CM5102016 - 2GB RAM, 16 GB eMMC, Wifi)
    <ul>
      <li>The SYNC input for the PTP is only available on CM4 and CM5 (i.e. not available on the RPi 4 and 5).</li>
      <li>N.B. Wifi is not necessary, but this will become my router in the near future</li>
    </ul>
  </li>
  <li>Mainboard: SupTronics X1501
    <ul>
      <li>Dual ethernet, did I already tell this board will become my router?</li>
    </ul>
  </li>
  <li>GPS: Waveshare MAX-M8Q GNSS HAT for Raspberry Pi
    <ul>
      <li>Because it has a PPS output</li>
      <li>Can be replaced by the NEO-M8T HAT, which is especially designed for timing
applications, but is 3.5x more expensive.</li>
    </ul>
  </li>
  <li>Battery: ML1220 to store settings on the NEO-M8T HAT</li>
  <li>Case: SupTronics X15-C1</li>
  <li>Passive cooler: SC1752</li>
  <li>PSU: USB-C (27W recommended by SupTronics)</li>
</ul>

<p>:warning: I may have ordered the hardware too fast, the CM5 needs kernel &gt;
6.12 <a href="https://github.com/jclark/rpi-cm4-ptp-guide/blob/76f497332d5ccd35eeb008e935b8fc2b935716a2/os.md?plain=1#L38" class="external">info from here</a>,
and OpenWRT ships with kernel 6.6…</p>

<p>So, the PTP functionality will be tested using ubuntu 25.10 sever</p>

<h2 id="sw---os-and-basic-settings">SW - OS and basic settings</h2>
<ol>
  <li><a href="tag/openwrt.html"><code class="language-plaintext highlighter-rouge">OpenWRT</code></a> 24.10.5 setup.</li>
</ol>

<p>It may be possible to use <code class="language-plaintext highlighter-rouge">rpiboot</code> to flash the eMMC as a USB mass device,
  but since I can’t find any documentation on the mainboard manufacturer’s
  site, I used a USB drive to flash the OpenWRT image on <code class="language-plaintext highlighter-rouge">/dev/mmcblk0</code>. And
  since <code class="language-plaintext highlighter-rouge">rpi-eeprom-config</code> does not work on OpenWRT, I used Raspberry Pi OS
  Lite on the USB drive.</p>

<ul>
  <li>
    <p>Write the Raspberry Pi OS Lite image on the USB drive, and boot on it.
 If you don’t have an official power supply, you may need
 <code class="language-plaintext highlighter-rouge">usb_max_current_enable=1</code> in your <code class="language-plaintext highlighter-rouge">config.txt</code>.</p>
  </li>
  <li>
    <p>Configure BOOT_ORDER (see the <a href="https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#BOOT_ORDER" class="external">doc</a>).</p>

    <p>The factory settings is 0xf2461 (SD (eMMC) -&gt; NVMe -&gt; USB -&gt; Network).
  Since the eMMC is soldered (not removable like a SD card), the there
  is no way to boot on something else, once it is configured.</p>

    <p>So let’s configure BOOT_ORDER to USB -&gt; NVMe -&gt; SD.</p>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="c"># Configure BOOT_ORDER to USB -&gt; NVMe -&gt; SD and disable other factory settings</span>
  <span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> &gt;boot.conf
  [all]
  BOOT_UART=0
  POWER_OFF_ON_HALT=0

  # USB -&gt; NVMe -&gt; SD
  BOOT_ORDER=0xf164
</span><span class="no">  EOF

</span>  <span class="nb">sudo </span>rpi-eeprom-config <span class="nt">--apply</span> boot.conf

  <span class="nb">sudo </span>reboot <span class="c"># Rebooting in the same OS is necessary to write the eeprom</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>Now install OpenWRT on the eMMC</p>

    <p>:point_up: I find the <em>squashfs</em> more stable than the <em>ext4</em> one, and will cause less wear on the flash. Feel free to use another image.</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c"># download OpenWRT</span>
 wget https://downloads.openwrt.org/releases/24.10.5/targets/bcm27xx/bcm2712/openwrt-24.10.5-bcm27xx-bcm2712-rpi-5-squashfs-factory.img.gz

 <span class="c"># verify the dowload</span>
 <span class="nb">echo</span> <span class="s2">"a3356a692ccc4e22896b9fb57a001d949f7c967d924c534732272fa1745bb00d  openwrt-24.10.5-bcm27xx-bcm2712-rpi-5-squashfs-factory.img.gz"</span> | shasum <span class="nt">-c</span> -

 <span class="c"># flash it</span>
 zcat openwrt-24.10.5-bcm27xx-bcm2712-rpi-5-squashfs-factory.img.gz | <span class="nb">sudo dd </span><span class="nv">bs</span><span class="o">=</span>4M <span class="nv">of</span><span class="o">=</span>/dev/mmcblk0


 <span class="c"># edit eMMC/boot/config.txt and eMMC/boot/cmdline.txt</span>
 <span class="nb">mkdir</span> /tmp/boot
 <span class="nb">sudo </span>mount /dev/mmcblk0p1 /tmp/boot/ <span class="nt">-o</span> noatime

 <span class="c"># config.txt setup</span>
 <span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> | sudo tee -a /tmp/boot/config.txt
 [all]
 dtparam=pciex1                # for X1501 ssd
 dtoverlay=pps-gpio,gpiopin=18 # PPS on GPIO 18
 dtparam=uart0=on              # enable /dev/ttyAMA0 for the GPS
 dtparam=watchdog=off          # disable watchdog
 usb_max_current_enable=1
</span><span class="no"> EOF

</span> <span class="c"># The GNSS will need the serial port, so don't put a console on it</span>
 <span class="nb">sudo sed</span> <span class="nt">-i</span> <span class="s1">'s/ .*115200//'</span> /tmp/boot/cmdline.txt
 <span class="nb">sudo </span>umount /tmp/boot
</code></pre></div>    </div>
  </li>
  <li>
    <p>Remove the USB drive and reboot OpenWRT on the eMMC</p>
  </li>
</ul>

<ol>
  <li>The raspberry will have the <code class="language-plaintext highlighter-rouge">192.168.1.1</code> address, but I prefer it to DHCP.
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci <span class="nb">set </span>network.lan.proto<span class="o">=</span>dhcp
uci commit
/etc/init.d/network restart
</code></pre></div>    </div>
  </li>
  <li>Since this machine is not a router :
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/firewall disable
/etc/init.d/odhcpd disable
/etc/init.d/dnsmasq disable
reboot
</code></pre></div>    </div>
  </li>
  <li>Setup a root password
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@OpenWrt:~# passwd
Changing password <span class="k">for </span>root
New password:
Bad password: too weak
Retype password:
passwd: password <span class="k">for </span>root changed by root
</code></pre></div>    </div>
  </li>
  <li>
    <p>Setup <code class="language-plaintext highlighter-rouge">authorized_keys</code> and disable root password login</p>
  </li>
  <li>Configure <code class="language-plaintext highlighter-rouge">hostname</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci <span class="nb">set </span>system.@system[0].hostname<span class="o">=</span>pim-ptp
uci <span class="nb">set </span>system.@system[0].timezone<span class="o">=</span><span class="s1">'CET-1CEST,M3.5.0,M10.5.0/3'</span>
uci <span class="nb">set </span>system.@system[0].zonename<span class="o">=</span><span class="s1">'Europe/Zurich'</span>
uci commit
<span class="nb">echo </span>pim-ptp <span class="o">&gt;</span> /proc/sys/kernel/hostname
</code></pre></div>    </div>
  </li>
  <li>Install the tools
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>opkg update
uci <span class="nb">set </span>system.ntp.enable<span class="o">=</span><span class="s1">'0'</span>
uci commit
/etc/init.d/sysntpd disable
/etc/init.d/sysntpd stop
/etc/init.d/ntpd disable
/etc/init.d/ntpd stop
opkg <span class="nb">install </span>chrony kmod-pps-gpio gpsd gpsd-clients <span class="se">\</span>
nano rsync umdns coreutils-who zabbix-agentd python3-light kmod-usb-net-rtl8152
/etc/init.d/chronyd <span class="nb">enable</span>
</code></pre></div>    </div>
  </li>
</ol>

<h2 id="sw---gpsd-chrony-and-pps">SW - GPSD, chrony and PPS</h2>

<ol>
  <li>Configure gpsd
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci <span class="nb">set </span>gpsd.core.device<span class="o">=</span><span class="s1">'/dev/ttyAMA0'</span>
uci <span class="nb">set </span>gpsd.core.enabled<span class="o">=</span><span class="s1">'1'</span>
uci commit
/etc/init.d/gpsd <span class="nb">enable</span>
/etc/init.d/gpsd start
</code></pre></div>    </div>
  </li>
  <li>Check GPS connectivity : <code class="language-plaintext highlighter-rouge">cgps -s -u m</code> should show <code class="language-plaintext highlighter-rouge">Status 3D FIX</code></li>
  <li>Configure <code class="language-plaintext highlighter-rouge">chronyd</code> for using country specific servers in <code class="language-plaintext highlighter-rouge">/etc/config/chrony</code>:
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">config</span> <span class="err">pool</span>
        <span class="err">option</span> <span class="err">hostname</span> <span class="err">'0.ch.pool.ntp.org'</span>
        <span class="err">option</span> <span class="err">iburst</span> <span class="err">'yes'</span>
<span class="err">config</span> <span class="err">systemclock</span> <span class="err">'systemclock'</span>
<span class="err">...</span>
</code></pre></div>    </div>
  </li>
  <li>Add the GNSS and PPS sources at the end of : <code class="language-plaintext highlighter-rouge">/etc/chrony/chrony.conf</code>
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code></code></pre></div>    </div>
    <p>refclock PPS /dev/pps0 refid PPS poll 0</p>

    <p>local stratum 10 orphan
…</p>
  </li>
  <li>(Re-) Start <code class="language-plaintext highlighter-rouge">chronyd</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Restarting network after chrony configuration will get the NTP servers</span>
<span class="c"># from the DHCP server</span>
/etc/init.d/network restart
/etc/init.d/chronyd restart
</code></pre></div>    </div>
  </li>
  <li>Check GPS and PPS functionality :
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chronyc sources
</code></pre></div>    </div>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MS Name/IP address         Stratum Poll Reach LastRx Last sample               
<span class="o">===============================================================================</span>
<span class="c">#- GNSS                         0   2   377     6    +43ms[  +43ms] +/-  100ms</span>
<span class="c">#* PPS                          0   1   377     2   -343ns[ -716ns] +/- 2600ns</span>
^- redacted1.example.com        1   6   377    22  <span class="nt">-3130us</span><span class="o">[</span><span class="nt">-3128us</span><span class="o">]</span> +/-   10ms
^- redacted2.example.com        1   6   377    22  <span class="nt">-3188us</span><span class="o">[</span><span class="nt">-3187us</span><span class="o">]</span> +/- 7391us
^- redacted3.example.com        2   6   377    21  <span class="nt">-5598us</span><span class="o">[</span><span class="nt">-5597us</span><span class="o">]</span> +/-   18ms
^- redacted4.example.com        2   6   377    20  <span class="nt">-3383us</span><span class="o">[</span><span class="nt">-3382us</span><span class="o">]</span> +/-   36ms
^- router.lan                   2   6   377    15  <span class="nt">-3231us</span><span class="o">[</span><span class="nt">-3231us</span><span class="o">]</span> +/-   41ms
^- pim-ntp.lan                  1   6   377    14    <span class="nt">-12us</span><span class="o">[</span>  <span class="nt">-12us</span><span class="o">]</span> +/-  290us
^? pim-ptp.lan                  0   8   377     -     +0ns[   +0ns] +/-    0ns

</code></pre></div>    </div>
  </li>
</ol>

<h2 id="configure-ntp-pool-dns-and-dhcp-on-a-openwrt-router">Configure NTP pool DNS and DHCP on a OpenWRT router</h2>
<ol>
  <li>Setup all your NTP servers in a DNS pool (<code class="language-plaintext highlighter-rouge">/etc/config/dhc</code>)
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">...</span>
<span class="err">config</span> <span class="err">domain</span>
    <span class="err">option</span> <span class="err">name</span> <span class="err">'ntp'</span>
    <span class="err">option</span> <span class="err">ip</span> <span class="err">'XXX.XXX.XXX.XXX'</span> <span class="c"># address of the router with a NTP server
</span>
<span class="err">config</span> <span class="err">domain</span>
    <span class="err">option</span> <span class="err">name</span> <span class="err">'ntp'</span>
    <span class="err">option</span> <span class="err">ip</span> <span class="err">'XXX.XXX.XXX.YYY'</span> <span class="c"># address of the ntp server (from our older post)
</span>
<span class="err">config</span> <span class="err">domain</span>
    <span class="err">option</span> <span class="err">name</span> <span class="err">'ntp'</span>
    <span class="err">option</span> <span class="err">ip</span> <span class="err">'XXX.XXX.XXX.YYY'</span> <span class="c"># address of the ntp+ptp server (from this post)
</span><span class="err">...</span>
</code></pre></div>    </div>
  </li>
  <li>Setup the DHCP to announce NTP servers:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci add_list dhcp.lan.dhcp_option<span class="o">=</span><span class="s1">'42,XXX.XXX.XXX.XXX,XXX.XXX.XXX.YYY,XXX.XXX.XXX.ZZZ'</span>
uci commit
</code></pre></div>    </div>
  </li>
  <li>Restart <code class="language-plaintext highlighter-rouge">dnsmasq</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/dnsmasq restart
</code></pre></div>    </div>
  </li>
</ol>

<h2 id="optional-optimisation-for-timing">(Optional) Optimisation for timing</h2>

<p>:point_up: The backup battery on the Waveshare MAX-M8Q GNSS HAT is mandatory.
   Whitout it, the module will lose it’s configuration every power loss. The
   symptom will be <code class="language-plaintext highlighter-rouge">NO FIX</code>, since the module will go back to 9600 bauds.</p>

<ul>
  <li>set jumpers on A</li>
  <li>connect to your favorite Linux host using the USB cable</li>
  <li>start gpsd on the usb port
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ubxtool <span class="nt">-s</span> 9600 <span class="nt">-S</span> 115200
 ubxtool <span class="nt">-p</span> MODEL,2
 ubxtool <span class="nt">-p</span> CFG-PMS,0
 ubxtool <span class="nt">-p</span> SAVE
 ubxtool <span class="nt">-p</span> COLDBOOT <span class="c"># validate the settings are OK</span>
</code></pre></div>    </div>
  </li>
  <li>re-set jumpers on B</li>
  <li>configure 11500 bauds using <code class="language-plaintext highlighter-rouge">-s 115200</code> in <code class="language-plaintext highlighter-rouge">/etc/init.d/gpsd</code>:
 ```bash
 …
 [ “$enabled” = “0” ] &amp;&amp; return 1</li>
</ul>

 	    procd_open_instance
 	    procd_set_param command “$PROG” -N -n -s 115200

 	    [ “$listen_globally” -ne 0 ] &amp;&amp; procd_append_param command -G
 	    procd_append_param command -S “$port”
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  ...
  ```
</code></pre></div></div>

<h2 id="x-ptp-using-ubuntu-server-2510-x">:x: ptp (using ubuntu server 25.10) :x:</h2>

<p>:x: the PTP server does not work at this time :x:</p>

<p>The complete install will be documented once the required drivers reach OpenWRT.</p>

<p>In brief:</p>
<ul>
  <li>install ubuntu server 25.10</li>
  <li>add the <code class="language-plaintext highlighter-rouge">config.txt</code> lines into <code class="language-plaintext highlighter-rouge">/boot/firmware/config.txt</code></li>
  <li>remove the serial console from <code class="language-plaintext highlighter-rouge">/boot/firmware/current/cmdline.txt</code>.</li>
  <li>reboot</li>
  <li>install and configure <code class="language-plaintext highlighter-rouge">gpsd</code> (in <code class="language-plaintext highlighter-rouge">/etc/default/gpsd</code>)
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c"># Devices gpsd should collect to at boot time.
</span> <span class="c"># They need to be read/writeable, either by user gpsd or the group dialout.
</span> <span class="py">DEVICES</span><span class="p">=</span><span class="s">"/dev/ttyAMA0"</span>

 <span class="c"># Other options you want to pass to gpsd
</span> <span class="py">GPSD_OPTIONS</span><span class="p">=</span><span class="s">"-n -s 115200"</span>

 <span class="c"># Automatically hot add/remove USB GPS devices via gpsdctl
</span> <span class="py">USBAUTO</span><span class="p">=</span><span class="s">"true"</span>
</code></pre></div>    </div>
  </li>
  <li>install and configure <code class="language-plaintext highlighter-rouge">chrony</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo rm</span> /etc/chrony/sources.d/ubuntu-ntp-pools.sources
<span class="nb">echo</span> <span class="s2">"pool 0.ch.pool.ntp.org iburst"</span> | <span class="nb">sudo tee</span> /etc/chrony/sources.d/pim.sources
<span class="nb">echo</span> <span class="s2">"pool ntp.lan iburst"</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/chrony/sources.d/pim.sources
<span class="nb">echo</span> <span class="s2">"refclock PPS /dev/pps0 refid PPS poll 0"</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/chrony/conf.d/pim.conf
<span class="nb">echo</span> <span class="s2">"local stratum 10 orphan"</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/chrony/conf.d/pim.conf
<span class="nb">sudo </span>systemctl restart chrony
</code></pre></div>    </div>
  </li>
  <li>connect GNSS module PPS pin (GPIO8 or dedicated output) to Ethernet_SYNC_OUT (J2 pin 6)</li>
  <li>configure Ethernet_SYNC_OUT as a PPS input
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c"># Configure the pin as input, 1 means input, 0 is the ptp channel 0 (from ethtool -T eth0 | grep 'Hardware timestamp provider index:')</span>
 <span class="nb">echo </span>1 0 | <span class="nb">sudo tee</span> /sys/class/ptp/ptp0/pins/SYNC_OUT

 <span class="c"># Enable timestamping (0 is the ptp channel number and 1 is enable</span>
 <span class="nb">echo </span>0 1 | <span class="nb">sudo tee</span> /sys/class/ptp/ptp0/extts_enable

 <span class="c"># should display 1 timestamp per second</span>
 <span class="c"># disconnect the cable and the timestamps will stop</span>

 <span class="k">while </span><span class="nb">true</span><span class="p">;</span> <span class="k">do </span><span class="nb">cat</span> /sys/class/ptp/ptp0/fifo <span class="p">;</span> <span class="k">done</span>
</code></pre></div>    </div>
  </li>
  <li>configure ptp timemaster
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nb">sudo </span>apt <span class="nb">install </span>linuxptp
 <span class="nb">sudo </span>systemctl disable timemaster.service
</code></pre></div>    </div>
  </li>
  <li>Sync PTP hardware clock to PPS
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c"># we don't use nmea for time of day (gpsd uses the gps data), so sync</span>
 <span class="c"># PTP with the system clock. TAI is 37 seonds ahead of TAI</span>
 <span class="nb">sudo </span>phc_ctl eth0 <span class="s2">"set;"</span> adj 37 <span class="c"># fixme get it from leap-seconds.list</span>
 <span class="c"># ubuntu is not up to date</span>
 <span class="nb">sudo </span>wget <span class="nt">-P</span> /etc/linuxptp https://data.iana.org/time-zones/tzdb-2026a/leap-seconds.list
 <span class="nb">cat</span> <span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> | sudo tee -a /etc/linuxptp/ts2phc.conf
 [global]
 leapfile /etc/linuxptp/leap-seconds.list
 step_threshold 0.1
 ts2phc.tod_source generic
 logging_level 7

 [eth0]
 ts2phc.pin_index 0
</span><span class="no"> EOF

</span> ts2phc <span class="nt">-f</span> /etc/linuxptp/ts2phc.conf <span class="nt">-m</span> <span class="nt">-q</span> <span class="nt">-l</span> 7
</code></pre></div>    </div>
  </li>
  <li>Sync chrony with the the PTP hardware clock
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nb">echo</span> <span class="s2">"refclock SHM 0 refid GNSS precision 1e-1 offset 0.044 poll 0 filter 8"</span> | <span class="nb">sudo tee</span> /etc/chrony/conf.d/pim.conf
 <span class="nb">echo</span> <span class="s2">"refclock PPS /dev/pps0 refid PPS lock GNSS poll 2"</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/chrony/conf.d/pim.conf
 <span class="nb">echo</span> <span class="s2">"refclock SHM 2 refid PPSp tai lock GNSS poll 2"</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/chrony/conf.d/pim.conf
 <span class="nb">sudo </span>systemctl restart chrony

 <span class="c"># -M2 -&gt; write to SHM 2</span>
 <span class="c"># offset is zero, since it is configured as TAI in chrony</span>
 phc2sys <span class="nt">-s</span> eth0 <span class="nt">-E</span> ntpshm <span class="nt">-O</span> 0 <span class="nt">-M</span> 2
</code></pre></div>    </div>
  </li>
  <li>
    <p>ptp master :warning: work in progress</p>

    <p>At this time <code class="language-plaintext highlighter-rouge">ptp4l --serverOnly 1 -i eth0 -l 7 --tx_timestamp_timeout 500</code> fails with this error:</p>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>timed out while polling for tx timestamp
increasing tx_timestamp_timeout or increasing kworker priority may correct this issue, but a driver bug likely causes it
port 1 (eth0): send sync failed
port 1 (eth0): MASTER to FAULTY on FAULT_DETECTED (FT_UNSPECIFIED)
</code></pre></div>    </div>
  </li>
</ul>]]></content><author><name>RandomReaper</name></author><category term="openwrt" /><category term="raspberry" /><category term="ntp" /><category term="ptp" /><summary type="html"><![CDATA[If you think having your own stratum 0 NTP server is not cool enough, why not have a PTP server at home?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Using the `ch(fr)` keyboard under Linux</title><link href="https://cli.pignat.org/pages/linux-swiss-french-keyboard.html" rel="alternate" type="text/html" title="Using the `ch(fr)` keyboard under Linux" /><published>2026-02-23T00:00:00+01:00</published><updated>2026-02-23T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/linux-swiss-french-kbd</id><content type="html" xml:base="https://cli.pignat.org/pages/linux-swiss-french-keyboard.html"><![CDATA[<h2 id="symbols-im-always-looking-for">Symbols I’m always looking for</h2>

<table>
  <thead>
    <tr>
      <th>Symbol</th>
      <th>Keys</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>É</td>
      <td><kbd>Alt Gr</kbd> + <kbd>?</kbd> release, then <kbd>E</kbd></td>
      <td>Uppercase E with acute accent</td>
    </tr>
    <tr>
      <td>È</td>
      <td><kbd>Shift</kbd> + <kbd>^</kbd> release, then <kbd>E</kbd></td>
      <td>Uppercase E with grave accent</td>
    </tr>
    <tr>
      <td>·</td>
      <td><kbd>Alt Gr</kbd> + <kbd>.</kbd></td>
      <td>Middle dot (<em>point médian</em>)</td>
    </tr>
    <tr>
      <td>¡</td>
      <td><kbd>Alt Gr</kbd> + <kbd>Shift</kbd> + <kbd>1</kbd></td>
      <td>Inverted exclamation mark</td>
    </tr>
    <tr>
      <td>¿</td>
      <td><kbd>Alt Gr</kbd> + <kbd>Shift</kbd> + <kbd>?</kbd></td>
      <td>Inverted question mark</td>
    </tr>
  </tbody>
</table>

<h2 id="displaying-the-keyboard-map">Displaying the keyboard map</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gkbd-keyboard-display <span class="nt">-l</span> <span class="s2">"ch(fr)"</span>
</code></pre></div></div>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="locale" /><summary type="html"><![CDATA[Symbols I’m always looking for]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/tab.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/tab.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Raspberry Pi stratum 0 NTP server</title><link href="https://cli.pignat.org/pages/raspberry-openwrt-ntpd-pps.html" rel="alternate" type="text/html" title="Raspberry Pi stratum 0 NTP server" /><published>2026-02-12T00:00:00+01:00</published><updated>2026-02-12T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/raspberry-openwrt-ntpd-pps</id><content type="html" xml:base="https://cli.pignat.org/pages/raspberry-openwrt-ntpd-pps.html"><![CDATA[<h2 id="hw">HW</h2>
<ul>
  <li>Raspberry Pi 3</li>
  <li>SD card (200MB will do, yes, 200<strong>MB</strong>!)</li>
  <li>Waveshare MAX-M8Q GNSS HAT for Raspberry Pi</li>
  <li>Raspberry Pi official case for 3B+</li>
</ul>

<h2 id="sw---os-and-basic-settings">SW - OS and basic settings</h2>
<ol>
  <li>
    <p>Download OpenWRT 24.10.5 <a href="https://downloads.openwrt.org/releases/24.10.5/targets/bcm27xx/bcm2710/openwrt-24.10.5-bcm27xx-bcm2710-rpi-3-squashfs-factory.img.gz">openwrt-24.10.5-bcm27xx-bcm2710-rpi-3-squashfs-factory.img.gz</a>, flash it on the flash.</p>

    <p>:point_up: I find the <em>squashfs</em> more stable than the <em>ext4</em> one, and it will cause less wear on the SD card.</p>
  </li>
  <li>Modify the <code class="language-plaintext highlighter-rouge">/boot/config.txt</code> (<code class="language-plaintext highlighter-rouge">config.txt</code> in the <code class="language-plaintext highlighter-rouge">boot</code> partition):
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">...</span>
<span class="err">[all]</span>
<span class="c"># Place your custom settings here.
</span><span class="py">dtoverlay</span><span class="p">=</span><span class="s">pps-gpio,gpiopin=18</span>
<span class="err">...</span>
</code></pre></div>    </div>
  </li>
  <li>Disable the serial console (we need the serial port for the GPS) in <code class="language-plaintext highlighter-rouge">/boot/dline.txt</code>
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">console</span><span class="p">=</span><span class="s">tty1 root=PARTUUID=c8dca970-02 rootfstype=squashfs,ext4 rootwait</span>
</code></pre></div>    </div>
  </li>
  <li>Assemble all the HW, and boot. The raspberry will have the <code class="language-plaintext highlighter-rouge">192.168.1.1</code> address, t I prefer it to DHCP.
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci <span class="nb">set </span>network.lan.proto<span class="o">=</span>dhcp
uci commit
/etc/init.d/network restart
</code></pre></div>    </div>
  </li>
  <li>Since this machine is not a router :
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/firewall disable
/etc/init.d/odhcpd disable
/etc/init.d/dnsmasq disable
reboot
</code></pre></div>    </div>
  </li>
  <li>Setup a root password
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@OpenWrt:~# passwd
Changing password <span class="k">for </span>root
New password:
Bad password: too weak
Retype password:
passwd: password <span class="k">for </span>root changed by root
</code></pre></div>    </div>
  </li>
  <li>Setup <code class="language-plaintext highlighter-rouge">authorized_keys</code> and disable root password login</li>
  <li>Configure <code class="language-plaintext highlighter-rouge">hostname</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> uci <span class="nb">set </span>system.@system[0].hostname<span class="o">=</span>pim-ntp
 uci commit
 <span class="nb">echo </span>pim-ntp <span class="o">&gt;</span> /proc/sys/kernel/hostname
</code></pre></div>    </div>
  </li>
  <li>Install the tools
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>opkg update
uci <span class="nb">set </span>system.ntp.enable<span class="o">=</span><span class="s1">'0'</span>
uci commit
/etc/init.d/sysntpd disable
/etc/init.d/sysntpd stop
/etc/init.d/ntpd disable
/etc/init.d/ntpd stop
opkg <span class="nb">install </span>chrony kmod-pps-gpio gpsd gpsd-clients <span class="se">\</span>
nano rsync umdns coreutils-who zabbix-agentd python3-light kmod-usb-net-rtl8152
/etc/init.d/chronyd <span class="nb">enable</span>
</code></pre></div>    </div>
    <h2 id="sw---gpsd-chrony-and-pps">SW - GPSD, chrony and PPS</h2>
  </li>
  <li>Configure gpsd
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci <span class="nb">set </span>gpsd.core.device<span class="o">=</span><span class="s1">'/dev/ttyAMA0'</span>
uci <span class="nb">set </span>gpsd.core.enabled<span class="o">=</span><span class="s1">'1'</span>
uci commit
/etc/init.d/gpsd <span class="nb">enable</span>
/etc/init.d/gpsd start
</code></pre></div>    </div>
  </li>
  <li>Check GPS connectivity : <code class="language-plaintext highlighter-rouge">cgps -s -u m</code> should show <code class="language-plaintext highlighter-rouge">Status 3D FIX</code></li>
  <li>Configure <code class="language-plaintext highlighter-rouge">chronyd</code> for using country specific servers in <code class="language-plaintext highlighter-rouge">/etc/config/chrony</code>:
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">config</span> <span class="err">pool</span>
	       <span class="err">option</span> <span class="err">hostname</span> <span class="err">'0.ch.pool.ntp.org'</span>
        <span class="err">option</span> <span class="err">iburst</span> <span class="err">'yes'</span>
<span class="err">...</span>
</code></pre></div>    </div>
  </li>
  <li>Add the GPS and PPS sources at the end of : <code class="language-plaintext highlighter-rouge">/etc/chrony/chrony.conf</code>
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code></code></pre></div>    </div>
    <p>refclock PPS /dev/pps0 refid PPS poll 0</p>

    <p>local stratum 10 orphan
…</p>
  </li>
  <li>(Re-) Start <code class="language-plaintext highlighter-rouge">chronyd</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/chronyd restart
</code></pre></div>    </div>
  </li>
  <li>Check GPS and PPS functionality :
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chronyc sources
</code></pre></div>    </div>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MS Name/IP address         Stratum Poll Reach LastRx Last sample               
<span class="o">===============================================================================</span>
<span class="c">#- GPS                           0   2   377     4  +1157us[+1157us] +/-  100ms</span>
<span class="c">#* PPS                           0   1   377     1   -114ns[ -209ns] +/-  669ns</span>
^- redacted1.example.com         3  10   377  1028  <span class="nt">-9345us</span><span class="o">[</span><span class="nt">-9381us</span><span class="o">]</span> +/-   52ms
^- redacted2.example.com         2  10   377   824  <span class="nt">-4990us</span><span class="o">[</span><span class="nt">-5019us</span><span class="o">]</span> +/-   11ms
^- redacted3.example.com         2  10   377   174  <span class="nt">-3748us</span><span class="o">[</span><span class="nt">-3755us</span><span class="o">]</span> +/-   35ms
^- redacted4.example.com         1  10   377  1023  <span class="nt">-3986us</span><span class="o">[</span><span class="nt">-4022us</span><span class="o">]</span> +/- 8996us
^- router.lan                    2   6   377    33  <span class="nt">-3157us</span><span class="o">[</span><span class="nt">-3157us</span><span class="o">]</span> +/-   40ms
^? pim-ntp.lan                   0   8     0     -     +0ns[   +0ns] +/-    0ns
</code></pre></div>    </div>
    <h2 id="configure-ntp-pool-dns-and-dhcp-on-a-openwrt-router">Configure NTP pool DNS and DHCP on a OpenWRT router</h2>
  </li>
  <li>Setup all your NTP servers in a DNS pool (<code class="language-plaintext highlighter-rouge">/etc/config/dhc</code>)
    <div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">...</span>
<span class="err">config</span> <span class="err">domain</span>
    <span class="err">option</span> <span class="err">name</span> <span class="err">'ntp'</span>
    <span class="err">option</span> <span class="err">ip</span> <span class="err">'XXX.XXX.XXX.XXX'</span> <span class="c"># address of the router with a NTP server
</span>
<span class="err">config</span> <span class="err">domain</span>
    <span class="err">option</span> <span class="err">name</span> <span class="err">'ntp'</span>
    <span class="err">option</span> <span class="err">ip</span> <span class="err">'XXX.XXX.XXX.YYY'</span> <span class="c"># address of the ntp server (from this post)
</span><span class="err">...</span>
</code></pre></div>    </div>
  </li>
  <li>Setup the DHCP to announce NTP servers:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uci add_list dhcp.lan.dhcp_option<span class="o">=</span><span class="s1">'42,XXX.XXX.XXX.XXX,XXX.XXX.XXX.YYY'</span>
uci commit
</code></pre></div>    </div>
  </li>
  <li>Restart <code class="language-plaintext highlighter-rouge">dnsmasq</code>
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/init.d/dnsmasq restart
</code></pre></div>    </div>
    <h2 id="result">Result</h2>

    <p>A small animation :  <code class="language-plaintext highlighter-rouge">watch chronyc sources</code> (<code class="language-plaintext highlighter-rouge">opkg install procps-ng-watch</code>)</p>
  </li>
</ol>
<asciinema-player src="../data/a/chronyc.jsonl" preload="" autoplay="" loop="" cols="80" rows="11" poster="npt:5.1" font-size="small"></asciinema-player>

<ol>
  <li>
    <p>(Optional) Optimisation for timing</p>

    <p>:point_up: The backup battery on the Waveshare MAX-M8Q GNSS HAT is mandatory.
Whitout it, the module will lose it’s configuration every power loss. The
symptom will be <code class="language-plaintext highlighter-rouge">NO FIX</code>, since the module will go back to 9600 bauds.</p>

    <ul>
      <li>set jumpers on A</li>
      <li>connect to your favorite Linux host using the USB cable</li>
      <li>start gpsd on the usb port
        <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ubxtool <span class="nt">-s</span> 9600 <span class="nt">-S</span> 115200
 ubxtool <span class="nt">-p</span> MODEL,2
 ubxtool <span class="nt">-p</span> CFG-PMS,0
 ubxtool <span class="nt">-p</span> SAVE
 ubxtool <span class="nt">-p</span> COLDBOOT <span class="c"># validate the settings are OK</span>
</code></pre></div>        </div>
      </li>
      <li>re-set jumpers on B</li>
      <li>configure 11500 bauds using <code class="language-plaintext highlighter-rouge">-s 115200</code> in <code class="language-plaintext highlighter-rouge">/etc/init.d/gpsd</code>:
        <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ...
 <span class="o">[</span> <span class="s2">"</span><span class="nv">$enabled</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"0"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="k">return </span>1

  	    procd_open_instance
  	    procd_set_param <span class="nb">command</span> <span class="s2">"</span><span class="nv">$PROG</span><span class="s2">"</span> <span class="nt">-N</span> <span class="nt">-n</span> <span class="nt">-s</span> 115200

  	    <span class="o">[</span> <span class="s2">"</span><span class="nv">$listen_globally</span><span class="s2">"</span> <span class="nt">-ne</span> 0 <span class="o">]</span> <span class="o">&amp;&amp;</span> procd_append_param <span class="nb">command</span> <span class="nt">-G</span>
  	    procd_append_param <span class="nb">command</span> <span class="nt">-S</span> <span class="s2">"</span><span class="nv">$port</span><span class="s2">"</span>
 ...
</code></pre></div>        </div>
      </li>
    </ul>
  </li>
</ol>]]></content><author><name>RandomReaper</name></author><category term="openwrt" /><category term="raspberry" /><category term="ntp" /><summary type="html"><![CDATA[HW Raspberry Pi 3 SD card (200MB will do, yes, 200MB!) Waveshare MAX-M8Q GNSS HAT for Raspberry Pi Raspberry Pi official case for 3B+]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Disable network access for a group of users</title><link href="https://cli.pignat.org/pages/ubuntu-disable-network-for-a-gid.html" rel="alternate" type="text/html" title="Disable network access for a group of users" /><published>2026-01-19T00:00:00+01:00</published><updated>2026-01-19T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/ubuntu-disable-network-for-a-gid</id><content type="html" xml:base="https://cli.pignat.org/pages/ubuntu-disable-network-for-a-gid.html"><![CDATA[<p>It may be needed to prevent network access for some users, for security or while
proctoring students. Here is how this can be achieved.</p>

<h2 id="add-the-user--to-the-nonet-group">Add the user  to the <code class="language-plaintext highlighter-rouge">nonet</code> group</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># create the nonet group</span>
<span class="nb">sudo </span>groupadd <span class="nt">-g</span> FREE_GID nonet <span class="c"># If you don't care about the GID : sudo groupadd nonet</span>

<span class="c"># add the user THE_USER to the group</span>
<span class="nb">sudo </span>usermod <span class="nt">-a</span> <span class="nt">-G</span> nonet THE_USER
</code></pre></div></div>

<h2 id="create-the-service-file-etcsystemdsystemnonet-for-group-nonetservice">Create the service file /etc/systemd/system/nonet-for-group-nonet.service</h2>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">Disable network for group nonet</span>

<span class="err">[Service]</span>
<span class="py">Type</span><span class="p">=</span><span class="s">oneshot</span>
<span class="py">RemainAfterExit</span><span class="p">=</span><span class="s">yes</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">iptables -A OUTPUT -o lo -p all -m owner --gid-owner nonet --suppl-groups -j ACCEPT</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">iptables -A OUTPUT -p all -m owner --gid-owner nonet --suppl-groups -j REJECT</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">ip6tables -A OUTPUT -o lo -p all -m owner --gid-owner nonet --suppl-groups -j ACCEPT</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">ip6tables -A OUTPUT -p all -m owner --gid-owner nonet --suppl-groups -j REJECT</span>

<span class="py">ExecStop</span><span class="p">=</span><span class="s">iptables -D OUTPUT -o lo -p all -m owner --gid-owner nonet --suppl-groups -j ACCEPT</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">iptables -D OUTPUT -p all -m owner --gid-owner nonet --suppl-groups -j REJECT</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">ip6tables -D OUTPUT -o lo -p all -m owner --gid-owner nonet --suppl-groups -j ACCEPT</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">ip6tables -D OUTPUT -p all -m owner --gid-owner nonet --suppl-groups -j REJECT</span>

<span class="err">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
</code></pre></div></div>

<h2 id="reload-services">Reload services</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl daemon-reload
</code></pre></div></div>

<h2 id="test-network-for-user-the_user-should-work-fine">Test network for user THE_USER (SHOULD work fine):</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-u</span> THE_USER curl <span class="nt">-I</span> https://cli.pignat.org/pages/ubuntu-disable-network-for-a-gid.html
HTTP/2 200 OK
...
</code></pre></div></div>
<h2 id="start-the-service">Start the service</h2>
<ul>
  <li><code class="language-plaintext highlighter-rouge">sudo systemctl start</code> to disable network access for</li>
  <li><code class="language-plaintext highlighter-rouge">sudo systemctl enable</code> to disable network access at boot</li>
  <li><code class="language-plaintext highlighter-rouge">sudo systemctl stop</code> to allow network access</li>
</ul>

<h2 id="test-network-for-user-the_user-should-not-work">Test network for user THE_USER (SHOULD NOT work):</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-u</span> THE_USER curl <span class="nt">-I</span> https://cli.pignat.org/pages/ubuntu-disable-network-for-a-gid.html
curl: <span class="o">(</span>7<span class="o">)</span> Failed to connect to cli.pignat.org port 443 after 2 ms: Couldn<span class="s1">'t connect to server
</span></code></pre></div></div>

<p>:warning: <code class="language-plaintext highlighter-rouge">ping</code> will still work because it is installed with <code class="language-plaintext highlighter-rouge">setuid</code> root on Debian-based distributions.</p>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="24.04" /><summary type="html"><![CDATA[It may be needed to prevent network access for some users, for security or while proctoring students. Here is how this can be achieved.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Disable ubuntu automatic upgrades (**all**)</title><link href="https://cli.pignat.org/pages/ubuntu-disable-automaic-upgrades.html" rel="alternate" type="text/html" title="Disable ubuntu automatic upgrades (**all**)" /><published>2026-01-15T00:00:00+01:00</published><updated>2026-01-15T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/ubuntu-disable-automatic-upgrades</id><content type="html" xml:base="https://cli.pignat.org/pages/ubuntu-disable-automaic-upgrades.html"><![CDATA[<p>Trust me, upgrades <strong>MUST</strong><a href="#rfc2119">*1</a> be <strong>attended</strong>.</p>

<p id="rfc2119">* <em>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
“SHOULD NOT”, “RECOMMENDED”,  “MAY”, and “OPTIONAL” in this document are to be
interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119" class="external">RFC 2119</a></em>.</p>

<h2 id="disable-automatic-upgrades">Disable automatic upgrades</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="c"># list of systemd services/timers to disable</span>
<span class="nb">declare</span> <span class="nt">-a</span> <span class="nv">svc</span><span class="o">=(</span>
  <span class="s2">"unattended-upgrades.service"</span>
  <span class="s2">"apt-daily-upgrade.service"</span>
  <span class="s2">"apt-daily-upgrade.timer"</span>
  <span class="s2">"apt-daily.service"</span>
  <span class="s2">"apt-daily.timer"</span>
  <span class="s2">"apt-news.service"</span>
  <span class="s2">"fwupd-offline-update.service"</span>
  <span class="s2">"fwupd-refresh.service"</span>
  <span class="s2">"fwupd-refresh.timer"</span>
  <span class="s2">"fwupd.service"</span>
<span class="o">)</span>

<span class="k">for </span>i <span class="k">in</span> <span class="s2">"</span><span class="k">${</span><span class="nv">svc</span><span class="p">[@]</span><span class="k">}</span><span class="s2">"</span>
<span class="k">do
   </span><span class="nb">sudo </span>systemctl disable <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span>
   <span class="nb">sudo </span>systemctl stop <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span>
   <span class="nb">sudo </span>systemctl mask <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span>
<span class="k">done</span>

<span class="c"># disable snap updates</span>
<span class="nb">sudo </span>snap refresh <span class="nt">--hold</span><span class="o">=</span>forever

<span class="c"># disable update-notifier (so it won't trigger when we do a manual update)</span>
<span class="nb">sudo sed</span> <span class="nt">-i</span> <span class="s1">'s/DPkg::Post-Invoke/#DPkg::Post-Invoke/'</span> /etc/apt/apt.conf.d/99update-notifier

<span class="c"># disable periodic apt updates</span>
<span class="nb">sudo sed</span> <span class="nt">-i</span> <span class="s1">'s/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/'</span> /etc/apt/apt.conf.d/10periodic


<span class="c"># forget new packages in aptitude</span>
<span class="nb">echo</span> <span class="s1">'Aptitude::Forget-New-On-Update "true";'</span> | <span class="nb">sudo tee</span> /etc/apt/apt.conf.d/99aptitude-forget-new
</code></pre></div></div>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="24.04" /><summary type="html"><![CDATA[Trust me, upgrades MUST*1 be attended.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Find a device on the network, knowing it’s MAC address</title><link href="https://cli.pignat.org/pages/find-network-mac.html" rel="alternate" type="text/html" title="Find a device on the network, knowing it’s MAC address" /><published>2026-01-06T00:00:00+01:00</published><updated>2026-01-06T00:00:00+01:00</updated><id>https://cli.pignat.org/pages/find-netword-mac</id><content type="html" xml:base="https://cli.pignat.org/pages/find-network-mac.html"><![CDATA[<h2 id="tldr">TL;DR;</h2>

<p>Use <strong>the_hosname</strong><strong><em>.local</em></strong> as URI, exemple:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user@host:/anywhere<span class="nv">$ </span>ping <span class="nt">-c1</span> pim-checker.local
PING pim-checker.local <span class="o">(</span>X.X.X.95<span class="o">)</span> 56<span class="o">(</span>84<span class="o">)</span> bytes of data.
64 bytes from X.X.X.95: <span class="nv">icmp_seq</span><span class="o">=</span>1 <span class="nv">ttl</span><span class="o">=</span>64 <span class="nb">time</span><span class="o">=</span>1.57 ms

<span class="nt">---</span> pim-checker.local ping statistics <span class="nt">---</span>
1 packets transmitted, 1 received, 0% packet loss, <span class="nb">time </span>0ms
rtt min/avg/max/mdev <span class="o">=</span> 1.568/1.568/1.568/0.000 ms
user@host:/anywhere<span class="err">$</span>
</code></pre></div></div>

<p>Avahi uses <a href="https://en.wikipedia.org/wiki/Zero-configuration_networking" class="external">zeroconf</a> (also called <a href="https://en.wikipedia.org/wiki/Bonjour_(software)" class="external">Bonjour</a> by Apple) to discover hosts. On a minimal
setup, it may not be installed (<code class="language-plaintext highlighter-rouge">sudo apt-get install avahi-daemon</code>).</p>

<h2 id="or-the-good-old-method">or the good old method</h2>

<p>Here is how to find a device IP address on a DHCP network, knowing only it’s MAC address, an open TCP port
and our own IP on the network.</p>

<ul>
  <li>Look at the device MAC address, here I’m searching for a raspberry PI, so I know it will start with 88:a2:9e<a href="#rpi-mac">*</a>.</li>
  <li>Put the empty file named ssh on the boot partition of the raspberry PI to enable ssh.</li>
  <li>Detect a host running ssh on the network:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap <span class="nt">-p</span> 22 <span class="nt">--open</span> X.X.X.0/24
</code></pre></div>    </div>
  </li>
  <li>Search the know host in the ARP table:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>arp <span class="nt">-a</span> | <span class="nb">grep </span>88:a2:9e
? <span class="o">(</span>X.X.X.95<span class="o">)</span> at 88:a2:9e:YY:YY:YY <span class="o">[</span>ether] on br0
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="rpi-mac">Known Rapberry Pi OUIs (Organizationally Unique Identifiers)</h2>
<p>Did you say MAC address? Here is how to find all possible</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user@host:/anywhere<span class="nv">$ </span><span class="nb">sudo </span>update-ieee-data
...
user@host:/anywhere<span class="nv">$ </span><span class="nb">cat</span> /var/lib/ieee-data/oui.txt | <span class="nb">grep</span> <span class="nt">-i</span> hex | <span class="nb">grep</span> <span class="nt">-i</span> <span class="s2">"Raspberry Pi"</span>
D8-3A-DD   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi Trading Ltd
DC-A6-32   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi Trading Ltd
E4-5F-01   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi Trading Ltd
88-A2-9E   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi <span class="o">(</span>Trading<span class="o">)</span> Ltd
28-CD-C1   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi Trading Ltd
B8-27-EB   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi Foundation
2C-CF-67   <span class="o">(</span>hex<span class="o">)</span>		Raspberry Pi <span class="o">(</span>Trading<span class="o">)</span> Ltd
user@host:/anywhere<span class="err">$</span>
</code></pre></div></div>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="raspberry" /><category term="network" /><summary type="html"><![CDATA[TL;DR;]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">using `portainer` with user namespace</title><link href="https://cli.pignat.org/portainer-userns-nginx.html" rel="alternate" type="text/html" title="using `portainer` with user namespace" /><published>2025-12-12T00:00:00+01:00</published><updated>2025-12-12T00:00:00+01:00</updated><id>https://cli.pignat.org/portainer-userns-nginx</id><content type="html" xml:base="https://cli.pignat.org/portainer-userns-nginx.html"><![CDATA[<h2 id="failed-loading-environment-the-environment-named-local-is-unreachable">Failed loading environment The environment named local is unreachable.</h2>

<p>You’re using <code class="language-plaintext highlighter-rouge">docker</code> with namespace isolation (<strong>userns-remap</strong>) and portainer can’t access <code class="language-plaintext highlighter-rouge">/var/run/docker.sock</code>?</p>

<p>Here is the solution, please note the <code class="language-plaintext highlighter-rouge">--userns host</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">--userns</span> host <span class="nt">-d</span> <span class="nt">--name</span> portainer <span class="nt">--restart</span><span class="o">=</span>unless-stopped <span class="nt">-v</span> /var/run/docker.sock:/var/run/docker.sock:z <span class="nt">-v</span> portainer_data:/data portainer/portainer-ce:lts
</code></pre></div></div>

<p>No published ports, since <a href="tag/nginx.html" class="set-5"><code class="language-plaintext highlighter-rouge">nginx</code></a>, runs on the same host.</p>

<p>Here is the <a href="tag/nginx.html" class="set-5"><code class="language-plaintext highlighter-rouge">nginx</code></a> config:</p>

<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">server</span> <span class="err">{</span>
	<span class="err">server_name</span> <span class="err">portainer.example.com;</span>

	<span class="err">include</span> <span class="err">snippets/my_ssl_config.conf;</span>
	<span class="err">listen</span> <span class="err">443</span> <span class="err">ssl;</span>
	<span class="err">listen</span> <span class="err">[::]:443</span> <span class="err">ssl;</span>

	<span class="err">location</span> <span class="err">/</span> <span class="err">{</span>
		<span class="err">proxy_set_header</span> <span class="err">Host</span> <span class="err">$host;</span>
		<span class="err">proxy_pass</span> <span class="py">http</span><span class="p">:</span><span class="s">//PORTAINER_IP:9000/;</span>
		<span class="err">proxy_set_header</span> <span class="err">X-Real-IP</span> <span class="err">$remote_addr;</span>
		<span class="err">proxy_set_header</span> <span class="err">X-Forwarded-For</span> <span class="err">$proxy_add_x_forwarded_for;</span>
		<span class="err">proxy_set_header</span> <span class="err">X-Forwarded-Proto</span> <span class="err">$scheme;</span>
		<span class="err">proxy_set_header</span> <span class="err">Upgrade</span> <span class="err">$http_upgrade;</span>
		<span class="err">proxy_set_header</span> <span class="err">Connection</span> <span class="err">"upgrade";</span>
		<span class="err">proxy_http_version</span> <span class="err">1.1;</span>
	<span class="err">}</span>
<span class="err">}</span>
</code></pre></div></div>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="24.04" /><category term="server" /><category term="docker" /><category term="nginx" /><summary type="html"><![CDATA[Failed loading environment The environment named local is unreachable.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/tab.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/tab.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">`motd` please be quiet!</title><link href="https://cli.pignat.org/ubuntu-24.04-motd.html" rel="alternate" type="text/html" title="`motd` please be quiet!" /><published>2025-12-04T00:00:00+01:00</published><updated>2025-12-04T00:00:00+01:00</updated><id>https://cli.pignat.org/ubuntu-24.04-motd</id><content type="html" xml:base="https://cli.pignat.org/ubuntu-24.04-motd.html"><![CDATA[<h1 id="ubuntu-login-motd-is-too-verbose">ubuntu login (<code class="language-plaintext highlighter-rouge">motd</code>) is too verbose</h1>

<p>This page is about <a href="tag/24.04.html" class="set-5">24.04</a>, here is the page about <a href="ubuntu-18.04-motd.html">motd in 18.04</a>.</p>

<p>My current ubuntu server greets me like this :</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">Welcome to Ubuntu 24.04.3 LTS (GNU/Linux 6.8.0-88-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Thu Dec  4 01:02:03 UTC 2025

  System load:           0.0
  Usage of /:            16.5% of 23.17GB
  Memory usage:          6%
  Swap usage:            0%
  Processes:             126
  Users logged in:       0
  IPv4 address for enX0: 23.75.345.200
  IPv6 address for enX0: 0:0:0:0:0:ffff:174b:159c8

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Wed Dec  3 01:02:03 2025 from 75.748.86.91
</span><span class="gp">user@machine:~$</span><span class="w">
</span></code></pre></div></div>

<h1 id="make-it-less-verbose">Make it less verbose</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># I know where to find help</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/10-help-text

<span class="c"># The state of my system is fine (otherwise zabbix, monit or OnlineBot would have told me).</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/50-landscape-sysinfo

<span class="c"># I know about meltdown and spectre, since I'm a grumpy reader of https://lwn.net</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/50-motd-news

<span class="c"># I won't buy support for my home server:</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/91-contract-ua-esm-status

<span class="c"># I manage updates myself</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/85-fwupd
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/92-unattended-upgrades
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/90-updates-available

<span class="c"># LTS releases are every 2 years</span>
<span class="nb">sudo chmod</span> <span class="nt">-x</span> /etc/update-motd.d/91-release-upgrade
</code></pre></div></div>

<h1 id="result">Result</h1>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">Welcome to Ubuntu 24.04.3 LTS (GNU/Linux 6.8.0-88-generic x86_64)

Last login: Thu Dec  4 02:03:04 2025 from 75.748.86.91

</span></code></pre></div></div>
<p><a href="https://en.wikipedia.org/wiki/Veni,_vidi,_vici">Veni, vidi, vici</a>.</p>]]></content><author><name>RandomReaper</name></author><category term="ubuntu" /><category term="24.04" /><summary type="html"><![CDATA[ubuntu login (motd) is too verbose]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cli.pignat.org/data/img/wide/site.jpg" /><media:content medium="image" url="https://cli.pignat.org/data/img/wide/site.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>