ArchLinux Archives - Technik - Blogbasis.net https://technik.blogbasis.net/tag/archlinux Die Basis des freien Wissens – Technik Thu, 19 May 2016 23:05:34 +0000 de hourly 1 https://wordpress.org/?v=6.8.1 Windows ohne USB-Stick & CD-Laufwerk installieren https://technik.blogbasis.net/windows-ohne-usb-stick-cd-laufwerk-installieren-20-05-2016 https://technik.blogbasis.net/windows-ohne-usb-stick-cd-laufwerk-installieren-20-05-2016#respond Thu, 19 May 2016 23:05:34 +0000 http://technik.blogbasis.net/?p=1405 Ein Bekannter hat sich letztens einen neuen Laptop gekauft, allerdings ohne CD-Laufwerk und ohne vorinstalliertes Betriebssystem. Die Windows-auf-USB-Stick-Installation klappte nicht, also musste eine alternative Lösung her. Diese werde ich in diesem Blogpost erläutern.

Die Situation

Funfact vor weg: Notebooksbilliger.de hat zum CD-laufwerklosen Laptop eine Treiber-CD mitgeliefert. Der Sinn ergibt sich mir bis jetzt nicht. Zudem war auf dem „betriebssystemlosen“ Laptop ein Linpus-Linux (Chinalinux) vorinstalliert.

Nichtsdestotrotz war das Ziel ein Windows auf diesem Laptop zu installieren. Der Versuch eine Windows-ISO auf einem USB-Stick bootbar zu machen klappte zunächst, jedoch meldete die Installationsroutine der USB-Stick könne nicht gefunden werden.

Der Workaround

Da es schon spät abends war, hatte ich auch keine Lust mehrere solcher Windows-USB-Sticks zu erstellen. Eine alternative Lösung musste her.

Da erinnerte ich mich an den Google-CTF, in dem man mit dem NBD-Protokoll arbeiten musste.

Folgende Idee kam mir dabei in den Kopf:

  • Auf beiden Laptops Linux starten
  • Festplatte über NBD freigeben und einhängen
  • Mit VirtualBox Windows auf die freigegebene Festplatte installieren

Das hört sich kompliziert an, hatte am Ende aber einige Vorteile, da Windows 7 leider keine passenden USB- bzw. Netzwerktreiber für den Laptop mitbrachte:

  • USB-Zugriff über VirtualBox
  • Netzwerk-Zugriff über VirtualBox
  • CD-Zugriff über VirtualBox

Die Umsetzung

Zunächst bootet man auf zwei Rechnern Linux. In meinem Fall habe ich für den neuen Laptop (A) ein Archlinux-Livesystem genutzt, da auf meinem Laptop (B) bereits Archlinux läuft. Andere Distributionen sollten für dieses Vorhaben auch nutzbar sein, allerdings muss wahrscheinlich ein andersnamiges Paket installiert werden.

Der erste Schritt besteht darin, auf beiden Laptops NBD zu installieren. Unter Archlinux heißt das Paket „nbd“.

sudo pacman -S nbd

Als nächstes baut man ein Netzwerk zwischen beiden Rechnern auf. Dazu habe ich diese mit einem LAN-Kabel direkt verbunden. Es ist aber auch möglich einen Router und automatische IP-Konfiguration (DHCP) zu nutzen.

Auf Laptop B:

sudo ip a a 192.168.50.1/16 dev enp2s0f0

wobei „enp2s0f0“ euer Netzwerkinterface ist.

Auf Laptop A:

sudo ip a a 192.168.50.2/24 dev enp2s0
sudo ip r a 192.168.50.0/24 via 192.168.50.1 dev enp2s0

Danach sollten beide Geräte sich pingen können.

Als nächstes gibt man in diesem Netzwerk die Festplatte von A frei:

nbd-server -d -C /dev/null 1337 /dev/sda

Parameter:

  • -d : Debugmodus, Prozess geht nicht in den Hintergrund
  • -C /dev/null: Keine Konfigurationsdatei laden
  • 1337: Port, auf dem die Freigabe läuft
  • /dev/sda: Festplatte, die freigegeben werden soll

Auf B bindet man das Gerät entsprechend ein:

nbd-client -nofork 192.168.50.2 1337 /dev/nbd0

Parameter:

  • -nofork: Nicht in den Hintergrund gehen
  • 192.168.50.2: IP von A
  • 1337: Port auf dem A die Freigabe hat
  • /dev/nbd0: 1. Freigabe von A.

Als nächstes braucht man ein wenig VirtualBox-Magic, um VirtualBox die Netzwerkfreigabe als eigenständige Festplatte vorzugaukeln:

VBoxManage internalcommands createrawvmdk -filename /tmp/laptop-windows.vmdk -rawdisk /dev/nbd0 

Parameter:

  • -filename: Pfad zur neuen vmdk-Datei („Symlink“)
  • -rawdisk: Pfad zur echten Festplatte, nämlich der Netzwerkfreigabe, also der Festplatte auf A

Nun kann man in VirtualBox eine neue virtuelle Maschine anlegen. Dabei gibt man als „vorhandene Festplatte“ den Pfad „/tmp/laptop-window.vmdk“ an. Alle Änderungen die man in der virtuellen Maschine vornimmt, werden dann über das Netzwerk auf die Festplatte von Laptop A geschrieben.

Problem gelöst und Windows endlich installiert :)

