From a97d526f85299c4b96a9ae750f79e5f4fbbe052b Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Mon, 21 Oct 2024 03:29:07 -0400 Subject: [PATCH] various fixes --- .bashrc | 6 +- brc2 | 65 +++++++++++++------ conflink | 10 +++ distro-end | 5 +- .../system/transmission-daemon-nn.service | 1 + .../etc/udev/rules.d/50-kaleidoscope.rules | 25 +++++++ ...ursor-usb.rules => 50-precursor-usb.rules} | 0 .../etc/udev/rules.d/99-kaleidoscope.rules | 22 ------- .../usr/local/bin/joins-namespace-of-check | 61 +++++++++++++++++ mail-setup | 13 +++- pkgs | 1 + 11 files changed, 163 insertions(+), 46 deletions(-) create mode 100644 filesystem/etc/udev/rules.d/50-kaleidoscope.rules rename filesystem/etc/udev/rules.d/{99-precursor-usb.rules => 50-precursor-usb.rules} (100%) delete mode 100644 filesystem/etc/udev/rules.d/99-kaleidoscope.rules create mode 100755 filesystem/usr/local/bin/joins-namespace-of-check diff --git a/.bashrc b/.bashrc index 7085f71..1ace08b 100644 --- a/.bashrc +++ b/.bashrc @@ -70,8 +70,10 @@ _ran_bashrc=t # Test if we are in noninteractive ssh shells or tty. tty because often # i use it when for example, io on the remote host is really slow and my -# bashrc is too slow. -if [[ $LC_USEBASHRC != t && ( $SSH_CONNECTION || $TERM == linux ) ]]; then +# bashrc is too slow. 3 SECONDS because if the shell is around longer +# than that, I'm probably sourcing the file manually, not as part of +# shell startup. +if [[ ( $SECONDS && $SECONDS -lt 3 ) && $LC_USEBASHRC != t && ( $SSH_CONNECTION || $TERM == linux ) ]]; then # Here we did not opt-in to running our .bashrc file so we just # return, but we still setup a function to source it without returning # so if we want it we don't have to restart our ssh connection. diff --git a/brc2 b/brc2 index ce21d4f..b1bfb36 100644 --- a/brc2 +++ b/brc2 @@ -1048,7 +1048,7 @@ beetag() { first_play=false for (( i=0; i<20; i++ )); do if [[ $(mpvrpco '{ "command": ["get_property", "idle-active"] }' 2>/dev/null | jq .data) == true ]]; then - mpvrpc-loadfile "$path" 2>/dev/null + mpvrpc-loadfile "$path" break fi sleep .1 @@ -3078,7 +3078,7 @@ sdmn() { ns=$1 unit=$2 shift 2 - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) env-tmpf "$@" if $alt_user; then final_args=("$@") @@ -3120,7 +3120,7 @@ mnsd() { # mount namespace + systemd network namespace shift 2 ## end command line args ## - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) env-tmpf "$@" if $alt_user; then final_args=("$@") @@ -4120,9 +4120,25 @@ enn() { fi } -# get pid of systemd service +# Check that ns of pid $1 really exists, like joins-namespace-of-check +ns-exists() { + local service_ns default_ns pid + pid="$1" + [[ $pid ]] + service_ns=$(s readlink /proc/$pid/ns/net) + default_ns=$(s readlink /proc/1/ns/net) + [[ $service_ns && $service_ns != "$default_ns" ]] +} + +# Get pid of systemd service +# +# -n also call ns-exists on pid. servicepid() { - local pid unit dir + local pid unit dir ns_check=false + if [[ $1 == -n ]]; then + ns_check=true + shift + fi unit="$1" pid=$(systemctl show --property MainPID --value "$unit") case $pid in @@ -4142,6 +4158,7 @@ servicepid() { ;; esac if [[ $pid ]]; then + ns-exists "$pid" printf "%s\n" "$pid" else return 1 @@ -4155,7 +4172,7 @@ sdnbash() { # systemd namespace bash return 1 fi unit=$1 - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) m sudo nsenter -t $pid -n -m sudo -u $USER -i bash } @@ -4166,7 +4183,7 @@ sdnbashroot() { # systemd namespace bash as root return 1 fi unit=$1 - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) m sudo nsenter -t $pid -n -m bash } @@ -4191,7 +4208,7 @@ sdncmd() { unit=$1 shift - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) env-tmpf "$@" if $alt_user; then final_args=("$@") @@ -4209,7 +4226,7 @@ sdncmdroot() { # systemd namespace root command fi unit=$1 shift - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) m sudm nsenter -t $pid -n -m "$@" } @@ -4244,7 +4261,7 @@ sdnncmd() { fi unit=$1 shift - pid=$(servicepid $unit) + pid=$(servicepid -n $unit) env-tmpf "$@" m sudo nsenter -t $pid -n sudo -u $USER -i bash -c ". $tmpf" } @@ -4290,25 +4307,35 @@ mailnncheck() { # mailvpn would belong on the list if using openvpn for unit in mailnn unbound dovecot $spamd_ser exim4 radicale; do - pid=$(servicepid $unit) + if ! pid=$(servicepid $unit); then + if [[ $unit == mailnn ]]; then + echo error: could not find service pid of unit: $unit returning early + return 1 + else + echo error: could not find service pid of unit: $unit, continuing with other units + continue + fi + fi echo debug: unit=$unit pid=$pid if [[ ! $pid ]]; then - echo failed to find pid for unit=$unit + echo error: failed to find pid for unit=$unit continue fi if ! ns=$(s readlink /proc/$pid/ns/net); then - echo failed to find ns for unit=$unit pid=$pid + echo error: failed to find ns for unit=$unit pid=$pid continue fi - if [[ $mailnn ]]; then - if [[ $ns != "$mailnn" ]]; then - echo "$unit ns $ns != $mailnn" - fi - else + if [[ $unit == mailnn ]]; then mailnn=$ns + default_ns=$(s readlink /proc/1/ns/net) + fi + if [[ $ns == "$default_ns" ]]; then + echo error: $unit ns == default_ns, $ns == $default_ns + fi + if [[ $ns != "$mailnn" ]]; then + echo "error: $unit ns $ns != $mailnn" fi done - } diff --git a/conflink b/conflink index 5edc21e..31bccf3 100755 --- a/conflink +++ b/conflink @@ -328,6 +328,16 @@ case $user in m rsync -clgoDiSAX --chmod=g+r --chown=root:icecast /p/c/user-specific/icecast2/icecast.xml /etc/icecast2 fi + # note: if we wanted to be robust, in the case that cupsd is + # running, we would do a dry run, see if anything would change, then + # stop cupsd, rsync, and start it again. + if [[ -e /p/c/user-specific/cups && -d /etc/cups/ppd ]] && getent group lp &>/dev/null && ! systemctl is-active --quiet cupsd; then + # note, group lp shouldn't matter since it has no permissions, but I'm just replicating the default. + m rsync -clgoDiSAX --chown=root:lp /p/c/user-specific/cups/printers.conf /etc/cups + m rsync -clgoDiSAX --chmod=g+r --chown=root:lp /p/c/user-specific/cups/ppd/* /etc/cups/ppd + fi + + # disabled # if [[ -d /var/lib/bitcoind && -d /p/c/user-specific/bitcoin ]]; then # s rsync -clpgoDiSAX --chown=bitcoin:bitcoin /p/c/user-specific/bitcoin/settings.json /var/lib/bitcoind diff --git a/distro-end b/distro-end index a0fcf88..a2723c0 100755 --- a/distro-end +++ b/distro-end @@ -1315,9 +1315,10 @@ if [[ ! -e ~/.linphonerc && -e /p/.linphonerc-initial ]]; then m cp /p/.linphonerc-initial ~/.linphonerc fi -# linphone in t10 wont do dns with systemd-resolved or something +# linphone in t10 & t11 wont do dns with systemd-resolved or something s teeu /etc/hosts <<'EOF' -74.94.156.215 watson.fsf.org +209.51.188.90 watson.fsf.org +2001:470:142::90 watson.fsf.org EOF diff --git a/filesystem/etc/systemd/system/transmission-daemon-nn.service b/filesystem/etc/systemd/system/transmission-daemon-nn.service index 0843fc2..0abd856 100644 --- a/filesystem/etc/systemd/system/transmission-daemon-nn.service +++ b/filesystem/etc/systemd/system/transmission-daemon-nn.service @@ -11,6 +11,7 @@ User=debian-transmission # https://github.com/transmission/transmission/issues/6991 #Type=notify Type=simple +ExecStartPre=/usr/local/bin/joins-namespace-of-check openvpn-client-tr@client ExecStart=/usr/bin/transmission-daemon -f --log-error ExecReload=/bin/kill -s HUP $MAINPID PrivateNetwork=true diff --git a/filesystem/etc/udev/rules.d/50-kaleidoscope.rules b/filesystem/etc/udev/rules.d/50-kaleidoscope.rules new file mode 100644 index 0000000..fc4e17a --- /dev/null +++ b/filesystem/etc/udev/rules.d/50-kaleidoscope.rules @@ -0,0 +1,25 @@ +## This file sets up a few things for selected Kaleidoscope-powered keyboards: +## - We first symlink the device to a more friendly name, based on the product +## name. +## - We then ask ModemManager to ignore the serial ports on the device, and not +## consider them a candidate. +## - We also tell systemd to grant access to the device (via ACLs) to the user +## at-seat. +## +## For more information about the access part, see the following resources: +## - https://github.com/systemd/systemd/issues/4288 +## - https://www.freedesktop.org/software/systemd/man/sd-login.html + +## iank: substituted := for =, based on +## Jun 09 12:27:48 so systemd-udevd[1385]: /etc/udev/rules.d/99-kaleidoscope.rules:18 ENV key ta +## kes '==', '!=', '=', or '+=' operator, assuming '='. + +## iank, starting in t12, this has to be a number less than 70 due to /usr/lib/udev/rules.d/70-uaccess.rules +## pretty lame. + +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="2300", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="2301", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="2302", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="2303", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" +SUBSYSTEM=="usb", ATTR{idVendor}=="3496", ATTR{idProduct}=="0005", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" +SUBSYSTEM=="usb", ATTR{idVendor}=="3496", ATTR{idProduct}=="0006", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" diff --git a/filesystem/etc/udev/rules.d/99-precursor-usb.rules b/filesystem/etc/udev/rules.d/50-precursor-usb.rules similarity index 100% rename from filesystem/etc/udev/rules.d/99-precursor-usb.rules rename to filesystem/etc/udev/rules.d/50-precursor-usb.rules diff --git a/filesystem/etc/udev/rules.d/99-kaleidoscope.rules b/filesystem/etc/udev/rules.d/99-kaleidoscope.rules deleted file mode 100644 index 636ebe8..0000000 --- a/filesystem/etc/udev/rules.d/99-kaleidoscope.rules +++ /dev/null @@ -1,22 +0,0 @@ -## This file sets up a few things for selected Kaleidoscope-powered keyboards: -## - We first symlink the device to a more friendly name, based on the product -## name. -## - We then ask ModemManager to ignore the serial ports on the device, and not -## consider them a candidate. -## - We also tell systemd to grant access to the device (via ACLs) to the user -## at-seat. -## -## For more information about the access part, see the following resources: -## - https://github.com/systemd/systemd/issues/4288 -## - https://www.freedesktop.org/software/systemd/man/sd-login.html - -## iank: substituted := for =, based on -## Jun 09 12:27:48 so systemd-udevd[1385]: /etc/udev/rules.d/99-kaleidoscope.rules:18 ENV key ta -## kes '==', '!=', '=', or '+=' operator, assuming '='. - -SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2300", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2301", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2302", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2303", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0005", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0006", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat" diff --git a/filesystem/usr/local/bin/joins-namespace-of-check b/filesystem/usr/local/bin/joins-namespace-of-check new file mode 100755 index 0000000..7305a87 --- /dev/null +++ b/filesystem/usr/local/bin/joins-namespace-of-check @@ -0,0 +1,61 @@ +#!/bin/bash +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to change +# to a recommended GPL license. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# This script is for use like: +# ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn +# to do a check that the unit is being started in the intended network namespace. +# +# +# This exists due to the note in man systemd.exec: +# +# PrivateNetwork= ... Note that the implementation of this setting might +# be impossible (for example if network namespaces are not available), +# and the unit should be written in a way that does not solely rely on +# this setting for security. +# +# And based on experience that I've encountered unexpected conditions +# which caused the JoinsNamespaceOf setting to fail. + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + + +unit="$1" +pid=$(head -n1 /sys/fs/cgroup/system.slice/$unit.service/cgroup.procs) +ns=$(readlink /proc/$pid/ns/net) +default_ns=$(readlink /proc/1/ns/net) + +if [[ ! $ns || ! $default_ns || $ns == "$default_ns" ]]; then + echo "error: unexpected: ns=$ns default_ns=$default_ns" >&2 + exit 1 +fi + +our_ns=$(readlink /proc/$$/ns/net) +if [[ $our_ns != "$ns" ]]; then + echo "error: our_ns:$our_ns != ns:$ns" + exit 1 +fi diff --git a/mail-setup b/mail-setup index 5038299..bae2d81 100755 --- a/mail-setup +++ b/mail-setup @@ -734,6 +734,7 @@ BindsTo=mailnn.service StartLimitIntervalSec=0 [Service] +ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn PrivateNetwork=true # i dont think we need any of these, but it doesnt hurt to stay consistent BindPaths=$bindpaths @@ -764,6 +765,7 @@ Type=notify RuntimeDirectory=openvpn-client RuntimeDirectoryMode=0710 WorkingDirectory=/etc/openvpn/client +ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn ExecStart=/usr/sbin/openvpn --suppress-timestamps --nobind --config /etc/openvpn/client/mail.conf #CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE LimitNPROC=10 @@ -803,6 +805,7 @@ StartLimitIntervalSec=0 Type=simple RemainAfterExit=true PrivateNetwork=true +ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn ExecStart=/usr/bin/flock -w 20 /tmp/newns.flock /a/bin/newns/newns -n 10.173.8 start mail ExecStop=/usr/bin/flock -w 20 /tmp/newns.flock /a/bin/newns/newns stop mail Restart=always @@ -817,7 +820,13 @@ EOF u /etc/systemd/system/mailnn.service <<'EOF' [Unit] Description=Network Namespace for mail vpn service that will live forever and cant fail -After=syslog.target network-online.target +# These are the same as unbound.service. Note, that if we had an After= for a later target +# than nss-lookup, systemd would just ignore unbound's After=mailnn.service and +# start it first. It seems logically, that we should not need the Before= here, +# but I'm not confident that systemd would do something unexpected and still start +# unbound earlier than this. +After=network.target +Before=nss-lookup.target Wants=network-online.target [Service] @@ -914,6 +923,7 @@ BindsTo=mailnn.service StartLimitIntervalSec=0 [Service] +ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn PrivateNetwork=true # note the nsswitch bind is actually not needed for bk, but # its the same file so it does no harm. @@ -2088,6 +2098,7 @@ JoinsNamespaceOf=mailnn.service StartLimitIntervalSec=0 [Service] +ExecStartPre=/usr/local/bin/joins-namespace-of-check mailnn PrivateNetwork=true BindPaths=$bindpaths Restart=always diff --git a/pkgs b/pkgs index dc10690..d3a74ae 100644 --- a/pkgs +++ b/pkgs @@ -264,6 +264,7 @@ p3=( pixz # unattended-upgrades.log: Please install powermgmt-base package to check power status powermgmt-base + pngtools profanity # for pactl pulseaudio-utils -- 2.30.2