IBM RS/6000 von 1993

Von den Leuten, die uns “STRG”, “ENTF” und “EINFG” gebracht haben, ein Highlight, das sich leider nie durchgesetzt hat: Die GRDST-Taste.

Diese RS/6000 hat den Weg zu mir so um 2000 gefunden, als mein erster Vollzeit-Linuxjob noch ein paar Jahre entfernt war.

Damals kuschelte IBM etwas widerwillig mit Linux und hatte auf AIX 4.3.3 parallel zur Einführung von AIX 5L (das L sollte für die Nähe zu Linux stehen) RPM als additiven Paketmanager eingeführt. Die Liste der damals verfügbaren Pakete kann bei bullfreeware.com bewundert werden (hier ein lokaler Mirror). Ich habe zuletzt noch einige davon installiert, um das Tool zum Benchmarking übersetzen zu können.

Zur 7012 besitze ich auch noch das passende SCSI-CDROM mit der passenden obskuren Blockgröße. Installationsmedien sind aber keine mehr vorhanden. Die Demo-Installation mit User root und Password root muss also für immer halten. Außer AIX ist mir kein Betriebssystem bekannt, das auf dem System nutzbar wäre.

SSH fehlt, aber per Telnet über den wackeligen AUI-Transceiver mit 10 Megabit/s macht das System einen sehr guten und responsiven Eindruck, fast besser als heute manche VMware-Instanz. 😉

Die Towers of Hanoi aus dem BYTE Unix Benchmark führt die RS/6000 mit ca. 1050 Loops pro Sekunde aus. Ein halbwegs aktuelles Vergleichssystem mit Intel-CPU und 3,6 GHz kommt auf ca. 3200000 Loops pro Sekunde.

Divisionen in der folgenden Schleife macht die RS/6000 mit 16500/s (Perl 5.5 vorinstalliert) bzw. 14500/s (Perl 5.8 aus dem RPM); mein moderneres Vergleichssystem kommt auf knapp 7 Millionen/s.

perl -e '$o=time();$s=$o;while(10>$o-$s)
{rand()/(rand()+1);$i++;$n=time();if($n!=$o)
{printf"%i\n",$i;$i=0};$o=$n}'

Softwaretechnisch größtes Highlight dürfte das installierte Java 1.1.8 sein. IPv6 wird zur Konfiguration angeboten, funktioniert aber in dieser aus dem Jahr 1999 stammenden Implementation nicht wirklich zufriedenstellend.

Technische Daten: POWER1-Prozessor mit 50 MHz, 128 MB Arbeitsspeicher, 2 GB Festplatte. Produktionszeitraum 1993-1994. (Mirror vom Datenblatt)

(Dieser Beitrag stand 2014 schon mal an anderer Stelle. Die Benchmarks auf heutigen Systemen wurden aktualisiert und ein lokaler Mirror der Bullfreeware-Liste und des Datenblatts gesichert.)

Posted in UNIX & Linux | Tagged , , , | Leave a comment

Too good to #0006

“Sudo on demand” from TGT0003 considered more useful for downgrading privileges on the fly

#!/usr/bin/env bash

want_user=letsencrypt
am_user="$(id -un)"
printf "Running as: %s\n" "${am_user}"
if [[ "${want_user}" != "${am_user}" ]]
then
        printf "Re-executing with sudo.\n"
        exec sudo -u "${want_user}" "${0}"
fi
...

JSON export of all installed packages on Debian/Ubuntu

#!/bin/bash

function dpkg_json(){
    printf "{\n"
    format='"${Package}": { "Version": "${Version}", "Architecture": "${Architecture}", "Status": "${db:Status-Abbrev}" },\n'
    dpkg-query --show --showformat="${format}" | sed '$s/,$//'
    printf "}\n"
}

dpkg_json | jq .

Urlwatch for a new version of a package in the Ubuntu package pool

---
name: "Ubuntu Curtin package (waiting for apt-key fix)"
url: http://archive.ubuntu.com/ubuntu/pool/main/c/curtin/
filter:
  - xpath: //table//td[2]
  - html2text
  - grep: ^curtin.*\.deb$
---
Posted in Too Good To, UNIX & Linux | Tagged , , , , , | 1 Comment

Letsencrypt und DNS Round-Robin

Ich weiß jetzt wieder, wie ich Letsencrypt auf DNS Round-Robin mit zwei Servern aufgesetzt hatte und finde es auch mit einigen Jahren Abstand gar nicht mal so schrecklich.

