Aktive Hardwaretreiber ermitteln

Wer kennt das nicht, das Laptop läuft unrund, erkennt vielleicht den WLAN Chip nicht mehr sauber und man möchte den Treiber ersetzen.

Erste Frage: Woher weiß man, welcher Treiber überhaupt zuständig ist ?

Dazu gibt es den wirklich tollen Befehl „lshw“ , den wir hier nur auf das Netzwerk ansetzen. Er kann aber auch alle andere HW ermitteln, einfach das -C Network  weglassen.

$  lshw -C Network
  *-network                 
       description: Ethernet interface
       product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:02:00.0
       logical name: enp2s0
       version: 09
       serial: 40:16:7f:22:5b:43
       size: 1Gbit/s
       capacity: 1Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress msix vpd bus_master cap_list ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=r8169 driverversion=2.3LK-NAPI duplex=full firmware=rtl8168f-1_0.0.5 06/18/12 ip=192.168.0.99 latency=0 link=yes multicast=yes port=MII speed=1Gbit/s
       resources: irq:45 ioport:d000(size=256) memory:d2104000-d2104fff memory:d2100000-d2103fff
  *-network:0
       description: Ethernet interface
       physical id: 1
       logical name: virbr0
       capabilities: ethernet physical
       configuration: broadcast=yes driver=bridge driverversion=2.3 firmware=N/A ip=192.168.122.1 link=no multicast=yes
  *-network:1 DISABLED
       description: Ethernet interface
       physical id: 2
       logical name: virbr0-nic
       serial: 52:54:00:0a:cf:07
       size: 10Mbit/s
       capabilities: ethernet physical
       configuration: autonegotiation=off broadcast=yes driver=tun driverversion=1.6 duplex=full link=no multicast=yes port=twisted pair speed=10Mbit/s

In Fett finden sich hier die Angaben zu den Treiber:

driver=tun driverversion=1.6
driver=bridge driverversion=2.3
driver=r8169 driverversion=2.3LK-NAPI

„tun“ ist der Tunneltreiber, also zum Aufbau von VPN Tunneln aller Art, „bridge“ ist für die Virtualisierungsbrücke, also wenn man per Boxen, VirtualBox oder KVM virtuelle Maschinen betreibt und „r8169“ ist dann endlich der RealTek Treiber für meine Netzwerkkarte. Je nach verbauter Hardware bekommt Ihr hier natürlich andere Treiber angezeigt.

Kurz Verifizieren:

# lsmod | grep r8169
r8169                  81920  0
mii                    16384  1 r8169

„lsmod“ zeigt die geladenen Kernelmodule an und nach unserem Treiber gefragt, sagt es, daß das Modul mii diesen Treiber einmal geöffnet hat. „mii“ ist ein Standard für Netzwerkkarten. Entsprechend benannt sind die mii-tools: u.a.

# mii-tool enp2s0
enp2s0: negotiated 1000baseT-HD flow-control, link ok

Die können natürlich noch viel mehr machen.

Wo findet man diesen Treiber jetzt ?

Unter /usr/lib/modules liegen sämtliche Kernelmodule nach kernels gruppiert, also suchen wir dort :

# find  /usr/lib/modules -name „*r8169*“
/usr/lib/modules/4.8.6-201.fc24.x86_64/kernel/drivers/net/ethernet/realtek/r8169.ko.xz
/usr/lib/modules/4.8.7-200.fc24.x86_64/kernel/drivers/net/ethernet/realtek/r8169.ko.xz
/usr/lib/modules/4.8.4-200.fc24.x86_64/kernel/drivers/net/ethernet/realtek/r8169.ko.xz

„ko“ steht für „kernelobject“ und „.xz“ ist ein einfacher Kompressionsalgorithmus, damit die Treiber nicht so viel Platz wegnehmen.  Jetzt darf man nicht auf die Idee kommen, daß wenn der Treiber im einen Kernel defekt ist, man einfach die Datei von einem alten Kernel kopiert, das klappt nicht 🙂 Selbst kompilieren ist angesagt, und das ist leider ein anderes Thema.

Das Ganze hier kann natürlich nur klappen, wenn der Treiber überhaupt funktioniert.

Wie bekommt man jetzt raus, welcher Treiber der richtige wäre, wenn er denn ginge ?

