Archiv der Kategorie: Linux

Eigenes Debian/Ubuntu Repository aufbauen

Kurzanleitung zum Aufbau eines APT Paket Repository

In dem Repo wird das hallo-1.0.0.deb verwendet um die Funktion von reprepro zu zeigen, wie eigene DEB Pakete erstellt werden können könnt Ihr hier lesen.

Installation der benötigten Pakete

apt install reprepro apache2 gnupg

Erstellen eines GnuPG keys

Mit diesem GPG Schlüssel wird das Repository und die Pakete signiert. Der Public Key muss auf den Zielsystemen als Trusted Key hinterlegt werden. (siehe unten)

Beim Erstellen des Keys muss man ein Passwort angeben. Nur mit diesem Passwort ist es möglich neue Pakete zum Repository hinzuzufügen und zu signieren.

gpg --gen-key

...

Ihr Name ("Vorname Nachname"): Mein APT Repo Key
Email-Adresse: example@example.org
Sie haben diese User-ID gewählt:
    "Mein APT Repo Key <example@example.org>"

Ändern: (N)ame, (E)-Mail oder (F)ertig/(A)bbrechen? f

...


Öffentlichen und geheimen Schlüssel erzeugt und signiert.

pub   rsa3072 2020-10-11 [SC] [verfällt: 2022-10-11]
      4A2E138451DD449DF3FC2C7A28C7770DD3A8D10D
uid                      Mein APT Repo Key <example@example.org>
sub   rsa3072 2020-10-11 [E] [verfällt: 2022-10-11]

Der Key hat eine Gültigkeit von 2 Jahren, man kann die Gültigkeit verlängern. Das geht mit „gpg –edit-key <key_id>“. Mit „expire“ kann die Gültigkeit des Keys geändert werden.

gpg --edit-key 4A2E138451DD449DF3FC2C7A28C7770DD3A8D10D


gpg (GnuPG) 2.2.12; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Geheimer Schlüssel ist vorhanden.

sec  rsa3072/28C7770DD3A8D10D
     erzeugt: 2020-10-11  verfällt: 2022-10-11  Nutzung: SC
     Vertrauen: ultimativ     Gültigkeit: ultimativ
ssb  rsa3072/236EB690D64E39D8
     erzeugt: 2020-10-11  verfällt: 2022-10-11  Nutzung: E
[ ultimativ ] (1). Mein APT Repo Key <example@example.org>



gpg> expire
Ändern des Verfallsdatums des Hauptschlüssels.
Bitte wählen Sie, wie lange der Schlüssel gültig bleiben soll.
         0 = Schlüssel verfällt nie
      <n>  = Schlüssel verfällt nach n Tagen
      <n>w = Schlüssel verfällt nach n Wochen
      <n>m = Schlüssel verfällt nach n Monaten
      <n>y = Schlüssel verfällt nach n Jahren
Wie lange bleibt der Schlüssel gültig? (0) 10y
Key verfällt am Mi 09 Okt 2030 21:37:42 CEST
Ist dies richtig? (j/N) j

sec  rsa3072/28C7770DD3A8D10D
     erzeugt: 2020-10-11  verfällt: 2030-10-09  Nutzung: SC
     Vertrauen: ultimativ     Gültigkeit: ultimativ
ssb  rsa3072/236EB690D64E39D8
     erzeugt: 2020-10-11  verfällt: 2022-10-11  Nutzung: E
[ ultimativ ] (1). Mein APT Repo Key <example@example.org>


gpg> key 1
gpg> expire
Ändern des Verfallsdatums des Unterschlüssels.
Bitte wählen Sie, wie lange der Schlüssel gültig bleiben soll.
         0 = Schlüssel verfällt nie
      <n>  = Schlüssel verfällt nach n Tagen
      <n>w = Schlüssel verfällt nach n Wochen
      <n>m = Schlüssel verfällt nach n Monaten
      <n>y = Schlüssel verfällt nach n Jahren
Wie lange bleibt der Schlüssel gültig? (0) 10y
Key verfällt am Mi 09 Okt 2030 21:37:42 CEST
Ist dies richtig? (j/N) j

sec  rsa3072/28C7770DD3A8D10D
     erzeugt: 2020-10-11  verfällt: 2030-10-09  Nutzung: SC
     Vertrauen: ultimativ     Gültigkeit: ultimativ
ssb  rsa3072/236EB690D64E39D8
     erzeugt: 2020-10-11  verfällt: 2030-10-09  Nutzung: E
[ ultimativ ] (1). Mein APT Repo Key <example@example.org>


gpg> quit
Änderungen speichern? (j/N) j



Erstellen des REPO Verzeichnis

mkdir -p /var/www/repos/apt/debian
mkdir /var/www/repos/apt/debian/conf

Erstellen der Apache Konfiguration

In dem einfachen Beispiel habe ich einfach die Default Virtual Host Konfiguration ersetzt/angepasst, diese liegt unter /etc/apache2/sites-enabled/000-default

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www

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

        <Directory /var/www/repos/ >
                Options Indexes FollowSymLinks Multiviews
                Require all granted
        </Directory>

        <Directory "/var/www/repos/apt/*/db/">
                Require all denied
        </Directory>

        <Directory "/var/www/repos/apt/*/conf/">
                Require all denied
        </Directory>

        <Directory "/var/www/repos/apt/*/incoming/">
                Require all denied
        </Directory>
</VirtualHost>

Entfernen von unnötigen Files im Webroot /var/www

rm -rf /var/www/html

Testen der Apache Konfiguration und Neustart des Services

root@repodev:~# apache2ctl configtest
Syntax OK
root@repodev:~# /etc/init.d/apache2 reload
[ ok ] Reloading apache2 configuration (via systemctl): apache2.service.

Erstellen der distributions Datei

Die Datei beschreibt das Repository und für welche Distribution das Repo ist. Bei „SignWith“ wird die Key ID verwendet von dem eben erzeugten GPG Key.

Bei Codename wird der OS Release Name angegeben, z.B. bei Debian „buster“ oder bei Ubuntu „bionic“, das hängt von dem jeweiligen Release ab. Ist es ein generisches Repo dann kann hier auch z.B. „all“ genommen werden.

/var/www/repos/apt/debian/conf/distributions

Origin: Mein APT Repo
Label: Mein APT Repo
Codename: <osrelease>
Architectures: i386 amd64
Components: main
Description: APT repository fuer meine Pakete
SignWith: 4A2E138451DD449DF3FC2C7A28C7770DD3A8D10D

/var/www/repos/apt/debian/conf/options

verbose
basedir /var/www/repos/apt/debian
ask-passphrase

Exportieren des GnuPG Keys

Der GPG Key muss in den APT Keyring auf dem Zielsystem aufgenommen werden damit man Pakete installieren kann. Dazu exportieren wir Ihn und stellen Ihn auf dem Webserver bereit.

gpg --armor --output /var/www/repo_key.key --export 4A2E138451DD449DF3FC2C7A28C7770DD3A8D10D

Ein Paket veröffentlichen

Mit folgendem Befehl wird ein neues Paket z.B. hallo_1.0.0.deb dem Repository hinzugefügt. Wird das Kommando ausgeführt fragt der Assistent nach dem Passwort für den GPG Key.

# reprepro -b /var/www/repos/apt/debian includedeb <osrelease> /root/hallo_1.0.0.deb

/root/hallo-1.0.0.deb: component guessed as 'main'
Exporting indices...




Im Browser kann man ebenfalls prüfen ob die Veröffentlichung geklappt hat, dazu http://<repo>/repos/apt/debian/pool/main/h/hallo/ aufrufen:

Installieren von hallo aus eigenem Repository

Als erstes muss der Public Key des Repositorys zur Keychain hinzugefügt werden.

wget -O - http://10.10.10.10/repo_key.key|apt-key add -

Erstellen einer sources.list.d Datei

Die Datei wird verwendet um das Repo einzubinden.

/etc/apt/sources.list.d/mein_repo.list

deb http://10.10.10.10/repos/apt/debian <osrelease> main

Aktualisieren von APT Quellen

# apt update