Die Server kennen sich auf Port 80 unter ihrem Namen im Round-Robin und unter einem eigenen Rollennamen:

ServerName www.example.com
ServerAlias www-foo.example.com
ServerName www.example.com
ServerAlias www-bar.example.com

mod_rewrite auf Port 80 fängt zunächst mal alles ab, was nicht nach Letsencrypt aussieht und leitet nach HTTPS weiter; hier auf www-foo.example.com:

ServerName www.example.com
ServerAlias www-foo.example.com

RewriteEngine On

RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Was jetzt noch übrig bleibt, wird daraufhin geprüft, ob a) die angeforderte Challenge im Dateisystem nicht vorhanden ist und b) der Request an den Namen aus dem Round-Robin gestellt wurde (um endlose Proxy-Rekursionen zu verhindern). Falls die Challenge lokal nicht existiert, wird der Request per Reverse Proxy an einen nachgelagerten Server gestellt:

ServerName www.example.com
ServerAlias www-foo.example.com

RewriteEngine On

RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} "www.example.com"
RewriteRule ^/(.*)$ http://www-bar.example.com%{REQUEST_URI} [P,QSA,L]

Mit 2 Servern ist klar, wo die Challenge zu holen ist. Bei 3 und mehr Servern würde ich eher nicht riskieren, in multiple Proxy-Weiterleitungen zu gehen, sondern mod_rewrite über RewriteMap aktiv ermitteln lassen, auf welchem der anderen Server die Challenge denn tatsächlich liegt.

Posted in UNIX & Linux | Tagged , , , | Comments Off on Letsencrypt und DNS Round-Robin

Too good to #0005

Prioritizing own NTP servers for systemd-timesyncd

# cat /etc/systemd/timesyncd.conf.d/timesyncd-corporate.conf 
[Time]
NTP=ntp1.example.com ntp2.example.com ntp.ubuntu.com

Test if text is empty (even if it does contain a linebreak)

Good job by: https://unix.stackexchange.com/q/386499/2028

if ! grep -q '[^[:space:]]' "${file}"; then echo "Text is empty"; fi

Watch for changes in the Gnome registry

(To reproduce manual changes, for configuration management.)

dconf watch / # (Sorry, thats all)

Trigger Debian/Ubuntu unattended-upgrade

(For testing configuration changes)