Der einfachste Weg: Linux Livedisk auf einen USB Stick ziehen, davon Booten und mit lshw nachsehen, was das System dazu meint. Die Treiber in den Livedisks sind i.d.R. etwas sagen wir mal „robuster“ gewählt. Ist natürlich keine Garantie. Ich empfehle auch eine Distro Livedisk zunehmen,  die entweder komplett anders ist als die auf dem System Distro installierte, oder viel neuer bzw. älter ist. Die Chance eine andere Treiberversion zu bekommen, ist dann einfach höher.

Es kommt leider mal vor, daß ein Patch für eine Chipserie eines Herstellers, den Support für ganz alte Chips entfernt oder daß die Initialparameter zum Ansteuern des älteren Chips mit Werten neuerer Chips der gleichen Serie ausgetauscht wurden. Das passiert einfach und ist keine böse Absicht des Herstellers Eurer Distro. Die Versuchen es halt auf soviel wie möglich Laptops/Mainboards zum Laufen zu bringen.

Wenn man erstmal eine funktionierende Version gefunden hat, kann man sich aus den dazugehörigen SOURCEN einen funktionierenden Treiber kompilieren und den dann auch im System laden. Idealerweise würde man den anders nennen, als den aus der Distro, so daß man den paralell installiert haben kann, ohne das er gleich wieder übergenagelt wird.

Treiber kann man im System üblicherweise beim Booten per Kernelparameter blacklisten, so das die nicht geladen werden, auch wenn sie vorhanden sind. Man trägt dann seinen eigenen Treiber in die /etc/modprobe.conf ein und der wird dann beim Start geladen. Dummerweise muß man den Treiber für jeden Kernel neu bauen. Kleiner Tip, schaut Euch mal AKMODS an, die bauen sich bei Updates selbst zusammen, wenn ein Treiber fehlt.

RPM: wie man die Changelogs einsieht

Wenn man wissen möchte, was sich bei einem Update einer Software geändert hat, kann man auf die Herstellerseite gehen oder sich die von Fedora/RedHat zur Verfügung gestellten Changelogs eines Paketes ansehen.

In der Konsole geht das mit einem Befehl: „rpm -q –changelog pdfmod“ in diesem Fall für das Programm „pdfmod“

Schwieriger wird es, wenn der Kernel im Spiel ist. Davon gibt es auf jedem Linuxsystem i.d.R. mehrere Versionen, falls einer der Kernel mal nicht booten möchte. Gibt man als Paket also nur „kernel“ an, muß das nicht der Kernel sein, für den man das eigentlich wissen wollte. Daher muß man den kompletten Identifikationsstring angeben:

rpm -q --changelog kernel-4.8.4-200.fc24.x86_64

Mehr zum Thema RPM, gibts hier:

RPM Abhängigkeiten rausfindenDNF deinstalliert und nu ?

RPM: Reverse Depencies herausfinden

Neulich stolperte ich über einen Loginversuch mit einem Benutzer den ich nicht kannte. Der paranoide Adminteil in mir schlug natürlich sofort Alarm. Zum Glück gehörte der Benutzer nur zu einem Paket, daß ich nicht kannte, war also legitim, aber vermutlich überflüssig.

Jetzt stellt sich natürlich die Frage: was machen?

Erstmal sollte man jetzt Fakten sammeln. Der User gehörte zu einer Lib namens unbound. Sofern man keine selbstkompilierten Programm benutzt, kann man über die Systemtools recht umfangreiche Recherchen und damit Antworten auf diese Frage bekommen. Wenn man selbstkompilierte Programm einsetzt, kann man z.b. verwendete Libs einfach mit „ldd filename | grep libname“ aufspüren. Das setzt aber voraus, daß man ein kleines Script einsetzt, daß alle Binaries raussucht und checkt.

Wir gehen mal vom einfachen Fall aus und identifizieren erstmal das Paket. Dafür gibt es zwei Wege:

# yum provides /usr/lib/libunbound.so.2
 ...
 unbound-libs-1.5.1-2.fc20.i686 : Libraries used by the unbound server and client applications
 Quelle : @updates
 Übereinstimmung von:
 Dateiname : /usr/lib/libunbound.so.2
 ...

oder mit RPM (empfohlen) :

# rpm -qf /usr/lib/libunbound.so.2
 unbound-libs-1.5.1-2.fc20.i686