Holen:1 http://10.10.10.10/repos/apt/debian all InRelease [2.331 B]
Holen:2 http://10.10.10.10/repos/apt/debian all/main amd64 Packages [1.018 B]
OK:3 http://deb.debian.org/debian buster InRelease
Holen:4 http://deb.debian.org/debian buster-updates InRelease [51,9 kB]
OK:5 http://security.debian.org/debian-security buster/updates InRelease
Es wurden 55,2 kB in 1 s geholt (86,7 kB/s).
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Alle Pakete sind aktuell.

Installieren ….

# apt install hallo

Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden NEUEN Pakete werden installiert:
  hallo
0 aktualisiert, 1 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 776 B an Archiven heruntergeladen werden.
Nach dieser Operation werden 0 B Plattenplatz zusätzlich benutzt.
Holen:1 http://10.10.10.10/repos/apt/debian all/main amd64 hallo all 1.0-0 [776 B]
Es wurden 776 B in 0 s geholt (0 B/s).
Vormals nicht ausgewähltes Paket hallo wird gewählt.
(Lese Datenbank ... 35202 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von .../archives/hallo_1.0-0_all.deb ...
Entpacken von hallo (1.0-0) ...
hallo (1.0-0) wird eingerichtet ...

Viel Spaß 😉

Eigene Debian/Ubuntu Pakete bauen

Dies ist eine Kurzanleitung wie man selber einfache Debian/Ubuntu Pakete bauen kann um z.B. eigene Skripte etc. zu verteilen.

Als erstes wird ein Projekt Ordner erstellt. z.B. hallo-1.0.0

mkdir ~/hallo-1.0.0

Die Struktur innerhalb des Ordners wird so auf das System kopiert, legt Ihr z.B. eine „hallo“ Datei in ~/hallo-1.0.0/usr/bin ab wird sie im Zielsystem in /usr/bin installiert.

mkdir -p ~/hallo-1.0.0/usr/bin
mkdir -p ~/hallo-1.0.0/DEBIAN

Im Ordner DEBIAN liegen die Dateien die für das bauen des Pakets benötigt werden.

nano ~/hallo-1.0.0/usr/bin/hallo

Hier ein kleines Testscript das wir verteilen wollen:

#!/bin/sh
echo "Hallo :-)"

Rechte die für Dateien gesetzt sind werden übernommen.

chmod +x ~/hallo-1.0.0/usr/bin/hallo

Jetzt noch die „control“ Datei im Ordner DEBIAN erstellen. Die Datei beinhaltet den Namen, die Beschreibung und Abhänigkeiten.

Package: hallo
Version: 1.0-0
Section: base
Priority: optional
Architecture: all
Maintainer: "Der Packetbauer <example@example.org>"
Description: Ein Skript das Hallo sagt

Das bauen des Pakets wird mit dpkg-deb gemacht.

dpkg-deb --build ~/hallo-1.0.0/

Ist die Erstellung des Pakets erfolgreich kommt folgende Meldung:

mt@dev:~# dpkg-deb --build hallo-1.0.0/
dpkg-deb: Paket »hallo« wird in »hallo-1.0.0.deb« gebaut.

Im Verzeichnis sollte jetzt eine hallo-1.0.0.deb vorhanden sein.

Kleine Kontrolle:

mt@dev:~# dpkg -I hallo-1.0.0.deb
 neues Debian-Paket, Version 2.0.
 Größe 776 Byte: control-Archiv= 340 Byte.
     172 Byte,     7 Zeilen      control
 Package: hallo
 Version: 1.0-0
 Section: base
 Priority: optional
 Architecture: all
 Maintainer: "Der Packetbauer <example@example.org>"
 Description: Ein Skript das Hallo sagt

Jetzt kann man versuchen das Paket zu installieren:

mt@dev:~# dpkg -i hallo-1.0.0.deb
Vormals nicht ausgewähltes Paket hallo wird gewählt.
(Lese Datenbank ... 34468 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von hallo-1.0.0.deb ...
Entpacken von hallo (1.0-0) ...
hallo (1.0-0) wird eingerichtet ...

Die Installation war erfolgreich, in /usr/bin ist jetzt die Datei hallo und ist ausführbar.

mt@dev:~# ls -la /usr/bin/hallo
-rwxr-xr-x 1 root root 27 Okt 11 16:52 /usr/bin/hallo

mt@dev:~# hallo
Hallo :-)

Beim Entfernen des Pakets werden die Dateien entsprechend entfernt.

mt@dev:~# apt remove hallo
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden Pakete werden ENTFERNT:
  hallo
0 aktualisiert, 0 neu installiert, 1 zu entfernen und 0 nicht aktualisiert.
Nach dieser Operation werden 0 B Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n] j
(Lese Datenbank ... 34469 Dateien und Verzeichnisse sind derzeit installiert.)
Entfernen von hallo (1.0-0) ...

Natürlich ist noch wesentlich mehr möglich und das ist ein einfaches Beispiel. Zum Nachlesen eignen sich folgende Seiten:

https://wiki.debian.org/Packaging/Intro?action=show&redirect=IntroDebianPackaging

https://packaging.ubuntu.com/html/

borgbackup und borgmatic mit pip installieren

borgmatic ist erst in Ubuntu 20.04 in den offiziellen Paketquellen und wenn man das aktuellste haben möchte empfiehlt sich die Installation über pip.

Benötigte Pakete

apt install python3-setuptools python3-dev python3-pip libssl-dev libacl1-dev build-essential

Anschließend mit pip3 borgmatic und borgbackup installieren:

pip3 install borgbackup borgmatic

Ich hatte bei mir das Problem das borgmatic und borg in den cronjobs nicht funktioniert haben. borgmatic/borgbackup werden in /usr/local/bin installiert das per Default dem Cron nicht bekannt sind. In der Crontab folgende Ergänzung durchführen (Achtung diese Änderung ist global und gilt für alle Cronjobs):

# m h  dom mon dow   command

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
LD_LIBRARY_PATH=/usr/local/lib

24 23 * * * borgmatic -v 1 2>&1 | mail -s "Backup Report" example@example.com

SMTP Mailserver testen mit swaks

swaks – Swiss Army Knife SMTP, the all-purpose smtp transaction tester

Unter Ubuntu/Debian lässt sich swaks einfach installieren:

apt install swaks

Hier ein paar einfache Testcases um verschiedene Einlieferungsverfahren zu testen:

SMTP ohne Authentifizierung testen

swaks --server <server_to_test> --from absender@example.com --to empfaenger@example.net

SMTP mit Authentifizierung (PLAIN)

swaks --server <server_to_test> --from absender@example.com --to empfaenger@example.net --auth --auth-user absender@example.com --auth-password foobar

SMTP mit Authentifizierung (SMTPS auf Port 465)

swaks --server <server_to_test> --from absender@example.com --to empfaenger@example.net --auth --auth-user absender@example.com --auth-password foobar --port 465 -tlsc

SMTP mit Authentifizierung (SUBMISSION auf Port 587)

swaks --server <server_to_test> --from absender@example.com --to empfaenger@example.net --auth --auth-user absender@example.com --auth-password foobar --port 587 -tls

GITEA Install script for Ubuntu 20.04 LTS

Get source code: https://github.com/lanbugs/gitea_installer

This script pulls the newest version of gitea and install all requirements.

The following will be installed:

  • GIT
  • Nginx
  • MariaDB
  • Letencrypt (optional)
  • UFW (optional)

Use it 😉

This installer script is for Ubuntu 20.04 LTS, other versions may work but not tested.

Available flags:

-f FQDN - Systemname of GITEA system
-e EMAIL - E-Mail for letsencrypt
-i IP - IPv4 address of this system
-p PASSWORD - Used for GITEA DB
-r SQLROOT - MySQL ROOT password
-l LETSENCRYPT - Use letsencrypt
-u UFW - Use UFW

Install

wget https://github.com/lanbugs/gitea_installer/raw/main/gitea_installer.sh
chmod +x gitea_installer.sh

./gitea_installer.sh -f git.example.com -e admin@example.com -i 10.10.10.10 -p securepassword -r sqlrootpw -l -u

Finished screen:

--------------------------------------------------------------------------------------
 GITEA 1.12.5 installed on system git.example.com
--------------------------------------------------------------------------------------
 Mysql database        : giteadb
 Mysql user            : gitea
 Mysql password        : securepassword
 Mysql character set   : utf8mb4
--------------------------------------------------------------------------------------
 Mysql root user       : root
 Mysql root password   : sqlrootpw
--------------------------------------------------------------------------------------
 System is accessable via https://git.example.com
--------------------------------------------------------------------------------------
 >>> You must finish the initial setup <<<
--------------------------------------------------------------------------------------
 Site Title            : Enter your organization name.
 Repository Root Path  : Leave the default /home/git/gitea-repositories.
 Git LFS Root Path     : Leave the default /var/lib/gitea/data/lfs.
 Run As Username       : git
 SSH Server Domain     : Use git.example.com
 SSH Port              : 22, change it if SSH is listening on other Port
 Gitea HTTP Listen Port: 3000
 Gitea Base URL        : Use https://git.example.com/
 Log Path              : Leave the default /var/lib/gitea/log
--------------------------------------------------------------------------------------
 Following firewall rules applied:
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 80/tcp                     ALLOW IN    Anywhere
[ 3] 443/tcp                    ALLOW IN    Anywhere
[ 4] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 5] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 6] 443/tcp (v6)               ALLOW IN    Anywhere (v6)

--------------------------------------------------------------------------------------

When the script finished you must complete the installation of gitea in the web UI.

SQL settings

You should choose utf8mb4 encoding.

SQL

Common settings

Common

Additional settings

Common

Check_MK: Export hosts to SecureCRT Session Manager

This script exports over an Check_MK View hosts and imports them in SecureCRT Session Manager.

Get source code: https://github.com/lanbugs/check_mk_to_securecrt_export

