Archiv der Kategorie: Office

Softwarehinweise und -tipps

Nextcloud Talk mit Coturn auf CX11

Einen eigenen Coturn für Videochats über die eigene Nextcloud zu betreiben ist nicht schwer. Gute Anleitungen für den Einstieg sind im Netz zu haben. Lauscht der Coturn auf Port 443, ist man gleich noch die Routerprobleme bei den Nutzern los.

In der Annahme, dass man da nicht genug Ressourcen hinwerfen kann, stellte ich Coturn bei meinen ersten Gehversuchen eine VM unter KVM mit 4 CPUs und 8GB RAM zur Verfügung. Heute weiß ich, dass das overkill ist, wenn das System nur gelegentlich und dann meist nur von wenigen Menschen parallel benutzt wird.

Die Grafik oben ist ein Screenshot aus OMD und zeigt die CPU Auslastung während eines Videotelefonats zwischen zwei Personen auf einem CX11 bei Hetzner (2,96€ / Monat). Top zeigte eine CPU Auslastung von rund 7% – OMD ein wenig mehr. Aber festhalten lässt sich, dass für eine NC-Talk-Familieninstanz der CX11 ausreichend ist – und vermutlich sogar für eine Schule, weil es sehr selten dazu kommen dürfte, dass mehrere L gleichzeitig ihren S Nachhilfe via Talk geben.

Jetzt hängen vier Nextcloud Instanzen am CX11 – zwei private und zwei Kollegien. Mal sehen, was passiert.

Joplin dual

Mich trieb die Idee um, Joplin nicht nur selbst zu nutzen, sondern auch mit anderen zusammen.

Ein einzelnes Joplin mit anderen zusammen (also: gemeinsam) zu verwenden ist kein Problem: Voraussetzung hierfür ist, dass alle Beteiligten einen Zugang zu einer Nextcloud haben. Dann teilt man in der Nextcloud den Ordner, in dem Joplin seine Daten ablegt. Sofern man nicht gleichzeitig an der gleichen Notiz herum schreibt, klappt das – synchrone Kollaboration funktioniert also nicht, sondern füllt nur den Ordner „Konflikte“.

Will man weiterhin sein eigenes Joplin nutzen, dann legt man sich für das gemeinsame ein gesondertes Profil lokal an und startet Joplin mit diesem:

/home/.../.joplin/Joplin.AppImage --profile /home/.../.config/joplin-2/

Dieses zweite Joplinprofil konfiguriert man sich dann auf einen frischen Ordner in der Nextcloud, den man wiederum für die Kooperationspartner als Share freigibt.

Dann noch ein alias dazu, damit man dieses Joplin einfacher starten kann – und voila! Was leider nicht klappen wollte hier, war, beide Joplins parallel offen zu haben.

nextCloud 15 mit LDAPs an LD-Server und Automount von Tausch und Home

Weil es so ein unschönes Gefummel war, dokumentiere ich hier für mich (und auch andere Benutzer von LD / SBE) die Anbindung der nextCloud per LDAPs an den LD-Server, die dafür sorgt, dass beim Login der Benutzer gleich noch deren Tausch- und Homeverzeichnisse in die nextCloud gelupft werden. Dass dann bei uns noch Collabora CODE dazukommt rundet die Sache schön ab.

Siehe zu diesem Thema auch den Vorgängerartikel.

Kurz zum allgemeinen Setup: Eine VM mit Ubuntu 18.04 LTS werkelt intern auf einem Virtualisierungshost, der mit seinen Netzwerkkarten in den jeweils für ihn wichtigen VLANs hängt. Auf diesem bridgen die VMs direkt in die VLANs rein. In Richtung Internet steht vor diesem VM-Host eine PFSense als Firewall in den jeweils relevanten Netzen.

Die VM für nextCloud etc. hat zwei virtuelle Netzwerkkarten: Eine zeigt via grauem VLAN in Richtung PFSense (damit in Richtung Internet) und trägt die öffentliche IP des Servers. Die andere Netzwerkkarte hängt als Bridge im grünen VLAN und wird vom LD-Server direkt versorgt. Über diese zweite („grüne“) Netzwerkkarte hole ich mir per LDAPs die Benutzerdatenbank und führe den SMB/CIFS-Mount der Homeverzeichnisse aus.

Netzwerkdiagramm