~ Sebastian

]]>
https://technik.blogbasis.net/windows-ohne-usb-stick-cd-laufwerk-installieren-20-05-2016/feed 0
RaspberryPi + DS18B20 = ThermometerPi https://technik.blogbasis.net/raspberrypi-ds18b20-thermometerpi-13-05-2016 https://technik.blogbasis.net/raspberrypi-ds18b20-thermometerpi-13-05-2016#respond Fri, 13 May 2016 18:34:21 +0000 http://technik.blogbasis.net/?p=1393 Ich bin vor einigen Wochen über einen Blogpost gestoßen, in dem erklärt wurde, wie man aus einem RaspberryPi und einem Wärmesensor (DS18B20) sich ein eigenes Thermometer bauen kann. Dieser Idee bin ich nachgegangen und möchte in diesem Blogpost beschreiben, welche Tweaks dabei nötig waren.

Irgendwo auf Twitter oder einem anderen Medium habe ich ein Link zu dem Blogpost „[Tutorial] DS18S20 Temperatur Sensor an einem Raspberry Pi“ gefunden. Das hat mich so sehr fasziniert, dass ich das nachbauen wollte.

Dazu bestellte ich mir auf Amazon zunächst 10 solcher Sensoren mit entsprechend langem Kabel und Abdichtung: 10 x DS18B20 Digitale Temperaturfühler für ~15€. Dazu kamen noch ein paar 4.7k Ohm Widerstände. Nach ein paar Tagen war alles in meinem Briefkasten. Angeblich kann man sich von Maximintegrated ein kostenloses Sample zuschicken lassen. Allerdings kam bei mir bisher nichts an, vielleicht auch einfach Pech oder ein Fehler auf meiner Seite.

Aufbau

Für die Verkabelung des Sensors mit dem RaspberryPi bin ich den Schritten in dem oben genannten Blogpost gefolgt. Für mehr Informationen möchte ich dorthin verweisen.

Quelle: https://kopfkino.irosaurus.com/tutorial-ds18s20-temperatur-sensor-an-einem-raspberry-pi/

Quelle: https://kopfkino.irosaurus.com/tutorial-ds18s20-temperatur-sensor-an-einem-raspberry-pi/

Wichtig ist scheinbar nur, dass man den GPIO-Pin 4 nutzt. Ich habe es selbst nicht mit anderen GPIO-Pins probiert. Wenn es bei euch mit anderen klappt, bitte einen kurzen Kommentar hinterlassen.

Konfiguration

Ich habe auf meinem RaspberryPi Archlinux mit einem halbwegs aktuellen Kernel am Laufen. Das führte dazu, dass die weiteren Schritte in dem oben genannten Blogpost nicht funktionierten. Nachdem ich ein wenig recherchiert habe, kam ich zu einer klein wenig modifizierten Lösung.

Zunächst muss man in die /boot/config.txt folgende Zeile anhängen:

dtoverlay=w1-gpio,gpiopin=4,pullup=on

Danach muss man noch Kernelmodule laden. Dies erledigt man am Besten direkt beim Booten, in dem man folgendes in die Datei /etc/modules einträgt:

w1-gpio pullup=1
w1_therm

Nach einem Neustart sollte der Sensor unter  „/sys/bus/w1/devices/<sensor-id>“ verfügbar sein. Mit folgendem Einzeiler kriegt man die aktuelle Temperatur heraus:

$> cat /sys/bus/w1/devices/28-041621eb50ff/w1_slave | grep -oP "t=(\d+)" | sed -e "s/t=//g"
21687

Automatisierung & Webseite

Ich wollte mir eine kleine grafische Ansicht über den Temperaturverlauf bauen. Dazu entschied ich mich, die Daten von zwei Sensoren (1x Indoor, 1x Outdoor) alle 30 Sekunden auszulesen und in eine SQLite3-Datenbank zu schreiben.

Dazu habe ich zwei Scripte unter „/opt/thermo/“ zu liegen. Das Erste kümmert sich nur um das Auslesen der Daten und heißt „data.sh“:

#!/bin/bash

outdoor=$(cat /sys/bus/w1/devices/28-041621eb50ff/w1_slave | grep -oP "t=(\d+)" | sed -e "s/t=//g")
indoor=$(cat /sys/bus/w1/devices/28-041621fadbff/w1_slave | grep -oP "t=(\d+)" | sed -e "s/t=//g")
seconds=$(TZ=Europe/Berlin date +"%s")

echo "$seconds,$indoor,$outdoor"

Die IDs müssen natürlich entsprechend angepasst werden.

Das zweite Script „insertdata.sh“ ruft „data.sh“ auf und schreibt die Daten in eine SQLite3-Datenbank.

#!/bin/bash
olddir=$(pwd)
cd /opt/thermo/
sqlite3 thermo.sqlite3 "insert into temperatures VALUES ($(./data.sh));"
cd "$olddir"

Da Archlinux mit Systemd kommt, können wir dessen Timer nutzen, um die Aufgabe alle 30 Sekunden abzufeuern. Dazu legen wir zunächst den Service unter „/etc/systemd/system/thermo.service“ an:

[Unit]
Description=Thermometer data collector

[Service]
Type=oneshot
ExecStart=/bin/bash /opt/thermo/insertdata.sh

Der Timer „/etc/systemd/system/thermo.timer“ führt diesen Service dann periodisch aus:

[Unit]
Description=Thermo data collector timer

[Timer]
Persistent=true
OnUnitActiveSec=30s
OnBootSec=30s

[Install]
WantedBy=timers.target

Diesen muss man mit einem kurzem Kommando aktivieren:

sudo systemctl enable thermo.timer

