Samstag, 10. April 2021

Installation Ubuntu on a encryptet system

 Challenge:

  • I have an encryptet system
    • 2 disks encryptet with LUKS
  • I want to install a fresh Ubuntu distro

How to go...

  • First boot the system with a Live-CD of Ubuntu -> try Ubuntu
  • open a terminal in this session
  • become root
    sudo su -
  • have a look to all available disks and search the ones you need
    lsblk --all
    NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    loop0                   7:0    0   9,1M  1 loop  /snap/kubectl/655
    ...
    loop15                  7:15   0         0 loop
    sda                     8:0    0 465,8G  0 disk
    ├─sda1                  8:1    0   512M  0 part  /boot/efi
    ├─sda2                  8:2    0   732M  0 part  /boot
    └─sda3                  8:3    0 464,6G  0 part
      └─sda3_crypt        253:0    0 464,6G  0 crypt
        ├─neon--vg-root   253:1    0 463,6G  0 lvm   /
        └─neon--vg-swap_1 253:2    0   980M  0 lvm   [SWAP]
    sdb                     8:16   0 238,5G  0 disk
    ├─sdb1                  8:17   0   512M  0 part
    ├─sdb2                  8:18   0   732M  0 part
    └─sdb3                  8:19   0 237,3G  0 part
  • In my case the necessary disk were sda and sdb
  • Next step search the partition of the disks which are encrypted
    lsblk -f /dev/sdb
    NAME   FSTYPE      LABEL UUID                                 MOUNTPOINT
    sdb
    ├─sdb1 vfat              9BCC-475E
    ├─sdb2 ext4              ad2fcd47-3725-4a8a-8ea6-90943b5914d2
    └─sdb3 crypto_LUKS       a740ff78-58b7-4ccd-87a1-92ba8715edcf
  • Open the encryptet partition
    cryptsetup open /dev/sdb3 rootdisk
    • rootdisk is here a free name which will be important at the end of the Ubuntu installation
  • After open both of my encrypted disks I could start the Ubuntu installation as usual
  • Before restart the fresh Ubuntu installation you have to clicked "Continue Testing" and return to the terminal
  • First get the UUIDs of the encrypted partitions and note them
    sudo blkid </dev/DEV_ROOTFS>
    sudo blkid </dev/DEV_HOME>
  • Then mount the Ubuntu OS
    sudo mount /dev/mapper/vgroot-lvroot /mnt
    sudo mount </dev/DEV_BOOT> /mnt/boot
    sudo mount /dev/mapper/vghome-lvhome /mnt/home
    sudo mount --bind /dev /mnt/dev
    sudo chroot /mnt
    mount -t proc proc /proc
    mount -t sysfs sys /sys
    mount -t devpts devpts /dev/pts
  • Create the file /etc/crypttab
    sudo nano /etc/crypttab
  • Add the following lines
    # <target name> <source device> <key file> <options>
    rootdisk UUID=<UUID_ROOTFS> none luks,discard
    homedisk UUID=<UUID_HOME> none luks,discard
    • IMPORTANT: rootdisk and homedisk are the names you used during open the encrypted disks at the beginning of this description
  • After editing /etc/crypttab execute the following command
    update-initramfs -k all -c
    • Here have a look at the output. If you using the wrong target name of the disks, you can see it here
  • Leave the terminal and reboot the system. During the reboot you now should be asked for the password for the encrypted disks

Freitag, 9. April 2021

Evolution unter Ubuntu Mate 20.04 einrichten

  • Assistent zur Einrichtung eines neuen Kontos in Evolution aufrufen
  • Email Adresse eingeben
  • Für Posteingang:


    • Port 993 auswählen
    • TLS auf dedizierten Port 
    • OAuth2 als Authentifizierung wählen
  • Für Posteingang


    • Port 587 auswählen
    • Haken bei "Server erfordert Legitimation" muss gesetzt sein 
    • STARTTLS nach Verbinden
    • OAuth2 als Authentifizierung
Konto, welche per Passwort Authentifizierung agiert, habe ich noch nicht zum laufen bekommen.

Montag, 25. Januar 2021

OpenShift 4 Deploy ein Standalone Grafana ohne Grafana Operator