LDAPs Anbindung

Das Paket php-ldap muss an Bord und konfiguriert sein.

Hinweis: Den Zertifikatscheck kann man im nC LDAP Modul ausschalten für die ersten Tests – oder direkt auf der VM in /etc/ldap/ldap.conf durch den Eintrag TLS_REQCERT allow. Nicht schön, aber zum Testen eine Fehlerquelle weniger.

Die Server-IP mit vorangestelltem ldaps:// und im Feld Port 636 eintragen. Die zwei folgenden Felder können für LD-Server leer gelassen werden.

Da das automatische Auslesen der Base DN bei mir nicht funktioniert hat, musste ich diese von Hand angeben. In meinem Fall: ou=users,dc=kvfg-schule,dc=de

Beim LD-Server liegen die User in ldUserAccount.

Die Loginattribute wählt das von mir hier verwendete nC 15 dann von selbst richtig aus.

DIe passende Objektklasse ist posixGroup.

Das würde nun reichen, um die Benutzer in nC rein zu lassen und auch, um das Tauschverzeichnis automatisch einzubinden, aber nicht, um die Homeverzeichnisse der User automatisch zu mounten. Das liegt daran, dass nC aus dem LDAP die UUID nimmt, um die nC-Benutzernamen zu erstellen. Wir brauchen aber für den Automount der Homes unserer Benutzer deren uid (das ist dann gleichzeitig der Benutzername des Users). Es gilt demnach, nC zu überreden, die UUID zu ignorieren und stattdessen die uid der LDAP-Benutzer zu verwenden.

Auf der Registerkarte Expert finden wir diese Möglichkeit. Bei Internal Username Attribute muss uid eingetragen werden.

Hinweis: Im Reiter Advanced gibt es die Möglichkeit, die von nC lokal erstellten Benutzerverzeichnisse (im Datenverzeichnis von nC) mit %uid benamen zu lassen, statt mit der UUID. Das geschieht durch die Einstellungen oben nun automatisch so. Man darf die Angabe auf keinen Fall doppelt machen (also im Reiter Advanced und im Reiter Expert). Die Fehlermeldungen, die man nach einem Doppeleintrag erhält, beziehen sich auf Homeverzeichnispfade, die nicht aus dem LDAP gelesen werden können. Nicht wirklich hilfreich.

Das Debugging ist wenig witzig. Was hilft, ist hier schon ausführlich beschrieben worden, weswegen ich mir diese Ausführungen heute sparen will. Was hier und heute dazu kommt: Es lohnt der regelmäßige Blick in die Datenbank von nC (z.B. über phpmyadmin). Da dürfen bei den Benutzern keine UUIDs auftauchen (das sind kryptische Kombinationen aus Zahlen und Buchstaben), sondern ausschließlich deren uids (also deren Benutzernamen). Hat das nicht geklappt, darf man von Vorne beginnen. Es empfiehlt sich deswegen, zuerst eine Basiskonfiguration anzulegen und diese zu sichern, die dann wieder eingespielt werden kann, wenn man sich in eine blöde Ecke konfiguriert hat. Das ebenfalls sehr nervige LDAP-Caching von nC lässt sich mit einem beherzten Restart des Apachen beeinflussen.

SMB/CIFS Mount

Die Pakete libsmbclient php-smbclient php-smb und auch die cifs-utils müssen installiert und konfiguriert sein. Letzteres nicht nur zum Testen, ob der SMB-Mount überhaupt funktioniert, sondern auch, weil die anderen Pakete ohne die cifs-utils nicht rund laufen werden.

Nachdem den Benutzern von nC die Verwendung von SMB/CIFS erlaubt wurde, die Einträge wie im Bild aus dem Adminaccount heraus vornehmen. Dabei den Folder Name und die IP des SMB-Servers den eigenen Gegebenheiten anpassen.

Nicht irritieren lassen, dass die „Böbbel“ beim Admin rot bleiben. Da der nC-Admin nicht aus dem LDAP kommt, sondern ein rein lokaler nC-Benutzer ist, muss der SMB-Mount hier auf die Nase fallen.

Die Einträge Login-creditials, saved in session sorgen bei den LDAP-Benutzern aber später dafür, dass die automatischen Mounts klappen. Das $user sorgt für die Ersetzung des Namens für das Home-Share durch den Benutzernamen (die uid), der beim Login in der nC angegeben wurde. Deswegen ja auch das Gefrickel mit dem LDAP oben!

