Alle Beiträge von adlerweb

Video: Karnevalsumzug Saffig 2018

Wie auch die letzten Jahre war ich mit meiner Kamera beim Karnevalsumzug in Saffig unterwegs. Wie üblich gibt es die Aufzeichnung drüben auf YouTube

http://www.youtube.com/watch?v=s0fqmJum5Jk

VMWare vCenter Server Appliance mit Proxy aktualisieren

Die Aktualisierung einer VCSA ist eigentlich ja recht einfach: Man geht über den Port 5480 auf das Appliance-Management (aka MUI, VAMI), klickt auf Update und das drunterliegende Linux wird samt aller Programme auf den aktuellen Release aktualisiert. Die Programme kommen dabei direkt von den Updateservern – zumindest wenn man eine direkte Internetverbindung hat. Steht das System in einem Netz, welches keinen direkten Zugang bietet und nicht über einen transparenten Proxy verfügt, lässt die UI die nötige Konfiguration einfach erscheinen: Unter Netzwerk -> Verwalten findet sich ein Menüpunkt „Proxy-Einstellungen“, welcher die direkte Eingabe ermöglicht. Theoretisch.

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2018/01/vcsa.png

Die Praxis sieht leider anders aus: Dieses GUI-Element setzt lediglich die Umgebungsvariable http_proxy, welche ausschließlich für unverschlüsselte Verbindungen gültig ist. Da der Update-Download inzwischen per HTTPS läuft wird der Proxy praktisch ignoriert und der Download-Versuch läuft ins Leere. Dieses Problem tritt mindestens zwischen der Version 6.0 und der aktuellen 6.5U1 auf.

Zur Abhilfe muss man selbst Hand anlegen: In der Datei /etc/sysconfig/proxy findet sich neben der, von der GUI bereits gesetzten, Variable HTTP_PROXY auch ein passendes HTTPS_PROXY. Füllt man dies manuell aus ist der Update-Download fehlerfrei möglich. Wer vSAN einsetzt, sollte hier auch gleich noch die lokalen Server als Ausnahme definieren um den VMWare-Bug #2150523 zu umgehen.

Es zeigt sich wie so oft: Der Texteditor ist mächter als die Maus.

Danke an Andrew Richardson/VirtualSlices für das Aufklären des ursprünglichen Fehlers.

Feinstaubmessung an Neujahr

In der letzten Live-Sendung hatte ich für den Jahreswechsel einen Feinstaubsensor reaktiviert. Die Ergebnisse fallen recht dünn aus: Nicht nur, dass in meiner Nähe ohnehin eher wenig los ist, andauernder Nieselregen hat dieses mal wohl viele Feiernde in die Wohnungen getrieben und die Hinterlassenschaften schnell wieder zu Boden gebracht. Dies würde sich jedenfalls mit meinen Beobachtungen decken: Während man die letzten Jahre nach dem Feuerwerk teils stark eingeschränkte Sicht hatte war dieses mal keine nennenswerte Beeinträchtigung zu sehen.
Bild: https://www.adlerweb.info/blog/wp-content/uploads/2018/01/feinstaub17-300×120.png
Zu übersehen ist der Jahreswechsel trotzdem nicht: Wenige Minuten nach Mitternacht verdreifachten sich die Werte für PM2.5 und PM10. Dies stieg weiter an bis gegen 00:35 ein Spitzenwert von 39.5µg/m³ (PM10) bzw. 21.5µg/m³ (PM2.5) zu messen war – das 15-20-fache des Ausgangswertes. Nachdem sich die Lage beruhigte sanken die Werte schnell wieder, blieben jedoch im Schnitt doppelt so hoch wie vor dem Jahreswechsel. Alles Dank des schnellen Abnehmens deutlich unter den relevanten Grenzwerten.
Insgesamt sind die Werte für die Messstelle überschaubar – an trockenen Wintertagen werden durch alte Heizanlagen deutlich höhere Werte erreicht. Schauen wir dann nächstes Jahr nochmal, eventuell ist es dann ja trockener.