The bundled python of SecureCRT not support urllib / urllib2 (see https://forums.vandyke.com/showthread.php?t=13127). I don`t want to modify the bundled python version of SecureCRT, so i have decided to put the code in an extra binary. The advantage is that you can deploy the binary to every client without install python on every client. You can encrypt the source code (that is NOT 100% safe) so the credentials stored in the helper are not visable.

Sessions will be imported in the Folder _Check_MK_Imports. Existing Sessions will be overwirtten in the folder. Note: If a host is removed in Check_MK it will not be removed in SecureCRT. This is a feature improvement, for the moment simple delete the _Check_MK_Imports folder and sync it again.

Requirements

  • Installed python 3.8 with pyinstaller and tinyaes installed.
  • Automation User on Check_MK instance
  • Extra view in Check_MK with the hosts to export to SecureCRT

Install python requirements on dev machine

pip install pyinstaller[encryption] tinyaes

Create automation user in Check_MK

Check_MK Create User
  • Create user as normal monitoring user with automation secret

Create view in Check_MK

Go to edit views

Check_MK Edit Views

Clone allhosts view, click on the copy symbol.

Check_MK Allhosts view

Modify name of the view, hide the view from sidebar and make it available for all.

Check_MK Allhosts view

Modify the view that only 3 colums are present. Remove sorting and grouping, it is not required.

Check_MK Allhosts view

You can apply custom filtering for the view if you want e.g. filter on a special hostgroup.

Test the view

You can try to access the view with your securecrt automation user in every browser, the response should be json content.

https://<check_mk host>/<check_mk instance>/check_mk/view.py?view_name=<view name>&output_format=json&_username=<securecrt automation user>&_secret=<password>

Example resonse

[
 [
  "host", 
  "host_ipv4_address", 
  "wato_folder_abs"
 ], 
 [
  "router", 
  "2.2.2.2", 
  "Main directory / network"
 ], 
 [
  "lalala", 
  "1.2.3.4", 
  "Main directory / network"
 ], 
 [
  "lololo", 
  "2.3.4.5", 
  "Main directory / network / test"
 ], 
 [
  "linux", 
  "1.2.3.6", 
  "Main directory / network"
 ]
]

Modify sourcecode of the helper

Add the correct URL and credentials in the file.

########################################################################################################################
# Settings

# User to interact with check_mk, user need automation secret!
user = "securecrt"

# Automation secret
secret = "OYPCCOJCCMDPQSCLYFOI"

# URL to check_mk instance with ? at the end
url = "https://checkmk.company.local/core/check_mk/view.py?"

# View which shows prefiltered the hosts you want to create sessions in check_mk
# Only tree columns are allowed in the view:
# hostname,ip,wato_folder_abs
# See details on https://github.com/lanbugs/check_mk_to_securecrt_export or https://lanbugs.de
# You can test it manually if you browse the url in an browser.
# e.g. https://checkmk.company.corp/central_mon/check_mk/view.py?view_name=allhosts_securecrt&_username=securecrt&_secret=OYPCCOJCCMDPQSCLYFOI&output_format=json
# You should see an json output with the 3 columns.
view_name = "allhosts_securecrt"

Build the helper binary

Without encryption

c:\Python38\python.exe -OO -m PyInstaller -D check_mk_to_securecrt_export_helper.py

With encryption

Define an 16 char encryption key like 0123456789ABCDEF (not safe!)

c:\Python38\python.exe -OO -m PyInstaller --key=0123456789ABCDEF -D check_mk_to_securecrt_export_helper.py

Deploy files

Create a folder like c:\securecrt_scripts

  1. Copy the dist folder to c:\securecrt_scripts
  2. Copy the check_mk_to_securecrt_export.py to c:\securecrt_scripts

Use it!

Run it once …

Goto Script > Run …

SecureCRT RUN

Select check_mk_to_securecrt_export.py

SecureCRT RUN

Run it 🙂

Add button to button bar

Enable the button bar.

View > Button Bar

SecureCRT RUN

On the bottom of SecureCRT you can see now the button bar. Right click on the bar and click „New Button…“

SecureCRT Button Bar

Select in the dropdown Function „Run Script“

SecureCRT Button Bar Add

Choose in „Run Script“ the check_mk_to_securecrt_export.py, in Arguments you can add your username, every session will be created with thhis username.

SecureCRT Button Bar Config

Finished 🙂

SecureCRT Button Bar Button

Finally

SecureCRT Session Manager

Have fun 🙂

Known bugs

  • Sometimes you must sync twice that all sessions are created, this is under investigation.

Backup mit Borgmatic und Borg zu eigenem Backup Server via SSH

Borgmatic ist ein Tool um borgbackup zu steuern. Hier eine kleine Anleitung.

Backup Server vorbereiten

Erstellen eines Backup Users

Unter diesem User werden die Backup Repos zur Verfügung gestellt.

adduser backupmaster

Installieren von Borg

Bei Ubuntu/Debian befindet sich borgbackup im Standard Repo.

apt install borgbackup

Repo anlegen

Für jedes Backup habe ich ein eigenes Repo, dies wird auf dem Backup Server initial mit borg init angelegt.

borg init -e repokey-blake2 backuprepo_srv1

SSH Key generieren für Borgbackup

Für jedes Repo wird ein individueller SSH Key erzeugt, dieser wird verwendet um sich per Public/Private Key gegen den Backup Server zu authentifizieren.

ssh-keygen -t ed25519 -C borgbackup

SSH Key für Repo berechtigen in authorized_keys

Der Public Key wird in die authorized_keys eingetragen mit dem command=““ Block. Wenn sich jemand mit dem Private Key anmeldet wird das angegebene Kommando ausgeführt. In diesem Fall wird borg serve gestartet, es wird das Repo bereitgestellt.

su - backupmaster
mkdir .ssh
touch .ssh/authorized_keys

Inhalt authorized_keys

Bei dem borg serve Kommando wird der Pfad des Borg Repos angegeben. append-only erlaubt ausschließlich das hinzufügen zum Repo, ein gesamtes Löschen ist nicht möglich. Siehe https://borgbackup.readthedocs.io/en/stable/usage/notes.html#append-only-mode

command="borg serve --restrict-to-path /home/backupmaster/backuprepo_srv1 --append-only" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHEdIlaEyXfB1FlzRioCOQboN+ZWRTG2nawkDuRb4oUm borgbackup

Backup auf einer Maschine einrichten

Installieren der nötigen Pakete

Die benötigten Pakete sind alle im Standard Repo bei Ubuntu/Debian dabei.

apt install borgmatic borgbackup mailutils

Conf. Verzeichnis erstellen

Für Borgmatic muss ein Konfigurationsverzeichnis erstellt werden. In diesem Verzeichnis wird eine YAML Datei abgelegt mit den Backup Einstellungen.

mkdir -p /root/.config/borgmatic

config.yaml

In source_directories werden alle zu sichernden Ordner als Liste angegeben. Bitte auf die korrekte Formatierung der YAML Datei achten. Unter repositories muss der Backupserver incl. Repo Namen angegeben werden. Unter storage kann man einen Encryption Key angeben für das Backup falls der Backupserver z.B. im Internet steht. Bei ssh_command wird der Private Key des oben erzeugten SSH Keys angegeben, diesen nach /root/.config/borgmatic/id_ed25519 kopieren. Bei retention kann die Aufbewahrungszeit der Backups festgelegt werden. Wer noch Scripte vor oder nach dem Backup starten möchte kann das unter „hooks“ machen. In meinem Fall exportiere ich die Liste der installierten Pakete in eine Datei.

location:
    source_directories:
        - /etc
        - /srv
        - /opt
        - /var/lib
        - /var/mail
        - /var/www
        - /root
        - /home

    one_file_system: true

    repositories:
        - backupmaster@backupserver.example.org:backuprepo_srv1

    exclude_caches: true

storage:
    compression: auto,zstd
    encryption_passphrase: CHANGE ME
    archive_name_format: '{hostname}-{now}'
    ssh_command: ssh -i /root/.config/borgmatic/id_ed25519 -p 22

retention:
    keep_daily: 3
    keep_weekly: 7
    keep_monthly: 12
    keep_yearly: 2
    prefix: '{hostname}-'

consistency:
    checks:
        - repository
        - archives

    check_last: 3
    prefix: '{hostname}-'

hooks:
    before_backup:
        - dpkg-query -f '${binary:Package}\n' -W > /root/packages_list.txt

Cronjob für regelm. Backups

Damit das Backup auch regelmäig läuft empfiehlt es sich einen Cronjob einzurichten. In diesem Beispiel jeden Tag um 23:15, das Ergebnis schicke ich mir als E-Mail.

contab -e


15 23 * * * borgmatic -v 1 2>&1 | mail -s "Backup Report" admin@example.org

Viel Spaß 🙂

Schnelle rsync Alternative für Filetransfer

Auf der Suche nach einer alternative zu RSYNC für einen einmaligen Filetransfer zwischen Linux Systemen bin ich auf folgenden Artikel gestoßen. Die Methode eignet sich besonders wenn das Zielsystem leer ist und keine Files verglichen werden müssen.

https://www.schirmacher.de/display/Linux/Fastest+rsync+command

root@sourcesystem:/home/sourcefolder# tar cf - * | mbuffer -m 1024M | ssh 10.23.49.1 '(cd /home/targetfolder; tar xf -)'
in @ 120.1 MB/s, out @ 84.3 MB/s, 123.3 GB total, buffer  68% full

Debian/Ubuntu Liste installierter Pakete exportieren und diese Liste auf einem neuen System installieren

Mit diesem Befehl lassen sich die installieren Pakete in eine Liste exportieren.

sudo dpkg-query -f '${binary:Package}\n' -W > packages_list.txt

Mit xargs lässt sich apt install z.B. auf einem neuen System füttern.

sudo xargs -a packages_list.txt apt install

ARISTA bash event-handler in different VRF context

We are using an event-handler with on-startup-config write to push the configuration to our langley service which push the config in the central GIT repository.

To execute an bash command in an different vrf context use „ip netns exec ns-<VRF>“ before the command. See the example:

event-handler ARCHIVE_LANGLEY
   trigger on-startup-config
   action bash sudo ip netns exec ns-MANAGEMENT curl https://10.1.1.1/langley/put/$(hostname)/1 --upload-file /mnt/flash/startup-config

Gitolite mit ansible-playbook post-update hook zum Verteilen von Konfigurationen etc.

Gitolite ist ein einfaches Script um einen GIT Repo Server aufzusetzen. Zusammen mit Ansible nutze ich es um z.B. Zonenfiles auf Bind9 Server zu verteilen. Das werde ich in diesem Beispiel zeigen. Ansible und Gitolite laufen auf dem gleichen Server.

Installation Gitolite

apt install gitolite3

Während der Installation wird nach dem Public SSH Key des Admins gefragt. Dieser Key ist später berechtigt das gitolite-admin Repo welches die Konfiguration der Repos beinhaltet zu benutzen.

Klonen von gitolite-admin und neues Repo dns anlegen

git clone gitolite3@10.1.1.1:gitolite-admin

gitolite-admin/conf/gitolite.conf

repo gitolite-admin
    RW+    =     admin

repo testing
    RW+    =     @all

repo dns
    option hook.post-update = dns-deploy
    RW+    =     admin

Hier wurde bereits ein post-update Hook definiert. Es müssen aber noch weitere Einstellungen angepasst werden damit dieser funktioniert.

Neue User legt man an in dem Verzeichnis gitolite-admin/keydir <username>.pub mit dem entsprechenden SSH Key anlegt. Die Usernamen können dann in der gitolite.conf verwendet werden. Ausführliche Doku zu gitolite -> http://gitolite.com/gitolite/index.html

Installation ansible 

apt install software-properties-common
apt-add-repository ppa:ansible/ansible
apt update
apt install ansible

Konfiguration ansible

Ich verwende auf den Zielsystemen eigene User um Dinge per Ansible zu deployen. Im Beispiel heist der „vader“.

/etc/ansible/hosts

[dns-servers]
ns1.example.com
ns2.example.com

/etc/ansible/group_vars/dns-servers

---
ansible_ssh_private_key_file: /etc/ansible/sshkey/id_rsa
ansible_ssh_user: vader
ansible_sudo_pass: lukeiamyourfather

SSH Key für vader erzeugen

mkdir -p /etc/ansible/sshkey
ssh-keygen -t rsa -f /etC/ansible/sshkey/id_rsa

Den SSH Key ohne Passwort ablegen.

Anpassen der Verzeichnis Rechte:

chmod 600 /etc/ansible/sshkey
chmod 600 /etc/ansible/sshkey/id_rsa
chmod 644 /etc/ansible/sshkey/id_rsa.pub
chown root:root -R /etc/ansible/sshkey

Auf den Zielsystemen muss jeweils der User vader mit dem Passwort eingerichtet werden und der Public Key des SSH Keys muss als authorized_key hinterlegt werden. Der User muss in der sudo Gruppe sein.

gitolite hook aktivieren

/var/lib/gitolite3/.gitolite.rc

Bei folgenden Zeilen Kommentierung entfernen.

LOCAL_CODE                =>  "$ENV{HOME}/local",

# allow repo-specific hooks to be added
            'repo-specific-hooks',

Verzeichnis anlegen für Hooks

mkdir -p /var/lib/gitolite3/local/hooks/repo-specific

dns-deploy hook anlegen

/var/lib/gitolite3/local/hooks/repo-specific/dns-deploy

sudo /opt/ansible/dns.sh

Owner und Rechte ändern

chown gitolite3:gitolite3 dns-deploy
chmod +x dns-deploy

Das Hook Script liegt in /opt/ansible:

mkdir -p /opt/ansible

/opt/ansible/dns.sh

#!/bin/bash


REPO=/opt/ansible/dns

if [ ! -d $REPO ]
then
   ssh-agent bash -c 'ssh-add /etc/ansible/sshkey/id_rsa; git clone gitolite3@10.1.1.1:dns'
else
    cd $REPO
    ssh-agent bash -c 'ssh-add /etc/ansible/sshkey/id_rsa; git pull'
fi


cd $REPO
ansible-playbook dns.yaml

# End

Das Hook Script klont das Repo dns nach /opt/ansible/dns und führt das ansible playbook aus dem Repo aus.

Anpassen der Rechte

chown root:root /opt/ansible/dns.sh
chmod 700 /opt/ansible/dns.sh

Den gitolite3 User berechtigen das Script ohne Passwort per Sudo auszuführen

/etc/sudoers

gitolite3 ALL = (root) NOPASSWD: /opt/ansible/dns.sh

Das Repo dns

git clone gitolite3@10.1.1.1:dns
cd dns

Anlegen des Playbooks

dns.yaml

---

- hosts: dns-servers

  tasks:

  - name: create or update named.conf.local
    become: true
    register: named
    template:
      src: /opt/ansible/dns/conf/named.conf.local.j2
      dest: /etc/bind/named.conf.local
    vars:
      zones:
      - lanbugs.de

  - name: create or update zone files
    become: true
    register: zones
    template: src={{ item }} dest=/etc/bind/{{ item | basename | regex_replace('\.j2','') }} owner=root group=root mode=0644
    with_fileglob:
      - /opt/ansible/dns/conf/db.*.j2

  - name: restart bind
    become: true
    service:
      name: bind9
      state: restarted
    when: zones.changed or named.changed

DNS Files

mkdir conf

named.conf.local.j2

{% for zone in zones %}
zone "{{ zone }}" {
    type master;
    file "/etc/bind/db.{{ zone}}";
};
{% endfor %}

db.lanbugs.de.j2

; BIND db file for lanbugs.de

$TTL 86400

{% include "zone_header.j2" %}

@               1800    IN      TXT     "v=spf1 a mx ptr ~all"

test            1800    IN      A       1.2.3.4


$ORIGIN lanbugs.de.

zone_header.j2

@       IN      SOA     ns1.example.com.      admin.example.com. (
                        2018111101      ; serial number YYMMDDNN
                        28800           ; Refresh
                        7200            ; Retry
                        864000          ; Expire
                        86400           ; Min TTL
                        )

@       1800    IN      NS      ns1.example.com.
@       1800    IN      NS      ns2.example.com.

@       1800    IN      MX      10 mail1.example.com.
@       1800    IN      MX      20 mail2.example.com.

Files zu dns Repo hinzufügen und pushen

git add -A
git commit -m "initial commit"

git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Identity added: /etc/ansible/sshkey/id_rsa (Ansible vader)
remote: From 10.1.1.1:dns
remote:    63bf7b0..63d2dc5  master     -> origin/master
remote: Updating 63bf7b0..63d2dc5
remote: Fast-forward
remote:  conf/db.lanbugs.de.j2 | 1 -
remote:  1 file changed, 1 deletion(-)
remote: 
remote: PLAY [dns-servers] *************************************************************
remote: 
remote: TASK [Gathering Facts] *********************************************************
remote: ok: [ns1.example.com]
remote: ok: [ns2.example.com]
remote: 
remote: TASK [create or update named.conf.local] ***************************************
remote: ok: [ns1.example.com]
remote: ok: [ns2.example.com]
remote: 
remote: TASK [create or update zone files] *********************************************
remote: changed: [ns1.example.com] => (item=/opt/ansible/dns/conf/db.lanbugs.de.j2)
remote: changed: [ns2.example.comc] => (item=/opt/ansible/dns/conf/db.lanbugs.de.j2)
remote: 
remote: TASK [restart bind] ************************************************************
remote: changed: [ns1.example.com]
remote: changed: [ns2.example.com]
remote: 
remote: PLAY RECAP *********************************************************************
remote: ns1.example.com        : ok=4    changed=2    unreachable=0    failed=0   
remote: ns2.example.com        : ok=4    changed=2    unreachable=0    failed=0   
remote: 
To 10.1.1.1:/dns
   63bf7b0..63d2dc5  master -> master

Have fun 🙂

 

 

 

 

 

Flask, uWSGI und Nginx auf Ubuntu 16.04

– Kurze Zusammenfassung, ausführlich siehe Quelle am Ende des Artikels –

Python Virtual Environment aufsetzen

pip install virtualenv

virtualenv projekt

source projekt/bin/activate

pip install uwsgi flask


Mini Flask Applikation projekt.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello world!"

WSGI Startfile wsgi.py

from projekt import app

if __name__ == "__main__":
    app.run()

Virtual Environment verlassen

deactivate

uWSGI Configfile erstellen

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = /opt/projekt/projekt.sock
chmod-socket = 660
vacuum = true

die-on-term = true

systemd File erstellen  /etc/systemd/system/projekt.service

[Unit]
Description=uWSGI instance to serve projekt
After=network.target

[Service]
User=projekt
Group=www-data
WorkingDirectory=/opt/projekt
Environment="PATH=/opt/projekt/bin"
ExecStart=/opt/projekt/bin/uwsgi --ini projekt.ini

[Install]
WantedBy=multi-user.target

uWSGI Projekt Service starten

sudo systemctl start projekt
sudo systemctl enable projekt

NGINX Config erstellen – /etc/nginx/sites-available/projekt

server {
    listen 80;
    server_name 10.10.10.10;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/opt/projekt/projekt.sock;
    }
}