Zuletzt fehlte nur noch eine kleine Webseite, die die Daten aus der SQLite-Datenbank ausliest und anzeigt. Dazu habe ich einfach Apache + PHP installiert und folgende „index.php“ im DocumentRoot abgelegt.

thermo-website

<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0/Chart.js"></script>
</head>
<body class="container">
<?php
$db = new SQLite3('/opt/thermo/thermo.sqlite3');
$beginOfDay = strtotime("midnight", time());

$current = $db->query('SELECT * FROM temperatures order by timestamp desc limit 1');
$row = $current->fetchArray();

$currentDate = date("H:i:s - d.m.Y", $row['timestamp']);
$currentIndoor = round($row['indoor']/1000,3);
$currentOutdoor = round($row['outdoor']/1000,3);

$minmax = $db->query("SELECT MIN(indoor) as minIndoor, MIN(outdoor) as minOutdoor, MAX(indoor) as maxIndoor, MAX(outdoor) as maxOutdoor FROM temperatures where timestamp >= $beginOfDay order by timestamp desc");
$row = $minmax->fetchArray();

$minIndoor = round($row['minIndoor']/1000,3);
$maxIndoor = round($row['maxIndoor']/1000,3);
$minOutdoor = round($row['minOutdoor']/1000,3);
$maxOutdoor = round($row['maxOutdoor']/1000,3);

echo "<h1>Last measurement: $currentDate</h1>";
echo "<table class='table'><tr><th>Location</th><th>Current °C</th><th>Todays Min °C</th><th>Todays Max °C</th></tr>";
echo "<tr><td>Indoor</td><td>$currentIndoor</td><td>$minIndoor</td><td>$maxIndoor</td>";
echo "<tr><td>Outdoor</td><td>$currentOutdoor</td><td>$minOutdoor</td><td>$maxOutdoor</td>";
echo "</table>";

?>
<canvas id="myChart" width="300" height="100"></canvas>

<?php
$minmax = $db->query("SELECT * FROM temperatures where timestamp >= $beginOfDay order by timestamp asc");
$labels = array();
$indoor = array();
$outdoor = array();
$diff = array();
while($row = $minmax->fetchArray()) {
    $labels[] = date("H:i:s", $row['timestamp']);
    $indoor[] = round($row['indoor']/1000,3);
    $outdoor[] = round($row['outdoor']/1000,3);
    $diff[] = abs(round((abs($row['indoor']) - abs($row['outdoor']))/1000,3));
}
?>

<script>
var data = {
    labels: <?php echo json_encode($labels); ?>,
    datasets: [
        {
            label: "Indoor",
            fill: false,
            lineTension: 0.1,
            backgroundColor: "rgb(209,12,8)",
            borderColor: "rgb(209,12,8)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgb(209,12,8)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgb(209,12,8)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            pointRadius: 1,
            pointHitRadius: 10,
            data: <?php echo json_encode($indoor);?>,
        },
        {
            label: "Outdoor",
            fill: false,
            lineTension: 0.1,
            backgroundColor: "rgb(8,209,8)",
            borderColor: "rgb(8,209,8)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgb(8,209,8)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgb(8,209,8)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            pointRadius: 1,
            pointHitRadius: 10,
            data: <?php echo json_encode($outdoor);?>,
        },
        {
            label: "Difference",
            fill: false,
            lineTension: 0.1,
            backgroundColor: "rgba(75,192,192)",
            borderColor: "rgba(75,192,192)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgba(75,192,192)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgba(75,192,192)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            pointRadius: 1,
            pointHitRadius: 10,
            data: <?php echo json_encode($diff);?>,
        }
    ]
};

var ctx = document.getElementById("myChart");
var myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
});
</script>
</body>
</html>

~ Sebastian

]]>
https://technik.blogbasis.net/raspberrypi-ds18b20-thermometerpi-13-05-2016/feed 0
Vicious – Warnung bei niedriger Batterie https://technik.blogbasis.net/vicious-warnung-bei-niedriger-batterie-16-12-2015 https://technik.blogbasis.net/vicious-warnung-bei-niedriger-batterie-16-12-2015#respond Wed, 16 Dec 2015 21:32:36 +0000 http://technik.blogbasis.net/?p=1382 Aufgrund eines Wackelkontaktes in meinem Laptop kam es in letzter Zeit häufiger zum Wechsel von Netz- auf Batteriebetrieb. Das hab ich meist nicht mitbekommen und saß schlagartig vor einem schwarzen Bildschirm, da der Akku alle war.  Eine Warnmeldung musste her!

Ich nutze das Plugin „Vicious“ für den Batteriestatus in Awesome. Eine beispielhafte Implementierung für das Battery-Widget findet man in der README, allerdings bei mir im Textmodus:

batwidget = wibox.widget.textbox()
vicious.register(batwidget, vicious.widgets.bat, "⚡: $2%/$3", 30, "BAT0")

Der 3. Parameter kann netterweise eine Funktion sein, sodass man einfach den Batteriestatus prüfen und entsprechend eine Meldung ausgeben kann:

vicious.register(batwidget, vicious.widgets.bat, function(widget, args) 
 if args[2] <= 15 then
 naughty.notify({
 title="BATTERY!!",
 text="Battery left: "..args[2].."%",
 bg="#ff0000",
 fg="#000",
 timeout=5,
 border_width=5,
 font="Arial 25" 
 })
 end
 return "⚡: "..args[2].."%/".. args[3]
 end, 30, "BAT0")

In meinem Fall wird die Meldung angezeigt, wenn weniger als 15% Akku verbleiben. Das sieht dann so aus (100% nur, da es ein Test ist):

battery

Damit sollten sich die unbemerkten Abschaltungen meines Laptops in Zukunft drastisch reduzieren.

~ Sebastian

]]>
https://technik.blogbasis.net/vicious-warnung-bei-niedriger-batterie-16-12-2015/feed 0
Arch: Automount encrypted sdcard – udev + systemd https://technik.blogbasis.net/arch-automount-encrypted-sdcard-udev-systemd-09-10-2015 https://technik.blogbasis.net/arch-automount-encrypted-sdcard-udev-systemd-09-10-2015#respond Fri, 09 Oct 2015 14:14:45 +0000 http://technik.blogbasis.net/?p=1362 Einen wundervollen Nachmittag,

in diesem Blogpost möchte ich beschreiben wie man mit Hilfe einer udev-Regel und Systemd eine mit luks verschlüsselte SD-Karte automatisch mounten lassen kann.

Vorwort: SD-Karte verschlüsseln

Damit man die SD-Karte automatisch entschlüsseln lassen kann, bietet es sich an, diese mit einem Keyfile zu verschlüsseln. Dazu erstellt man zunächst ein Keyfile:

sudo dd bs=512 count=4 if=/dev/urandom of=/etc/sdkey iflag=fullblock

Damit nicht jeder diesen Schlüssel lesen kann, verpasst man ihm noch die korrekten Rechte und einen Änderungsschutz:

sudo chmown root:root /etc/sdkey
sudo chmod 500 /etc/sdkey
sudo chattr +i /etc/sdkey

Danach kann man auch schon mit cryptsetup die SD-Karte verschlüsseln:

sudo cryptsetup luksFormat /dev/mmcblk0p1 /etc/sdkey
  • /dev/mmcblk0p1 ist die zu verschlüsselnde Partition auf der SD-Karte
  • /etc/sdkey ist das Keyfile, dass zur Verschlüsselung genutzt wird

Zuletzt öffnet man die SD-Karte und erstellt ein Dateisystem:

sudo cryptsetup --key-file=/etc/sdkey luksOpen /dev/mmcblk0p1 sdcard
sudo mkfs.ext4 /dev/mapper/sdcard

Fertig.

Automatische Entschlüsselung und Einbindung

Zum automatischen Entschlüsseln und Mounten der SD-Karte müssen wir eine neue udev-Regel und ein passendes Systemd Unitfile schreiben.

Systemd Unitfile

Wir beginnen mit dem Systemd Unitfile, da dieses relativ straight forward ist. Man legt eine neue Datei an: ‚/etc/systemd/system/sdcardencrypt.service‘. Der Inhalt kann so aussehen:

[Unit]
Description=Automount encrypted sdcard

[Service]
Type=oneshot
ExecStart=/usr/bin/cryptsetup --key-file=/etc/sdkey luksOpen /dev/sdcard sdcard
ExecStart=/usr/bin/mount /dev/mapper/sdcard /sdcard

Möchte man in dem Unitfile mehere ‚ExecStart‘-Kommandos ausführen, so ist ‚Type=oneshot‘ zu setzen.

Das erste Kommando ist bereits von oben bekannt und öffnet den luks-Container. Neu ist hier, dass als Device ‚/dev/sdcard‘ statt ‚/dev/mmcblk0p1‘ angegeben wird. Das erklärt sich aber später mit unserer udev-Regel.

Der zweite Befehl mountet den luks-Container in ‚/sdcard‘. Der Mountpoint muss einmalig davor erstellt werden und/oder geändert werden.

Damit Systemd das neue Unitfile korrekt ausführt, müssen wir einen kurzen Reload durchführen:

sudo systemctl daemon-reload

Udev-Regel

Als nächstes machen wir uns an die udev-Regel, welche den Symlink zu ‚/dev/sdcard‘ erstellt und das unser Unitfile aufruft. Dazu erstellen wir eine Datei in ‚/etc/udev/rules.d/‘ mit dem Namen ’10-sdcard.rules‘ und folgendem Inhalt:

ACTION=="add", KERNEL=="mmcblk0p1", SUBSYSTEM=="block", ATTR{size}=="124702720", ATTR{start}=="32768", SYMLINK+="sdcard", ENV{SYSTEMD_WANTS}="sdcardencrypt.service"

Hier passieren mehrere Dinge:

  • ACTION: Nur wenn das neue Gerät eingesteckt wird, soll die Regel ausgeführt werden
  • KERNEL, SUBSYSTEM, ATTR: Verundete Kriterien; Nur wenn alle matchen, wird die Regel ausgeführt
  • SYMLINK: Erzeuge ein Symlink von der gematchten Partition ‚/dev/mmcblk0p1‘ zu ‚/dev/sdcard‘
  • ENV: Führe danach das ’sdcardencrypt.service‘ Unitfile aus.

Das einzige, was ihr an der Regel ändern müsst, sind die Werte hinter KERNEL, ATTR{size}, ATTR{start}. Da wir hier von einer SD-Karte reden, wird SUBSYSTEM wahrscheinlich den Wert beibehalten. Alle anderen Werte nutze ich, um meine verschlüsselte SD-Karte (eindeutig) zu identifizieren.

An die entsprechenden Attribute gelangt man die SD-Karte einsteckt und danach das folgende Kommando ausführt:

udevadm info -a -p (udevadm info -q path -n /dev/mmcblk0p1)

Dabei ersetzt man ‚/dev/mmcblk0p1‘ mit der entsprechenden Partition der SD-Karte. Die Ausgabe kann so ähnlich aussehen:

udevadm info -a -p (udevadm info -q path -n /dev/mmcblk0p1)

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

 looking at device '/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/mmc_host/mmc0/mmc0:aaaa/block/mmcblk0/mmcblk0p1':
 KERNEL=="mmcblk0p1"
 SUBSYSTEM=="block"
 DRIVER==""
 ATTR{alignment_offset}=="0"
 ATTR{discard_alignment}=="8388608"
 ATTR{inflight}==" 0 0"
 ATTR{partition}=="1"
 ATTR{ro}=="0"
 ATTR{size}=="124702720"
 ATTR{start}=="32768"
 ATTR{stat}==" 38 0 1099 136 0 0 0 0 0 56 136"

 looking at parent device '/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/mmc_host/mmc0/mmc0:aaaa/block/mmcblk0':
 KERNELS=="mmcblk0"
 SUBSYSTEMS=="block"
 DRIVERS==""
 ATTRS{alignment_offset}=="0"
 ATTRS{capability}=="10"
 ATTRS{discard_alignment}=="0"
 ATTRS{ext_range}=="8"
 ATTRS{force_ro}=="0"
 ATTRS{inflight}==" 0 0"
 ATTRS{range}=="8"
 ATTRS{removable}=="0"
 ATTRS{ro}=="0"
 ATTRS{size}=="124735488"
 ATTRS{stat}==" 52 0 2155 206 0 0 0 0 0 96 206"

 looking at parent device '/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/mmc_host/mmc0/mmc0:aaaa':
 KERNELS=="mmc0:aaaa"
 SUBSYSTEMS=="mmc"
 DRIVERS=="mmcblk"
 ATTRS{cid}=="035344534c36344780295762d200f800"
 ATTRS{csd}=="400e00325b590001dbd37f800a404000"
 ATTRS{date}=="08/2015"
 ATTRS{erase_size}=="512"
 ATTRS{fwrev}=="0x0"
 ATTRS{hwrev}=="0x8"
 ATTRS{manfid}=="0x000003"
 ATTRS{name}=="SL64G"
 ATTRS{oemid}=="0x5344"
 ATTRS{preferred_erase_size}=="25165824"
 ATTRS{scr}=="0245800300000000"
 ATTRS{serial}=="0x295762d2"
 ATTRS{type}=="SD"

 looking at parent device '/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/mmc_host/mmc0':
 KERNELS=="mmc0"
 SUBSYSTEMS=="mmc_host"
 DRIVERS==""

 looking at parent device '/devices/pci0000:00/0000:00:1c.0/0000:02:00.1':
 KERNELS=="0000:02:00.1"
 SUBSYSTEMS=="pci"
 DRIVERS=="sdhci-pci"
 ATTRS{broken_parity_status}=="0"
 ATTRS{class}=="0x080501"
 ATTRS{consistent_dma_mask_bits}=="32"
 ATTRS{d3cold_allowed}=="1"
 ATTRS{device}=="0x16bc"
 ATTRS{dma_mask_bits}=="64"
 ATTRS{driver_override}=="(null)"
 ATTRS{enable}=="1"
 ATTRS{irq}=="17"
 ATTRS{local_cpulist}=="0-3"
 ATTRS{local_cpus}=="0f"
 ATTRS{msi_bus}=="1"
 ATTRS{numa_node}=="-1"
 ATTRS{subsystem_device}=="0x0504"
 ATTRS{subsystem_vendor}=="0x1025"
 ATTRS{vendor}=="0x14e4"

 looking at parent device '/devices/pci0000:00/0000:00:1c.0':
 KERNELS=="0000:00:1c.0"
 SUBSYSTEMS=="pci"
 DRIVERS=="pcieport"
 ATTRS{broken_parity_status}=="0"
 ATTRS{class}=="0x060400"
 ATTRS{consistent_dma_mask_bits}=="32"
 ATTRS{d3cold_allowed}=="0"
 ATTRS{device}=="0x1c10"
 ATTRS{dma_mask_bits}=="32"
 ATTRS{driver_override}=="(null)"
 ATTRS{enable}=="1"
 ATTRS{irq}=="17"
 ATTRS{local_cpulist}=="0-3"
 ATTRS{local_cpus}=="0f"
 ATTRS{msi_bus}=="1"
 ATTRS{numa_node}=="-1"
 ATTRS{subsystem_device}=="0x0504"
 ATTRS{subsystem_vendor}=="0x1025"
 ATTRS{vendor}=="0x8086"

 looking at parent device '/devices/pci0000:00':
 KERNELS=="pci0000:00"
 SUBSYSTEMS==""
 DRIVERS==""

Am Besten nimmt man die Attribute von weiter oben. Es stellt allerdings auch kein Problem dar, wenn man Attribute nutzt, die weiter unten stehen, nur sind diese etwas genereller und könnten gegebenenfalls auf andere SD-Karten matchen. Allerdings darf man nur Attribute von einem ‚Parent‘ des Devices nutzen. Für bessere Robustheit könnte man noch zusätzliche folgende Attribute einführen:

  • ATTRS{manfid}==“0x000003″
  • ATTRS{name}==“SL64G“
  • ATTRS{oemid}==“0x5344″
  • ATTRS{serial}==“0x295762d2″
  • ATTRS{type}==“SD“

Zuletzte sollte man noch die Regeln neu einlesen. Das klappt einfach mit einem:

sudo udevadm trigger

Fazit

