AfNaS Superbook

In diesem Dokument möchte ich Dinge niederschreiben, die ich ständig aus verschiedenen Quellen, ob Blogs oder Manpages zusammenlesen muss. So möchte ich im Laufe der Zeit ein “Buch” schreiben, dass vielleicht auch anderen Menschen helfen kann.

Welche Form dieses “Buch” annehemn wird steht noch nicht fest. Evtl. als Blog, Wiki oder ähnliches. aber vielleicht auch als pdf (oder gar in gedruckter Form?). Ich weiß auch noch nicht, unter welcher Lizens ich das ganze laufen lasse.

Jetzt muss ich erst einmal anfangem meine Erkenntnisse aufzuschreiben!

Ich teste jetzt ein git hook, um eine website hieraus zu erzeugen!

Linux

Core Dump

Signale

Signale können unter anderem mit dem Programm kill an einen Prozess gesendet werden. kill -TERM 1234 sendet das Signal SIGTERM an den Prozess mit der PID 1234.

Quelle man 7 signal

Signal Nummer (x86/ARM) Bedeutung
SIGHUP 1 Hangup detected on controlling terminal or death of controlling process.
SIGINT 2 Interrupt from keyboard (STRG + C)
SIGQUIT 3 Interrupt from keyboard
SIGKILL 9 Kill-Signal! Beendet den Prozess, ohne ihm vorher die Kontrolle zu geben.
SIGTERM 15 Termination Signal (Soft Shutdown)

Benutzer und Gruppen

Die Benutzer und Gruppen werden in den Dateien /etc/passwd (Benutzer) und /etc/group (Gruppen) gespeichert (TODO: Aufbau)

# Neue Gruppe neue_gruppe erstellen
$ groupadd neue_gruppe

#  Neue Gruppe neue_gruppe mit gid 1001 erstellen
$ groupadd -g 1001 neue_gruppe

# Ein existierendne Benutzer einer existierenden Gruppe hinzufügen
# -a, --append: Benutzer einer Gruppen hinzufügen (nur mit -G zu benutzen)
# -G, --groups GROUP1[GROUP2,..,[GROUPn]]: Liste von Gruppen, die der Benutzer hinzugefügt werden soll
$ usermod -a -G neue_gruppe benutzername

Dateiattribute

Berechtigungen

chmod

Berechtigungen können mit chmod gesetzt werden.

Oktale Darstellung: Fehlende Ziffern werden von links an mit 0 aufgefüllt. chmod 74 datei is also das gleiche wie chmod 0074 datei

