PHP auf der Kommandozeile bei Strato

Versucht man die Kommandozeilentools von NextCloud occ und updater.phar bei Strato zu benutzen dann bekommt man so nette Fehlermeldungen:

> php updater/updater.phar
Nextcloud Updater - version: v20.0.0beta4-11-g68fa0d4
Current version is 20.0.3.
Update to Nextcloud 20.0.12 available. (channel: "stable")
Following file will be downloaded automatically: https://download.nextcloud.com/server/releases/nextcloud-20.0.12.zip
Open changelog ↗
Steps that will be executed:
[ ] Check for expected files
[ ] Check for write permissions
[ ] Create backup
[ ] Downloading
[ ] Verify integrity
[ ] Extracting
[ ] Enable maintenance mode
[ ] Replace entry points
[ ] Delete old files
[ ] Move new files in place
[ ] Done
Start update? [y/N] PHP Warning:  Use of undefined constant STDIN - assumed 'STDIN' (this will throw an Error in a future version of PHP) in phar:///mnt/web120/e2/56/510XXX56/htdocs/cloud/updater/updater.phar/vendor/symfony/console/Helper/QuestionHelper.php on line 117
PHP Warning:  fgets() expects parameter 1 to be resource, string given in phar:///mnt/web120/e2/56/510XXX56/htdocs/cloud/updater/updater.phar/vendor/symfony/console/Helper/QuestionHelper.php on line 133
[RuntimeException]
Aborted
update [--no-backup]
X-Powered-By: PHP/7.4.23
Content-type: text/html

oder bei occ:

php occ upgrade
X-Powered-By: PHP/7.4.23
Content-type: text/html
An unhandled exception has been thrown:
TypeError: Return value of OC\AppFramework\Http\Request::getScriptName() must be of the type string, null returned in /mnt/web120/e2/56/51008256/htdocs/WordPress-WH3/cloud/lib/private/AppFramework/Http/Request.php:837
Stack trace:
#0 /mnt/web120/e2/56/510XXX56/htdocs/cloud/lib/base.php(163): OC\AppFramework\Http\Request->getScriptName()
#1 /mnt/web120/e2/56/510XXX56/htdocs/cloud/lib/base.php(576): OC::initPaths()
#2 /mnt/web120/e2/56/510XXX56/htdocs/cloud/lib/base.php(1091): OC::init()
#3 /mnt/web120/e2/56/510XXX56/htdocs/cloud/console.php(49): require_once('/mnt/web120/e2/...')
#4 /mnt/web120/e2/56/510XXX56/htdocs/cloud/occ(11): require_once('/mnt/web120/e2/...')
#5 {main}

Dazu kommt, dass die PHP-Version nicht unbedingt zur Version passt, die für den Webspace eingestellt ist (in diesem Fall wäre es eigentlich PHP 7.3 gewesen).

Ein funktionierendes PHP-Binary findet man unter /opt/ in einem Versionsspezifischen Ordner:

/opt/RZphp73/bin/php-cli occ db:add-missing-indices
The current PHP memory limit is below the recommended value of 512MB.
Check indices of the share table.
Check indices of the filecache table.
Adding additional size index to the filecache table, this can take some time...
Filecache table updated successfully.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.

Damit funktionieren sowohl occ als auch updater.phar einwandfrei 🙂

Unprivilegierte Container in einer Multiuser Umgebung

In der Standardkonfiguration ist es einem Docker-User ein leichtes, sich über einen Container root-Rechte auf dem Hostsystem zu verschaffen.

Um das zu vermeiden gibt es zwei Möglichkeiten, rootless mode und userns-remap. Die erste Variante benötigt nicht einmal root-Rechte um Docker zu installieren, es wird alles im Homeverzeichnis des Users installiert. Das macht es zwar relativ einfach, aber leider ungeeignet für größere Umgebungen wo eine beliebige Anzahl von Usern, die idealerweise noch aus einem Verzeichnisdienst kommen, den Docker-Dienst nutzen können soll.

Unprivilegierte Container in einer Multiuser Umgebung weiterlesen

SCM-Manager Repositories von Usern finden

Ich brauchte eine Übersicht aller Repositories, bei denen eine Gruppe von Usern direkt oder indirekt (über Gruppen) als Owner eingetragen waren.

Die User holte ich mir mit Powershell aus dem Active Directory:

$users = Get-AdGroup Hauptgruppe | Get-AdGroupMember -Recursive | Get-AdUser -Properties memberof

Die Gruppen, in der die User Mitglieder waren holte ich mir auf ähnliche Weise:

$users.memberof | Sort | Unique | Foreach-Object { $_ -Replace 'CN=(.+?),.+','$1' }

Damit hatte ich eine simple Liste aller User und ihrer Gruppen die ich als Textdatei abspeichern konnte.

