Zertifikat mit easy-rsa erzeugen

Private key erzeugen

openssl genrsa -out myserver.key 4096

Zertifikatsrequest erzeugen

openssl req -new -key myserver.key -out myserver.req -subj "/C=AT/L=Vienna/O=Gallauner/CN=myserver.fqdn"

Request in easy-rsa importieren

./easyrsa import-req myserver.req myserver

Request in easy-rsa signieren, optional mit SAN(s) – CN wird per default als SAN eingetragen wenn –san nicht extra angegeben ist:

./easyrsa --san=DNS:myserver.fqdn,DNS:alternatename.fqdn sign-req server myserver

Ergebnis in

./pki/myserver.crt

EU Lebensmittelcodes

Auf Lebensmitteln mit Inhaltsbestandteilen aus tierischer Herkunft muss ja der zuletzt beteiligte Betrieb als Code abgedruckt werden – in DE gibts da öffentliche Datenbanken mit Suchfunktion in AT ist das ein wenig schwieriger (ich hab zumindestens nix gefunden) – hier gibts aber alle Codes in PDF-Listenform:

https://vis.statistik.at/fileadmin/ovis/pdf/index.html

Die erste Stelle der Nummer zeigt übrigens das Bundesland:

  • 1 = Burgenland
  • 2 = Kärnten
  • 3 = Niederösterreich
  • 4 = Oberösterreich
  • 5 = Salzburg
  • 6 = Steiermark
  • 7 = Tirol
  • 8 = Vorarlberg
  • 9 = Wien

OpenShift Persistent Volume im Ceph FS finden

Hatte die Herausforderung dass ich PVC erweitert habe (Größe verdoppelt) und das Ding Events vom Typ

NodeExpandVolume.NodeExpandVolume failed for volume "pvc-....guid...." : Expander.NodeExpand found CSI plugin kubernetes.io/csi/openshift-storage.cephfs.csi.ceph.com to not support node expansion

gespuckt hat obwohl das Webinterface überall die neue Größe angezeigt hat. Wollte schauen wie Ceph das sieht.

Schritt 1: Ceph Tools Pod erzeugen

oc patch OCSInitialization ocsinit -n openshift-storage --type json --patch  '[{ "op": "replace", "path": "/spec/enableCephTools", "value": true }]'

erzeugt im Namespace openshift-storage einen Pod mit Namen “rook-ceph-tools-*”, dort Shell öffnen:

oc rsh -n openshift-storage rook-ceph-tools-tralala-dada

Schritt 2: Name vom Filesystem/Volume rausfinden (zu finden auch in den Specs vom PV):

ceph fs ls    (oder ceph fs volume ls)

Schritt 3: SubVolumeGroup rausfinden

ceph fs subvolumegroup ls <Name aus Schritt 2>

Schritt 4: Volumes in der SubVolumeGroup auflisten

ceph fs subvolume ls <Name aus Schritt 2> --group_name <Name aus Schritt 3>

Schritt 5: Infos zu Volume/PV anzeigen (Name des Volumes aus YAML des PV – “subvolumeName”)

ceph fs subvolume info <Name aus Schritt 2> <Name aus Schritt 4> --group_name <Name aus Schritt 3>

Red Hat OpenShift Image Registry not configured

Wer einfach zum spielen einen OpenShift Cluster (Assisted über Web mit je einer Zusatzdisk (200 GB pro Knoten) damit OpenShift Data Foundation einen StorageCluster mit Ceph erzeugt) erzeugt hat zwar am Ende einen Cluster aber keine (funktionierende) Image Registry (weil die kein Storage hat), will man eine Application dann deployen schlägt man sehr schnell (in meinem Fall beim Build) bei “Image Registry not configured” (oder so ähnlich, in irgendwelchen Events) auf.

Habs vermutlich nur überlesen aber man muss der Registry Storage besorgen (PVC, oc apply -f meineregistry.yml) und mitteilen (Cluster Config):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-storage-pvc
namespace: openshift-image-registry
spec:
accessModes:
  - ReadWriteMany
resources:
  requests:
     storage: 100Gi
storageClassName: ocs-storagecluster-cephfs
oc patch config.image/cluster -p '{"spec":{"managementState":"Managed","replicas":2,"storage":{"managementState":"Unmanaged","pvc":{"claim":"registry-storage-pvc"}}}}' --type=merge

Quelle (für 4.13, Version auswählbar): https://docs.openshift.com/container-platform/4.13/registry/configuring_registry_storage/configuring-registry-storage-rhodf.html#registry-configuring-registry-storage-rhodf-cephfs_configuring-registry-storage-rhodf

Superbilliger hochverfügbarer Ingress Load Balancer

Hintergrund: Kubernetes, mehrere Ingresses, 3 Ingressknoten (ingress1-3.fun), ein Ingress/Service kann mit Prefixen nicht umgehen (absoluter Redirect) – daher verschiedene externe Namen und ein externer Load Balancer notwendig (webservice1+2.fun).

Superbillige Lösung:

  • 2 VMs (1 vCPU, 1 GB RAM, 10 GB Disk)
  • je eine für Zielclients erreichbare Adresse für webservice1+2.fun
  • HAProxy mit zwei frontends für webservice1+2.fun
  • keepalived mit VRRP Failover (die zwei öffentlichen Adressen)
  • Ingress Rules gehen auf die Namen, also http://webserviceX.fun/ => pod_für_webserviceX:port_für_webserviceX