was darin enthalten ist, kann man sich mit rpm -ql packagename anzeigen lassen:

# rpm -ql unbound-libs
 /etc/cron.d/unbound-anchor
 /etc/unbound
 /etc/unbound/dlv.isc.org.key
 /etc/unbound/icannbundle.pem
 /etc/unbound/root.key
 /usr/lib/libunbound.so.2
 /usr/lib/libunbound.so.2.3.3
 /usr/sbin/unbound-anchor
 /usr/share/doc/unbound-libs
 /usr/share/doc/unbound-libs/LICENSE
 /usr/share/doc/unbound-libs/README
 /var/lib/unbound
 /var/lib/unbound/root.key

Aber wer braucht das Paket jetzt ?

Am Beispiel von Webalizer wollen wir das kurz zeigen. Die Abhängigkeiten eines Pakets auflisten kann man sich mit :

# rpm -q -R webalizer
 /bin/bash
 /bin/sh
 /usr/sbin/useradd
 config(webalizer) = 2.23_08-1.fc21
 crontabs
 httpd
 libbz2.so.1
 libc.so.6
 ...

Das sagt mir zwar, was Webalizer braucht, aber nicht wer das Webalizer Paket benötigt. Wenn die RPM Datenbank in Ordnung ist, geht das ganz leicht mit :

rpm -q –whatrequires packagename

Beispiel:

# rpm -q --whatrequires webalizer
 rdt-webalizer-5-1.i386

Gegencheck :

# rpm -q -R rdt-webalizer
 httpd
 webalizer
 /bin/sh
 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
 rpmlib(CompressedFileNames) <= 3.0.4-1

und schon weiß man, ob man ein Paket löschen kann oder nicht, denn wenn das Paket nicht gebraucht wird und da keine für Einen selbst wichtigen Befehle enthalten sind, kann man es einfach mit yum erase packagename entfernen, wenn, ja, wenn da nicht noch ein dicker Bug wäre 🙂

Das Aber

Am Anfang ging es ja um das Paket unbound-libs und wer das braucht. RPM meinte dazu: niemand . Was aber nicht stimmt:

# yum erase unbound-libs
Geladene Plugins: langpacks
Abhängigkeiten werden aufgelöst
–> Transaktionsprüfung wird ausgeführt
—> Paket unbound-libs.i686 0:1.5.1-2.fc20 markiert, um gelöscht zu werden
–> Abhängigkeit libunbound.so.2 wird für Paket libreswan-3.12-1.fc20.i686 verarbeitet
–> Transaktionsprüfung wird ausgeführt
—> Paket libreswan.i686 0:3.12-1.fc20 markiert, um gelöscht zu werden
–> Abhängigkeitsauflösung beendet

Abhängigkeiten aufgelöst

===========================================================================================================================================================================================================
Package                                             Arch                                        Version                                             Paketquelle                                     Größe
===========================================================================================================================================================================================================
Entfernen:
unbound-libs                                        i686                                        1.5.1-2.fc20                                        @updates                                        869 k
Entfernt für Abhängigkeiten:
libreswan                                           i686                                        3.12-1.fc20                                         @updates                                        3.1 M

Transaktionsübersicht
===========================================================================================================================================================================================================
Entfernen  1 Paket (+1 Abhängiges Paket)

Installationsgröße: 4.0 M
Ist dies in Ordnung? [j/N] :n

Das bedeutet, das RPM uns nicht alles gesagt hat, was es wußte und leider haben wir keine Möglichkeit das aus RPM rauszuquetschen. Eingangs habe ich ja auf ldd hingewiesen und mit dem überprüft man die Binaries direkt :

# ldd  /usr/libexec/ipsec/* | grep unbound
    libunbound.so.2 => /lib/libunbound.so.2 (0x4004f000)
    libunbound.so.2 => /lib/libunbound.so.2 (0x40394000)
    libunbound.so.2 => /lib/libunbound.so.2 (0x40047000)

Da haben wir die unbound-libs und damit die Abhängigkeit. Dank der Gründlichkeit von Yum, die einem desöftern auf den Senkel geht, konnte das System gerettet werden, denn hinter libreswan steht Pluto und damit die IPSEC VPN Serverfiles. Keine gute Idee, die zu löschen.