Posts Tagged ‘Debian’

Sonntag, 21. Juli 2019

pixelserver-tls läuft nicht unter Debian 10 „Buster“

Mittels eines „manuellen“ Canary-Releases habe ich vor einer Woche einen meiner Linux-Server hier im Haus von Debian 9 „Stretch“ auf Debian 10 „Buster“ migriert.

Wie es zu erwarten war, klappte das nicht ganz ohne Schluckauf. Beispielsweise schaltet sich der Monitor meines Lenovo ThinkPads X201 (P/N 3626GN7) nicht mehr automatisch aus. Leider habe ich die Lösung im Internet noch nicht gefunden.

Das beunruhigendste Problem war aber folgende Fehlermeldung von monit, die nach der Neukompilierung von pixelserv-tls mit Debian 10 „Buster“ in meinem Postfach landete:

Connection failed Service pixelserv-tls 

	Date:        Mon, 15 Jul 2019 22:44:25
	Action:      restart
	Host:        ADBLOCKER
	Description: failed protocol test [HTTP] at [10.1.2.3]:443 [TCP/IP TLS] -- SSL connection error: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error

Your faithful employee,
Monit

Der Aufruf der Statusseite unter http://10.1.2.3/servstats funktionierte ebenfalls nicht.

Am letzten Freitag fand ich nun etwas Zeit, um das Problem genauer anzuschauen.

Software-Versionen

pixelserv-tls hat seit Monaten keine Anpassung mehr erfahren — beim Abgleich meiner Sourcen mit denjenigen auf GitHub gab es nur in cert.c eine Anpassung, die ich einspielte, aber eigentlich nichts mit dem hier beschriebenen Problem zu tun hat.

Eine Ursache für das Problem war aber, dass die OpenSSL-Library, gegen welche pixelserv-tls kompiliert wird, aktualisiert worden war. Auf einem System mit Stretch (stable) waren installiert …

# dpkg --list | grep -i ssl
ii  libcurl3:amd64                       7.52.1-5+deb9u9                   amd64        easy-to-use client-side URL transfer library (OpenSSL flavour)
ii  libcurl4-openssl-dev:amd64           7.52.1-5+deb9u9                   amd64        development files and documentation for libcurl (OpenSSL flavour)
ii  libflac8:amd64                       1.3.2-1                           amd64        Free Lossless Audio Codec - runtime C library
ii  libgnutls-openssl27:amd64            3.5.8-5+deb9u4                    amd64        GNU TLS library - OpenSSL wrapper
ii  libio-socket-ssl-perl                2.044-1                           all          Perl module implementing object oriented interface to SSL sockets
ii  libnet-smtp-ssl-perl                 1.04-1                            all          Perl module providing SSL support to Net::SMTP
ii  libnet-ssleay-perl                   1.80-1                            amd64        Perl module for Secure Sockets Layer (SSL)
ii  libssl-dev:amd64                     1.1.0j-1~deb9u1                   amd64        Secure Sockets Layer toolkit - development files
ii  libssl-doc                           1.1.0j-1~deb9u1                   all          Secure Sockets Layer toolkit - development documentation
ii  libssl1.0.0:amd64                    1.0.1t-1+deb8u6                   amd64        Secure Sockets Layer toolkit - shared libraries
ii  libssl1.0.2:amd64                    1.0.2r-1~deb9u1                   amd64        Secure Sockets Layer toolkit - shared libraries
ii  libssl1.1:amd64                      1.1.0j-1~deb9u1                   amd64        Secure Sockets Layer toolkit - shared libraries
ii  mitmproxy                            0.18.2-6                          all          SSL-capable man-in-the-middle HTTP proxy
ii  openssl                              1.1.0j-1~deb9u1                   amd64        Secure Sockets Layer toolkit - cryptographic utility
ii  perl-openssl-defaults:amd64          3                                 amd64        version compatibility baseline for Perl OpenSSL packages
ii  python-backports.ssl-match-hostname  3.5.0.1-1                         all          Backport of the Python 3.5 SSL hostname checking function
ii  python-brotli                        0.5.2+dfsg-2                      amd64        lossless compression algorithm and format (Python 2 version)
ii  python-certifi                       2016.2.28-1                       all          root certificates for validating SSL certs and verifying TLS hosts
ii  python-openssl                       16.2.0-1                          all          Python 2 wrapper around the OpenSSL library
ii  python-passlib                       1.7.0-2                           all          comprehensive password hashing framework
ii  python-service-identity              16.0.0-2                          all          Service identity verification for pyOpenSSL (Python 2 module)
ii  ssl-cert                             1.0.39                            all          simple debconf wrapper for OpenSSL

… auf dem neuen System war hingegen installiert:

# dpkg --list | grep -i ssl
ii  libcurl4:amd64                 7.64.0-4                     amd64        easy-to-use client-side URL transfer library (OpenSSL flavour)
ii  libgnutls-openssl27:amd64      3.6.7-4                      amd64        GNU TLS library - OpenSSL wrapper
ii  libio-socket-ssl-perl          2.060-3                      all          Perl module implementing object oriented interface to SSL sockets
ii  libnet-smtp-ssl-perl           1.04-1                       all          Perl module providing SSL support to Net::SMTP
ii  libnet-ssleay-perl             1.85-2+b1                    amd64        Perl module for Secure Sockets Layer (SSL)
ii  libssl-dev:amd64               1.1.1c-1                     amd64        Secure Sockets Layer toolkit - development files
ii  libssl-doc                     1.1.1c-1                     all          Secure Sockets Layer toolkit - development documentation
ii  libssl1.0.0:amd64              1.0.1t-1+deb8u7              amd64        Secure Sockets Layer toolkit - shared libraries
ii  libssl1.1:amd64                1.1.1c-1                     amd64        Secure Sockets Layer toolkit - shared libraries
ii  libzstd1:amd64                 1.3.8+dfsg-3                 amd64        fast lossless compression algorithm
ii  mitmproxy                      4.0.4-5                      all          SSL-capable man-in-the-middle HTTP proxy
ii  openssl                        1.1.1c-1                     amd64        Secure Sockets Layer toolkit - cryptographic utility
ii  perl-openssl-defaults:amd64    3                            amd64        version compatibility baseline for Perl OpenSSL packages
ii  python3-brotli                 1.0.7-2                      amd64        lossless compression algorithm and format (Python 3 version)
ii  python3-certifi                2018.8.24-1                  all          root certificates for validating SSL certs and verifying TLS hosts (python3)
ii  python3-openssl                19.0.0-1                     all          Python 3 wrapper around the OpenSSL library
ii  python3-passlib                1.7.1-1                      all          comprehensive password hashing framework
ii  ssl-cert                       1.0.39                       all          simple debconf wrapper for OpenSSL

Relevant ist das Paket libssl-dev — auf Stretch war die Library 1.1.0j-1~deb9u1, in Buster 1.1.1c-1. Gegen diese kompiliert pixelserv-tls.

TLSv1.3?

Um Probleme mit TLSv1.3 auszuschliessen, hackte ich util.h und stellte das Script so ein, dass TLSv1.3-Support nie einkompiliert wird:

...
# ifdef TLS1_3_VERSION
#   define FEAT_TLS1_3  " no_tls1_3"
# else
#   define FEAT_TLS1_3  " no_tls1_3"
# endif
...

Leider half dies nichts zur Lösung des Problems.

Indem man pixelserv-tls ausführt, erfährt man, ob TLSv1.3 einkompiliert ist oder nicht:

$ pixelserv-tls --help
pixelserv-tls 2.2.1 (compiled: Jul 15 2019 22:34:41 flags: tfo tls1_3)
...

Respektive:

$ pixelserv-tls --help
pixelserv-tls 2.2.1 (compiled: Jul 15 2019 22:48:04 flags: tfo no_tls1_3)
...

Dasselbe erfährt man auch in error.log, wenn pixelserv-tls gestartet wird:

...
Jul 19 19:52:46 localhost pixelserv-tls[28352]: pixelserv-tls 2.2.1 (compiled: Jul 19 2019 19:51:13 flags: tfo no_tls1_3) options: 10.1.2.3 -u root -p 80 -k 443 -l 5 -z /tmp/pixelserv
...

AppArmor?

Zuerst vermutete ich ein Problem mit AppArmor, welches in Debian 10 out-of-the-box aktiviert ist und läuft. Doch nachdem ich mich ein wenig eingelesen hatte, war mir klar, dass AppArmor nur dann zur Anwendung kommt, wenn ein entsprechendes Applikationsprofil erstellt wurde. Auch scheint es keine Standardeinstellungen zu geben, die auf alle Prozesse angewendet werden.

Log-Analyse

Basierend auf den lokalen Einstellungen loggt pixelserv-tls mehr oder weniger hilfreiche Informationen in das syslog. Auf Grund der von mir temporär gewählten Kommandozeilenoption -l 4 („4“ steht für den Loglevel „info“) las ich dort:

$ tail -f /var/log/error.log
...
Jul 19 19:04:00 localhost pixelserv-tls[22361]: create_child_sslctx: cannot find or use $CERTDIR/_.google-analytics.com
Jul 19 19:04:00 localhost pixelserv-tls[22361]: tls_clienthello_cb: fail to create sslctx or cache _.google-analytics.com
...

Fragezeichen über Fragezeichen — haben wir ein Problem mit den Zertifikatsdateien?