Es braucht nicht viel Bastelei, um eine verschlüsselte SD-Karte automatisch einzubinden. Möglicherweise möchte man sich aber noch Gedanken darüber machen, dass der Mountpoint bzw. Luks-Container geschlossen wird, wenn die SD-Karte ausgehängt wird. Da ich das nicht häufig/wirklich benötige, ist dies dem interessierten Leser überlassen.

~ Sebastian

]]>
https://technik.blogbasis.net/arch-automount-encrypted-sdcard-udev-systemd-09-10-2015/feed 0
Pactree & Graphviz: Paketabhängigkeiten schön darstellen https://technik.blogbasis.net/pactree-graphviz-paketabhaengigkeiten-schoen-darstellen-28-05-2015 https://technik.blogbasis.net/pactree-graphviz-paketabhaengigkeiten-schoen-darstellen-28-05-2015#respond Thu, 28 May 2015 21:53:48 +0000 http://technik.blogbasis.net/?p=1346 Moin Moin,

heute habe ich nach einer Möglichkeit gesucht, herauszufinden, welche Pakete welche Abhängigkeiten haben. Am Ende meiner Recherche wurden mir schöne bunte Graphen erzeugt. Dabei benötigt man dazu eigentlich nur zwei kleine Programme: Pactree und Graphviz.

Pactree

Pactree beschreibt sich selbst als „A simple dependency tree viewer.“ für Arch Linux. Man kann sich zum Beispiel ausgeben lassen, welche Abhängigkeiten das Paket „glibc“ hat:

> pactree glibc
glibc
├─linux-api-headers
├─tzdata
└─filesystem
 └─iana-etc

Die folgenden Switches werden wir gleich verwenden, um aus diesen Informationen schöne Grafiken zu bauen:

-c, --color          colorize output
-g, --graph          generate output for graphviz's dot

Die Abhängigkeiten von Oben ergeben folgende „dot“-Beschreibung:

> pactree -c -g glibc
digraph G { START [color=red, style=filled];
node [style=filled, color=green];
 "START" -> "glibc";
"glibc" -> "linux-api-headers" [color=chocolate4];
"glibc" -> "tzdata" [color=chocolate4];
"glibc" -> "filesystem" [color=chocolate4];
"filesystem" -> "iana-etc" [color=chocolate4];
}

Interessant kann auch die Verwendung des Switches „-r“ sein.

 -r, --reverse        list packages that depend on the named package

Graphviz

Graphviz ist eine kleine Toolsammlung, welche genutzt werden kann, um schöne Graphen zu erzeugen. Zum Beispiel aus dem o.g. Code.

Um die Umwandlung durchzuführen, führt man folgendes Kommando aus:

dot -Tgif deps.graph -o deps.gif

Wobei „deps.graph“ für den Eingabegraphen in dot-Notation und deps.gif für die Ausgabe im GIF-Format steht. Eine Liste mit weiteren Formaten gibt es natürlich auch. Man muss nur entsprechend „-Tgif“ durch „-TFORMAT“ ersetzen.

Die Aufrufe lassen sich natürlich verketten:

pactree -c -g glibc | dot -Tgif -o /tmp/glibc.gif

Das Ergebnis sieht dann so aus:

glibc

Oder etwas komplexer, wie z.B. für das „Gimp“-Programm.

gimp

 

~ Sebastian

]]>
https://technik.blogbasis.net/pactree-graphviz-paketabhaengigkeiten-schoen-darstellen-28-05-2015/feed 0
Banana Pi als WLAN & LAN Router einrichten https://technik.blogbasis.net/banana-pi-als-wlan-lan-router-einrichten-01-03-2015 https://technik.blogbasis.net/banana-pi-als-wlan-lan-router-einrichten-01-03-2015#respond Sun, 01 Mar 2015 13:25:46 +0000 http://technik.blogbasis.net/?p=1303 Ich habe mir vor Kurzem einen BananaPi bestellt und wollte diesen probeweise als WLAN & LAN Router einrichten, wobei WLAN und LAN sich gemeinsam ein Netzwerk teilen.

Mit den Programmen hostapd, dnsmasq und Arch-Linux lässt sich das ohne größere Schwierigkeiten umsetzen.

Hardware & Betriebssystem

Wie schon angedeutet, handelt es sich um ein Banana Pi. Das Ding ist so ähnlich wie ein Raspberry Pi, nur kommt es mit einer DualCore CPU und 1 GB RAM, sowie einer 1GBit Netzwerkschnitstelle.

Die Wahl des Betriebssystems fiel auf das Arch Linux v2.0 Image. Dieses kann man, wie gewohnt, einfach herunterladen und auf die SD Karte spielen.

Des Weiteren benötigt man noch einen USB-Ethernet Adapter, sowie einen USB-WLAN Adapter. Die folgenden Produkte hatte ich bei mir noch rumliegen und können out-of-the-box genutzt werden.

  • LogiLink UA0025C
  • TP Link TL-WN722N

Ziel

Wenn wir die folgende Konfiguration annehmen:

  • eth0 : Schnittstelle zum Internet (WAN)
  • eth1 : Schnittstelle zum LAN
  • wlan0 : Schnittstelle zum WLAN

Dann möchten wir folgendes Setup erreichen:

  • eth0 bekommt seine IP per DHCP
  • eth1 & wlan0 teilen sich das Subnet 192.168.4.0/24
  • Die IPs aus dem Subnet werden per DHCP verteilt
  • Dem Subnet wird ein DNS Server zur Verfügung gestellt

Um das zu erreichen, werden wir das Setup in drei größere Konfigurationsabschnitte unterteilen:

  • Netzwerkschnittstellen konfigurieren (systemd-networkd)
  • Iptables konfigurieren
  • Dnsmasq & Hostapd konfigurieren