Die Herausforderung besteht daraus, ein Standalone Grafana in einem OpenShift 4.5 Cluster zu deployen, welches einen OpenShift Login hat und auf den internen Prometheus des Cluster Monitorings zugreift. Somit wird es möglich, das vorhanden Cluster Monitoring um eigene Dashboards zu erweitern.

Eine weitere Herausforderung, die sich mir stellte war, dass ich nicht nur den Grafana Operator nicht verwenden konnte, sondern auch die von Red Hat bereitgestellten Images verwenden musste. Damit war das Bitnami Helm Chart raus ;-).

Nach einigen Versuchen bin ich dazu übergegangen, die Grafana Komponente aus dem "openshift-monitoring" Projekt zu kopieren. Dabei bin ich über ein paar Besonderheiten gestolpert, die ich hier erläutere:

  • Der ServiceAccount "grafana" wird als oauth Client verwendet
  • Wie generiere ich ein session secret für den outh-proxy? -> Auflösung unten
  • Und das Secret "grafana-tls" ist ein generiertes Secret, welches direkt über den Service "grafana" erzeugt wird.
  • Ach ja und die spezielle ConfigMap "grafana-trusted-ca-bundle"
Einen Teil meiner Lösungen habe ich dann in dem Artikel von Red Hat gefunden.

Wie habe ich nun das Projekt aufgebaut?

(Alle Dateien werden mit oc apply -f <datei.yaml> an das Projekt übergeben)

oc new-project grafana -> Erzeugt ein neues Projekt

ServiceAccount "grafana"

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    serviceaccounts.openshift.io/oauth-redirectreference.grafana: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"grafana"}}'
  name: grafana
  namespace: grafana

ConfigMap "grafana-trusted-ca-bundle"

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    config.openshift.io/inject-trusted-cabundle: "true"
  name: grafana-trusted-ca-bundle
  namespace: grafana

Service "grafana", der über die Annotaion auch das Secret "grafana-tls" erzeugt

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.alpha.openshift.io/serving-cert-secret-name: grafana-tls
  labels:
    app: grafana
  name: grafana
spec:
  ports:
  - name: https
    port: 3000
    protocol: TCP
    targetPort: https 
  selector:
    app: grafana
  type: ClusterIP

Session Secret für den oauth Proxy erzeugen
oc create secret generic grafana-proxy --from-literal=session_secret=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c43)

Datei "grafana.ini" erzeugen, aus der dann das Secret "grafana-config" erzeugt wird

[analytics]
check_for_updates = false
reporting_enabled = false
[auth]
disable_login_form = true
disable_signout_menu = true
[auth.basic]
enabled = false
[auth.proxy]
auto_sign_up = true
enabled = true
header_name = X-Forwarded-User
[paths]
data = /var/lib/grafana
logs = /var/lib/grafana/logs
plugins = /var/lib/grafana/plugins
provisioning = /etc/grafana/provisioning
[security]
admin_user = admin
admin_password = password
cookie_secure = true
[server]
http_addr = 127.0.0.1
http_port = 3001

oc create secret generic grafana-config --from-file=grafana.ini

Und nun das Herzstück: Das eigentliche Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: grafana
    spec:
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
      securityContext: {}
      serviceAccount: grafana
      containers:
        - resources:
            requests:
              cpu: 4m
              memory: 100Mi
          terminationMessagePath: /dev/termination-log
          name: grafana
          ports:
            - name: http
              containerPort: 3001
              protocol: TCP
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: grafana-storage
              mountPath: /var/lib/grafana
            - name: grafana-log
              mountPath: /var/log/grafana
#            - name: grafana-datasources
#              mountPath: /etc/grafana/provisioning/datasources
#            - name: grafana-dashboards
#              mountPath: /etc/grafana/provisioning/dashboards
#            - name: grafana-dashboard-cluster-overview 
#              mountPath: /grafana-dashboard-definitions/0/cluster-overview
            - name: grafana-config
              mountPath: /etc/grafana
          terminationMessagePolicy: File
          image: registry.redhat.io/openshift4/ose-grafana 
          args:
            - '-config=/etc/grafana/grafana.ini'
        - resources:
            requests:
              cpu: 1m
              memory: 20Mi
          readinessProbe:
            httpGet:
              path: /oauth/healthz
              port: https
              scheme: HTTPS
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          name: grafana-proxy
          env:
            - name: HTTP_PROXY
            - name: HTTPS_PROXY
            - name: NO_PROXY
          ports:
            - name: https
              containerPort: 3000
              protocol: TCP
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: secret-grafana-tls
              mountPath: /etc/tls/private
            - name: secret-grafana-proxy
              mountPath: /etc/proxy/secrets
            - name: grafana-trusted-ca-bundle
              readOnly: true
              mountPath: /etc/pki/ca-trust/extracted/pem/
          terminationMessagePolicy: File
          image: registry.redhat.io/openshift4/ose-oauth-proxy
          args:
            - '-provider=openshift'
            - '-https-address=:3000'
            - '-http-address='
            - '-email-domain=*'
            - '-upstream=http://localhost:3001'
            - '-openshift-sar={"resource": "namespaces", "verb": "get"}'
            - >-
              -openshift-delegate-urls={"/": {"resource": "namespaces", "verb":
              "get"}}
            - '-tls-cert=/etc/tls/private/tls.crt'
            - '-tls-key=/etc/tls/private/tls.key'
            - >-
              -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token
            - '-cookie-secret-file=/etc/proxy/secrets/session_secret'
            - '-openshift-service-account=grafana'
            - '-openshift-ca=/etc/pki/tls/cert.pem'
            - '-openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'
            - '-skip-auth-regex=^/metrics'
      serviceAccount: grafana
      volumes:
        - name: grafana-storage
          emptyDir: {}
        - name: grafana-log
          emptyDir: {}
#        - name: grafana-datasources
#          secret:
#            secretName: grafana-datasources
#            defaultMode: 420
#        - name: grafana-dashboards
#          configMap:
#            name: grafana-dashboards
#            defaultMode: 420
#        - name: grafana-dashboard-cluster-overview 
#          configMap:
#            name: grafana-dashboard-cluster-overview
#            defaultMode: 420
        - name: grafana-config
          secret:
            secretName: grafana-config
            defaultMode: 420
        - name: secret-grafana-tls
          secret:
            secretName: grafana-tls
            defaultMode: 420
        - name: secret-grafana-proxy
          secret:
            secretName: grafana-proxy
            defaultMode: 420
        - name: grafana-trusted-ca-bundle
          configMap:
            name: grafana-trusted-ca-bundle
            items:
              - key: ca-bundle.crt
                path: tls-ca-bundle.pem
            defaultMode: 420
            optional: true
      dnsPolicy: ClusterFirst
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

Nachdem das Deployment erfolgreich durch geführt wurde, müssen wir noch eine Route bauen

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: grafana
  namespace: grafana 
spec:
#  host: <host-name>
  port:
    targetPort: https
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: reencrypt
  to:
    kind: Service
    name: grafana
    weight: 100
  wildcardPolicy: None

Jetzt sollte das nackte Grafana erreichbar sein (wenn wir alle Router, Host-Dateien und sonstiges richtig gefüttert haben)

Hat das funktioniert, können wir die Dashboards und die Datasource einfügen. Da ich für meinen Anwendungsfall den schon vorhandenen Prometheus einbinden wollte, führte ich folgenden Befehl aus:

oc get secret grafana-datasources -o yaml -n openshift-monitoring > secret-grafana-datasources.yaml

Die Datei secret-grafana-datasources.yaml muss noch an den Namespace "grafana" angepasst werden, und die ganzen unnötigen Zeilen entfernt werden. Danach mit oc apply -f übergeben.
Für ein Dashboard müsst ihr ein Dashboard in Json Format in eine ConfigMap packen. In meinem Fall habe ich die ConfigMap "grafana-dashboard-cluster-overview" genannt. Und damit es die übergordnete Struktur, wie auch im Cluster-Monitoring gibt, habe ich noch die ConfigMap grafana-dashboards aus dem "openshift-monitoring" Projekt kopiert und in dem Namespace "grafana" erzeugt. 
Dann nehmen wir die Kommentare aus der Deployment-Datei raus, übergeben die Änderungen an OpenShift, et voilá.... wir haben ein Grafana, welches auf den internen Prometheus zugreift und die Daten für eigene Dashboards verwendet.