Keepass: Crash durch kaputte Mountpoints

Keepass ist ein quelloffener Passwortmanager, welcher Zugangsdaten verschlüsselt in einer Datei sammelt. Heute musste ich auf einem Gerät feststellen, dass sich die Software nicht mehr starten ließ: Der Passwortdialog erschien kurz, dann verschwand das ganze Programm vom Desktop. Über die Konsole ist ein absturz mit folgendem Trace zu erkennen:

Stacktrace:

  at <unknown> &lt;0xffffffff>
  at (wrapper managed-to-native) System.IO.MonoIO.FindFirstFile (string,string&,int&,int&) [0x00000]
  at System.IO.FileSystemEnumerableIterator`1<tsource_ref>.CommonInit () [0x0001d]
  at System.IO.FileSystemEnumerableIterator`1</tsource_ref><tsource_ref>..ctor (string,string,string,System.IO.SearchOption,System.IO.SearchResultHandler`1</tsource_ref><tsource_ref>,bool) [0x000d6]
  at System.IO.FileSystemEnumerableFactory.CreateFileNameIterator (string,string,string,bool,bool,System.IO.SearchOption,bool) [0x00009]
  at System.IO.Directory.InternalGetFileDirectoryNames (string,string,string,bool,bool,System.IO.SearchOption,bool) [0x00000]
  at System.IO.Directory.InternalGetFiles (string,string,System.IO.SearchOption) [0x00000]
  at System.IO.Directory.GetFiles (string,string) [0x0001c]
  at System.IO.DirectoryInfo.GetFiles (string) [0x0000e]
  at System.IO.DirectoryInfo.GetFiles (string,System.IO.SearchOption) [0x00009]
  at (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.GetFiles (string,System.IO.SearchOption) [0x00033]
  at KeePassLib.Utility.UrlUtil.GetFileInfos (System.IO.DirectoryInfo,string,System.IO.SearchOption) [0x00010]
  at KeePass.Forms.KeyPromptForm.AddKeyDriveSuggAsync (object) [0x0001c]
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (object) [0x00007]
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00071]
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00000]
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00021]
  at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074]
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000]
  at (wrapper runtime-invoke) <module>.runtime_invoke_bool (object,intptr,intptr,intptr) [0x0001e]
</module></tsource_ref></unknown>

Die Ursache ist etwas schwer zu finden, da nicht direkt ersichtlich: Netzwerkstörungen und Dateisysteme. Keepass durchsucht offenbar beim Start alle eingehangenen Partitionen, tritt hierbei ein Fehler auf kommt es zum Absturz. Dies betrifft nicht nur jene Speicherorte, auf denen Datenbank und ggf. Keyfile hinterlegt sind. In meinem Fall war durch einen Server-Neustart ein NFS-Mount abhanden gekommen (stale file handle), ähnliches war jedoch auch mit sshfs & co zu sehen. Eine Liste der aktuell genutzten Partitionen findet sich unter /etc/mtab, kaputte Dateisysteme lassen sich auch ohne Verbindung mit „umount -l“ oder „fusermount -u“ aushängen, hierbei kann jedoch möglicherweise Datenverlust entstehen, wenn noch Dinge im Schreibcache liegen. Nach Beseitigung des Fehlers lässt sich Keepass wieder regulär starten.

Postfix: Alle ausgenenden Mails mit einer Absenderadresse

Standardmäßig versendet Postfix die Mails wie sie ankommen, also z.B. mit dem jeweiligen Nutzernamen als Absendeadresse. Nutzt man jedoch einen Smarthost, lässt ausgehende Mails also z.B. über den Server des Providers abwickeln, ist dies häufig nicht erlaubt, einzig die eigene E-Mail wird akzeptiert.

Mit diesen Schritten kann man Postfix anweisen alle ausgehenden Mails so umzuschreiben, dass die vorgegebene E-Mail-Adresse als Absender genutzt wird. Da so auch nicht mehr auf den ersten Blick ersichtlich ist wer die Mail versendet hat, eignen sich diese Schritte nur für Systeme, auf denen ausschließlich vertrauenswürdige Personen Zugang gewährt wurde. Weiterhin gehe ich davon aus, dass Postfix bereits funktionsfähig konfiguriert wurde und für den Versand per Smarthost eine Authentifizierung notwendig ist.

Fangen wir damit an das Passwort zu hinterlegen. Hierzu legen wir eine neue Datei /etc/postfix/relay_password an und tragen Benutzername und Passwort ein.

mail.myprovider.example myuser:mypass

Ggf. sollte die Datei über entsprechende Dateirechte vor neugierigen Blicken geschützt werden. Da Postfix üblicherweise aus geschwindigkeitsgründen Datenbankdateien nutzt müssen wir unsere Textdatei noch entsprechend umwandeln:

postmap /etc/postfix/relay_password

Nun bereiten wir noch eine Absenderersetzung vor. Die Datei sender_canonical biegt mWn den internen Absender um, welcher z.B. im Envelope verwendet wird, header_check kümmert sich um das FROM:-Feld. Je nach Provider kann es ausreichend sein nur eine der Varianten zu verwenden, beachtet jedoch, dass solche Mails gerne von SPAM-Filtern aussortiert werden.

/.+/ myuser@myprovider.example
/From:.*/ REPLACE From: myuser@myprovider.example

Hier sind die Dateien als regexp deklariert und können ohne Mapping genutzt werden.

Zuletzt machen wir diese Dateien noch in der Postfix-Konfiguration bekannt:

[...]
relayhost = mail.myprovider.example

smtp_sasl_password_maps=hash:/etc/postfix/relay_password
smtp_sasl_auth_enable=yes
smtp_sasl_security_options = noanonymous

sender_canonical_classes = envelope_sender, header_sender
sender_canonical_maps = regexp:/etc/postfix/sender_canonical
smtp_header_checks = regexp:/etc/postfix/header_check

In der ersten Zeile wird der eigentliche Server des Providers als ausgehender Server definiert – mit dieser Einstellung wird Postfix nicht mehr selbst versuchen Mails zuzustellen sondern alles an diesen weiterleiten. Im nächsten Block wird angegeben, dass für den ausgehenden Server eine Authentifizierung notwendig ist und wo die Passwörter zu finden sind. In den letzten Zeilen definieren wir unsere Filter, welche die Ersetzung vornehmen.

Nach dem nächsten Reload des MTA sollten nun alle E-Mails mit der gesetzten Absenderadresse über den angegebenen Smarthost versendet werden.

Firefox statt IE im Unternehmen – Deployment, Konfiguration und Co

In vielen Firmen gilt noch immer Microsoft Edge bzw. der Internet Explorer als Standardbrowser für Inter- und Intranet. Einer der wichtigsten Gründe ist die Verwaltbarkeit: Updates werden über die Systemfunktionen automatisch installiert, Eintellungen lassen sich komfortabel über Gruppenrichtlinien zuweisen. Was viele IT-Abteilungen nicht auf dem Schirm haben ist, dass es auch mit alternativen Browsern nicht vollkommen unmöglich ist eine solch zentrale Konfiguration einzurichten. Hier möchte ich ein paar Kniffe für den Einsatz von Firefox in größeren Installationen geben.

Deployment und Updates

Fangen wir kurz mit Deployment und Updates an: In vielen Firmen laufen Updates des IE über WSUS. Dieser ermöglicht es Aktualisierungen erst in einem Laborumfeld auf unerwünschte Nebenwirkungen zu testen und im Anschluss an die Clients zu verteilen. Prinzipitell gut, jedoch ist WSUS hauptsächlich für Microsoft-Produkte ausgelegt, wird vom Hersteller etwas stiefmütterlich behandelt und ist – zumindest nach meiner Erfahrung – nur mäßig zuverlässig. Nicht zuletzt weil nahezu kein Unternehmen ohne Drittanbietersoftware auskommt, wird in vielen Firmen ein weiteres Deployment-System wie z.B. SCCM oder das kostenfreie OPSI zum Einsatz. Über diese kann man auch Firefox recht schnell ausrollen. Hierzu benötigt man statt dem kleinen Stub-Installer, welcher für Windows üblicherweise ausgeliefert wird, den Offline-Installer, welcher z.B. auf der Sprachübersicht zu finden ist. Wer neue Funktionen gegen seltenere Wartung tauschen möchte kann alternativ auf den Extended Service Release“ (ESR) zurückgreifen. Hierbei handelt es sich um eine spezielle Version von Firefox, welche über einen längeren Zeitraum mit Sicherheitsaktualisierungen versorgt wird. Im Gegensatz zur Desktop-Version werden bei diesen Updates – soweit mögich – keine Funktionen verändert. Der Befehl für eine Silent-Installation lautet

Firefox Setup 55.0.3.exe /S

Achtung: Beim Download haben 32- und 64-Bit-Varianten aktuell, trotz unterschiedlichem Inhalt, den selben Dateinamen. Über den selben Weg kann man neuere Versionen zur Aktualisierung installieren. Möchte man die Software später wieder löschen findet sich im Installationsverzeichnis eine passende Datei

"%PROGRAMFILES%\Mozilla Firefox\uninstall\helper.exe" /S

Konfiguration

Bleibt die Konfiguration. Hier lässt sich ein Überbleibsel aus der Netscape-Zeit nutzen, welche die Ausführung von Scripten beim Start des Browsers erlaubt. Im ersten Schitt legt man eine neue Datei im Ordner „%PROGRAMFILES%\Mozilla Firefox\defaults\pref\“ an. Der Name kann frei gewählt werden, jedoch erfolgt die Ausführung alphabetisch. Als inoffizielle Konvention hat sich „autoconfig.js“ durchgesetzt. Erste Falle: Die erste Zeile. Diese wird automatisch übersprungen, dort hinterlegte Befehle also ignoriert. Als Workarround sollte man in dieser folglich besser einen Kommentar unterbringen. Zweite Falle: Zwar können in dieser Datei bereits Konfigurationen gesetzt werden, jedoch wird sie während des Browserstarts zu einem Zeitpunkt geladen, an dem noch nicht alle Subsysteme verfügbar sind. Um dies zu umgehen wird stattdessen ein Verweis auf eine weitere Konfiguration hinterlegt, welche am Ende des Starts geladen wird. In diesem Beispiel nenne ich diese „mycompany.js„. Standardmäßig sind diese nachgeladenen Dateien mir ROT13 (sic!) codiert um neugierige Blicke und Änderungen von Nutzerseite zu erschweren. Da Ersteres ohnehin auch über die Browserfunktionen möglich ist und sich Schreibzugriffe über die Berechtigungen des Dateisystems effektiver verhindern lassen, schalte ich diese Funktion aus, so sind Änderungen einfacher.

// File must start with a comment
pref("general.config.filename", "mycompany.js");
pref("general.config.obscure_value", 0);

Nun geht es daran die eigentliche Konfiguration zu erstellen. Die zuvor referenzierte „mycompany.js“ wird im Programmverzeichnis, also „%PROGRAMFILES%\Mozilla Firefox\„, erwartet. Für das Setzen von Konfigurationen stehen uns verschiedene Befehle zur Verfügung – hier die wichtigsten:

Befehle

pref()

So gesetzte Einstellungen sind identisch zu jenen, die der Nutzer in der GUI oder about:config vornimmt. Die Änderungen werden als „vom Benutzer eingestellt“ angezeigt. Benutzer können diese weiterhin ändern, da das Konfigurationsscript jedoch bei jedem Browserstart läuft werden die Änderungen nach dem Neustart des Browsers wider auf den vorgegebenen Wert zurückgesetzt.

defaultPref()

Hiermit wird die Standardeinstellung geändert. Der Nutzer hat auch hier die Möglichkeit diese selbstständig zu ändern, jedoch sind Benutzeranpassungen bei dieser Variante persistent und werden bei einem Neustart nicht automatisch zurückgesetzt.

lockPref()

Hiermit wird eine Einstellung gesetzt und gleichzeitig gesperrt. Sie kann im Anschluss nicht mehr vom Nutzer geändert werden, entsprechende Konfigurationsfelder werden ausgegraut.

unlockPref()

Hebt die Sperre wieder auf. Interessant wenn man z.B. mit einer globalen Konfiguration arbeitet, bestimmten Benutzergruppen jedoch Funktionen über eine weitere Konfigurationsdatei wieder freigeben möchte.

getPref()

Liest die Konfiguration – z.B. um ein „identisch zu X“ umzusetzen.

clearPref()

Löscht die Konfiguration

getenv()

Liest eine Umgebungsvariable

Wie am Namen zu erkennen handelt es sich um Javascript, man kann also auch eigene Logik einbringen. Auch hier nutze ich die erste Zeile zur Sicherheit als Kommentar. Die Bezeichnungen der Konfigurationsfelder kann man im Browser zu großen Teilen in about:config finden.

Beispiele

Automatische Updates ausschalten

Da Updates, wie oben erwähnt, über das zentrale Deployment laufen sollen, wird der Auto-Updater des Browsers ausgeschaltet. So wird der Nutzer nicht mit entsprechenden Aufforderungen konfrontiert und Änderungen können vor einem breiten Rollout in einer überwachten Umgebung auf Kompatibilität mit den Unternehmensanforderungen geprüft werden. Achtung: Einige der Updater-Einstellungen lassen sich nur mit lockPref() setzen.

	// Deaktiviert den Updater
	lockPref("app.update.enabled", false);

	// Stellt sicher dass er tatsächlich abgestellt ist
	lockPref("app.update.auto", false);
	lockPref("app.update.mode", 0);
	lockPref("app.update.service.enabled", false);

	// Deaktiviert die Kompatbilitätsprüfung der Add-ons
	clearPref("extensions.lastAppVersion");
	
	//Deaktiviert das 'plugin checking'
	lockPref("plugins.hide_infobar_for_outdated_plugin", true);
	clearPref("plugins.update.url");
	
	// Verhindert die Frage nach der Installation des Flash Plugins
	pref("plugins.notifyMissingFlash", false);

Branding und Telemetrie

Je nach Firmen-Policy kann ein Branding oder der Upload von Telemetrieinformationen an Mozilla unerwünscht sein.

	// Deaktiviert 'Kenne deine Rechte' beim ersten Start
	pref("browser.rights.3.shown", true);

	// Versteckt 'Was ist neu?' beim ersten Start nach jedem Update
	pref("browser.startup.homepage_override.mstone", "ignore");
	
	// Deaktiviert den 'health reporter'
	lockPref("datareporting.healthreport.service.enabled", false);

	// Disable all data upload (Telemetry and FHR)
	lockPref("datareporting.policy.dataSubmissionEnabled", false);

	// Deaktiviert den 'crash reporter'
	lockPref("toolkit.crashreporter.enabled", false);
	Components.classes["@mozilla.org/toolkit/crash-reporter;1"].getService(Components.interfaces.nsICrashReporter).submitReports = false;

Startseite

Wenn ein Intranet-Portal o.Ä. automatisch geladen werden soll kann dies als Startseite hinterlegt werden

	// Stellt eine Standart-Homepage ein
	pref("browser.startup.homepage", "https://portal.mycompany.local/");

Zertifikate

SSL-Zertifikate sind bei Drittbrowsern immer eine Qual. Statt den Systemzertifikatspeicher zu verwenden bringen die meisten Browser einen eigenen Zertifikatspeicher mit. Firmen, welche interne CAs verwenden müssen hier eine separate Konfiguration erzeugen und können sich nicht auf die Verteilung per GPO o.Ä. verlassen. Bei Firefox gibt es hier die Möglichkeit über certutil Zertifikate per Script zu importieren.
Bei neueren Installationen kann man Firefox jedoch instruieren auch Zertifikate zu akzeptieren, welche im Windows-Zertifikatspeicher hinterlegt sind.

	//Accept system certificates
	pref("security.enterprise_roots.enabled", true);

Proxy-Server

Verwendet die Firma einen Proxyserver, welcher nicht über den Router als „transparenter Proxy“ betrieben wird, kann dieser ebenfalls hier hinterlegt werden.

	//proxy
	defaultPref("network.proxy.type", 1);
	defaultPref("netword.proxy.ssl", "proxy.mycompany.local");
	defaultPref("netword.proxy.http", "proxy.mycompany.local");
	defaultPref("netword.proxy.ftp", "proxy.mycompany.local");
	defaultPref("netword.proxy.ssl_port", "3128");
	defaultPref("netword.proxy.http_port", "3128");
	defaultPref("netword.proxy.ftp_port", "3128");
	defaultPref("network.proxy.no_proxies_on", "localhost, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, .mycompany.local");
	defaultPref("network.proxy.share_proxy_settings", true);

Lesezeichen

Das Erstellen von Lesezeichen ist etwas komplizierter, da man hier mit Datenbank und GUI interagieren muss, welche erst am Ende des Browserstarts zur Verfügung stehen. Um sicherzugehen, dass hier alle Module verfügbar sind, wird das Erstellen in eine eigene Funktion ausgelagert und mit einem Hook des Browsers verknüpft. Das Erstellen erfolgt über den nsINavBookmarksService. Dieser ermöglicht auch das Verwalten von Ordnern oder das Löschen von Elementen.

	var observer = {
		observe: function observe(subject, topic, data) {
			// DO BOOKMARKS WORK HERE
			var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
			var uri1 = ios.newURI("https://helpdesk.mycompany.local/", null, null);
			var uri2 = ios.newURI("https://nextcloud.mycompany.local/", null, null);
			var navBookmarksService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Components.interfaces.nsINavBookmarksService);
			if (!navBookmarksService.isBookmarked(uri1)) {
				navBookmarksService.insertBookmark(navBookmarksService.toolbarFolder, uri1, navBookmarksService.DEFAULT_INDEX, "Helpdesk");
			}
			if (!navBookmarksService.isBookmarked(uri2)) {
				navBookmarksService.insertBookmark(navBookmarksService.toolbarFolder, uri2, navBookmarksService.DEFAULT_INDEX, "Nextcloud");
			}
		}
	}

	Components.utils.import("resource://gre/modules/Services.jsm");
	Services.obs.addObserver(observer, "distribution-customization-complete", false);

Alternativen

Wer weniger administriert und lieber herumklickt eine GUI der Textkonfiguration vorzieht kann einen Blick auf CCK2 werfen, welches die Konfiguration grafisch aufbereitet.

VMWare RDM: ESXi-Boot wird minutenlang verzögert

Schlecht. Ein ESXi-Host sollte zwecks Update „mal schnell“ neu gestartet werden, doch nun sind mehr als 30 Minuten vergangen und es gibt noch immer kein Lebenszeichen. Selbst für Server etwas ungewöhnlich und lange genug um den VMWare-Updater in einen Timeout laufen zu lassen. Nach einiger Zeit war das System zwar wieder korrekt gebootet und zeigte keine weiteren Auffälligkeiten, eine solche Wartezeit wäre bei Störungen jedoch sehr hinderlich, also gehen wir mal auf Quellensuche.

Im Log finden sich mehrere Einträge, welche durch die Zeitstempel massive Wartezeiten erkennen lassen:

***T09:53:18.467Z cpu1:***)vmw_psp_mru: psp_mruSelectPathToActivateInt:346: Changing active path from NONE to vmhba0:xx:xx:xx for device "Unregistered Device".
***T09:53:18.467Z cpu1:***)StorageApdHandler: xxx: APD Handle  Created with lock[StorageApd-0xxxx]
***T09:53:18.467Z cpu1:***)ScsiEvents: 501: Event Subsystem: Device Events, Created!

***T09:53:18.467Z cpu1:***)VMWARE SCSI Id: Id for vmhba1:xx:xx:xx xxxxx
***T09:53:18.467Z cpu1:***)VMWARE SCSI Id: Id for vmhba0:xx:xx:xx xxxxx
***T09:53:58.506Z cpu2:***)ScsiDeviceIO: xxx: Cmd(0xxxx) 0x1a, CmdSN 0x1 from world 0 to dev "naa.xxx" failed H:0x5 D:0x0 P:0x0 Possible sense data: 0x0 0x0 0x0.
***T09:53:58.506Z cpu1:***)ScsiDeviceIO: xxx: Could not detect setting of QErr for device naa.xxx. Error Timeout.
***T09:54:08.631Z cpu19:***)NMP: nmp_ResetDeviceLogThrottling:3343: Error status H:0x0 D:0x18 P:0x0 Sense Data: 0x0 0x0 0x0 from dev "naa.xxx" occurred 989 times(of 989 commands)
***T09:54:38.524Z cpu2:***)ScsiDeviceIO: xxx: Cmd(0xxxx) 0x1a, CmdSN 0x2 from world 0 to dev "naa.xxx" failed H:0x5 D:0x0 P:0x0 Possible sense data: 0x0 0x0 0x0.
***T09:54:38.524Z cpu1:***)ScsiDeviceIO: xxx: Could not detect setting of sitpua for device naa.xxx. Error Timeout.

Das Ganze wiederholt sich dann mehrfach. Also ein SCSI-Timeout? Der Host ist per FibreChannel an diverse Storage-Systeme angebunden, sollte jedoch auch nur die für ihn relevanten LUNs sehen. Zumal nach dem langem boot auch alle Datastores verfügbar und VMs ohne Fehler online waren.

Nach einigem Suchen dann die Erkenntnis: Die angekreideten LUNs gehören zu einem Windows-Cluster und sind als RDM vorgesehen. ESXi versucht nun beim Booten diese LUNs zu scannen, was jedoch nicht gelingt da der Cluster auf einem anderen Host aktiv und die Partition somit dauerhaft gesperrt ist. Zur Abhilfe muss man diesen Scan beim Boot explizit für die betroffenen LUNs auf jedem Host deaktivieren:

esxcli storage core device setconfig -d naa.xxxx --perennially-reserved=true

https://kb.vmware.com/kb/1016106

VMWare vSphere-Client per SSH-Tunnel

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2016/07/vmlist-300×205.pngUgh – eine VM hängt und ich habe kein VPN ins zugehörige Netz. Aber jetzt extra hinfahren? Auch unschön. Glücklicherweise gibt es noch einen SSH-Zugang, den ich hier nutzen kann. Also schnell Tunneln – doch welche Ports? Nunja, nehmen wir für den „alten“ vSphere-Client folgende:

  • 443
  • 992
  • 993

Wer jedoch versucht mit 127.0.0.1 oder localhost zu verbinden wird auf Probleme stoßen – bei mir lief der Client auf diesen IPs keinen Connect zu. Ein kurzer Griff in die IPv6-Kiste mit dem guten, alten [::1] half und ließ die Verbindung zu.

Linux: Optisches Laufwerk RAW über Netzwerk einbinden

(Hinweis: Der Artikel lag schon etwas rum – möglicherweise sind die verwendeten Tools nicht mehr aktuell)

Hmmm – ungünstig. Das einzige optische Laufwerk steckt in einem Linux-Server, ich möchte die Discs jedoch auf einem anderen Gerät verwenden. Üblicherweise reicht hier ein File-Share wie Samba, NFS o.Ä. aus, wenn man jedoch beispielsweise kopiergeschützte DVDs abspielen möchte ist eine solche Freigabe nicht ausreichend. Glücklicherweise können wir hier einen alten Bekannten bemühen: iSCSI. Dies hatten wie bereits für Festplatten besprochen, kann aber auch für optische Laufwerke genutzt werden.

Server / Target

Nach dem Aufruf von targetcli sollten wir die altbekannte Textkonsole erhalten, welche auf der Root (/) der Konfiguration startet. Im ersten Schritt registrieren wir das physikalische Laufwerk /dev/sr0 als Backstore und aktivieren es für iSCSI. Sofern nicht bereits vorhanden wird automatisch eine TPG erzeugt.

/> cd backstores/pscsi
/backstores/pscsi> create name=cdrom_backend dev=/dev/sr0
Note: block backstore recommended for SCSI block devices
Created pscsi storage object cdrom_backend using /dev/sr0
/backstores/pscsi> cd cdrom_backend
/backstores/p...cdrom_backend> /iscsi create
Created target iqn.2003-01.org.linux-iscsi.testserver.x8664:sn.3299e9a7999b.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.

Nun müssen wir noch eine LUN erstellen um Clients den Zugriff zum Gerät zu ermöglichen. Diese Konfiguration findet im Kontext der TPG statt, die nötige ID wurde ja weiter oben angezeigt. Da nur ein Backstore verfügbar ist wird dieser automatisch ausgewählt. Da es sich um ein Testnetz handelt verzichte ich auf eine Absicherung und alle alle Clients zu – bei CD-Laufwerken ein überschaubares Risiko.

/backstores/p...cdrom_backend> cd /iscsi/iqn.2003-01.org.linux-iscsi.testserver.x8664:sn.3299e9a7999b/tpg1/
/iscsi/iqn.20...e8a7999b/tpg1> cd luns
/iscsi/iqn.20...99b/tpg1/luns> create /backstores/pscsi/cdrom_backend
Created LUN 0.
/iscsi/iqn.20...99b/tpg1/luns> cd ..
/iscsi/iqn.20...e8a7999b/tpg1> set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
Parameter cache_dynamic_acls is now '1'.
Parameter authentication is now '0'.
Parameter generate_node_acls is now '1'.
Parameter demo_mode_write_protect is now '0'.
/iscsi/iqn.20...e8a7999b/tpg1>

Zuletzt wird die Konfiguration gespeichert, so ist sie z.B. auch nach einem Neustart noch vorhanden

/iscsi/iqn.20...e8a7999b/tpg1> cd /
/> saveconfig
Last 10 configs saved in /etc/target/backup.
Configuration saved to /etc/target/saveconfig.json
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup.
Configuration saved to /etc/target/saveconfig.json

Client / Initiator

Auf der Clientseite benötigen wir ebenfalls eine Userspace-Software. Ich nutze zur Konfiguration iscsiadm aus dem Paket open-iscsi. Hier wird erst über Discover geprüft welche LUNs auf der TPG/Ziel-IP verfügbar sind. Über Login werden diese dann verbunden.

# iscsiadm --mode discoverydb --type sendtargets --portal 10.11.12.13 --discover
10.11.12.13:3260,1 iqn.2003-01.org.linux-iscsi.testserver.x8664:sn.3299e9a7999b
# iscsiadm --mode node --login
Logging in to [iface: default, target: iqn.2003-01.org.linux-iscsi.testserver.x8664:sn.3299e9a7999b, portal: 10.11.12.13,3260] (multiple)
Login to [iface: default, target: iqn.2003-01.org.linux-iscsi.testserver.x8664:sn.3299e9a7999b, portal: 10.11.12.13,3260] successful.

Das Ergebnis ist ein zusätzliches Blockdevice, welches wie ein Lokales angesteuert werden kann.

# dmesg | tail
[269195.457603] Loading iSCSI transport class v2.0-870.
[269196.464444] iscsi: registered transport (tcp)
[269243.373172] scsi host5: iSCSI Initiator over TCP/IP
[269243.636444] scsi 5:0:0:0: CD-ROM TSSTcorp DVD+-RW TS-H653B D300 PQ: 0 ANSI: 5
[269243.668795] sr 5:0:0:0: [sr1] scsi-1 drive
[269243.669219] sr 5:0:0:0: Attached scsi CD-ROM sr1