Die Benutzer müssen nun nur noch aufpassen, dass sie sich nicht mit dem Desktop-Client automatisch das gesamte Verzeichnis Tausch/Schule syncen 🙂

Wie man sich per Docker noch ein Collabora CODE auf die VM mit der nC holt, ist an vielen anderen Stellen im Netz schon ausführlich beschrieben worden. Für den Alttag würde ich dann 6GB RAM und 4 CPUs für die VM empfehlen: CODE wie auch nC ziehen zusammen ziemlich an den Ressourcen.

Eines noch: Moodle 3.6 bringt die Möglichkeit zur Anbindung an eine nextCloud mit.

Summa summarum: Wer braucht da noch Ella? DIY and federation are the key!

TC und EDS-Lite

Als Notiz für die, die es brauchen: Für EDS-Lite können TrueCrypt-Container (ja – auch VeraCrypt geht, aber das Schutzniveau muss ja nicht in und für jeden Fall so gesetzt werden) mit den Einstellungen oben schneller auf dem Rechner, als auf dem Tablet angelegt werden:

Encryption Algorithm: Twofish
Hash-Algorithm: SHA-512

Die Standardvorgaben von TrueCrypt scheinen für EDS-Lite nicht zu funktionieren.

Etherpad auf 16.04

Ein Update zu der etwas in die Jahre gekommenen Anleitung zur Installation von Etherpad Lite auf Ubuntu, auch wenn sich viele Dinge nicht wirklich grundlegend geändert haben.

Erst einmal versorgen wir unseren Server mit einem aktuellen NodeJ.js sowie NPM. Die Anleitung hierzu: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions

Dieser wird gefolgt, bis mit

sudo apt-get install -y nodejs

nicht nur NodeJS, sondern auch NPM an Bord ist.

Es folgen die Vorbereitungen für die lokale Installation von EP:

apt-get install gzip git curl python libssl-dev pkg-config build-essential

Dazu gehört ein Benutzerkonto etherpad:

sudo adduser --system --home=/opt/etherpad --group etherpad

In dessen Kontext dann gewechselt wird, um EP zu installieren:

sudo su - etherpad -s /bin/bash
# Dann als User etherpad weiter
git clone git://github.com/ether/etherpad-lite.git
cd etherpad-lite
bin/run.sh

Der erste Start installiert die Abhängigkeiten und sollte es danach ermöglichen, die Etherpad Installation unter http://example.org:9001 aufzurufen. Gelingt dies, dann brechen wir EP mit STRG C ab, um in Ruhe die Datei settings.json in /opt/etherpad/etherpad-lite sowie den Web- und DB-Server anzupassen.

Da wir nun immer wieder EP neu starten (als user etherpad) und außerdem als root weitere Pakete nachinstallieren sowie Anpassungen vornehmen müssen macht eine zweite Shell zum Server Sinn.

Nach der Installation von Apache2 und der Einrichtung von SSL-Zertifikaten folgt die Aktivierung der entsprechenden Module im Apachen:

a2enmod proxy proxy_http deflate headers ssl wstunnel

Ich folge hier im Wesentlichen der Anleitung hier: https://github.com/ether/etherpad-lite/wiki/How-to-put-Etherpad-Lite-behind-a-reverse-Proxy und erhalte am Ende eine VirtualHost Definition, die so aussieht:

<VirtualHost *:443>
      ServerAdmin webmaster@example.com
      ServerName etherpad.example.com
      DocumentRoot /var/www/example.com

     SSLEngine on
     ServerSignature On
     SSLHonorCipherOrder on
     SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

     SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
     SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

        ProxyVia On
        ProxyRequests Off
        ProxyPreserveHost on

        <Location />
            ProxyPass http://localhost:9001/ retry=0 timeout=30
            ProxyPassReverse http://localhost:9001/
        </Location>

        <Location /socket.io>
            RewriteEngine On
            RewriteCond %{QUERY_STRING} transport=websocket    [NC]
            RewriteRule /(.*) ws://localhost:9001/socket.io/$1 [P,L]
            ProxyPass http://localhost:9001/socket.io retry=0 timeout=30
            ProxyPassReverse http://localhost:9001/socket.io
        </Location>

        <Proxy *>
            Options FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
        </Proxy>


        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                        SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                        SSLOptions +StdEnvVars
        </Directory>

</VirtualHost>

Nach einem Neustart des Apachen und einem erneuten Start von EP lite (aus dem Konto von etherpad heraus) sollte EP über https abgerufen werden können.

Hinweis zu den geladenen Apache-Modulen: wstunnel beseitigte bei mir Fehlermeldungen wie die diese:

[proxy:error] [pid 7926] [client 79.1.8.45:40652] AH00898: Error reading from remote server returned by /socket.io/
[proxy:warn] [pid 7934] [client 79.1.8.45:40848] AH01144: No protocol handler was valid for the URL /socket.io/. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

Wir können EP nun wieder mit STRG C anhalten und eine Datenbank für EP einrichten. Dazu benötigen wir einen MySQL-Server sowie, bei Bedarf, phpMyAdmin für die einfachere Verwaltung. Weiter sollte auch abiword mit an Bord geholt werden, damit Pads exportiert werden können.

Sind diese Schritte vollbracht, wird die settings.json überarbeitet:

/*
  This file must be valid JSON. But comments are allowed

  Please edit settings.json, not settings.json.template

  To still commit settings without credentials you can
  store any credential settings in credentials.json
*/
{
  // Name your instance!
  "title": "KvFG Etherpad",

  // favicon default name
  // alternatively, set up a fully specified Url to your own favicon
  "favicon": "favicon.ico",

  //IP and port which etherpad should bind at
  "ip": "0.0.0.0",
  "port" : 9001,

  // Option to hide/show the settings.json in admin page, default option is set to true
  "showSettingsInAdminPage" : true,

  /*
  // Node native SSL support
  // this is disabled by default
  //
  // make sure to have the minimum and correct file access permissions set
  // so that the Etherpad server can access them

  "ssl" : {
            "key"  : "/path-to-your/epl-server.key",
            "cert" : "/path-to-your/epl-server.crt",
            "ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"]
          },

  */

  //The Type of the database. You can choose between dirty, postgres, sqlite and mysql
  //You shouldn't use "dirty" for for anything else than testing or development
   "dbType" : "mysql",
   "dbSettings" : {
                    "user"    : "dbname",
                    "host"    : "localhost",
                    "password": "dbpassword",
                    "database": "dbuser",
                    "charset" : "utf8mb4"
                  },

  //the default text of a pad
  "defaultPadText" : "Welcome to Etherpad on Karlo!\n\nMit der Nutzung dieser Etherpad-Installation erklaerst Du Dich mit den folgenden Bedingungen einverstanden: https://example.com/doku.php?id=etherpad\n",

  /* Default Pad behavior, users can override by changing */
  "padOptions": {
    "noColors": false,
    "showControls": true,
    "showChat": true,
    "showLineNumbers": true,
    "useMonospaceFont": false,
    "userName": false,
    "userColor": false,
    "rtl": false,
    "alwaysShowChat": false,
    "chatAndUsers": false,
    "lang": "de"
  },

  /* Pad Shortcut Keys */
  "padShortcutEnabled" : {
    "altF9"     : true, /* focus on the File Menu and/or editbar */
    "altC"      : true, /* focus on the Chat window */
    "cmdShift2" : true, /* shows a gritter popup showing a line author */
    "delete"    : true,
    "return"    : true,
    "esc"       : true, /* in mozilla versions 14-19 avoid reconnecting pad */
    "cmdS"      : true, /* save a revision */
    "tab"       : true, /* indent */
    "cmdZ"      : true, /* undo/redo */
    "cmdY"      : true, /* redo */
    "cmdI"      : true, /* italic */
    "cmdB"      : true, /* bold */
    "cmdU"      : true, /* underline */
    "cmd5"      : true, /* strike through */
    "cmdShiftL" : true, /* unordered list */
    "cmdShiftN" : true, /* ordered list */
    "cmdShift1" : true, /* ordered list */
    "cmdShiftC" : true, /* clear authorship */
    "cmdH"      : true, /* backspace */
    "ctrlHome"  : true, /* scroll to top of pad */
    "pageUp"    : true,
    "pageDown"  : true
  },

  /* Should we suppress errors from being visible in the default Pad Text? */
  "suppressErrorsInPadText" : false,

  /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */
  "requireSession" : false,

  /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */
  "editOnly" : false,

  /* Users, who have a valid session, automatically get granted access to password protected pads */
  "sessionNoPassword" : false,

  /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly,
     but makes it impossible to debug the javascript/css */
  "minify" : true,

  /* How long may clients use served javascript code (in seconds)? Without versioning this
     may cause problems during deployment. Set to 0 to disable caching */
  "maxAge" : 21600, // 60 * 60 * 6 = 6 hours

  /* This is the absolute path to the Abiword executable. Setting it to null, disables abiword.
     Abiword is needed to advanced import/export features of pads*/
  "abiword" : "/usr/bin/abiword",

  /* This is the absolute path to the soffice executable. Setting it to null, disables LibreOffice exporting.
     LibreOffice can be used in lieu of Abiword to export pads */
  "soffice" : null,

  /* This is the path to the Tidy executable. Setting it to null, disables Tidy.
     Tidy is used to improve the quality of exported pads*/
  "tidyHtml" : null,

  /* Allow import of file types other than the supported types: txt, doc, docx, rtf, odt, html & htm */
  "allowUnknownFileEnds" : true,

  /* This setting is used if you require authentication of all users.
     Note: /admin always requires authentication. */
  "requireAuthentication" : false,

  /* Require authorization by a module, or a user with is_admin set, see below. */
  "requireAuthorization" : false,

  /*when you use NginX or another proxy/ load-balancer set this to true*/
  "trustProxy" : false,

  /* Privacy: disable IP logging */
  "disableIPlogging" : false,

  /* Time (in seconds) to automatically reconnect pad when a "Force reconnect"
     message is shown to user. Set to 0 to disable automatic reconnection */
  "automaticReconnectionTimeout" : 0,

  /* Users for basic authentication. is_admin = true gives access to /admin.
     If you do not uncomment this, /admin will not be available! */
  "users": {
    "admin": {
      "password": "adminpassword",
      "is_admin": true
    },
    "user": {
      "password": "changeme1",
      "is_admin": false
    }
  },

  // restrict socket.io transport methods
  "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],

  // Allow Load Testing tools to hit the Etherpad Instance.  Warning this will disable security on the instance.
  "loadTest": false,

  // Disable indentation on new line when previous line ends with some special chars (':', '[', '(', '{')
  /*
  "indentationOnNewLine": false,
  */

  /* The toolbar buttons configuration.
  "toolbar": {
    "left": [
      ["bold", "italic", "underline", "strikethrough"],
      ["orderedlist", "unorderedlist", "indent", "outdent"],
      ["undo", "redo"],
      ["clearauthorship"]
    ],
    "right": [
      ["importexport", "timeslider", "savedrevision"],
      ["settings", "embed"],
      ["showusers"]
    ],
    "timeslider": [
      ["timeslider_export", "timeslider_returnToPad"]
    ]
  },
  */

  /* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
  "loglevel": "INFO",

  //Logging configuration. See log4js documentation for further information
  // https://github.com/nomiddlename/log4js-node
  // You can add as many appenders as you want here:
  "logconfig" :
    { "appenders": [
        { "type": "console"
        //, "category": "access"// only logs pad access
        }
    /*
      , { "type": "file"
      , "filename": "your-log-file-here.log"
      , "maxLogSize": 1024
      , "backups": 3 // how many log files there're gonna be at max
      //, "category": "test" // only log a specific category
        }*/
    /*
      , { "type": "logLevelFilter"
        , "level": "warn" // filters out all log messages that have a lower level than "error"
        , "appender":
          {  Use whatever appender you want here  }
        }*/
    /*
      , { "type": "logLevelFilter"
        , "level": "error" // filters out all log messages that have a lower level than "error"
        , "appender":
          { "type": "smtp"
          , "subject": "An error occurred in your EPL instance!"
          , "recipients": "bar@blurdybloop.com, baz@blurdybloop.com"
          , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message
          , "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods
              "host": "smtp.example.com", "port": 465,
              "secureConnection": true,
              "auth": {
                  "user": "foo@example.com",
                  "pass": "bar_foo"
              }
            }
          }
        }*/
      ]
    }
}

Viel angepasst habe ich nicht: Die Datenbankverbindung, den einführenden Text in jedes Pad mit einem Verweis auf die Benutzerordnung und das Passwort für den administrativen Benutzer.

Ob die Datenbankverbindung glückt, wird erneut aus dem Kontext des Benutzers etherpad geprüft. Danach wird Etherpad als Service eingerichtet.

Dazu erstellt man sich eine Datei /etc/systemd/system/etherpad.service mit folgendem Inhalt:

[Unit]
Description=Etherpad
After=syslog.target network.target

[Service]
Type=simple
User=etherpad
Group=etherpad
WorkingDirectory=/opt/etherpad/etherpad-lite
ExecStart=/usr/bin/nodejs /opt/etherpad/etherpad-lite/node_modules/ep_etherpad-lite/node/server.js
Restart=always

[Install]
WantedBy=multi-user.target

Das entspricht bis auf die Pfade der Anleitung hier: https://github.com/ether/etherpad-lite/wiki/How-to-deploy-Etherpad-Lite-as-a-service 

Gelingt der Start mit service etherpad start kann man mit ufw den Port 9001 zu machen und in den Betrieb übergehen. Wer will kann etherpad auch automatisch starten lassen: systemctl enable etherpad

Der Login-Screen von Etherpad kann in /opt/etherpad/etherpad-lite/src/templates/index.html an die eigenen Wünsche angepasst und z.B. um Links zum Impressum und zur Benutzerordnung erweitert werden.