NGINX Config aktivieren

ln -s /etc/nginx/sites-available/projekt /etc/nginx/sites-enabled
systemctl restart nginx

Verifizieren NGINX und uWSGI

dev@dev1:~$ ps aux | grep projekt
projekt 17175  0.0  2.1  71216 21812 ?        Ss   19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini
projekt 17178  0.0  1.7  71216 17316 ?        S    19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini
projekt 17179  0.0  1.7  71216 17316 ?        S    19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini
projekt 17180  0.0  1.6  71216 16504 ?        S    19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini
projekt 17181  0.0  1.7  71472 17848 ?        S    19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini
projekt 17182  0.0  1.6  71216 16504 ?        S    19:26   0:00 /opt/projekt/bin/uwsgi --ini projekt.ini

dev@dev1:~$ tail -f /var/log/syslog
Jun 19 19:44:42 dev1 uwsgi[17175]: [pid: 17178|app: 0|req: 1/3] 10.10.10.1 () {46 vars in 834 bytes} [Wed Jun 19 19:44:42 2018] GET / => generated 40 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0)
Jun 19 19:44:43 dev1 uwsgi[17175]: [pid: 17179|app: 0|req: 1/4] 10.10.10.1 () {46 vars in 834 bytes} [Wed Jun 19 19:44:43 2018] GET / => generated 40 bytes in 4 msecs (HTTP/1.1 200) 2 headers in 79 bytes (2 switches on core 0)
Jun 19 19:44:44 dev1 uwsgi[17175]: [pid: 17179|app: 0|req: 2/5] 10.10.10.1 () {46 vars in 834 bytes} [Wed Jun 19 19:44:44 2018] GET / => generated 40 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 79 bytes (2 switches on core 0)
Jun 19 19:44:45 dev1 uwsgi[17175]: [pid: 17179|app: 0|req: 3/6] 10.10.10.1 () {46 vars in 834 bytes} [Wed Jun 19 19:44:45 2018] GET / => generated 40 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 79 bytes (2 switches on core 0)

Quelle / ausführlicher Artikel: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04

 

MongoDB Authentication aktivieren

Per Default ist bei einer MongoDB Instanz keine Authentication aktiviert. Hier der kurze Weg.

Admin Account anlegen

devusr@testsystem:~# mongo
MongoDB shell version v3.6.5
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.5
> use admin
switched to db admin
> db.createUser({user: "admin", pwd: "geheimes_passwort", roles: [{ role: "root", db: "admin" }]})
Successfully added user: {
        "user" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
> quit()

Authentication in mongod.conf aktivieren (Ubuntu: /etc/mongod.conf)

...
# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1

security:
  authorization: enabled
...

Mongod neustarten

service mongod restart

Erster Test: User anlegen für Test DB

> use test
switched to db test
> db.createUser({user: "devuser", pwd: "secure_pwd", roles: [{ role: "readWrite", db: "test" }]})
2018-06-18T08:05:53.448+0200 E QUERY    [thread1] Error: couldn't add user: not authorized on test to execute command { createUser: "devuser", pwd: "xxx", roles: [ { role: "readWrite", db: "test" } ], digestPassword: false, writeConcern: { w: "majority", wtimeout: 600000.0 }, $db: "test" } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.createUser@src/mongo/shell/db.js:1437:15
@(shell):1:1
>

Sieht gut aus, es geht nicht 😉

Anmelden und User für Test DB anlegen

use admin
db.auth("admin","geheimes_passwort")
1
use test
> db.createUser({user: "devuser", pwd: "secure_pwd", roles: [{ role: "readWrite", db: "test" }]})
Successfully added user: {
        "user" : "devuser",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "test"
                }
        ]
}
>