rm /var/lib/apt/periodic/*
systemctl start apt-daily.service 
systemctl start apt-daily-upgrade.service 

And remember:

tail -f /var/log/unattended-upgrades/*log
Posted in Too Good To, UNIX & Linux | Tagged , , , , , , , | Comments Off on Too good to #0005

Too good to #0004

systemd, the good parts: monotonic timers

When systemd makes you suffer because “run job every 10 minutes” is infinitely harder to specify than in crontab, remember there are monotonic timers in systemd that aren’t derived from wallclock time, or “Calendar Events” as they call it.

Run timer once 60 seconds after system startup, then every 10 minutes after the job finished:

# /etc/systemd/system/demo.timer
[Unit]
Description=demo monotonic timer

[Timer]
OnStartupSec=60
OnUnitInactiveSec=600

[Install]
WantedBy=timers.target    # When in a system session
# WantedBy=default.target # When in a user session (~/.config/systemd, systemctl --user etc.)

Python: Use tabulate to format output in columns

#!/usr/bin/env python3
from tabulate import tabulate

data = [
	[ 'foo', 'bar', 'baz' ],
	[ 'spam', 'eggs', 'bacon' ]
]

headers = ['Eine', '2', 'Whatever']

print(tabulate(data, headers=headers, tablefmt='simple'))

Output:

$ ./tab.py 
Eine    2     Whatever
------  ----  ----------
foo     bar   baz
spam    eggs  bacon

virsh/libvirt, automate key presses

(* Updated to sleep 5 seconds after each keypress.)

for key in R E I S U B; do virsh send-key "${domain}" KEY_LEFTALT KEY_SYSRQ KEY_${key}; sleep 5; done
Posted in Too Good To, UNIX & Linux | Tagged , , , | 1 Comment

Too good to #0003

Linux uptime in seconds, once and for all

awk '{printf "%i\n", $1}' /proc/uptime

“Sudo on demand”, re-exec shell script with sudo if not running as root

#!/usr/bin/env bash
printf "Running as: %s\n" "$(id -un)"
[[ ${EUID} -ne 0 ]] && printf "Re-executing with sudo.\n" && exec sudo "${0}"

See also TGT0006, this is just as useful for downgrading privileges on the fly.


“When was the last time apt-get on that Debian/Ubuntu machine installed package upgrades?”

  • Reliably answering this is a lot harder than it looks, subject of countless discussions and really does need to parse /var/log/apt/history.log, which is painful.
  • The script below maintains a file /var/log/apt/lastupgrade with the last upgrade’s time stamp, for further processing.
  • Does NOT track invocations of apt-get upgrade that did not lead to package upgrades.
  • Does NOT look behind logfile rotations, which should not be a problem because it’s closely hooked to dpkg.

/usr/sbin/apt-lastupgrade:

#!/bin/bash

while IFS=: read -r key value
do
	if [[ "${key}" == 'Start-Date' ]]
	then
		upgraded=0
	elif [[ "${key}" == 'Upgrade' ]]
	then
		upgraded=1
	elif [[ "${key}" == 'End-Date' ]]
	then
		if [[ ${upgraded} -eq 1 ]]
		then
			printf -v lastupgrade "%s" "${value}"
		fi
		upgraded=0
	fi
done < /var/log/apt/history.log

if [[ -v lastupgrade ]]
then
	tee /var/log/apt/lastupgrade <<-Here
	# Timestamp of last upgrade: ${lastupgrade}
	Here
	touch -d "${lastupgrade}" /var/log/apt/lastupgrade
fi

/etc/apt/apt.conf.d/90lastupgrade:

DPkg::Post-Invoke {"/usr/bin/systemd-run --on-active=60 /usr/sbin/apt-lastupgrade || /bin/true"};

Path of running shell script, dirname for locating config files, includes etc.

me_path="$(readlink -f "${0}")"
me_dir="$(dirname "${me_path}")"
me_base="$(basename "${me_path}")"
Posted in Too Good To, UNIX & Linux | Tagged , , , , , , | Comments Off on Too good to #0003

Too good to #0002

Show and update the comment in an SSH private key

ssh-keygen -l -f <keyfile> # show
ssh-keygen -c -f <keyfile> # change interactively
ssh-keygen -c -C <newcomment> -f <keyfile> # change and provide new

ssh-agent in Gitlab CI/CD

  • Define SSH_KEY as a “file” in Gitlab CI/CD variables and SSH_PASSPHRASE as a regular variable
  • If libcrypto errors on execution, make sure SSH_KEY has an additional line ending at the end
before_script:
  - DEBIAN_FRONTEND=noninteractive apt-get update -y
  - DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-client

sftp_to_somewhere:
  stage: deploy
  script:
    - chmod 600 "$SSH_KEY"
    - eval $(ssh-agent)
    - ssh-add "$SSH_KEY" <<< "$SSH_PASSPHRASE"
    - ssh-add -l

Urlwatch, but with a local pop-up window on Linux, no additional infrastructure

Systemd user service:

# ~/.config/systemd/user/urlwatch-to-zenity.service
[Unit]
Description=urlwatch to zenity (service)

[Service]
Type=oneshot
ExecCondition=sh -c 'nmcli net co | grep full'
ExecCondition=sh -c 'urlwatch > %h/.cache/urlwatch.out'
ExecCondition=sh -c 'test -s %h/.cache/urlwatch.out'
ExecStart=sh -c 'zenity --title Urlwatch --text-info --width=600 --height=400 --filename=%h/.cache/urlwatch.out'

[Install]
WantedBy=default.target

Systemd timer:

# ~/.config/systemd/user/urlwatch-to-zenity.timer
[Unit]
Description=urlwatch to zenity (timer)

[Timer]
OnStartupSec=1h
OnUnitInactiveSec=2h

[Install]
WantedBy=default.target

cookiecount – Load a page and show the cookies it sets

$ ./cookiecount https://example.com
0 cookies received.

ps1_anon.bash – anonymize bash prompt, for screenshots and pastes

# Anonymize bash prompt for screenshots and pastes
# Source from or add to ~/.bashrc
function ps1_anon (){
	if [[ -v SAVED_PS1 ]] 
	then
		PS1="${SAVED_PS1}" 
		unset SAVED_PS1 
	else
		SAVED_PS1="${PS1}" 
		PS1='\$ '
	fi
}

Example:

[martin@idefix ~/devel/cookiecount(main=)]$ ps1_anon
$ ./cookiecount https://reddit.com --json | jq .cookiecount
7
$ ps1_anon
[martin@idefix ~/devel/cookiecount(main=)]$
Posted in Too Good To, UNIX & Linux | Tagged , , , | 2 Comments

Administrivia 2022-09-06

  • binblog.info is now co-hosted here on binblog.de
  • A few old posts are already public again
  • Hit me up via Mastodon etc if you miss something: @unixtippse@mastodon.online
Posted in Metablogging | Comments Off on Administrivia 2022-09-06

Too good to #0001

Set X11 keyboard layout manually and temporarily (e.g. in i3 if I need to test exotic window managers for my users)

setxkbmap -layout us,us -variant altgr-intl -option caps:none

Speaking of which, set keyboard layout permanently in Gnome

gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us+altgr-intl')]"

Check if Gnome Screensaver is active (I use this for automated time tracking)

busctl --user call org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver GetActive


Urlwatch for a new package version in an APT repository

After a long wait, I was finally able to find another use for my awful Perl one-liner from 2019 that pivots a Debian Packages.gz into a space-separated table!

---
name: "Pop!OS Firefox package"
command: curl -s http://apt.pop-os.org/release/dists/jammy/main/binary-amd64/Packages.gz |
  gzip -dc | perl -ane 'if($F[0]=~/^Package:/){$p=$F[1]};if($F[0]=~/^Version:/){$v=$F[1];print"$p $v\n";}' |
  grep '^firefox '
diff_filter:
  - grep: '^[+-][^+-]'
---

Posted in Too Good To, UNIX & Linux | Tagged , , , , | Comments Off on Too good to #0001

Phönix aus dem mysqldump

“Haltet die Fresse! Glotzt mehr TV!”, das wählte ich im Sommer 2007 als Überschrift, irgendwie ganz und gar nicht im Verfolgungswahn, unter dem Eindruck des damals bereits nicht mehr ganz so frischen Landgerichts Hamburg, der noch etwas neueren Impressumpflicht, TKÜV, Mediendienstestaatsvertrag und Teledienstgesetz, und dem damals noch richtig neuen Hackerparagraphen.

Danach war zwei Jahre Funkstille, aber irgendwann ab 2009 mussten die Blogposts dann doch aus mir raus, und ich veröffentlichte über die Jahre noch eine Handvoll Artikel quasi-pseudo-überhauptnicht-anonym unter binblog.info, einem auf WordPress gehosteten Blog.

Nun ist es auf perverse Weise noch viel schlimmer gekommen, als ich es in meiner Paranoia damals erwartete. Hass und kriminelle Beschimpfungen regieren die leichter zugänglichen Teile des Social Web, und bis auf allerschwerste Fälle wird das alles mit einem Schulterzucken hingenommen. Ruf doch die Polizei! Oder, noch schlimmer, das Ordnungsamt, weil auf einer deutschen Domain das Impressum fehlt! Ha! Schieß doch!

Ein richtiger Nerd lässt keine Domainregistrierung verfallen, das Haus verliert nichts, und hier ist nun also der Re-Launch auf der alten Domain von 2003. Datenschutzverträglich selbst gehostet, ohne Analysetools und Werbeeinblendungen des kommerziellen WordPress-Service. Fast 20 Jahre Content in 1200 auf Privat geschalteten Posts stecken in der Datenbank. Die “temporäre” Domain, binblog.info, wird in Kürze hier hin migriert. Ausgewählte Artikel, insbesondere aus der OpenSSH-Ecke, die zahlreich extern verlinkt sind, werde ich Zug um Zug wieder freischalten.

Der erste neue Post hier wird unter dem Motto “Too good to” stehen, für Fundstücke aus der täglichen Arbeit, die bei Github oder Twitter nur hoffnungslos untergehen würden.

Der Plan ist, ab dem Relaunch die gesamte Kommentarfunktion über ActivityPub abzuwickeln. Viel Spaß beim Experimentieren.

Sollte binblog.de mit diesem Post bei jemandem nach 15 Jahren im RSS-Reader wieder auftauchen, vielen Dank für deine Hartnäckigkeit, du hast mir die ganze Zeit aufs Übelste gefehlt!

Posted in Metablogging | 2 Comments