/etc/haproxy/haproxy.cfg:

frontend webservice1
    bind webservice1.fun:80
    mode tcp
    default_backend backendnodes

frontend webservice2
    bind webservice2.fun:80
    mode tcp
    default_backend backendnodes

backend backendnodes
    balance source
    server node1 ingress1.fun:80 check
    server node2 ingress2.fun:80 check
    server node3 ingress3.fun:80 check

/etc/keepalived/keepalived.conf:

vrrp_instance VI_1 {
    state MASTER    # BACKUP am zweiten Knoten
    interface eth0
    virtual_router_id 51
    priority 255    # 254 am zweiten Knoten
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 12345
    }
    virtual_ipaddress {
        1.2.3.1/24          # öffentliche Adresse webservice1.fun
        1.2.3.2/24          # öffentliche Adresse webservice2.fun
    }

    notify_master "systemctl restart haproxy"
}

Durch das “notify_master” wird nach Failover der Adresse der HAProxy am jeweiligen Knoten neu gestartet und kann sich auf die virtuellen Adressen binden.

Mit “vrrp_track_process”/”track_process” oder “vrrp_script”/”track_script” könnte man noch Healthprobes (Existenz eines Prozesses – haproxy in diesem Fall oder ganzes Healthcheck Script) einführen – in der o.a. Konfiguration spricht keepalived nur an wenn VRRP Heartbeats vom MASTER nicht mehr ankommen.

Ingress spec (Controller=ingress-nginx):

spec:
  ingressClassName: nginx
  rules:
    - host: webservice1.fun
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: webservice1-server
                port:
                  number: 80

Das Ganze macht mit HTTPS dann naturgemäß 200x mal mehr Spaß 😀

WinRT mit C# in WinForms (.NET Framework)

  • Normales WinForms Projekt erzeugen
  • NuGet Package Management Format auswählbar machen:
    • Tools / Options / NuGet Package Manager / Allow format selection on first package install
  • NuGet Microsoft.Windows.SDK.Contracts mit der Version passend zur gewünschten Mindest-Windows-Version installieren
    • wenn die Auswahl PackageReference auswählen
  • Fröhlich WinRT Methoden verwenden, Beispiel (völlig non-async mal zur Abwechslung):
public static void SetLockscreen(string sUserPaper)
{
   Windows.Storage.StorageFile oUserPaper;

   oUserPaper=Windows.Storage.StorageFile.GetFileFromPathAsync(sUserPaper).AsTask().GetAwaiter().GetResult();
   Windows.System.UserProfile.LockScreen.SetImageFileAsync(oUserPaper).AsTask().Wait();
}

FIDO2/U2F Key für SUDO nutzen (Arch)

PAM Modul installieren

sudo pacman -S pam-u2f

Token für User registrieren

mkdir ~/.config/u2f
pamu2fcfg >~/.config/u2f/u2f_keys

SUDO PAM Config (/etc/pam.d/sudo) anpassen (vorm ersten “auth” einfügen)

auth sufficient pam_u2f.so cue prompt authfile=.config/u2f/u2f_keys

So wird bei angestecktem Key und Mapping im Configverzeichnis Touch angefordert und wenn nicht angesteckt/konfiguriert ist auf Kennwort zurückgefallen.

Optional/praktisch:

  • pinverification=1
  • debug

Quellen: yubico, arch-wiki

HP lt4132 unter Linux nutzen

Dreist geklaut/zusammengefasst von hier.

Existenz des Modems feststellen:

usb-devices

SYSFS Pfad feststellen

grep lt4132 /sys/bus/usb/devices/*/product

Einmal aus/so einschalten dass es Network/ModemManager auch sieht (1-3 vom vorigen Kommando ableiten):

sudo chmod 777 /sys/bus/usb/devices/1-3/bConfigurationValue
sudo echo 0 > /sys/bus/usb/devices/1-3/bConfigurationValue
sleep 1
sudo echo 3 > /sys/bus/usb/devices/1-3/bConfigurationValue

udev Rulefile erzeugen damits immer passiert

# /etc/udev/rules.d/hp-lt4132.rules

ACTION=="add|change", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="a31d", ATTR{bConfigurationValue}!="3", ATTR{bConfigurationValue}:="0"
ACTION=="add|change", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="a31d", ATTR{bConfigurationValue}!="3", RUN+="/bin/sh -c 'sleep 1; echo 3 > %S%p/bConfigurationValue'"
ACTION=="add|change", SUBSYSTEM=="net", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="a31d", ATTR{cdc_ncm/ndp_to_end}=="N", ATTR{cdc_ncm/ndp_to_end}:="Y"

PFX/P12 auf PEMmerl zerlegen

Public key aus PFX/P12:

openssl pkcs12 -in <zert>.pfx -nokeys -password pass:<passwort> -out <zert>.cert.pem   

Private key aus PFX/P12:

openssl pkcs12 -in <zert>.pfx -nocerts -nodes -password pass:<passwort> -out <zert>.key.pem

Private key in RSA Form:

openssl rsa -in <zert>.key.pem -out <zert>.rsakey.pem