Authentifizierung mit pymongo in Python Code

>>> from pymongo import MongoClient
>>> uri = "mongodb://devuser:secure_pwd@localhost/test?authSource=test"                                     
>>> client = MongoClient(uri)
>>> db = client.test
>>> collection = db.foo
>>> collection.insert_one({"foo":"bar"})
<pymongo.results.InsertOneResult object at 0x7fa764f2a998>
>>> collection.find_one()
{u'_id': ObjectId('5b274db939d9c0683b47c0e2'), u'foo': u'bar'}
>>>

Quellen / Weitere Informationen:

Enable Authentication – https://docs.mongodb.com/manual/tutorial/enable-authentication/

Built-In Roles – https://docs.mongodb.com/manual/core/security-built-in-roles/

pymongo authentication – http://api.mongodb.com/python/current/examples/authentication.html

MongoDB und Python

Ein paar Notizen zu Python und MongoDB 🙂 MongoDB ist eine NoSQL Datenbank, weitere Infos -> Wikipedia 🙂

Aktuelle MongoDB Version installieren (auf Ubuntu 16.04)

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
apt install apt-transport-https
apt update
apt-get install -y mongodb-org

siehe auch: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

Python Erweiterung pymongo für MongoDB installieren mit pip

python -m pip install pymongo

siehe auch: https://api.mongodb.com/python/current/

Verbindung zur MongoDB

from pymongo import MongoClient

client = MongoClient('localhost', 27017)

Connect zur Datenbank test

db = client.test

Collection myCollection in Datenbank test verbinden 

coll = db.myCollection

Einen Datensatz anlegen in einer Collection

post = {"author":"Fritz Fuchs", "book":"Hasenjagd"}
>>> coll.insert_one(post)
<pymongo.results.InsertOneResult object at 0x7fd0136ce3f8>

Mehrere Datensätze in einer Collection anlegen

>>> posts = [{"author":"Fritz Fuchs", "book":"Hasenjagd 5"}, {"author":"Fritz Fuchs", "book":"Hasenjagd 6"}, {"author":"Fritz Fuchs", "book":"Hasenjagd 7"}]
>>> result = coll.insert_many(posts)
>>> result.inserted_ids
[ObjectId('5b259b2c39d9c04f7b43af01'), ObjectId('5b259b2c39d9c04f7b43af02'), ObjectId('5b259b2c39d9c04f7b43af03')]

Datensatz suchen

>>> coll.find_one({"author":"Fritz Fuchs"}) 
{u'_id': ObjectId('5b25998139d9c04f7b43aefe'), u'book': u'Hasenjagd', u'author': u'Fritz Fuchs'}

Datensatz mit Regex suchen

>>> coll.find_one({"author":{"$regex": "^Fritz.*"}})     
{u'_id': ObjectId('5b25998139d9c04f7b43aefe'), u'book': u'Hasenjagd', u'author': u'Fritz Fuchs'}

Datensatz mit ObjectId abrufen

>>> from bson.objectid import ObjectId
>>> coll.find_one({"_id":ObjectId("5b25998139d9c04f7b43aefe")})
{u'_id': ObjectId('5b25998139d9c04f7b43aefe'), u'book': u'Hasenjagd', u'author': u'Fritz Fuchs'}

Mehrere Datensätze abrufen z.B. mit Regex

>>> for post in coll.find({"author":{"$regex": "^Fritz.*"}}):
...     print post
... 
{u'_id': ObjectId('5b25998139d9c04f7b43aefe'), u'book': u'Hasenjagd', u'author': u'Fritz Fuchs'}
{u'_id': ObjectId('5b259a8939d9c04f7b43aeff'), u'book': u'Hasenjagd 2', u'author': u'Fritz Fuchs'}
{u'_id': ObjectId('5b259a9039d9c04f7b43af00'), u'book': u'Hasenjagd 3', u'author': u'Fritz Fuchs'}

Index erzeugen für Collection z.B. Username ist Unique

>>> import pymongo
>>> db.users.create_index([('user_id', pymongo.ASCENDING)], unique=True)
u'user_id_1'
>>> new_users = [{'user_id':'max'},{'user_id':'fritz'}]     
>>> db.users.insert_many(new_users)
<pymongo.results.InsertManyResult object at 0x7fd0136cee18>                   
>>> new_user = {'user_id':'max'}      
>>> db.users.insert_one(new_user) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 683, in insert_one
    session=session),
  File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 599, in _insert
    bypass_doc_val, session)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 580, in _insert_one
    _check_write_command_response(result)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 207, in _check_write_command_response
    _raise_last_write_error(write_errors)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 188, in _raise_last_write_error
    raise DuplicateKeyError(error.get("errmsg"), 11000, error)
pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: test.users index: user_id_1 dup key: { : "max" }

ObjectId als String

>>> new_user = {'user_id':'maxx'} 
>>> result = db.users.insert_one(new_user) 
>>> result
<pymongo.results.InsertOneResult object at 0x7fd0122410e0>
>>> result.inserted_id
ObjectId('5b259ead39d9c04f7b43af07')
>>> str(result.inserted_id)   
'5b259ead39d9c04f7b43af07'

String ObjectId zu ObjectId Object wandeln und für Suche verwenden

>>> from bson.objectid import ObjectId
>>> str_obj = '5b259ead39d9c04f7b43af07'
>>> users.find_one({'_id':ObjectId(str_obj)})
{u'_id': ObjectId('5b259ead39d9c04f7b43af07'), u'user_id': u'maxx'}

Datensatz löschen

>>> users.delete_one({'_id':ObjectId(str_obj)})    
<pymongo.results.DeleteResult object at 0x7fd0136cee18>

Datensatz aktualisieren

>>> new_user = {'user_id':'maxx', 'name':'Hans Wurst'}
>>> users.insert_one(new_user)
>>> change = {'name': 'Fritz Fritz'}
>>> users.update_one({'_id':ObjectId('5b25a14f39d9c04f7b43af08')}, {'$set':change} )
<pymongo.results.UpdateResult object at 0x7fd0136ced40>
>>> users.find_one({'_id':ObjectId('5b25a14f39d9c04f7b43af08')})                                                            
{u'_id': ObjectId('5b25a14f39d9c04f7b43af08'), u'user_id': u'maxx', u'name': u'Fritz Fritz'}

Bereich bei Suche

>>> client = MongoClient()         
>>> db = client.huu
>>> c = db.test
>>> posts = [{"author":"Fritz Fuchs", "book":"Hasenjagd 5", "boo":1}, {"author":"Fritz Fuchs", "book":"Hasenjagd 6", "boo":5}, {"author":"Fritz Fuchs", "book":"Hasenjagd 7", "boo":10}] 
>>> c.insert_many(posts)

>>> for post in c.find({"boo": {"$lt": 6}}).sort("author"):
...     print post
... 
{u'author': u'Fritz Fuchs', u'_id': ObjectId('5b25bb9539d9c05186997b54'), u'book': u'Hasenjagd 5', u'boo': 1}
{u'author': u'Fritz Fuchs', u'_id': ObjectId('5b25bb9539d9c05186997b55'), u'book': u'Hasenjagd 6', u'boo': 5}

>>> for post in c.find({"boo": {"$gt": 6}}).sort("author"): 
...     print post
... 
{u'author': u'Fritz Fuchs', u'_id': ObjectId('5b25bb9539d9c05186997b56'), u'book': u'Hasenjagd 7', u'boo': 10}

>>> for post in c.find({"boo": {"$lt": 6, "$gt": 3}}).sort("author"): 
...     print post
... 
{u'author': u'Fritz Fuchs', u'_id': ObjectId('5b25bb9539d9c05186997b55'), u'book': u'Hasenjagd 6', u'boo': 5}

 