chmod sugo /name/of/file
      |`+´
      | `- Bitfelder für (u)ser, (g)roup und (o)ther:
      |    1: execute
      |    2: write
      |    4: read
      |
      `--- Bitfeld für "Spezialbits":
           1: sticky bit
           2: setgid bit
           4: setuid bit

Dateiattribute ausgeben

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>


void print_file_stat(int file_number)
{
  struct stat sb;
  fstat(file_number, &sb);

  syslog(LOG_INFO, "ID of containing device:  [%lx,%lx]\n",
    (long) major(sb.st_dev), (long) minor(sb.st_dev));

  syslog(LOG_INFO, "File type:                ");

  switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  syslog(LOG_INFO, "block device\n");            break;
    case S_IFCHR:  syslog(LOG_INFO, "character device\n");        break;
    case S_IFDIR:  syslog(LOG_INFO, "directory\n");               break;
    case S_IFIFO:  syslog(LOG_INFO, "FIFO/pipe\n");               break;
    case S_IFLNK:  syslog(LOG_INFO, "symlink\n");                 break;
    case S_IFREG:  syslog(LOG_INFO, "regular file\n");            break;
    case S_IFSOCK: syslog(LOG_INFO, "socket\n");                  break;
    default:       syslog(LOG_INFO, "unknown?\n");                break;
  }

  syslog(LOG_INFO, "I-node number:            %ld\n", (long) sb.st_ino);

  syslog(LOG_INFO, "Mode:                     %lo (octal)\n",
       (unsigned long) sb.st_mode);

  syslog(LOG_INFO, "Link count:               %ld\n", (long) sb.st_nlink);
  syslog(LOG_INFO, "Ownership:                UID=%ld   GID=%ld\n",
       (long) sb.st_uid, (long) sb.st_gid);

  syslog(LOG_INFO, "Preferred I/O block size: %ld bytes\n",
       (long) sb.st_blksize);
  syslog(LOG_INFO, "File size:                %lld bytes\n",
       (long long) sb.st_size);
  syslog(LOG_INFO, "Blocks allocated:         %lld\n",
       (long long) sb.st_blocks);

  syslog(LOG_INFO, "Last status change:       %s", ctime(&sb.st_ctime));
  syslog(LOG_INFO, "Last file access:         %s", ctime(&sb.st_atime));
  syslog(LOG_INFO, "Last file modification:   %s", ctime(&sb.st_mtime));

}

void fprint_file_stat(FILE *fp)
{
  print_file_stat(fileno(fp));
}

Tools

Allgemein

date

Umrechnen von Unix-Timestamp in Localtime:

$ date -d @1618393088
Mi 14. Apr 11:38:08 CEST 2021

strace

Mit strace können die Systemcalls eines Programms geloggt werden.

# Systemcalls auf stdout ausgeben:
$ strace <program> [program arguments]

# Systemcalls in eine Datei schreiben
$ strace -o Ausgabedatei <program> [program arguments]

# Allen Forks folgen und Systemcalls in Dateien schreiben (jeder Fork erhält eine eigene Datei "Ausgabedatei.pid")
$ strace -o Ausgabedatei -ff <program> [program arguments]

tee

tee ließt von stdin ein und schreibt das Gelesene nach stdout und in beliebig viele weitere Dateien (auch keine ist OK). Mit dem Parameter -a wird an die angegebenen Dateien angehängt.

$ echo "Teetrinken mit August" | tee
Teetrinken mit August

$ echo "Teetrinken mit August" | tee datei_1
Teetrinken mit August
$ cat datei_1
Teetrinken mit August

$ echo "Teetrinken mit August" | tee datei_1 datei_2
Teetrinken mit August
$ cat datei_1 datei_2
Teetrinken mit August
Teetrinken mit August

find

Verzeichnis von Suche ausschließen

$ find -name "finde_mich"
./.nicht_mich/finde_mich
./finde_mich
./sub/finde_mich

$ find -name "finde_mich" -not -path "./.nicht_mich/*"
./finde_mich
./sub/finde_mich

ssh

fingerprint aus known_hosts löschen

Wenn sich der Schlüssel eines hosts ändert, dann kann darauf nicht mehr per ssh zugegriffen werden. Es kommt die Meldung:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The RSA host key for foo-bar.net has changed,
and the key for the corresponding IP address 127.0.0.1
is unchanged. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
Offending key for IP in /home/user/.ssh/known_hosts:6
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

Es ist möglich den Fingerprint aus der known_hosts zu löschen. Achtung, das darf nur gemacht werden, wenn auch der Schlüssel wirklich geändert wurde. Sonst könnte auch ein Machine-In-The-Middle-Angriff dafür verantwortlich sein. !!Fingerprint vergleichen!!

# hostname aus knowm_hosts entfernen, danach kann per ssh verbunden werden!
ssh-keygen -R "hostname"

openssl

Certs aus einem CA-Bundle anzeigen

Mit dem Folgendem Befehl werden alle in dem ca_bundle.pem enthaltenen Certs ausgegben:

$ openssl crl2pkcs7 -nocrl -certfile ca_bundle.pem | openssl pkcs7 -print_certs
subject=C = CN, O = "E-Corp", CN = Root CA AUTH

issuer=C = CN, O = "E-Corp", CN = Root CA AUTH

-----BEGIN CERTIFICATE-----
MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
[...]
MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
-----END CERTIFICATE-----

# -noout: nur subject und issure ausgeben, nicht das CERT
$ openssl crl2pkcs7 -nocrl -certfile ca_bundle.pem | openssl pkcs7 -print_certs -noout
subject=C = CN, O = "E-Corp", CN = Root CA AUTH

issuer=C = CN, O = "E-Corp", CN = Root CA AUTH

TLS-Verschlüsselte TCP Verbindung aufbauen

Mit openssl kann eine TLS-Verschlüsselte Verbindung zu einem Server aufgebaut werden.

openssl s_client -connect <server>:<port>

tmux

TODO: schöner und evtl als Tabelle darstellen

Im folgenden sind ein paar nützliche tmux Kommandos aufgelistet. Zeilen die mit $ anfangen, werden in die Kommandozeile des OS eingegeben. Kommentare, die mit : starten sind tmux-interne Komanndos, und konnen aus tmux heraus eingegeben werden. Die Kommandozeile von tmux wird mit Ctrl + b aktiviert. Kommentare, die eine Tastenkürzelfolge beinhalten, sind auch als solche einzugeben. Sind mehere Zeilen für ein Kommando angegeben sind das Alternativen.

Sessions

# Neue Session erstellen
$ tmux
$ tmux new
$ tmux new-session
# :new

# Neue Session mit namen meine_session erstellen
$ tmux new -s meine_session
# : new -s meine_session

# Alle Sessions, bis auf die aktuelle, beenden
$ tmux kill-session -a

# Alle Sessions, bis auf die meine_session, beenden
$ tmux kill-session -a -t meine_session

# Von Session ablösen
# "Ctrl + b" "d"

# Alle anderen von der Session lösen
# : attach -d

# Sessions auflisten
$ tmux ls
$ tmux list-sessions

# Mit letzter Session verbinden
$ tmux a
$ tmux at
$ tmux attach
$ tmux attach-session

# Mit Session "meine_session" verbinden
$ tmux a -t meine_session
$ tmux at -t meine_session
$ tmux attach -t meine_session
$ tmux attach-session -t meine_session

# Session mit Vorschau wechseln
# "Ctrl + b" "w"

# Zur nächsten Session wechseln
# "Ctrl + b" ")"

# Zur vorherigen Session wechseln
# "Ctrl + b" "("

Windows

# Actuelles Window schließen
# "Ctrl + b" "&"

# Windows umsortieren: Quell (s) mit Ziel (t) Window tauschen
# :swap-window -s 1 -t 2

# Windows umsortieren: Aktuelles Window um 2 Positionen nach links verschieben (andere Zahlen möglich)
# :swap-window -t -2

Panes

# Window vertical (--) aufteilen
# :split
# :splitw
# :split-window

# Window horizontal ( | ) aufteilen
# :split -h

# Größe in Prozent mit angeben
# :split -p 33

# Größe in Zeilen(vertikal)/Zeichen(horizontal) angeben
# :split -l 15

bash Programmierung

Script-Parameter (getopt)

Ein Beispiel für getopt:

#! /usr/bin/bash

NAME=${0##*/}

usage() {
cat << EOF
${NAME} ist so zu benutzen:
-a oder/und -b <parameter>

EOF
}

# -o shortopts: 
# Mögliche Parameter. Folgt einem Parameter ein ":" benötigt dieser ein Argument
# Hier "-a" und "-b Argument"
shortopts='ab:'

# -l longopts:
# Die möglichen Paramter ausgeschrieben, getrennt durch Kommas
# Hier "--aopt" und "--bopt Argument"
longopts='aopt,bopt:'

# Alle übergebenen Argumente ($@) prüfen und die OKen in options speichern
options=$( getopt -o "$shortopts" -l "$longopts" -- "$@" )

# Wenn getopt eine unbekannte Optin gefunden hat (mit - oder -- startend) dann hier beenden
if [ $? -ne 0 ]; then
    usage
    exit 1 
fi

# die neu gebaute Argumentenliste awenden  
eval set -- "$options"

# über diese neuen Argumente itterieren:
while [ $# -gt 0 ]; do
    case "$1" in
        --aopt|-a)  
        echo A gesetzt
                ;;

        --bopt|-b)  
        echo B auf gesetzt auf: "$2"
        # nächstes Argument verarbeiten (da -b ein Parameter erwartet gibts hier auch ein shift):
                shift 
        ;;

        --) shift; break ;;
        *)  echo_abort 1 "$1: Unknown argument, aborting."
    esac
  # nächstes Argumetn verarbeiten
    shift
done

echo Die Restlichen Parameter: "${@}"

Variablen

Besondere Variablen

Quelle: https://www.gnu.org/software/bash/manual/bash.html#Special-Parameters

#! /bin/bash.sh 
# Datei: test.sh


return_me() {
  return $1
}

IFS='|'
echo  " \$\* ": ${*}
echo "\"\$\*\"": "${*}"

echo  " \$\@ ": ${@}
echo "\"\$\@\"": "${@}"

echo " \$\# :" ${#}

# kann auch ein Programm wie ls sein!
return_me 0
echo " \$\? :" ${?}
return_me 42
echo " \$\? :" ${?}

echo " \$\$ :" ${$}

echo  " \$0 :" ${0}

# ./test.sh eins zwei drei vier
# $\* : eins zwei drei vier
#"$\*": eins|zwei|drei|vier
# $\@ : eins zwei drei vier
#"$\@": eins zwei drei vier
# $\# : 4
# $\? : 0
# $\? : 42
# $$ : 14003

String ver/bearbeitung

TODO: IFS

Quelle: https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion

Strings verketten (concatenate)

# ${parameter1}${parameter2}
$ AA="Super"
$ BB="Cool"
$ echo ${AA}${BB}
SuperCool

Stringlänge

# ${#parameter}
$ AA="Super"
$ echo ${#AA}
5

Substring

Substring per offset

# ${parameter:offset:length}
$ AA="Super Cool"
$ echo ${AA:6}
Cool
$ echo ${AA:0:5}
Super
$ echo ${AA:6:3}
Coo

Substring per Regex

Entfernen des Matches von word aus dem parameter. Das word muss am Anfang des parameters matchen!

# ${parameter#word}
# ${parameter##word}
$ AA="/usr/local/bin/destroyer"
$ echo ${AA##/usr}
/local/bin/destroyer
$ echo ${AA##/bin}             
/usr/local/bin/destroyer

# Nützlich um programmname aus pfad zu extrahieren
$ echo ${AA##*/}
destroyer

Redirects

Here Document

Quelle: https://www.gnu.org/software/bash/manual/bash.html#Here-Documents

Die Shell, ließt (ab der nächsten Zeile) bis zu so lange die Eingabe ein, bis das angegebene Wort alleine in einer Zeile steht.

$ cat << BISZUMBITTERENENDE
Zeile 1 
Zeile 2 
BISZUMBITTERENENDE
# liefert:
Zeile 1 
Zeile 2 

# Weiteres Beispiel
$ VAR=$(cat << EOF
Dies ist ein Text über mehere Zeilen,
der endet, wenn EOF alleine in einer Zeile steht.
EOF muss dabei wirklich aleine in einer Zeile stehen.
EOF)
EOF
)

$ echo $VAR
Dies ist ein Text über mehere Zeilen,
der endet, wenn EOF alleine in einer Zeile steht.
EOF muss dabei wirklich aleine in einer Zeile stehen.
EOF)

C Programmierung

Operatoren nach Priorität

Priorität Operator Assoziativität (Reihenfolge der Abarbeitung)
1. (höchste) () [] -> . von Links nach Rechts
2. ! ~ ++ -- -(Vorzeichen) + (Vorzeichen) (Typ) * (Zeigerdereferenzierung) & (Addressoperator) sizeof von Rechts nach Links
3. * (Multiplikation) / % von Links nach Rechts
4. + (Addition) - (Substraktion) von Links nach Rechts
5. <<< >> von Links nach Rechts
6. << <= > >= von Links nach Rechts
7. == != von Links nach Rechts
8. & (bitweise Und) von Links nach Rechts
9. ^ von Links nach Rechts
10. | von Links nach Rechts
11. && von Links nach Rechts
12. || von Links nach Rechts
13. ?: von Rechts nach Links
14. = += -= *= /= %= &= |= ^= <<= >>= von Rechts nach Links
15. (niedrigste) , von Links nach Rechts

printf-Familie

printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf

formatierte Ausgabe

Format-String

Zeichen im Format-String, die nicht dem conversion-Spezifikation entsprechen, werden so ausgegben, wie sie sind.

Die conversion-Spezifikation hat folgende allgemeine Form:

%[<param-no>$][flags][width][.<precision>][type]<conversion>

bzw. folgende Form, wenn die Genauigkeit (<precision>) durch einen Parameter vorgegeben werden soll:

%[<param-no>$][flags][width].*[<param-no>$][type]<conversion>
<conversion> Erklärung Beispiel
d und i Integer als dezimale, vorzeichenbehaftete Ganzzahl ausgeben. Bei der Ausgabe verhalten sich d und i gleich, bei den Eingabefunktionen allerdings nicht (siehe ???) -235
u Integer als dezimale, vorzeichenlose Ganzzahl ausgeben. 42
o Integer als oktale, vorzeichenlose Ganzzahl ausgeben. 52
x und X Integer als hexadezimale, vorzeichenlose Ganzzahl ausgeben. x mit kleinen Buchstaben (a-f) und X mit großen Buchstaben (A-F) 2a
f Fließkommazahl als Festkommazahl (normale) Darstellung ausgeben 3.141593
e und E Fließkommazahl in wissenschaftlicher Notifikation (Exponent und Mantisse). e mit kleinem Buchstaben und E mit großem Buchstaben. 3.141592E+05
g und G Fließkommazahl wie bei e (bzw. E) oder ‘f’ (bzw. F) ausgeben, je nachdem welche Darstellung kürzer ist. g mit kleinem Buchstaben und G mit großen Buchstaben 3.141592
a und A Fließkommazahl in hexadezimaler Fließkommadarstellung ausgeben. a mit kleinen Buchstaben und A mit großen Buchstaben 0X1.32CBDP+18
c Einen einzelnen Buchstaben ausgeben p
C Ist ein Alias für lc (als Argument wird wint_t erwartet). Aus Kompatibilitätsgründen mit Unix. p
s Einen C-String ausgeben. Hallo!
p Den Wert eines Pointers ausgeben 0x7ffd22f15964
n Es wird nichts ausgegeben. Statt dessen wird die Anzahl der bisher geschriebenen Zeichen an die Adresse des dazugehörgien Arguments geschrieben (muss ein Pointer auf ein signed int sein)
% Gibt ein %-Zeichen aus. %

scanf-Familie

scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf

formatierte Eingabe

Format-String

Python Programmierung

Main Datei

Die built-in Variable __name__ gibt den Namen des aktuellen Moduls wieder. Der Name des Top-Level Moduls (von der Standardeingabe gelesen, ein gestartetet Skript oder eine interaktive Prompt) ist __main__. So kann eine Main-Funktion erstellt werden.

def main():
  pass

if __name__ == "__main__":
    # execute only if run as a script
    main()

Node.js

Typescript

Debugging mit Docker und Chromium

  1. Typescript lokal mit Sourcmap kompilieren: ./node_modules/typescript/bin/tsc --sourceMap true
  2. Typescript auch im Dockerimage mit Sourcmap kompilieren und node mit “–inspect” Parameter starten (0.0.0.0 damit jede IP als Debuger zugreifen kann) Dockerfile:
FROM node:18-alpine

WORKDIR /usr/src/app

COPY . .

RUN npm install && ./node_modules/typescript/bin/tsc --sourceMap true

CMD [ "node", "--inspect=0.0.0.0:9229", "index.js"]
  1. Port beim Deployen publishen. Z.B. für einen Service: docker service create --publish-add "9339:9229" <image>
  2. Chrome Starten und Devtools öffnen chrome://inspect
  3. Freigegebenen Port in Device list eintragen 127.0.0.1:9339 (localhost hat bei mir nicht funktioniert. Also 127.0.0.1 angeben)
  4. Jetzt sollte Chromium das Device finden.
  5. Wichtig!: Auf Open dedicated DevTools for Node klicken um den Node.js Debugger zu starten (sonst gibt es keinen Node-Tab)
  6. Verbindung herstellen
  7. Die JS Files sind im Reiter Sources unter Node zu finden. Hier fehlen allerdings die Sourcemaps
  8. Zu debuggendes JS File öffnen
  9. Mit Rechts in das Source-Fenster klicken.
  10. Add source map... auswählen
  11. Pfad zur entsprechenden lokalen Sourcemap einfügen und bestätigen
  12. Nun kann das TS File gedebugged werden

Git

Branches

TODO Aufteilung in Branch und Commit ist eher doof

Lokale Branches löschen

# -d ist die Abkürzung für `--delete`
git branch -d $branchname

# Zum Beispiel:
git branch -d origin/my_branch
git branch -d my_branch

Würde ein Commit durch das löschen des branches verwaisen, dann muss das Löschen erzwungen werden:

# -D ist die Abkürzung für `--delete --force`
git branch -D <brnachname>

Remote Branches löschen

git push $remote_repo --delete $branchname

# Beispiele:
git push origin --delete uneeded_branch
git push wurstrepo --delete timos_branch

Rebase

https://git-scm.com/book/de/v2/Git-Branching-Rebasing

Rebase kann noch mehr, aber hier erstmal das Verschieben einer Abfolge von Commits auf einen neuen Basis-Commit:

Beispiel:

Vorher:              Nachher:

  *  feature           * feature
  *                    *
  *                    *
* | master            /
* |                  * master
* |                  *
|/                   *
*                    *
|                    |
git checkout feature
git rebase master

Commits

Letzen Commit anzeigen

# letzte Commit Message anzeigen 
git log -1

# letzen Commit (inklusive Änderungen) anzeigen 
git show

Einzelne Commits erneut anwenden (cherry-pick)

Mit Cherry-Pick kann ein einzelner Commit erneut (auf einen anderen Branch) angewand werden.

In folgendem Beispiel soll Commit G aus dem feature-Branch auch in den master-Branch übernommen werden (ohne Commit E und F zu übernehmen).

Vorher:              Nachher:
                     G   master
  G  feature         | G feature
  F                  | F
  E                  | E
D | master           D |
C |                  C | 
B |                  B |
|/                   |/
A                    A
|                    |
git checkout master
git cherry-pick G

Einzelne Datei aus spezifischem Commit extrahieren

https://git-scm.com/docs/git-show

(Object: https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-emltrevgtltpathgtemegemHEADREADMEememmasterREADMEem)

Mit show kann der Inhalt einer Datei (oder eines anderen git Objekts ausgegeben werden)

# <rev>:<path>
git show feature:die/will/ich/haben.txt

oder https://git-scm.com/docs/git-restore

Mit restore kann eine Dattei aus einem Commit in die working-copy geschrieben werden:

# -s <commit>: Legt, den commit fest, aus dem restored werden soll (default ist HEAD)
git restore -s feature die/will/ich/haben.txt

Working Copy

Aufräumen

Mit git clean werden alle, nicht von git verfolgten Dateien gelöscht.

# Rekursiv alles löschen, was git nicht kennt (tracked und ignored Dateien sind ausgeschlossen)
# -f: force (alternativ -d für dry-run)
# -d: recursives löschen, auch wenn kein Ordner angegeben ist 
$ git clean -df [Optionaler ordner]

Ignore

# ignore-file, zum commiten (dann haben alle die gleichen ignores)
${REPO}/.gitignore

# persönliches ignore-file, dass nicht commited wird
${REPO}/.git/info/exclude

# persönliches, systemweites ignore-file wird in ~/.gitconfig mit der Option 'core.excludesFile' festgelegt
[core]
  excludesFile = /pfad/zur/systemweiten/persoenlichen/gitignore

GNU Debug

Kommandozeilen Argumente

$ gcc -g -o test.out test.c
$ pidof test
1504
$ gdb --pdi=1504 --symbols -test.out

Addons

Sehr sinvolle gdb features: https://hugsy.github.io/gef/

Befehle

https://sourceware.org/gdb/current/onlinedocs/gdb/TUI-Commands.html#TUI-Commands

Mit telnet kann eine TCP Verbindung zu einem Server aufgebaut werden. Über diese Verbindung können dann Protokolle, wie IMAP oder SMTP gesprochen werden.

TLS-Verschlüsselte Verbindungen können mit openssl s_client -connect <host>:<port> aufgebaut werden.

IMAP

Internet Message Access Protocol (IMAP)

RFC3501 Wikipedia

Den einzelnen Befehlen wird eine ID vorangestellt (TODO: warum, wieso, format?)

Kommunikation mit dem IMAP-Server kann per Telnet aufgebaut werden: $ telnet 172.17.0.2 143

# login:
a login james.kirk@daniel.local jkjk123

# List inbox:
b list inbox *

# select mailbox (hier inbox):
c select inbox

# infos zu mail 3 anfordern
d fetch 3 full

# header von mail 3 ausgeben:
e fetch 3 body[header]

# mail 3 ausgeben (komplett):
f fetch 3 body[]

# mail über uid fetchen (sonst wird eine session abhängige id verwendet)
g uid fetch 123 body[]

SASL PLAIN login:

# Logindaten base64 codieren '\0<username>\0<password>'
$ echo -en "\x00Username\x00mypassword" | base64 -w 0
AFVzZXJuYW1lAG15cGFzc3dvcmQ=

# IMAP commando:
a authenticate plain
# Antwort vom server:
+

# key senden:
AFVzZXJuYW1lAG15cGFzc3dvcmQ=

# Fertig!

SMTP

Debug-Server in Python: python -m smtpd -n -c DebuggingServer -d :2525 :2525

telnet mail.example.com 25

# Absenderadresse angeben:
MAIL FROM:<absende.adresse@domain.de>

# Empfängeradresse
RCPT TO:<empfangs.adresse@domain.de>

# Start der Mail (wird mit einem `.` beendet)
DATA
From: <absende.adresse@domain.de>
To: <empfangs.adresse@domain.de>
Subject: Testmail
Date: Fr, 13 Aug 2021 16:12:00 +0200

Das hier ist eine super tolle Testmail.
Mit einer Zweiten Zeile!
.

# Verbindung trennen
QUIT

SQL

# auflisten aller Tabellen in der Datenbank
sqlite3 /path/to/database.db ".tables"

# Aufbau einer Tabell ausgeben
sqlite3 /path/to/database.db ".schema tabellenname"

# Kompletten Inhalt einer Tabelle ausgeben
sqlite3 /path/to/database.db "SELECT * FROM tabellenname;"

redis

löschen von meheren keys:

# 1. Parameter: Keys, die mit diesem String beginnen werden gelöscht (hier also deltest:wurst:*)
# Returns: anzahl der keys, die gelöscht wurden
eval "local a = redis.call('keys', ARGV[1] .. '*') local i = 0 for b, c in ipairs(a) do redis.call('del', c) i = i + 1  end return i" 0 deltest:wurst:

Docker

Images auflisten

$ docker images

Image aus tar hinzufügen

# Direkt aus einer Datei laden
$ docker load --input path/to/image.tar

# Oder über stdin
$ cat path/to/image.tar | docker load -

# ?? klappt bei mir, weiß aber noch nciht warum das besser als load
# über stdin
$ cat path/to/image.tar | docker import - <Repository>:<tag>
# oder direkt aus einer Datei
$ docker import path/to/image.tar <Repository>:<tag>

Image umbennen

$ docker tag <old image_id or repo:tag> <new repo:tag>

Docker Registry

TODO: was ist das

https://www.docker.com/blog/how-to-use-your-own-registry-2/

Unsichere Registry hinzufügen

TODO: was genau bedeutet das?

In /etc/docker/daemon.json Folgendes Array hinzufügen:

{
    "insecure-registries": ["docker-registry.afnas.de:5000"]
}

Dann ist es möglich von dort aus Images zu pullen und zu pushen.

Images von Registry laden

docker pull docker-registry.afnas.de:5000/my-image

Image in Registry hochladen

docker tag my-image docker-registry.afnas.de:5000/my-image
docker push docker-registry.afnas.de:5000/my-image

Images in einem Registry auflisten

http://<ip/hostname>:<port>/v2/_catalog liefert eine JSON Datei mit allen Images im Registry.

curl -X GET -u <user>:<pass> https://myregistry:5000/v2/_catalog
curl -X GET -u <user>:<pass> https://myregistry:5000/v2/ubuntu/tags/list

Services

# Service erstellen
docker service create <imagename> [Command] [Arguments]

# Service updaten
docker service update --image=<imagename> <servicename>

# Service neustarten
docker service update --force <servicename>

# Umgebungsvariablen hinzufügen/ändern
docker service update --env-add ENVVAR=value <servicename>

# Umgebungsvariable entfernen
docker service update --env-rm ENVVAR <servicename>

Aufräumen

# Nicht laufende Container entfernen (Container, die mit --rm gestartet wurden, werden automatisch entfernt)
docker container prune

# Images, die zu keinem Container gehören UND kein Repository/Tag haben entfernen
docker image prune

TODO

Links

Hacking