Kernel vs. Systemd

Die Kernelversion des Images ist bisher bei 3.4.x stehen geblieben. Jedoch werden die Systemd Pakete weiter aktualisiert. Ab systemd-216 führt dies zu Problemen beim Laden von Treibern. Systemd erwartet, dass der Kernel diese Funktion übernimmt, jedoch ist diese in dieser älteren Version noch nicht implementiert.

Folgende Fehler können auf dieses Problem hinweisen:

[ 119.592292] usb 1-1.2: ath9k_htc: Firmware htc_9271.fw requested
[ 180.172266] usb 1-1.2: ath9k_htc: Failed to get firmware htc_9271.fw
[ 180.302130] usb 1-1.2: ath9k_htc: USB layer deinitialized

Natürlich sollte die Datei „htc_9271.fw“ in „/lib/firmware“ bzw. „/usr/lib/firmware“ vorhanden sein.

Die Lösung des Problems besteht darin, dass man Updates für folgende drei Pakete zurückhält:

  • libsystemd
  • systemd
  • systemd-sysvcompat

Diese drei Paketenamen trägt man hinter „IgnorePkg=“ in der „/etc/pacman.conf“ ein.

Danach kann man sich von Archlinux-Rollback die drei Pakete in der Version „216-3“ herunterladen und mittels „pacman -U <Paket>“ installieren.

Netzwerkschnittstellen konfigurieren

Der erste Schritt besteht darin dem System mitzuteilen, wie wir unsere Interfaces konfiguriert haben möchten. Ein Interface soll eine dynamische IP haben und die zwei verbleibenden Schnittstellen sollen ein virtuelles Device bilden.

Hierzu stellen wir erstmal sicher, dass die Voraussetzungen gegeben sind, in dem wir „systemd-networkd“ aktivieren und „netctl“ (ggf. andere Netzwerkmanager) deaktivieren.

systemctl enable systemd-networkd
systemctl stop netctl
systemctl disable netctl

Für die dynamischen IP Adressen benötigen wir dann noch das Paket „dhcpcd“ und entsprechend den aktivierten Dienst:

pacman -S dhcpcd
systemctl enable dhcpcd.service
systemctl start dhcpcd.service

Als nächstes wechselt man in das Verzeichnis „/etc/systemd/network/“. Dort legen wir die Datei für unser WAN-Interface an. Die Datei nennt man „eth0.network“.

[Match]
Name=eth0

[Network]
DHCP=yes

Als nächstes ist unser WLAN-Device dran. Dieses bekommt keine IP zugewiesen, da sich hostapd darum kümmern wird. Die Datei „wlan0.network“ enthält folgendes:

[Match]
Name=wlan0

[Network]
DHCP=no

Als nächstes definieren wirin der Datei „br0.netdev“ die virtuelle Netzwerkbrücke:

[NetDev]
Name=br0
Kind=bridge

Dieser weisen wir unser Subnetz zu (br0.network):

[Match]
Name=br0

[Network]
Address=192.168.4.1/24
DHCP=no

Zuletzt wird noch direkt unser LAN-Interface an die virtuelle Netzwerkschnittstelle gebunden (eth1.network):

[Match]
Name=eth1

[Network]
Bridge=br0

Nun sollte die Konfiguration soweit abgeschlossen sein. Das lässt sich so überprüfen:

systemctl restart systemd-networkd #Netzwerk neustarten

Die Ausgabe von „ip a s“ sollte so ähnlich aussehen:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
 link/ether 02:86:08:82:75:2e brd ff:ff:ff:ff:ff:ff
 inet 192.168.2.208/24 brd 192.168.2.255 scope global eth0

4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN group default qlen 1000
 link/ether 00:60:6e:42:57:d9 brd ff:ff:ff:ff:ff:ff

5: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
 link/ether f8:1a:67:17:66:e5 brd ff:ff:ff:ff:ff:ff

6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
 link/ether 00:60:6e:42:57:d9 brd ff:ff:ff:ff:ff:ff
 inet 192.168.4.1/24 brd 192.168.4.255 scope global br0

Wie man sieht, hat eth0 automatisch eine IP von meinem Router bekommen. Das virtuelle Interface br0 hat das Subnetz 192.168.4.1/24 zugewiesen bekommen. Eth0 ist bereits ein Teil vom virtuellen Interface.

Iptables konfigurieren

Damit der Traffic nicht unkontrolliert zwischen den Interfaces fließt bzw. das NAT konfiguriert werden kann, müssen die Iptables genutzt werden.

Normalerweise sind diese schon installiert. Ansonsten muss man das gleichnamige Paket nachinstallieren.

Die im Arch Wiki vorgestellte Konfiguration sieht ungefähr so aus:

# Generated by iptables-save v1.4.21 on Sat Feb 28 02:05:21 2015
*nat
:PREROUTING ACCEPT [5:231]
:INPUT ACCEPT [1:61]
:OUTPUT ACCEPT [2:122]
:POSTROUTING ACCEPT [2:122]
-A POSTROUTING -s 192.168.4.0/24 -o eth0 -j MASQUERADE
COMMIT
# Completed on Sat Feb 28 02:05:21 2015
# Generated by iptables-save v1.4.21 on Sat Feb 28 02:05:21 2015
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [55:4554]
:TCP - [0:0]
:UDP - [0:0]
:fw-interfaces - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j fw-interfaces
-A FORWARD -j REJECT --reject-with icmp-host-unreachable
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
-A TCP -i br0 -p tcp -m tcp --dport 53 -j ACCEPT
-A TCP -i br0 -p tcp -m tcp --dport 67 -j ACCEPT
-A UDP -i br0 -p udp -m udp --dport 53 -j ACCEPT
-A UDP -i br0 -p udp -m udp --dport 67 -j ACCEPT
-A fw-interfaces -i br0 -j ACCEPT
COMMIT
# Completed on Sat Feb 28 02:05:21 2015

Das speichert man sich in „/etc/iptables/iptables.rules“ und lädt die Regeln neu:

systemctl restart iptables.service
systemctl enable iptables.service

Die Iptables kann man bei diesem Schritt direkt für den Autostart markieren.

Die Regeln sind so aufgebaut, dass in der Input-Chain der Traffic in UDP/TCP unterteilt wird. In diesen Unter-Chains kann man dann Traffic zulassen oder ablehnen. Wir werden später udp/tcp Port 53,67 nutzen, um darüber DHCP/DNS zu verschicken.

Die Forward-Chain „fw-interfaces“ regelt, von welchen Netzwerken Traffic wohin weitergeleitet werden darf. Hier sagen wir ganz grob, dass alles vom br0 weitergeleitet werden darf.

Ansonsten kümmert sich das conntrack-Modul um die Verwaltung der Verbindungen, in dem es die Pakete zu einer „neuen/ähnlichen/verbundenen“ Verbindung zugeordnet wird.

Ganz wichtig ist die POSTROUTING-Regel im oberen Bereich. Diese kümmert sich um das NAT, in dem alle ausgehenden Pakete vom Subnetz 192.168.4.0/24 die IP vom eth0 verpasst bekommen.

Eine relativ gute Übersicht über alle Regeln bekommt man mit:

sudo iptables -L -vn

Zusätzlich muss das IP-Forwarding im System aktiviert werden:

sudo sysctl -w net.ipv4.ip_forward=1

Dnsmasq & Hostapd konfigurieren

Kommen wir nun zum letzten Teil. Zunächst installieren wir die nötigen Pakete:

sudo pacman -S dnsmasq hostapd

Dnsmasq ist ein kleiner DHCP/DNS Server und hostapd ein Tool zum Erstellen von Access Points.

Dnsmasq

Für Dnsmasq editieren wir die Datei „/etc/dnsmasq.conf“ und setzen dort diese Optionen:

interface=br0
dhcp-range=192.168.4.100,192.168.4.200,24h

Für einen erfolgreichen Betrieb reichen die o.g. Einstellungen aus. Allerdings sollte man sich die Konfigurationsdatei durchlesen, um ggf. Sicherheitsvorkehrungen zu treffen oder weitere Features zu aktivieren.

Mit der ersten Zeile wird festgelegt, dass nur Anfragen vom Interface br0 verarbeitet werden. Die zweite Zeile legt den zu vergebenden IP-Bereich bzw. die Leasetime fest.

Danach muss man dnsmasq neustarten und im Autostart verankern:

systemctl enable dnsmasq.service
systemctl restart dnsmasq.service

Hostapd

Auch hier müssen wir eine Konfigurationsdatei bearbeiten. Beispiele und eine ausführliche Dokumentation finden sich diesmal hier: „/usr/share/doc/hostapd/*“

Die Einstellungen landen dann in der „/etc/hostapd/hostapd.conf“. Diese kann zum Beispiel so aussehen:

interface=wlan0
bridge=br0
driver=nl80211
ssid=PiWiFi
channel=1
ignore_broadcast_ssid=0
country_code=DE
ieee80211d=1
hw_mode=g
beacon_int=100
dtim_period=2
macaddr_acl=0
max_num_sta=20
rts_threshold=2347
fragm_threshold=2346
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
auth_algs=3
wmm_enabled=0
wpa=2
rsn_preauth=1
rsn_preauth_interfaces=wlan0
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_group_rekey=600
wpa_ptk_rekey=600
wpa_gmk_rekey=86400
wpa_passphrase=DASPASSWORT!

Wichtig hierbei ist nur, dass der „Interface=wlan0“ und der „Bridge=br0“ Eintrag vorhanden sind.

Zuletzt muss hostapd noch neugestartet und im Autostart verankert werden:

systemctl restart hostapd.service
systemctl enable hostapd.service

Abschließende Worte

Das von uns definierte Ziel ist nun erreicht. Wir haben einen funktionierenden kleinen Router.

Ich hatte noch probiert „traffic shaping“ umzusetzen, jedoch schien das der Treiber bzw. der Kernel nicht zu unterstützen.

~ Sebastian

]]>
https://technik.blogbasis.net/banana-pi-als-wlan-lan-router-einrichten-01-03-2015/feed 0
[ArchLinux]random Mac-address for New Wireless Connections https://technik.blogbasis.net/1299-25-01-2015 https://technik.blogbasis.net/1299-25-01-2015#respond Sun, 25 Jan 2015 14:50:37 +0000 http://technik.blogbasis.net/?p=1299 I used to travel more over the past year. Goal was different places: England, Belgian. This means I also have to use untrusted wireless connection.

This leaves a good trace wherever you go. Simply by the fact that the MAC-Address being used every time you do a connection to any wlan. This is often stored, but How long? There are good example where this information is begin havest for money.

Beside, You never know who else listen and might want uses this data. To mitigate this problem I do following: I generate a random mac address for each new connection.

Keep reading here

]]>
https://technik.blogbasis.net/1299-25-01-2015/feed 0