Quelle / weitere Beispiele: http://api.mongodb.com/python/current/tutorial.html

 

Kein Platz mehr auf der /boot Partition in Ubuntu / Debian

Per Default ist die Boot Partition ca. 500M groß, da sich hier durch die Updates gerne alte Kernel ansammeln ist es ratsam zwischendurch aufzuräumen.

Beispiel einer abgebrochenen Installation, Meldung ist „No space left on device“

linux-image-4.4.0-116-generic (4.4.0-116.140) wird eingerichtet ...
Running depmod.
update-initramfs: deferring update (hook will be called later)
The link /initrd.img is a dangling linkto /boot/initrd.img-4.4.0-116-generic
vmlinuz(/boot/vmlinuz-4.4.0-116-generic
) points to /boot/vmlinuz-4.4.0-116-generic
 (/boot/vmlinuz-4.4.0-116-generic) -- doing nothing at /var/lib/dpkg/info/linux-image-4.4.0-116-generic.postinst line 491.
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.4.0-116-generic /boot/vmlinuz-4.4.0-116-generic
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.4.0-116-generic /boot/vmlinuz-4.4.0-116-generic
update-initramfs: Generating /boot/initrd.img-4.4.0-116-generic
W: mdadm: /etc/mdadm/mdadm.conf defines no arrays.

gzip: stdout: No space left on device
E: mkinitramfs failure cpio 141 gzip 1
update-initramfs: failed for /boot/initrd.img-4.4.0-116-generic with 1.
run-parts: /etc/kernel/postinst.d/initramfs-tools exited with return code 1
Failed to process /etc/kernel/postinst.d at /var/lib/dpkg/info/linux-image-4.4.0-116-generic.postinst line 1052.
dpkg: Fehler beim Bearbeiten des Paketes linux-image-4.4.0-116-generic (--configure):
 Unterprozess installiertes post-installation-Skript gab den Fehlerwert 2 zurück

Bei ubuntuusers gibt es einen nützlichen Artikel wie man am besten seine alten Kernel entsorgt.

Hier die Kurzfassung, weitere Details bitte direkt bei ubuntuusers nachlesen.

Aktuellen Kernel feststellen:

max@kronos01:~$ uname -a
Linux kronos01 4.4.0-109-generic #132-Ubuntu SMP Tue Jan 9 19:52:39 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Alte Kernel in Textdatei schreiben, prüfen ob aktueller Kernel dabei ist wenn ja entfernen:

max@kronos01:~$ dpkg -l 'linux-[ihs]*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\([-0-9]*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | tee zu_entfernende_Kernel
max@kronos01:~$ cat zu_entfernende_Kernel 
linux-headers-4.4.0-101
linux-headers-4.4.0-101-generic
linux-headers-4.4.0-103
linux-headers-4.4.0-103-generic
linux-headers-4.4.0-104
linux-headers-4.4.0-104-generic
linux-headers-4.4.0-108
linux-headers-4.4.0-108-generic
linux-headers-4.4.0-81
linux-headers-4.4.0-81-generic
linux-headers-4.4.0-93
linux-headers-4.4.0-93-generic
linux-headers-4.4.0-97
linux-headers-4.4.0-97-generic
linux-headers-4.4.0-98
linux-headers-4.4.0-98-generic
linux-image-4.4.0-101-generic
linux-image-4.4.0-103-generic
linux-image-4.4.0-104-generic
linux-image-4.4.0-108-generic
linux-image-4.4.0-81-generic
linux-image-4.4.0-93-generic
linux-image-4.4.0-97-generic
linux-image-4.4.0-98-generic
linux-image-extra-4.4.0-101-generic
linux-image-extra-4.4.0-103-generic
linux-image-extra-4.4.0-104-generic
linux-image-extra-4.4.0-108-generic
linux-image-extra-4.4.0-93-generic
linux-image-extra-4.4.0-97-generic
linux-image-extra-4.4.0-98-generic

Alte Kernel löschen und File löschen:

max@kronos01:~$ cat zu_entfernende_Kernel | xargs sudo apt-get -y purge 

max@kronos01:~$ rm zu_entfernende_Kernel

 

Quelle: https://wiki.ubuntuusers.de/Skripte/Alte_Kernel_entfernen/

 

 

KeeWeb: Self-hosted password manager with apache2

Add Authentication

First of all you’ll need to setup a .htpasswd file. To do so type in the following:

sudo htpasswd -c /etc/apache2/.htpasswd username

To use the authentication you can add the following to your VHost configuration:

<Location "/">
  AuthType "Basic"
  AuthName "KeeWeb"
  AuthBasicProvider file
  AuthUserFile "/etc/apache2/.htpasswd"
  Require valid-user
</Location>

Setup WebDAV

WebDAV is needed to store your password database.

To enable WebDAV on Apache2 you need to type in the following command:

sudo a2enmod dav_fs

Now create a new directory for WebDAV and make it only accessable for the apache user:

mkdir /var/www/webdav
chown www-data:www-data /var/www/webdav
chmod 700 /var/www/webdav

Now we are going to create a new config for WebDAV in apache2:

Type in:

sudo vi /etc/apache2/sites-available/webdav.conf

Add the following:

Alias /webdav "/var/www/webdav"
<Directory "/var/www/webdav">
  DAV On
  Options Indexes
</Directory>


Save it and type in: sudo a2ensite webdav.conf && sudo service apache2 reload

Now test your settings by accessing yoururl.com/webdav.
You should see the Index of WebDAV.

Install KeeWeb

First you need to install git:

sudo apt install git

After this you can clone the keeweb repository by typing in the following:

cd /var/www/
git clone -b gh-pages https://github.com/keeweb/keeweb.git

This will create a keeweb folder in your /var/www/ directory.

 

Now we need to create a keeweb config for our apache:

vi /etc/apache2/sites-available/keeweb.conf

Type in the following:

<VirtualHost *:443>
        ServerName pass.yourdomain.com
        ServerAlias www.pass.yourdomain.de
        DocumentRoot /var/www/keeweb
</VirtualHost>


Save it and type in: sudo a2ensite keeweb.conf && sudo service apache2 reload

Now we add the authentication to our keeweb site.

To do so you can either create a .htaccess or add the authentication to your VHost like we setup above.

.htaccess:

vi /var/www/keeweb/.htaccess

Add the following:

AuthType Basic
AuthName "KeeWeb"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

Save it and quit.

Test your KeeWeb installation:

If you enter the url pass.yourdomain.com you should see a login prompt and after this the keeweb index page.

YOU MADE IT!

Create a default database:

Go to your keeweb index page and click on new. Now you created a temporary database. We want to save the database to our WebDAV to access it from everywhere. To do so, click on new in the bottom left corner.

Now you can change a few settings. I highly recommend to set a master password and a username! If you changed all your settings click on „Save as…“ and choose WebDAV.

Type in the path to your webdav and your username + password.

Example:

 

Congratulations! Your password manager is ready to use!

Performance Probleme auf einem Linux System ermitteln

Aktuell habe ich auf einem meiner virtuellen Server Probleme mit der Performance, ein Blick in top offenbart das auf einer CPU 100% Waiting ist, Hintergrund war das der Provider einen ZFS scrub auf dem Host laufen ließ was die Disk Performance in den Keller gezogen hat. Ich nehme das zum Anlass ein paar Tools zu zeigen mit denen man sehen kann was in einem Linux System abgeht. Ich verzichte auf großartige Beschreibungen da die Tools und die MAN Pages für sich sprechen.

ATOP – AT Computing’s System & Process Monitor

atop lässt sich auf einem Ubuntu System mit apt install atop installieren.

In meinem Fall habe ich atop mit den Parametern -dD aufgerufen, so werden alle Prozesse angezeigt welche mit Festplatten Aktivität zu tun haben. avio zeigt die durchschnittlichen Millisekunden für eine Abfrage für Suche, Latenz und Datentransfer, der Wert mit 3035 ms ist viel zu hoch.

-d  show disk-related process-info
-D  sort processes in order of disk-activity