# ca ab Zeile 160

 <div id="wrapper">
         <% e.begin_block("indexWrapper"); %>
             <div id="inner">
                 <button id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button>
                 <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
                 <form action="#" onsubmit="go2Name();return false;">
                     <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech>
                     <button type="submit">OK</button>
                 </form>
                 <p><a href="https://link.zum.impressum" target="_blank">Impressum</a> | <a href="https://link.zur.nutzungsordnung" target="_blank">Benutzerordnung</a></    p>          
             </div>

Nur noch ein Punkt: Das Plugin, das man als schulischer Admin unbedingt haben will, ist das hier: https://www.npmjs.com/package/ep_adminpads

PDF Formulare

Seit acroread nicht mehr in den Repos ist und sich auch nicht mehr ohne Klimmzüge auf aktuelleren Linuxen installieren lässt, sieht es Mau aus mit dem Ausfüllen von PDF-Formularen. Man kann Okular nehmen … und dann damit leben, dass die Formularinhalte als XML Dateien im Homeverzeichnis „verschwinden“, statt direkt beim Dokument zu liegen. Für mich ist das ein No-go, weil ich PDF-Formulare noch Jahre später oder auch auf einer anderen Maschine ausgefüllt ansehen können will.

Eine unfreie aber praktikable Lösung scheint mir hier zu liegen:

https://code-industry.net/free-pdf-editor/

Erste Versuche mit den Beihilfeformularen zeigen, dass sich Master PDF Editor benimmt wie ein Acrobat Reader. Die Formulareinträge landen im PDF. Man kann das PDF also verschieben und kopieren und die Inhalte bleiben erhalten.

Die Installation wiegt mit rund 10MB nicht viel und abgesehen von einigen Qt Abhängigkeiten kommt wenig an Bord.

OCR revisited

Zwar liefert Finereader die besseren Ergebnisse und obendrein noch ein Layout für die Scans, aber für eine lokale Suche nach einem PDF reicht auch ein bischen weniger, so dass man sich die Ausgaben bei ABBYY für jede einzelne Seite zumindest teilweise sparen kann.

Unter einem Debian 9:

sudo apt-get install poppler-utils ocrmypdf tesseract-ocr-deu

Details und weitere Konfigurationsmöglichkeiten, Batch-Skripte und mehr sind hier zu haben. Ich setze ocrmypdf bisher gezielt auf einzelne Verzeichnis an mit diesem Einzeiler:

for i in $( ls *.pdf ) ; do ocrmypdf --skip-text -l deu --deskew --clean --rotate-pages --clean-final $i - | pdftotext - $i.txt ; done

Das ergibt dann TXT Dateien mit zu über 95% richtig erkanntem Inhalt, wenn die Vorlage gut ist. Presst man PDF-Faxe und ähnlichen Mist durch die tool chain, dann kommt leider weitaus weniger Brauchbares hinten raus – aber zum Wiederfinden auf der lokalen Platte mit recoll reicht es.

A Time Tracker

Ich nutze seit dem 01.08.2016 A Time Tracker (bei FDroid zu haben) als Zeiterfassungssoftware auf dem Smartphone – und das für mich überraschend diszipliniert und an vielen Stellen evtl. auch übergenau. Verlasse ich den Schreibtisch oder die SItzung etc., stoppe ich die Zeiterfassung.

Da das RP wie jedes Jahr um Pfingsten meinen Tätigkeitsbericht haben wollte, wollte ich mir die Arbeit nun erleichtern und zum ersten Mal einen echten Stundenzettel einreichen. Das klappte nur bedingt. Einerseits ist das RP-Formular dafür nicht gemacht, weil es sich nicht interessiert, wie viel man gearbeitet hat, sondern nur dafür, wie viele Stunden Unterricht ausgefallen sind, während man als Landesbeamter andere Dienstaufträge erfüllte.

Andererseits ging ich zuerst den falschen Weg und exportierte mir die SQLite Datenbank aus A Time Tracker (Mehr – Auf Speicher sichern). Mit der konnte ich lokal auf dem Rechner aber wenig anfangen: die Zeiten sind als Unix timestamps abgelegt, müssen also zuerst konvertiert werden und auch die Zuordnung von IDs zu den Tätigkeitsbezeichnungen ist derart auf einzelne Tabellen verteilt, dass das Zusammenführen viel zu viel Mühe macht.

Eine Übersicht über die eigene Arbeitszeit lässt sich aus dem CSV Export viel zügiger erstellen:

  1. Mehr – Zeitbereich ändern – Alle
  2. Mehr – Ansicht nach CSV exportieren

A Time Tracker legt die timetracker.db wie auch die all.csv auf der obersten Ebene des Nutzerverzeichnisses auf dem Smartphone ab – hier ist das /storage/emulated/0/.

Die Konvertierung von Unix timestamps ins Format YYYY-MM-DD HH-MM-SS wird von der App vorgenommen. Der Import nach LibreOffice gelingt ohne Mühe.

Formatiert man die Zellen für die Summen im Format [HH]:MM:SS, unterlässt LibreOffice jegliche Umrechnungen und addiert schlicht die Zeiten in Richtung Stunden. Entscheidend ist die eckige Klammer um das HH!

Man kann dann mit dem üblichen =SUMME(FeldA:FeldZ) rechnen, statt sich permanent zu wundern, was LibreOffice da gerade macht, und die Daten auch grafisch darstellen etc. pp.

Ganz hübsch erhellend für mich war, dass ich schon vor Monaten meine vorgesehene Jahresarbeitszeit „durch“ hatte. Dabei ist das Schuljahr noch nicht einmal zu Ende. Auch erhellend war die Verteilung meiner Stunden auf die von mir in A Time Tracker angelegten Kategorien. Ich weiß nun, wo ich mehr darauf achten muss, mich nicht zu sehr vereinnahmen zu lassen. Ich muss „Nein“ noch üben.

CODE versus OO

Die Installation von Collabora (CODE) in nextCloud hinter einem HTTPS-Apache-Proxy verläuft ohne Zicken. Einfach die Anleitung nachturnen und es funktioniert. Aber es funktioniert zäh und das auch bei 32GB RAM auf einem (etwas in die Jahre geratenen aber durchaus noch webtauglichen) Dell Poweredge T710 mit zwei Xeon Prozessoren. Zumindest im Vergleich zu einem OnlyOffice (OO).

OnlyOffice bringt viel mehr Funktionen mit, lässt sich flutschiger bedienen und sieht darüber hinaus auch noch schicker aus. Im Vergleich dazu fällt Collabora sehr weit zurück: zähe, zickige und schnarchige Bedienung und gerade mal ein paar Basisfunktionen an Bord. Hat man einmal mit OO gespielt, will man nicht mehr zu CODE zurück. Dafür würde ich sogar hinnehmen, dass OO alles ins OOXML Format konvertieren will.

Jedoch: OnlyOffice in ownCloud hinter einem HTTPS-Apache-Proxy warf sich mir mit weitaus mehr Problemen bei der Installation in den Weg als CODE. Aktuell habe ich noch nicht alle im Griff – es funktioniert erst im Prinzip. Und zwar hiermit:

docker pull onlyoffice/documentserver

Die Virtualhost für den Apache anpassen:

<VirtualHost *:443>
     ServerName onlyoffice.domain.tld:443

     SSLEngine on
     ServerSignature On
     SSLHonorCipherOrder on

     SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

     SSLCertificateFile /etc/letsencrypt/live/onlyoffice.domain.tld/fullchain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/onlyoffice.domain.tld/privkey.pem

     LogLevel warn
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     ErrorLog ${APACHE_LOG_DIR}/error.log

# Just in case - see below
SSLProxyEngine On
SSLProxyVerify None
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerName Off

# contra mixed content warnings
RequestHeader set X-Forwarded-Proto "https"

# basic proxy settings
ProxyRequests off

        ProxyPass / http://127.0.0.3:9090/
        <Location />
                ProxyPassReverse /
        </Location>
</VirtualHost>

Den OO Container starten:

docker run -i -t -d -p 127.0.0.3:9090:80 --restart always  onlyoffice/documentserver

die ownCloud App für OO installieren und die Kiste läuft. Im Prinzip.

Textverarbeitung funktioniert.

Präsentationssoftware funktioniert.

Tabellenkalkulation funktioniert.

Aber: Es funktioniert eben nur im Prinzip.

Denn man muss damit leben, dass einem der Firefox weiterhin in der Debug-Console Meldungen entgegen wirft:

Firefox kann keine Verbindung zu dem Server unter wss://onlyoffice.domain.tld/2017-02-17-15-53/doc/271488117372/c/493/1niaepga/websocket aufbauen.  sockjs.min.js:3:4835

Ich fummel mir hier nun seit Tagen einen ab, um diese Meldungen los zu werden. In der VHost Konfiguration des Apachen oben sind ja noch Reste davon zu sehen.

Für diese Versuche startete ich den docker container so, dass dessen Port 443 zum Wirt auf Port 9091 weiter gereicht wird

docker run -i -t -d -p 127.0.0.3:9090:80 -p 127.0.0.3:9091:443 onlyoffice/documentserver

und stellte dann Versuche in der VHost Config des Apachen nach dem Schema (!)

ProxyPassMatch "/(.*)/websocket"  wss://127.0.0.3:9091/$1/websocket

an. Erfolglos. Auch meine Versuche mit ProxyPass, ProxyPassReverse oder ReWrite Regeln scheiterten bisher.

Ich glaube, ich habe nun alle Anleitungen und Tutorials rund um Websockets mit HTTPs und Apache Proxy durch – ich fahr da noch immer vor die Wand. Und vor allem: Ich hab keine blassen Dunst, was ich eigentlich genau verzocke.

Drängen tut das Problem nicht. Ich roll weder OO noch CODE zum aktuellen Zeitpunkt aus. Denn ich vertraue weder dem auf einer eigenen Subdomain laufende OO Documentserver noch dem CODE Container. Zwar können Besucher theoretisch nur in den docker container reinfummeln und wohl nicht aus diesem oder dem Apache Proxy ausbrechen, aber schon dass finde ich irritierend.

Schlimmer ist vielmehr, dass ich den Websocket nicht an den Apache HTTPS Proxy so dran bekomme, dass der Firefox endlich Ruhe gibt. Falls da einer ne Idee hat … ich hab ein offenes Ohr. Vielleicht ist ja was dabei, was ich noch nicht probiert habe.

DOCX

Wir haben am LFB gerade das unschöne Problem, dass wir beim Öffnen von DOCX Dokumenten Bilder sehen, die MS Word nicht anzeigt und nicht druckt.

Packt man die DOCX mit unzip aus und durchsucht dann die Verzeichnisstruktur sieht man das Bild ebenfalls. Es ist eindeutig da. Das Problem ist demnach, dass MS Word Bilder beim Löschen durch den Anwender nicht immer löscht … sondern stellenweise und aus für uns nicht nachvollziehbaren Gründen im Dokument belässt. Pech gehabt.

LibreOffice z.B. bringt das dann an den Tag – oder, wie wir feststellen konnten, die Webansicht von MS Word.

Die potentiellen Katastrophen, die sich aus diesem Verhalten von MS Word ergeben, sind Legion: Von Abmahnungen bei Internetveröffentlichungen angefangen über die Weitergabe von geheim zu haltenden Informationen bis hin zu persönlichen Peinlichkeiten … MS macht’s möglich.

Das ist professionelle Software.