Für den SCM-Manager gibt es einen Command Line client. Leider ist er inzwischen nicht so einfach zu finden, auch die Doku dazu ist extrem dürftig. Aktuell war er hier zu finden.

Die Usernames und die Gruppennamen speicherte ich in zwei Textdateien, dann erstellte ich noch ein Template für die Ausgabe von scm-cli-client anzupassen. Als Templates wird hier FreeMarker verwendet.

#!/bin/bash
SERVER=https://scm.example.com/scm/
USERNAME=admin
PASSWORD=GEHEIM
CLI="java -jar /opt/scm-cli-client-1.60-jar-with-dependencies.jar --server $SERVER --user $USERNAME --password $PASSWORD"
# Nutzt FreeMarker Templates https://www.vogella.com/tutorials/FreeMarker/article.html
REPOS=`$CLI list-repositories --template-file ./grouptemplate.tpl`
GROUPNAMES=$(<groupnames.txt)
USERNAMES=$(<usernames.txt)
for GROUPNAME in "$GROUPNAMES"; do
echo "$REPOS" |grep "$GROUPNAME"
done;
for USERNAME in "$USERNAMES"; do
echo "$REPOS" |grep "$USERNAME"
done;

Das Template das ich dafür erstellt habe sieht folgendermaßen aus:

<#list repositories as repository>${repository.name}<#if repository.permissions??> <#list repository.permissions as permission><#if permission.type?starts_with("OWNER")>${permission.name} </#if></#list>
</#if>
</#list>

Damit wird schlicht und einfach der Name des Repositorys ausgegeben, gefolgt von allen Ownern. Das lässt sich einfach mittels grep filtern. Die Ausgabe davon habe ich dann noch gefiltert um jedes Repository nur einmal zu bekommen, für den Fall das jemand sowohl über eine Gruppe als auch über seinen Username Rechte hat

./findrepos.sh | sort | uniq

Voilá, alle Repositories in denen die User direkt oder indirekt Owner-Rechte haben.

Ansible Windows Server UNREACHABLE!

Auf einmal bekam ich beim Zugriff auf einen meiner Windows-Server via Ansible die folgende Fehlermeldung:

user@ansible:~/ansible$ ansible -m win_ping server.example.com
server.example.com | UNREACHABLE! => {
"changed": false,
"msg": "credssp: ('Connection aborted.', error(104, 'Connection reset by peer'))",
"unreachable": true
}

Auf dem Server nochmal das von Ansible zur Verfügung gestellte Konfigurationsscript durchlaufen lassen hat nichts gebracht.

Beim Durchschauen des Scripts fiel mir dann auf dass die Standard-Gültigkeitsdauer für das WinRM-Zertifikat 1095 Tage beträgt. Der Server war tatsächlich schon etwas länger in Betrieb.

Die Lösung war dann das Zertifikat für WinRM zu erneuern:

powershell.exe -ExecutionPolicy ByPass -File .\ConfigureRemotingForAnsible.ps1 -EnableCredSSP -ForceNewSSLCert

Danach funktionierte die Verbindung wieder einwandfrei.

user@ansible:~/ansible$ ansible -m win_ping server.example.com
server.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

SFTP mit Public Key Authentifizierung und Total Commander auf Android

Für Total Commander unter Android gibt es ein SFTP-Plugin, mit dem man per SSH auf das Dateisystem eines Servers zugreifen kann. Allerdings verlangt das Plugin den Private-Key nicht im unter Linux üblichen OpenSSH-Format, sondern im unter Windows üblichen PEM-Format.

Ich habe für mein Android-Handy einen neuen Schlüssel erstellt. Das habe ich auf meinem Linux Laptop gemacht, unter Windows geht das mit WSL genauso.

ssh-keygen -C "gerald@xperia" -f xperia -m pem

Danach habe ich den neuen Key auf den Server kopiert.

ssh-copy-id -i xperia pi@wohnzimmer

Dann habe ich die private Key-Datei umbenannt, so dass sie die Endung .pem hat (> xperia.pem, Total Commander listet nur Dateien mit der Endung .pem auf) und sie auf das Handy kopiert. Wie man das macht bleibt jedem selbst überlassen, ich habe Nextcloud verwendet. Erwähnenswert ist hier nur, dass ich in den SFTP-Einstellungen nur auf den internen Speicher meines Handys zugreifen konnte, nicht auf die SD-Karte, daher habe ich die xperia.pem einfach im Root-Verzeichnis des Geräts abgelegt.

Dann konnte ich den private Key in der Verbindung im Total Commander auswählen.

Danach wurde ich trotzdem noch beim Verbinden nach einem Passwort gefragt. Das konnte ich jedoch unterbinden indem ich einfach ein falsches Dummy-Passwort gesetzt habe, danach hat die Verbindung mit dem private Key direkt funktioniert.