TOP – display Linux processes

Das Standard Tool welches in der Regel auf jedem unixoiden Betriebsystem zur Verfügung steht.

Im Programm kann man noch Ansichten ändern etc. hier die aus meiner Sicht wichtigsten:

Dazu einfach die entsprechende Traste drücken:

  • d – Delay in Sekunden für die Aktualisierung einstellen
  • u – Usernamen eingeben, es werden nur laufende Prozesse des Users angezeigt
  • z – Wechsel zwischen Monocrome und Color Mode
  • 1 – Alle CPUs werden einzeln angezeigt
  • q oder STRG+C – Quit – Verlassen der Applikation

IOSTAT – Report Central Processing Unit (CPU) statistics and input/output statistics for devices and partitions.

iostat gibt die IO Statistiken aus. Wenn iostat mit dem Parameter 1 gestartet wird wird jede Sekunde eine Aktualisierung ausgegeben.

root@dev01:~# iostat 1
Linux 3.13.0-137-generic (dev01.m.test) 	12/24/2017 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.26    0.02    0.09    7.43    0.00   92.20

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               3.18        44.11        34.80    3049729    2406628

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.04    0.00    0.76   28.97    0.00   65.24

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               3.00         0.00        52.00          0         52

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.28    0.00    0.50   24.87    0.00   69.35

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.00         0.00         0.00          0          0

VMSTAT – Report virtual memory statistics

Gibt die Speichernutzung aus. Wenn vmstat mit dem Parameter 1 gestartet wird wird jede Sekunde eine Aktualisierung ausgegeben.

root@dev01:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 10447220 272300 3105828    0    0    11     9   63   60  0  0 92  8  0
 1  0      0 10446968 272300 3105956    0    0   128    24 2330  230  1  0 83 16  0
 0  1      0 10446684 272300 3106100    0    0     0     4 2317  416  1  0 99  0  0
 0  1      0 10446908 272300 3106100    0    0     0    96 2082  128  0  0 80 20  0
 0  1      0 10446616 272304 3106224    0    0   128    76 2247  117  0  0 76 24  0
 0  1      0 10446492 272304 3106356    0    0   128     0 2225  111  0  0 75 25  0
 0  1      0 10446524 272304 3106356    0    0     0     0 2096  105  0  0 75 25  0
 0  2      0 10446432 272304 3106484    0    0   128     0 2066  108  0  0 55 45  0
 0  2      0 10446528 272304 3106484    0    0   128    12 2052  100  0  0 51 49  0
 0  2      0 10446560 272304 3106484    0    0     0     0 1992   80  0  0 50 49  0
 0  1      0 10446132 272308 3106864    0    0   256    12 2058  103  0  0 58 42  0
 0  0      0 10445880 272308 3106868    0    0   128     0 2031  100  0  0 97  3  0
 1  1      0 10445756 272308 3106996    0    0   128     0 2187  234  1  0 95  4  0
 0  2      0 10445788 272308 3107124    0    0     0    28 2032  100  2  0 52 46  0
 0  2      0 10445820 272308 3107124    0    0     0     0 1906  107  0  0 50 50  0
 0  2      0 10445476 272308 3107124    0    0   256    16 2222  110  0  0 67 32  0

IOTOP – simple top-like I/O monitor

Zeigt alle Prozesse an und welchen I/O Load sie im System verursachen.

HTOP – interactive process viewer

htop ist ein grafisch gepimpter Prozess Viewer. Mit F5 lassen sich die Prozesse als Baum darstellen.

LSOF – list open files

Zeigt alle offenen Dateien in einem Linux System

 

root@dev1:~# lsof -u www-data
COMMAND   PID     USER   FD      TYPE DEVICE SIZE/OFF   NODE NAME
apache2 51385 www-data  cwd       DIR  252,0     4096      2 /
apache2 51385 www-data  rtd       DIR  252,0     4096      2 /
apache2 51385 www-data  txt       REG  252,0   662496 409596 /usr/sbin/apache2
apache2 51385 www-data  mem       REG  252,0    89696 653325 /lib/x86_64-linux-gnu/libgcc_s.so.1
apache2 51385 www-data  mem       REG  252,0    47600 653363 /lib/x86_64-linux-gnu/libnss_files-2.23.so
apache2 51385 www-data  mem       REG  252,0    47648 653367 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
apache2 51385 www-data  mem       REG  252,0    93128 653357 /lib/x86_64-linux-gnu/libnsl-2.23.so
apache2 51385 www-data  mem       REG  252,0    35688 653359 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
apache2 51385 www-data  mem       REG  252,0    22536 143878 /usr/lib/apache2/modules/mod_status.so
apache2 51385 www-data  mem       REG  252,0    14344 143967 /usr/lib/apache2/modules/mod_setenvif.so
apache2 51385 www-data  mem       REG  252,0    34832 143955 /usr/lib/apache2/modules/mod_negotiation.so
apache2 51385 www-data  mem       REG  252,0    63504 143890 /usr/lib/apache2/modules/mod_mpm_event.so
apache2 51385 www-data  mem       REG  252,0    18440 143969 /usr/lib/apache2/modules/mod_mime.so
apache2 51385 www-data  mem       REG  252,0    18440 143942 /usr/lib/apache2/modules/mod_filter.so
apache2 51385 www-data  mem       REG  252,0    10248 143913 /usr/lib/apache2/modules/mod_env.so
apache2 51385 www-data  mem       REG  252,0    14344 143881 /usr/lib/apache2/modules/mod_dir.so
apache2 51385 www-data  mem       REG  252,0   104864 653422 /lib/x86_64-linux-gnu/libz.so.1.2.8
apache2 51385 www-data  mem       REG  252,0    34824 143912 /usr/lib/apache2/modules/mod_deflate.so
apache2 51385 www-data  mem       REG  252,0    38928 143951 /usr/lib/apache2/modules/mod_autoindex.so
apache2 51385 www-data  mem       REG  252,0    10256 143964 /usr/lib/apache2/modules/mod_authz_user.so
apache2 51385 www-data  mem       REG  252,0    10256 143950 /usr/lib/apache2/modules/mod_authz_host.so
apache2 51385 www-data  mem       REG  252,0    22544 143873 /usr/lib/apache2/modules/mod_authz_core.so
apache2 51385 www-data  mem       REG  252,0    10256 143954 /usr/lib/apache2/modules/mod_authn_file.so
apache2 51385 www-data  mem       REG  252,0    10256 143947 /usr/lib/apache2/modules/mod_authn_core.so
apache2 51385 www-data  mem       REG  252,0    14352 143960 /usr/lib/apache2/modules/mod_auth_basic.so
apache2 51385 www-data  mem       REG  252,0    14344 143909 /usr/lib/apache2/modules/mod_alias.so
apache2 51385 www-data  mem       REG  252,0    10256 143920 /usr/lib/apache2/modules/mod_access_compat.so
apache2 51385 www-data  mem       REG  252,0    14608 653313 /lib/x86_64-linux-gnu/libdl-2.23.so
apache2 51385 www-data  mem       REG  252,0    18976 653418 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
apache2 51385 www-data  mem       REG  252,0   166032 653320 /lib/x86_64-linux-gnu/libexpat.so.1.6.0
apache2 51385 www-data  mem       REG  252,0    39224 653307 /lib/x86_64-linux-gnu/libcrypt-2.23.so
apache2 51385 www-data  mem       REG  252,0  1868984 653299 /lib/x86_64-linux-gnu/libc-2.23.so
apache2 51385 www-data  mem       REG  252,0   138696 653386 /lib/x86_64-linux-gnu/libpthread-2.23.so
apache2 51385 www-data  mem       REG  252,0   204936 409578 /usr/lib/x86_64-linux-gnu/libapr-1.so.0.5.2
apache2 51385 www-data  mem       REG  252,0   159488 409580 /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0.5.4
apache2 51385 www-data  mem       REG  252,0   456632 653379 /lib/x86_64-linux-gnu/libpcre.so.3.13.2
...

IFTOP – display bandwidth usage on an interface by host

Zeigt aktuelle Netzwerkverbindungen an und deren Traffic.