Datei- und Verzeichnisberechtigungen

Dann vermutete ich Probleme beim Lesen und Schreiben der Zertifikate, obwohl ich an der Ordnerstruktur und den Ordner- und Dateiberechtigungen nichts geändert hatte. Sowohl das Starten von pixelserv-tls mit der Option -u root (normalerweise läuft pixelserv-tls unter „nobody“ — Sicherheitstechnisch eine sehr weise Einstellung, da die Software wie auch OpenSSL Schwachstellen aufweisen könnten, die dann jeder im lokalen Netzwerk ausnützen könnte) als auch das Verschieben des Zertifikatsordner nach /tmp/pixelserv lösten das Problem nicht.

Mit strace die Syscalls auf das Dateisystem anschauen

Auch die Verwendung von strace — einem Werkzeug, das ich nur bei ganz hartnäckigen Problemen zur Anwendung kommen lasse, zeigte keinen Hinweis, der mich auf die richtige Fährte gebracht hätte. Was ich lernte: Mittels der Option -p kann man sich bei strace in einen bereits laufenden Prozess „einklinken“. Hier das Resultat

# strace -p %PID%
...
select(8, [5 6 7], NULL, NULL, NULL)    = 1 (in [6])
accept(6, {sa_family=AF_INET, sin_port=htons(64242), sin_addr=inet_addr("10.0.1.102")}, [16]) = 9
fcntl(9, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(9, F_SETFL, O_RDWR)               = 0
setsockopt(9, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(9, SOL_SOCKET, SO_RCVTIMEO, "\0\0\0\0\0\0\0\0\360I\2\0\0\0\0\0", 16) = 0
getsockname(9, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("10.1.2.3")}, [128->16]) = 0
read(9, "\26\3\1\0\353", 5)             = 5
read(9, "\1\0\0\347\3\3n\277\307zl\26\2155A\257@\nFK\272\326x:Z\320\32:\347\32\2\217"..., 235) = 235
stat("/usr/local/apps/pixelserv/certs/_.optimizely.com", {st_mode=S_IFREG|0644, st_size=1596, ...}) = 0
openat(AT_FDCWD, "/usr/local/apps/pixelserv/certs/_.optimizely.com", O_RDONLY) = 10
fstat(10, {st_mode=S_IFREG|0644, st_size=1596, ...}) = 0
read(10, "-----BEGIN CERTIFICATE-----\nMIIB"..., 4096) = 1596
close(10)                               = 0
getpid()                                = 23461
sendto(3, "<27>Jul 19 19:21:47 pixelserv-tl"..., 131, MSG_NOSIGNAL, NULL, 0) = 131
getpid()                                = 23461
sendto(3, "<27>Jul 19 19:21:47 pixelserv-tl"..., 109, MSG_NOSIGNAL, NULL, 0) = 109
write(9, "\25\3\3\0\2\2P", 7)           = 7
getpid()                                = 23461
sendto(3, "<28>Jul 19 19:21:47 pixelserv-tl"..., 141, MSG_NOSIGNAL, NULL, 0) = 141
shutdown(9, SHUT_RDWR)                  = 0
close(9)

Da sah alles Bestens aus — das Zertifikat kann gelesen werden, wie die erste Zeile read(10, "-----BEGIN CERTIFICATE-----\nMIIB"..., 4096) = 1596
verdeutlicht.

Quellcode-Analyse

Als nächstes muss man sich in solchen hartnäckigen Fällen mit dem Source-Code auseinandersetzen. Ich durchsuchte das GitHub-Repository nach folgender Fehlermeldung: „cannot find or use“. Fündig wurde ich dazu in cert.c, ab Zeile 814:

...
if(SSL_CTX_use_certificate_file(sslctx, full_pem_path, SSL_FILETYPE_PEM) <= 0
       || SSL_CTX_use_PrivateKey_file(sslctx, full_pem_path, SSL_FILETYPE_PEM) <= 0)
    {
        SSL_CTX_free(sslctx);
        log_msg(LGG_ERR, "%s: cannot find or use %s\n", __FUNCTION__, full_pem_path);
        return NULL;
    }
...

Na toll! Die Log-Meldung wird somit generiert, wenn die OpenSSL-nativen-Funktionen SSL_CTX_use_certificate_file() oder SSL_CTX_use_PrivateKey_file() einen Wert zurückgeben, der kleiner gleich 0 ist. Gemäss Dokumentation der quelloffenen Library meldet ein Rückgabewert von 1, dass die Funktion erfolgreich ausgeführt wurde.

Quellcode hacken

Ich bin kein C-Programmierer, aber mir gefiel die Programmlogik aus folgenden Gründen nicht:

  1. Wenn eine der beiden Funktionen einen Fehler zurückgibt, bricht der Programmcode ab. Schön, dass man den Code damit komprimiert hat, aber beim Debugging wäre es noch nett zu wissen, welche der beiden Funktionen den Fehler generiert.
  2. Die Fehlermeldung "%s: cannot find or use %s\n" mit den zwei Variablen "Funktion" sowie dem Pfad zum Zertifikat sagt rein gar nichts darüber, was denn nun konkret schiefgegangen ist.
  3. <= 0 empfinde ich als den falschen Ansatz: Ich würde stattdessen prüfen, ob der Rückgabewert NICHT 1 entspricht (an dem sind wir interessiert).

Um dem Problem näher zu kommen war es deshalb nötig, dass ich selbst Hand an den Code anlegte, die Logik entzwirnte sowie die in OpenSSL intern vorhandenen detaillierten Fehlermeldungen in das Log ausgab. Natürlich fand ich über etwas Googlen heraus, wie man OpenSSL diese Fehlermeldung entlockt. Dies führte zu folgendem Code:

...
    if(!SSL_CTX_use_certificate_file(sslctx, full_pem_path, SSL_FILETYPE_PEM)) {
        log_msg(LGG_ERR, "%s: SSL_CTX_use_certificate_file error for file %s with error %s\n", __FUNCTION__, full_pem_path, ERR_error_string( ERR_get_error(), NULL ));
    }
    if(!SSL_CTX_use_PrivateKey_file(sslctx, full_pem_path, SSL_FILETYPE_PEM)) {
        log_msg(LGG_ERR, "%s: SSL_CTX_use_PrivateKey_file error for file %s with error %s\n", __FUNCTION__, full_pem_path, ERR_error_string( ERR_get_error(), NULL ));
    }
...

Die wahre Fehlermeldung

Neu kompiliert, installiert und gestartet, dann die Werbeschleuder SPIEGEL Online angesurft und das Log überprüft:

$ tail -f /var/log/error.loa
...
create_child_sslctx: SSL_CTX_use_certificate_file error for file /tmp/pixelserv/_.ioam.de with error error:140AB18F:SSL routines:SSL_CTX_use_certificate:ee key too small
...

"ee key too small"? Now we're talking! Eine erneute Google-Suche ergab, dass sich OpenSSL 1.1.1 (im Gegensatz zu 1.1.0) weigert, ein Zertifikat zu verarbeiten, dessen RSA-Schlüssellänge kleiner als 2048 Bit ist.

Die Lösung des Problems

Ich nahm deshalb folgende zwei Anpassungen vor:

Zuerst einmal generierte ich eine neue ca.key mit einer Schlüssellänge von 2048 Bits:

$ openssl genrsa -out $CERTDIR/ca.key 2048

Anschliessend passte ich auch noch cert.c an, da dort die mittlerweile als schwach erachtete Schlüssellänge (1024) hartkodiert ist:

...
if (RSA_generate_key_ex(rsa, 2048, e, NULL) < 0)
...

Seit ich pixelserv-tls ein letztes Mal neu kompiliert und installiert habe, funktioniert das Schwarze Loch für alle Arten von Web-basierten Trackern wieder einwandfrei.

Verifikation

Überprüfen kann man das ... natürlich auch mit openssl auf einem separaten Client:

pixelserv-tls funktioniert nicht (richtig)

$ openssl s_client -connect www.googleadservices.com:443
CONNECTED(00000003)
140735858492360:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:s23_clnt.c:802:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 308 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1563537109
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

pixelserv-tls funktioniert (richtig)

Und jetzt:

CONNECTED(00000003)
depth=1 CN = Pixelserv CA
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
 0 s:/CN=10.1.2.3
   i:/CN=Pixelserv CA
 1 s:/CN=Pixelserv CA
   i:/CN=Pixelserv CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MII...=
-----END CERTIFICATE-----
subject=/CN=10.1.2.3
issuer=/CN=Pixelserv CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2148 bytes and written 434 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: F66E6966BF7CE8F970AF4834A1CC45FE396D1F7B041F512CA5B3F65419EACD24
    Session-ID-ctx: 
    Master-Key: 7EE1C54219A4CABF0BEB73BB420C93DD4F51F5F319897937137B9C1093045B4EB91B0FD50F30154DF5A7D18AD95A493C
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 3600 (seconds)
    TLS session ticket:
    0000 - e8 63 17 bb 31 c0 91 7d-95 eb f8 b4 78 dc a6 89   .c..1..}....x...
    0010 - be 14 43 2c ac cc 4c dd-f3 e9 9d f5 cb 36 46 a4   ..C,..L......6F.
    0020 - c6 9a 67 7c fb 83 a1 a6-6d 74 6b 62 4e b5 60 33   ..g|....mtkbN.`3
    0030 - 8b 1b 5f 1f cf ba c6 bf-73 c0 8a 7d 31 db 8a 75   .._.....s..}1..u
    0040 - 81 8b b3 c3 e5 76 1e 34-c3 3d 2e 11 e4 58 a3 fc   .....v.4.=...X..
    0050 - 73 5b 2e 9c 13 f5 64 4e-c3 26 10 98 96 e1 64 aa   s[....dN.&....d.
    0060 - ce 41 aa cd 54 68 12 a1-87 10 98 cc f0 e5 e9 d9   .A..Th..........
    0070 - de ec e6 2e 83 80 8f 51-71 ff 07 eb a7 b2 66 ae   .......Qq.....f.
    0080 - ad b5 44 c0 47 06 eb b7-5f 19 c2 74 5d 1f 47 20   ..D.G..._..t].G 
    0090 - 5d 93 0f 57 c4 ee 86 b7-7e 7f e3 2a ed 57 27 43   ]..W....~..*.W'C

    Start Time: 1563745313
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---

Das Problem habe ich nun auch im GitHub Issue-Tracker des Projekts beschrieben ("Use 2048-bit RSA key to make pixelserv-tls work on Debian 10 "Buster""). Eigentlich hätte ich den Patch ja auch gleich selber als Pull Request hochladen können, doch diese Funktion von Git verstehe ich immer noch nicht wirklich richtig ... hoffen wir, dass der Maintainer die Ursache des Problems deshalb selber bald beseitigt.

Tags: , , , , , , , , ,
Labels: IT

1 Kommentar | neuen Kommentar verfassen

Sonntag, 10. März 2019

pip: pkgcairo: Fehlende Debian-Pakete

Damit pip das Paket pkgcairo installieren kann, müssen auf dem Debian-System folgende Pakete installiert sein:

# apt-get install libcairo2 libcairo2-dev libjpeg-dev libgif-dev python-cairo

Leider halfen diese Pakete auf meinem System auch nicht viel, denn:

...
running build_ext
pycairo: new API
error: pycairo >= 1.11.1 required, 1.8.8 found.

Tags: , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

pip: pycurl: Could not run curl-config: [Errno 2] No such file or directory

Damit pip das Paket pycurl installieren kann, müssen auf dem Debian-System folgende Pakete installiert sein:

# apt-get install libcurl4-openssl-dev libssl-dev

Quelle: “Could not run curl-config: [Errno 2] No such file or directory” when installing pycurl

Sonst liest man folgende Fehlermeldungen:

...
Collecting pycurl
Downloading https://files.pythonhosted.org/packages/e8/e4/0dbb8735407189f00b33d84122b9be52c790c7c3b25286826f4e1bdb7bde/pycurl-7.43.0.2.tar.gz (214kB)
100% |████████████████████████████████| 215kB 15.2MB/s 
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 913, in <module>
    ext = get_extension(sys.argv, split_extension_source=split_extension_source)
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 582, in get_extension
    ext_config = ExtensionConfiguration(argv)
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 99, in __init__
    self.configure()
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 227, in configure_unix
    raise ConfigurationError(msg)
__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

pip: pygobject: Failed building wheel for pygobject

Damit pip das Paket pygobject installieren kann, müssen auf dem Debian-System folgende Pakete installiert sein:

# apt-get install libglib2.0-dev libgirepository1.0-dev

Sonst liest man folgende Fehlermeldungen:

...
running build_ext
Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'glib-2.0' found
Command '('pkg-config', '--print-errors', '--exists', 'glib-2.0 >= 2.38.0')' returned non-zero exit status 1

Try installing it with: 'sudo apt install libglib2.0-dev'

----------------------------------------
Failed building wheel for pygobject
Running setup.py clean for pygobject

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Montag, 23. Oktober 2017

Mit Debian Rescue eine CD mounten und auf einen USB-Stick kopieren

Unsere Wohnung ist (fast) eine DVD/CD-ROM-freie Zone. All unsere Endgeräte verfügen mittlerweile über kein optisches Laufwerk mehr.

Doch was nun, wenn man eine CD erhält, deren Daten man auf die Endgeräte laden möchte?

Man nimmt den herumliegenden Lenovo T400 zur Hilfe, welcher noch über ein CD-ROM-Laufwerk verfügt. Leider fehlt der guten Maschine die Festplatte, weil der auf AliExpress.com gekaufte Festplatten-Käfig sowie die Plasticschienen derzeit gerade aus China unterwegs in die Schweiz sind.

Damit man auf der Kiste also ein Linux zum Laufen kriegt, bootet man von einem USB-Stick, auf welchen die Netinst-Version von Debian 9.0 kopiert wurde. (tftp Netzwerk-Boot wäre noch ein Todo für die langen Winternächte).

Nach ein paar Kapriolen, um das Boot-Laufwerk auf USB umzubiegen, startet der Laptop mit der graphischen Installationsoberfläche. Dort wählt man unter Advanced Options den Rescue Modus ein (ohne graphische Benutzeroberfläche).

Nach viel zu vielen Dialogfenster hat man endlich eine Shell zur Hand. Sobald man die CD eingelegt hat, gibt man folgende Befehl ein:

# mkdir /mnt/cdrom
# mount /dev/cdrom /mnt/cdrom

Unter /mnt/cdrom sieht man mit ls -l den Inhalt der CD.

Hat man den zweiten USB-Stick, auf welchen die Daten der CD kopiert werden sollen, bereits bei der Anzeige des Debian-Menus eingestöpselt, könnte man dem Rescue-System in einem Dialog-Fenster sagen, diesen Stick ebenfalls bereits zu mounten.

Hat man dies nicht gemacht, sucht man sich zuerst einen weiteren freien USB-Port am Gerät und steckt den USB-Stick ein.

Anschliessend sucht man sich mit fdisk -l den Devicenamen sowie den Namen der Partition hervor. Gleichzeitig sieht man auch, ob der Stick mit FAT16/32 formatiert ist — ich konnte in meinem Versuch nur solche Sticks mounten.

In unserem Fall trägt die Partition des USB-Sticks den Pfad /dev/sdb1, deshalb mountet man den Stick so:

# mkdir /mnt/usb2
# mount /dev/sdb1 /mnt/usb2

Anschliessend wechselt man auf das CD-Laufwerk und verwendet — leider, da rsync in dieser Umgebung fehlt — folgenden Befehl, um die Daten auf den USB-Stick zu kopieren:

# cd /mnt/cdrom
# cp -R . /mnt/usb2

Doch OBACHT — nur weil der Kopierbefehl abgeschlossen ist, heisst das leider noch nicht, dass alle Daten bereits auf den USB-Stick geschrieben wurden:

USB write: delay between when Ubuntu says its done and it actually being done

Bevor man den USB-Stick ausstöpselt, muss man mit folgendem Befehl sicherstellen, dass auch wirklich restlos alle Daten auf den Stick geschrieben wurden:

# sync

Danach werkelt sync, was locker noch einmal ein oder zwei Minuten dauern kann.

Anschliessend kann man den Stick mit folgendem Befehl für die Entfernung bereitmachen:

# umount /mnt/usb2

Sobald dieser Befehl ausgeführt wurde, kann man den Stick aus dem USB-Port entfernen und auf einem Endgerät einstöpseln.

Tags: , , , , , , , , , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 14. Oktober 2017

Wenn eth0 plötzlich enp1s0 oder ähnlich kryptisch heisst

Heute habe ich einen meiner Lenovo-„Server“ ausgetauscht: T400 raus, T420 rein. Dabei habe ich die SSD vom alten Server in den neuen Server eingebaut — bei Windows ein Ding der Unmöglichkeit, bei Linux: Läuft bei mir (fast).

Leider gab es ein gravierendes Problem, was die Downtime etwas verlängert und an meinem Ehrgeiz gekratzt hat: Die Netzwerk-Interfaces kamen nicht hoch, weshalb das Gerät ohne Intra- und Internet-Verbindung dastand.

Dank Laptop-Tastatur und -Bildschirm fiel immerhin das Debugging leicht.

Die Ausgabe von ifconfig zeigte, dass nur das Loopback-Interface vorhanden war. Was zum Teufel? Den Ethernet-Netzwerkanschluss sah ich mit meinen eigenen Augen vor mir, ein Kabel war eingesteckt und er blinkte auch fröhlich vor sich hin.

# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1  (Local Loopback)
        RX packets 184819  bytes 33744666 (32.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 184819  bytes 33744666 (32.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Mit dem Befehl ip a dann die Gewissheit, dass die erwarteten Schnittstellen auch tatsächlich da waren:

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.10/24 brd 10.10.10.255 scope global enp1s0
       valid_lft forever preferred_lft forever
3: wlp3s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff

Wie sich herausstellte, hiess auf dem T420 die Netzwerkschnittstelle nicht wie erwartet und üblich eth0, sondern enp1s0.

Der Grund (bitte nicht lachen): Predictable Network Interface Names. Verursacht durch die Datei /etc/udev/rules.d/70-persistent-net.rules, welche bei der Installation auf dem T400 erstellt worden war. Linux fand die darin definierten Interfaces auf dem T420 nicht mehr.

Die Lösung des Problems fand sich in einem Benutzerforum zum Thema How to rename network interface in 15.10?.

An der Originaldatei …

...
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="11:11:11:11:11:11", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
...

… nahm ich folgende Anpassung vor:

...
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:00:00:00:00:00", NAME="eth0"
...

Wichtig: 11:11:11:11:11:11 ist die MAC-Adresse des Ethernet-Interfaces auf dem T400, 00:00:00:00:00:00 ist die MAC-Adresse des Ethernet-Interfaces auf dem T420. Als ich zuerst nur die MAC-Adresse geändert habe, kam die Netzwerkschnittstelle nicht hoch. Erst die Verschlankung des Eintrags auf die obige Form funktionierte: Nach dem nächsten Reboot war eth0 wieder vorhanden und alle Netzwerkdienste kamen hoch.

Tags: , , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 14. Oktober 2017

Vergesst Intel NUCs und RPIs als Linux-Server zu Hause

Bei mir im Haushalt habe ich beides stehen:

Einen Raspberry Pi 3, der auf einem 22 Zoll-Bildschirm neben der Wohnungstüre hochkant ein Dashboard mit Zeitzonen, Abfahrten von Trams und Bussen, Temperaturen von Netatmo und Sense Peanut-Sensoren, Wetterprognosen, Twitter-Meldungen, Aktienkurse und Umrechnungskurse anzeigt (vor Jahren inspiriert durch einen Besuch bei Cyon in Basel).

Der Raspberry Pi ist (vermeintlich) günstig, benötigt aber ein Gehäuse und flinke SD-Karten. Immerhin läuft er mit dem Strom eines USB-Ports eines Bildschirms und hat mittlerweile Bluetooth und WLAN direkt eingebaut. Trotzdem ein Gefrickel, was die Installation und Konfiguration angeht. Mit nicht immer zeitnahem Software-Support. Wehe, wenn ein Software-Update fehlschlägt oder eine Fehlkonfiguration ausgerollt wird — viel Spass, die SD-Karte unter macOS zu mounten, die Konfigurationsdateien anzupassen, neu zu booten und das Spiel von vorne zu wiederholen, bis man den wirklich Schuldigen gefunden hat (der DAU an der Tastatur, meistens). Ausserdem ist die Hardware sehr schwachbrünstig (Chrome im Fullscreen lässt ihn fast austicken) und eignet sich nicht für jeden Einsatzzweck.

Andererseits einen Intel NUC, welcher primär Netzwerkaufgaben übernimmt: OpenVPN, DHCP, DNS und UniFi-Controller.

Performance-mässig nichts auszusetzen, aber auf Grund der Dimensionen nicht wartungsfreundlich. Und teuer, weshalb meistens Overkill für Standardaufgaben im heimischen Haushalt.

Mein Tipp: Wer die perfekte Hardware für einen Linux-Server sucht, halte nach älteren, gebrauchten Lenovo-Laptops Ausschau. Auf dem Gebrauchtmarkt kriegt man die Modelle X200, X201 und X220 (12 Zoll-Monitor) sowie T400 und T420 (14 Zoll-Monitor) zwischen 50 und 250 CHF.

Wieso ich auf diese Dinger schwöre?

  • x86 respektive x86_64 Prozessorarchitektur, auf welchem ein hundsnormales Linux ohne irgendwelche Handstände läuft
  • Ausgezeichneter Linux-Treibersupport — das neueste Debian ISO mit Etcher auf einen USB-Stick schreiben, Standardinstallation durschpielen, läuft (abgesehen von der leidigen Geschichte mit den WLAN-Treibern, aber solche Server betreibt man am Ethernet, nicht im WLAN).
  • Günstig
  • Man findet sie auf Ricardo, Tutti und Anibis wie Sand am Meer
  • Eingebaute Tastatur und Bildschirm — Debugging leichtgemacht (man wird nie einen Ersatzbildschirm und eine USB-Tastatur anschleppen müssen, wenn das Ding mal die Netzwerkverbindung verliert)
  • Stromsparend
  • Leise
  • Überhitzen nicht kaum
  • RAM und Festplatten lassen sich problemlos aufrüsten; entweder mit kleinen, flinken SATA SSDs oder aber mit fetten, aber etwas teureren Magnetplatten
  • Funktionieren zugeklappt und nehmen dann etwas mehr als die Fläche eines Papierstapels und die Höhe eines Buches (kein Tolstoi) ein
  • Haben die „USV“ (richtig geraten, die Laptop-Batterie) gleich eingebaut. Und wenn deren Kapazität wegen Memory-Effekten und dergleichen nachlässt: Günstig ersetzbar.
  • Docks findet man auf dem Gebrauchtmarkt auch viele (wobei ich immer noch nicht sicher bin, ob es besser ist, diese Dinger im oder ausserhalb des Docks zu betreiben)

Tags: , , , , , , , , , ,
Labels: IT, Shopping

3 Kommentare | neuen Kommentar verfassen

Samstag, 1. Juli 2017

Debian von einem bootbaren USB-Stick installieren

Kürzlich ist Debian 9.0 Stretch erschienen. Zeit, meinen USB-Stick mit den neuesten Installationsdateien zu bestücken, um zukünftige Linux-PCs von diesem Stick aus aufsetzen zu können.

Hierzu habe ich mir das neueste Debian Netinst ISO (für „Netzwerk-Installation“) heruntergeladen, welches man hier findet:

Debian — Network install from a minimal CD

Anschliessend habe ich den USB-Stick an meinen Mac mini eingesteckt (muss zwingend vor dem Starten von unetbootin gemacht werden, da das Drop-Down der Zielvolumes sonst leer bleibt), das bereits installierte unetbootin gestartet, das ISO ausgewählt und danach auf den USB-Stick kopieren lassen. Fertig.

Mangels eines verfügbaren, leeren Geräts konnte ich den Stick noch nicht testen, dieses Prozedere hat aber mit Debian 8.3 (Jessie) bereits perfekt funktioniert.

Tags: , , , , , , , , , ,
Labels: IT, Linux

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 31. August 2016

MIBs unter Debian installieren

Da es sich dabei um teilweise Copyright-geschützte Werke handelt, stehen sie über die normalen Debian-Repositories nicht zur Verfügung. Nachfolgend ist erklärt, wie man diese trotzdem installiert.

/etc/apt/sources

Hier fügt man die non-free-Pakete hinzu:

...
deb 		http://debian.ethz.ch/debian/ testing main non-free
...
deb		http://debian.ethz.ch/debian/ stable main non-free
...

Danach aktualisiert man das Paketverzeichnis:

# apt-get update

Jetzt findet Debian das Paket snmp-mibs-downloader:

# apt-get install snmp-mibs-downloader

Sobald das Paket installiert ist, muss man das Bash-Script ausführen, welches unter /usr/bin/download-mibs liegt:

# download-mibs

Die (von mir nicht berührten) Konfigurationsdateien des Tools liegen unter /etc/snmp-mibs-downloader.

Das Script lädt allerlei MIBs herunter, deponiert diese zeitweile in /tmp und kopiert sie dann in das Verzeichnis /var/lib/mibs.

Interessanterweise finden sich gemäss einer E-Mail-Konversation auch unter /usr/share/snmp/mibs/ weitere MIBs. Ich denke aber, dass snmpwalk diese ignoriert.

/etc/snmp/snmp.conf

Damit snmpwalk diese MIBs nun auch wirklich interpretiert, muss noch die Konfigurationsdatei angepasst, das heisst konkret die Zeile mibs : auskommentiert werden:

# As the snmp packages come without MIB files due to license reasons, loading
# of MIBs is disabled by default. If you added the MIBs you can reenable
# loading them by commenting out the following line.
#mibs :

Quelle: SNMP Clients — Command line client applications

Um zu sehen, ob man richtig liegt, führt man am Besten den folgenden Testbefehl aus (vorausgesetzt, auf dem Server lauscht auch ein snmpd):

$ snmpwalk -c s1kr1t -v 1 localhost hrStorageTable
HOST-RESOURCES-MIB::hrStorageIndex.1 = INTEGER: 1
...

Auf einem System, welche diese MIBs nicht installiert hat, erhält man stattdessen folgende Fehlermeldung:

$ $ snmpwalk -c s1kr1t -v 1 localhost hrStorageTable
hrStorageTable: Unknown Object Identifier (Sub-id not found: (top) -> hrStorageTable)

Probiert man es mit der OID, klappt es — logischerweise:

$ snmpwalk -c s1kr1t -v 1 localhost .1.3.6.1.2.1.25.2.3
iso.3.6.1.2.1.25.2.3.1.1.1 = INTEGER: 1
...

Tags: , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 27. August 2016

Dem Raspberry Pi 3 chinesische Schriftzeichen beibringen

Seit einigen Woche betreibe ich mein heimisches Dashboard auf einem Raspberry Pi 3 und bin von der Performance begeistert! Sogar Chrome kriegt man nun als Installationspaket mitgeliefert.

Leider zeigte Chrome nach der Standardinstallation chinesische Schriftzeichen (bei den Währungsinfos) nicht an. Folgende Pakete rüsten chinesische Schriftzeichen nach:

# apt-get install fonts-arphic-bkai00mp fonts-arphic-bsmi00lp fonts-arphic-gbsn00lp

Quelle: Chinese Debian Mini Howto — 2. Installing Chinese Fonts

Tags: , , , , , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen