Results for category "Windows"

42 Articles

Attempting to perform the InitializeDefaultDrives operation on the ‘FileSystem’ provider failed.

Yesterday one of our check_mk monitoring scripts based upon PowerShell failed, because the error Attempting to perform the InitializeDefaultDrives operation on the ‘FileSystem’ provider failed. showed up. The initial reason for this is unknown but has to do with the New-PSDrive and Remove-PSDrive PowerShell commands we use inside the check_mk scripts.

Symptoms for the problem are:

  • The network drive is shown as disconnected in the Windows Explorer but you can still open the network drive
  • The network drive can not be disconnected as you receive the error “Drive is not connected” or “Access Denied”
  • Get-PSDrive returns the network share
  • net use does not return the network share
  • The network drive can’t be removed with net use $YOUR_DRIVE /delete /y
  • The network drive can’t be removed with Remove-PSDrive
  • Restarting the Windows Explorer still shows the drive

To remove the network drive I tried to remove all registry keys which belonged to it, killing the check_mk agent, restarting the virtual machine and so on. In the end I fixed it by disabling the check_mk agent, restarting the VM and re-enabling the check_mk agent.

Update 2017-06-14: The error occurs because the check_mk agent runs under the Local System account. As a normal user or administrator you have no permission to remove the drive. A good indicator for this is the existence of the mapped network drive in the registry key HKEY_USERS\S-1-5-18\Network\$YOUR_DRIVE (S-1-5-18 is the Well Known SID for Local System account). You can delete the registry key but the drive still exists until you reboot the Windows instance. In some circumstances even then the drive still shows up.

Microsoft suggests to set the registry key HKLM\System\CurrentControlSet\Control\SessionManager\ProtectionMode from 1 to 0. This values allows an administrator to access system resources. Just don’t do it for the sake of security.

Luckily for us we can use Mark Russinovich’s psexec tool to gain to Local System permissions. With this we can safely remove the drive without a reboot.

psexec64 -i -s powershell.exe
# gain Local System permissions
Remove-PSDrive -Name $YOUR_DRIVE
# drive automatically disappears from Explorer and a Get-PSDrive execution as non-Local System

Cross-domain migration from Windows Server 2008 R2 to Windows Server 2012 R2

In the first weeks of our company I made the mistake to set up the Active Directory domain with a .local suffix which caused a lot of problems with Windows and Linux-based clients in the longer run. Besides that after I have shifted back my work to my original tasks – I am still a developer – the network infrastructure went into some kind of unplanned chaos. Too many people tried too many things for which they had no experience or no sense for the implications they made. Besides that we got a parallel FreeIPA domain nix.internal which had a domain trust with the Windows domain. Due to the complexity no one really tried to push the domain migration, even if it has been a long outstanding issue on our Kanban board.

Because of internal changes a few weeks ago I took over the ownership of the infrastructure. To put the “structure” in “infrastructure” together with one of my co-workers I immediately started to plan the final migration phase.

Setting the goals

The new design of our infrastructure has been done over the last months.

  1. Instead of having the two domains domain.nix.internal and domain.local the new domains should be and is managed by Active Directory, by FreeIPA. Both domains have a bi-directional trust.
  2. The servers containing the domain controller and the Microsoft Exchange server must be both migrated from Windows Server 2008 R2 to Windows Server 2012 R2.
  3. The Exchange server must be migrated from Microsoft Exchange 2010 to Exchange 2016.

Besides that we had a lot of other goals like a global naming schema for hosts, CNAME usage, consolidating our VMs and other things but this is out of scope for this article.

I prepared an own JIRA project containing all the tasks we had to solve.

Setting up the new domain

Setting up the new Active Directory and FreeIPA server was straight forward. A domain trust between domain.local and just as between and were established. I had to manually change the file permissions on our Linux-based file store as our permission concept has been also changed. Instead of assigning user permissions to files or directories we wanted to use security groups. Best practice. This took some time but was worth the effort as I fixed a lot of permission problems with the manual review.

After setting up the domain itself I prepared the (inactive) DHCP server, imported the existing settings via PowerShell from the domain.local controller, set up the DNS forwarding and so on.

Migration of Microsoft Exchange 2010 to 2016

It is one thing to make a migration from Exchange 2010 to a newer version but a complete different story to make a cross-domain migration of Exchange. Google’s results for such a constellation are relatively comprehensible. Microsoft does not support such a migration since Exchange 2007, using PowerShell and own scripts does also not work. We ended up in buying CodeTwo Exchange Migration which saved us a lot of time and pain. If you ever need to do a cross-domain migration of Exchange purchase a license. It is worth every cent.

After the initial installation of the new Microsoft Exchange 2016 server and joining it to the new domain we set up the new Exchange server as a mail relay in our old Exchange Server 2010, both servers were listening to the same e-mail domain. This approach allowed us to test the new mail server with the existing domain. All other server settings were either exported and imported by using PowerShell or configured by hand/PowerShell.

On the migration day we disabled the POP3 collector on our old Exchange 2010, reconfigured the proxy server to point to the new Exchange 2016, did a last CodeTwo Exchange Migration run and enabled the POP3 collector on the new Exchange 2016. Apart from some hickups with the internal/external MAPI URL of the Exchange this went suprisingly smoothly.

Migrating clients into the new domain

The migraiton of the existing clients (PCs, notebooks) took much longer than expected. The migration of the local profiles did not work on all workstations. During the next logon the users were presented with the error “There are Currently No Logon Servers Available” (“Es stehen momentan keine Anmeldeserver zur Verfügung”). I figured out that this was a problem with the DNS configuration of the clients. During the join process, the new DHCP server were still disabled and the clients used the old domain controller for domain.local as DNS resolver. The server had a forwarded domain to so the clients were able to join the new domain. But during the logon process, the client asked for a SRV record on the DNS controller and got the old domain returned, resulting in the error above. After disabling the old DHCP server, enabling the new DHCP server, manually setting the DNS server to the new domain controller and re-joining the new domain the logon issue was gone.

Status Quo

There is still a lot do, e.g. our Atlassian instances are still connected to the old domain. As the security groups are completely different in both domains I’ll have to fix this by hand. Maybe I’ll write a blog post on that, too.

Lessons learned

  1. If you don’t really need to do a cross-domain migration, don’t do it.
  2. Planning, planning, planning. 2/3 of the time I invested for this project I spent with planning.
  3. Don’t underestimate the effort. Even if you have a good plan and everything is prepared, there is so much what can go wrong. The week between Christmas and New Year was the only time we could do this without having a large impact to our business.
  4. Don’t trust any profile migration tools. Reset the user’s password and log in with their credentials.
  5. If you don’t really need to do a cross-domain migration, don’t do it.

Das Zertifikat für den Web Deployment Service austauschen

Für heute hatte ich geplant, dass eines unserer Projekte automatisch mit Hilfe von Microsoft WebDeploy auf einem IIS veröffentlicht werden sollte. Die Applikation wurde mit TeamCity und MSBuild-Scripten erstellt und somit hatte ich auch bereits die passende *.deploy.cmd-Datei generiert bekommen.

Als ich danach das Deployment erst einmal manuell testen wollte, bekam ich den Fehler ERROR_CERTIFICATE_VALIDATION_FAILED geliefert. Das war auch klar, da der Webverwaltungsdienst bei der Installation ein eigenes Zertifikat erstellt, dieses aber natürlich von meiner Arbeitsstation mangels autorisierter Root-CA nicht erkannt wird. An dieser Stelle hätte ich natürlich das Standard-Zertifikat in meinem eigenen Zertifikatspeicher und danach im Zertifikatespeicher des TeamCity-Benutzerkontos installieren können. Ist aber natürlich nicht Sinn der Sache, da das Root-Zertifikat unseres Domänen-Controllers sowieso per Gruppenrichtlinie auf alle Clients veröffentlicht wird und wir somit auch direkt von unserer CA ein Zertifikat ausstellen lassen können.

Die Option, “-allowUntrusted=true” an die *.deploy.cmd zu hängen, war übrigens nicht erfolgreich, da Microsoft im Batch-Script geschlampt hat und die Gleichheitszeichen durch Leerzeichen ersetzt werden.

Wie dem auch sei: Ich entschloss mich also dazu, ein Zertifikat auszustellen. Zuerst überprüfte ich die einzelnen Zertifikatespeicher auf dem Webserver. Der Webverwaltungsdienst greift dazu auf die Zertifikate des Computerkontos zu und präsentiert sie dann in der Auswahlliste.

Ein neues Zertifikat zu erstellen gestaltete sich nun schwieriger als ich anfangs dachte. Per Weboberfläche des Certifcation-Service vom Domänen-Controller konnte ich mir zwar ein Webserver-Zertifikat ausstellen lassen und dieses auch im Computerkonto installieren, allerdings lies sich nach dem Auswählen des Zertifikats im Server-Manager unter Rollen > Webserver (IIS) > Internetinformationsdienste > $Instanz > Verwaltungsdienst der Dienst nicht mehr starten. Die Ereignisanzeige meldete, dass der private Schlüssel nicht exportiert worden war. Dies scheint standardmäßig bei den Webserver-Zertifikaten nicht der Fall zu sein.

Ich folgte nun einem anderen Weg und rief dazu in der Zertifikate-MMC unter Zertifikate (Lokaler Computer) > Eigene Zertifikate > Zertifikate > Rechtsklick “Alle Aufgaben” > Neues Zertifikat anfordern auf.
Dies sorgt dafür, dass man mit Hilfe eines kleinen Tools direkt bei der CA bzw. DC ein Certification Request einreichen kann. Auf der zweiten Seite bekommt man die verfügbaren Zertifikatsvorlagen zur Verfügung, die für den gerade ausgewählten Zertifikatespeicher benutzt werden können. Da ich beim Aufsetzen der CA nur die Kopien von den Vorlagen Benutzer, Computer und Key Recovery Agent gemacht habe, stand für das Computerkonto nur die Vorlage Computer zur Verfügung.

Schnell die MMC Zertifikatsvorlagen aufgerufen, als Domänen-Administrator mit der Zertifizierungsstelle verbunden und mit Rechtsklick auf Webserver > Doppelte Vorlage eine neue Vorlage erstellt. Die Gültigkeitsdauer setzte ich auf einige Jahre hoch und wählte unter dem Tab Anforderungsverarbeitung die Option Exportieren von privatem Schlüssel zulassen.

Nach dem Speichern hätte ich nun meine Zertifikatsvorlage beim Certification Request eigentlich angezeigt bekommen müssen. Tat es aber nicht – ich bekam nur die Fehlermeldung “Sie besitzen keine Berechtigung zum Anzeigen dieses Typs von Zertifikat“. Nach dem Überprüfen der Einstellungen war ich etwas ratlos, dass ich diesen Fehler bekam. An sich hatte alles gestimmt. Ich war ja Domänen-Administrator und hatte dementsprechend für diese Zertifikatsvorlage durchaus eine Berechtigung (Tab Sicherheit in der von mir duplizierten Zertifikatsvorlage).
Diese Berechtigungen waren aber nicht ausreichend. Ich stellte ja schließlich für das Computerkonto ein Zertifikat aus, also musste der Computer im Sicherheit-Tab die Rechte Lesen, Schreiben und Registrieren bekommen.

Nun bekam ich auch die Zertifikatsvorlage angezeigt, wählte bei den zusätzlichen Einstellungen als Allgemeiner Name den internen FQDN des Webservers und überprüfte, dass der private Schlüssel exportiert wird.
Im Anschluss konnte ich das so eben erstellte Zertifikat auch bei den Eigenschaften des Verwaltungsdiensts im IIS auswählen.

Windows 7 & Lokales System: %PATH% Umgebungsvariable nicht vollständig

Momentan bin ich dabei, TeamCity aufzusetzen und die von uns benutzten Programmiersprachen inklusive der Unit-Testing-Frameworks zu integrieren.
Für PHPUnit gibt es zwei ganz passable XML-Dateien (Ant-Script zum Ausführen von PHPUnit & PHPUnit-Beispielkonfiguration), die an sich auch funktionieren. Ich testete nach einigen Anpassungen die Konfiguration mit Ant und PHPUnit unter meinem Benutzeraccount und war zufrieden. Nachdem ich dann allerdings das Projekt in TeamCity eingebunden hatte, lieferten mir die Log-Dateien (phpunit.txt etc. die im verlinkten Ant-Script hinterlegt sind) folgenden Fehler zurück: “Der Befehl “phpunit.bat” ist entweder falsch geschrieben oder konnte nicht gefunden werden.“.

Höchst seltsam – ich hatte zuerst McAfee in Verdacht, die Ausführung von Batchdateien unter dem Benutzeraccount Lokales System (denn darunter läuft TeamCity standardmäßig) durch eine Richtlinie zu unterbinden. Allerdings funktionierte es mit deaktiviertem Virenscanner immer noch nicht. Also gab ich in der build.xml den absoluten Pfad zur phpunit.bat und siehe da: das klappte.
Der Verdacht lag nun nahe, das phpunit.bat nicht in einem Verzeichnis der Umgebungsvariablen %PATH%  des Systems definiert worden war, sondern in der PATH-Variable meines Benutzeraccounts. Dem war allerdings auch nicht so. phpunit.bat lag im %PATH% des Systems.
Ich fügte in der build.xml zum Testen also Folgendes ein

<exec executable="cmd" failonerror="false" output="${buildDir}/logspath.txt">
	<arg line="/c echo %PATH%" />

und bekam in der path.txt einen äußerst kurzen Eintrag mit zwei Ordnern geloggt, die ich so nicht bewusst eingetragen habe.
Ein kurzes Suche in der Registry brachte dann das Ergebnis, dass die %PATH%-Variable unter HKEY_USERS/.DEFAULT/Environment/PATH definiert wird.
Nachdem ich wusste, wonach ich zu suchen hatte, fand ich auch schnell die passende Erklärung.

Zusammenfassung: Dienste, die unter dem Account Lokales System (Local System) laufen und auf eine .bat-, .exe- oder .cmd-Datei zugreifen wollen, die innerhalb der %PATH%-Umbgebungsvariable liegen, können dies nur tun, wenn der Pfad unter HKEY_USERS/.DEFAULT/Environment/PATH eingetragen ist.
Die Optionen Benutzervariablen (logisch) und Systemvariablen haben für den Account unter keine Auswirkungen.

"Der Benutzer besitzt nicht den benötigten Anmeldetyp auf diesem Computer" beim Zugriff auf Netzwerkzugriff von Windows 7

Am Wochende ist mal wieder Netzwerkparty gewesen und wie jedes Mal gab es Probleme mit dem Zugriff auf die Netzwerkfreigaben. Diesmal hatten wir das Problem, das beim Zugriff von Windows 7 auf andere Windows 7 Netzwerkfreigaben der Fehler “Der Benutzer besitzt nicht den benötigten Anmeldetyp auf diesem Computer” erschien.

Die im Internet verfügbaren Lösungen sind alle nicht sonderlich hilfreich und funktionieren vielleicht unter Windows Vista, aber nicht unter Windows 7.

Nach kurzem Testen stellte sich heraus, dass folgende Einstellugnen in den lokalen Sicherheitsrichtlinien gesetzt werden müssen (dazu secpol.msc starten und unter Sicherheitseinstellungen -> Lokale Richtlinien -> Zuweisen von Benutzerrechten die Registrierungseinträge setzen):

  • Auf diesen Computer vom Netzwerk zugreifen: Die Einstellung Jeder muss gesetzt sein
  • Lokal anmelden verweigern: Die Einstellungen Jeder und HomeGroupUser$ müssen entfernt werden
  • Lokal anmelden zulassen: Die Einstellung Jeder muss gesetzt sein
  • Zugriff vom Netzwerk auf diesen Computer verweigern: Die Einstellungen Jeder und HomeGroupUser$ müssen entfernt werden

Ausschlaggebend war für uns im Nachhinein, dass wir in der selben Arbeitsgruppe (WORKGROUP) gewesen sind und eben der Eintrag HomeGroupUser$ gesetzt gewesen ist. Bei den einzelnen Netzwerkfreigaben muss eventuell noch der Benutzer Gast mit Leserechten versorgt werden. Nach der Netzwerkparty sollten sicherheitshalber die Einstellungen wieder zurückgesetzt werden.

Schleierhaft, warum mit jeder Version von Windows die Netzwerkfreigabe komplizierter wird…

Windows 2003 als zentraler Event Log-Server / Freigeben von Event Logs an bestimmte Benutzer

Florian hatte vor einigen Wochen das Tool eventcreatef vorgestellt.  Es dient dazu, dass komplette Log-Dateien und nicht nur einzelne Log-Nachrichten in die Ereignisanzeige von Windows geschrieben werden können. eventcreatef delegiert die Aufrufe an das Microsoft-Tool eventcreate, dass die übergebenen Daten in kleinere Teile an den jeweiligen Server sendet.

Somit kann man mit Hilfe von eventcreatef einen zentralen Log-Server auf Basis von Windows Server 2003 o.ä. aufsetzen, der alle Log-Dateien sammelt, z.B. die, die während eines nächtlichen Backups auftreten.

Leider gibt es für Linux kein Tool, dass direkt in die Ereignisanzeige von Windows Server 2003 schreiben kann. Für unsere heterogene Umgebung war dies ein ungünstiger Sachverhalt. Ich musste also einen generischen Service schreiben, der per SOAP die Log-Daten entgegen nehmen konnte und dann dementsprechend an eventcreatef weiterdelegiert.

Dabei ist das unten angehängte Script namens eventcreateservice.php (ECS)heraus gekommen: Es stellt über das Zend Framework eine SOAP-Schnittstelle bereit, die die einfache Methode create besitzt. Wird das Script über eventcreateservice.php?wsdl aufgerufen, wird die WSDL-Datei ausgegeben, über eventcreateservice.php?bash lässt sich ein Bash-Script downloaden, dass mit Hilfe von curl eine Verbindung mit dem SOAP-Service herstellt. An dem Bash-Script muss nichts weiter angepasst werden, da die URLs automatisch generiert werden. Somit lassen sich nativ auf Linux-Maschinen Einträge in die (native) Ereignisanzeige von Windows-basierten Maschinen schreiben.
Ein Syslog-Server ist also nicht mehr nötig. Das Konzept ist besonders für kleinere Unternehmen interessant, die mehr Windows-Maschinen als Linux-Maschinen besitzen und für die ein zentraler Syslog-Server oversized ist.

Nachdem ich ECS fertig entwickelt hatte, ging es nun darum, dass ich die von mir erstellten Log-Einträge nicht in den Standard-Log-Dateien Applikation, System und Sicherheit schreiben wollte, sondern in eine Extra-Logdatei namens Backups.
Florian stellt in der oben bereits genannten URL ein kleines Tool namens CreateEventLog2 bereit. Über die Aufmachung und Fehlerbehandlung der GUI lässt sich streiten, mir ging es um den Funktionsumfang: CreateEventLog2 erzeugt eine neue Log-Datei, die dann in der Ereignsanzeige der MMC angezeigt werden kann.
Damit hatte ich schon ein Großteil erreicht: Ich konnte nun von Windows-Systemen aus Log-Nachrichten auf unserem Log-Server speichern, die Linux-Systeme konnten über das Bash-Script und den SOAP-Service ebenfalls in die Windows-Ereignisanzeige schreiben und schließlich hatte ich ein weiteres Log neben den Standard-Windows-Logs.

Im letzten Schritt ging es nun darum, das von mir definierte Log einem dedizierten Benutzer zugänglich zu machen. Ich wollte in der Konfigurationsdatei von ECS (logischerschweise) keinen Domänen-Administratoraccount eintragen, sondern einen Benutzer mit beschränkten Rechten. Für dieses Vorhaben muss man zuerst einmal ein paar Sachen wissen: Der Zugriff auf die Log-Dateien eines Systems werden über Registry-Einträge geregelt. Es gibt unter HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLog zu jeder Log-Datei einen Schlüssel, der wiederum diverse Attribute enthält. Wichtig ist das Attribut CustomSD: dieses beschreibt anhand eines SDDLs, ob und wer auf dieses Objekt zugreifen darf. Standardmäßig steht in der CustomSD (in meinem Fall zu finden unter HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLogBackupsCustomSD) ein String der folgenden Art: O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3). Sieht kryptisch aus, ist es aber eigentlich nicht – wenn man weiß, wie die SDDLs aufgebaut sind.
Kurz dazu: Jeder eingeklammerte Eintrag, z.B. (D;;0xf0007;;;AN) definiert eine Zugriffsregel (ACE). Die erste Regel, die vom System gefunden wird und zutrifft, wird benutzt.

Wie dem auch sei: Es gibt glücklicherweise ein Tool namens sddlparse, das die zugegebenermaßen etwas kryptisch anmutende Zeichenkette analysiert und dann wieder in lesbarer Form ausspuckt.
Nachdem ich damit die benötigten Rechte für einen schreibenden Zugriff auf die Ereignisanzeige auslesen konnte (ADS_RIGHT_DELETE, ADS_RIGHT_READ_CONTROL, ADS_RIGHT_WRITE_DAC, ADS_RIGHT_WRITE_OWNER, ADS_RIGHT_DS_CREATE_CHILD, ADS_RIGHT_DS_DELETE_CHILD und ADS_RIGHT_ACTRL_DS_LIST), erstellte ich einen neuen ACE mit eben diesen Rechten. Die ACE muss an erster Stelle eingefügt werden, so dass der Registry Key wie folgt aussieht: O:BAG:SYD:(A;;LCDCCCWOWDSDRC;;;S-1-5-21-xxx-xxx-xxx-xxx)(nächste ACE…). Der Registry Key wird übrigens bei jedem Aufruf der Ereignisanzeige ausgelesen, somit tritt die Änderung sofort in Kraft.
Ich fügte die SID unseres dedizierten Ereignisanzeigen-Benutzer mit Hilfe der obigen ACE hinzu und war in der Lage mit diesem in die Ereignisanzeige zu schreiben.

Während ich mich in SDDLs und ACEs einarbeitete, fiel auch ein kleineres Tool namens ACECreator ab. Es verbindet sich mit dem Active Directory und sucht mit Hilfe von Ambigious Name Resolution (ANR) Objekte heraus. Diesen Objekten lassen sich dann die Einstellungen verpassen, die man braucht, das passende ACE wird automatisch erzeugt.

Alles in allem war dieses Projekt äußerst spannend. Zwar klingt die Durchführung relativ einfach, allerdings gab einige Probleme mit den Rechten bzw. Benutzeraccount, unter dem eventcreatef lief u.s.w.
Lesenswert sind folgende Links, die ich u.a. für den ACECreator als Referenz herangezogen habe:

Angehängte Downloads
[download id=5]
[download id=6]

Server Name Indication (SNI) unter Apache 2.0.63 (Windows)

Heute kam bei uns in der Firma wieder das Thema Zertifikate zu sprechen. Unsere momentane Umgebung auf dem auch dieser Blog gehostet ist, ist ein Windows-System, auf dem Apache 2.0.63 läuft. Einige der Subdomains sind über SSL zugänglich, allerdings besteht bei SSL das generelle Problem, dass pro IP-Adresse nur ein SSL-Zertifikat benutzt werden darf. Wenn man mehrere Subdomains als virtuelle Hosts betreibt (, u.s.w.) wird immer nur das Zertifikat des ersten VHosts benutzt (im Beispiel das Zertifikat von

Seit einiger Zeit bietet das Unternehmen StartCom kostenlose Zertifikate an. Das CA-Zertifikat von StartCom ist in den aktuellen Browsern sowie im Zertifikate-Speicher von Windows verfügbar. Leider besteht nicht die Möglichkeit, ein kostenloses Wildcard-Zertifikat zu erhalten. StartCom teilt nur Zertifikate vom Typ C1 und nicht C2 kostenlos aus.

Mit dem Wildcard-Zertifikat wäre es möglich gewesen, dass alle VHosts unter https://* sich ein Zertifikat teilen. Die andere Möglichkeit, für jede Domain ein eigenes Zertifikat einzurichten, entfällt aus den bereits genannten Gründen: pro IP nur ein Zertifikat.

Seit 2003 existiert die RFC 3456, in der Server Name Indication (SNI) definiert wird. Damit ist es möglich, pro IP-Adresse mehrere Zertifikate zu benutzen. Leider implementieren bis jetzt nur wenige Webserver SNI nativ.

Als ich im Internet nach dem Thema googelte, wurde ich in Wolfs Blog fündig. Er beschrieb die Implementierung und Kompilierung von SNI unter Apache 2.2.xx. Durch seine Ausführungen war ich mehr als motiviert und hatte nun den Plan, SNI unter Apache 2.0.63 und Windows zum Laufen zu bringen.

Durch meine letzten Tätigkeiten beim mod_auth_ldap-Patch hatte ich noch die Sourcen von Apache 2.0.63 auf der Festplatte und sammelte nun die benötigten Dateien zusammen:

Nachdem ich die beiden Backport-Patches in meine Sourcen eingespielt hatte, musste ich noch die Lib-Pfade für die OpenSSL-Dateien einpassen und außerdem das zlib-Verzeichnis inkludieren, da OpenSSL irgendwie auf zlib referenzierte.

Die Kompilierung verlief danach ohne Probleme und ich machte mich an das Deployen der Dateien. Wichtig dabei war, das auf dem Server folgende neue Dateien kamen:

  • openssl.exe aus Wolfs-SSL-Package nach Apache2/bin
  • libeay32.dll und ssleay32.dll aus Wolfs-SSL-Package nach Apache2/bin bzw. %SYSTEM32%
  • Release/libhttpd.dll aus dem Apache-Kompiliat nach Apache2/bin
  • modules/ssl/Release/ nach Apache2/modules

Das Starten des Apaches schlug beim ersten Mal fehl, da ich die libhttpd.dll vergessen hatte zu kopieren. Diese wird aber benötigt, da der Backport von ap_vhost_iterate_given_conn auf diese Library abzielt.
Danach fuhr der Apache normal hoch, ich richtete nun in aller Kürze zwei Virtuelle Hosts in meiner httpd.conf ein und erzeugte zwei Self Signed Certificates. Das Ergebnis war mehr als erfreulich, denn soweit funktionierte alles.
Der nächste Schritt wird für mich sein, dass ich nun unsere Zertifikate von der StartCom-CA signieren lasse.

[download id=”2″]

Sharepoint mit Apache als Reverse Proxy veröffentlichen

Heute stand ich vor der Aufgabe, dass unsere interne Sharepoint-Seite im Apache veröffentlicht werden sollte. An sich hätte das kein Problem sein sollen – war es im Endeffekt aber.

Bei uns schaut es schematisch so aus, dass der Apache alle Anfragen anhand des Domain-Namens auf die virtuellen Server weiterreicht bzw. als Proxy fungiert: Internet -> Apache / DMZ -> Virtueller Host / Backend Server.

Anhand des Blog-Eintrags von Todd Klint den Sharepoint-Service so eingerichtet, dass er auf die richtige URL lauscht. Die Konfigurationsdatei des virtuellen Hosts sah dann folgendermaßen aus:

<VirtualHost *:443>
SSLEngine On
SSLProxyEngine On
SSLCertificateFile "$CERT_FILE"
SSLCertificateKeyFile "$CERT_KEY_FILE"
SSLProxyCACertificateFile "$CERT_CA_FILE"
ProxyRequests Off
ProxyVia On

DocumentRoot $VHOST_DIR/sps/web
ErrorLog "|rotatelogs.exe $VHOST_DIR/sps/logs/%Y%m%d_ssl_error.log 86400"
CustomLog "|rotatelogs.exe $VHOST_DIR/sps/logs/%Y%m%d_ssl_access.log 86400" common

# AddDefaultCharset ISO
LogLevel debug
ProxyPreserveHost Off
KeepAlive Off

ProxyPass /  http://backend-srv:8080/
ProxyPassReverse /  http://backend-srv:8080/

<Proxy *>
Order allow,deny
Allow from all

<Directory "$VHOST_DIR/sps/">
Order allow,deny
Allow from all

Es ist noch zu sagen, dass der Sharepoint nicht mit HTTPS sondern mit Plain-HTTP läuft. Der Apache kümmert sich um die Verschlüsselung. Im IIS muss außerdem als Authentifizierungsmethode für die Sharepoint-Seite Standardauthentifizerung und nicht Integrierte Windows-Authentfizierung benutzt werden. Apache 2.0.63 kam bei mir mit der Benutzung von NTLM nicht klar.

Ein weiterer Fehler der auftrat war, dass der Sharepoint-Server über zwei Netzwerkkarten verfügte, die zu veröffentlichende SharePoint-Instanz aber an keine IP fest gebunden gewesen ist. Der Apache hatte Probleme damit arge Probleme (sporadisches “Verbindung fehlgeschlagen”), deshalb habe ich die SP-Instanz einer IP direkt im IIS zugewiesen.

How-To: Module des Apache Webservers unter Windows mit Visual Studio kompilieren und debuggen

Aus aktuellem Anlass musste ich mal wieder ein Apache-Modul gerade biegen. Diesmal war es mod_auth_ldap. mod_auth_ldap sollte als Modul zur Authentifizierung und Autorisierung von LDAP-Benutzern (Active Directory, eDirectory, OpenLDAP etc.) vielen Leuten ein Begriff sein.

Diese Anleitung zeigt in wenigen Schritten, wie man aus den Sourcen des Apache Webserver 2.0.63 ein Modul patcht, kompiliert und debuggt. Voraussetzung für die Kompilierung ist ein Visual Studio Express bzw. Visual C++. Ich verwende auf meinem Rechner ein (relativ altes) Visual Studio 2005 Professional.

Auf meinem Arbeitsrechner schaut es so aus, dass ich unter c:ckldevsrvwebapache2.0.63 ($DIR_BIN) die installierte und kompilierte Version des Apache Webservers habe und unter c:ckldevprojectsappapache2.0.63 ($DIR_SRC) die zugehörigen Sourcen liegen.

Zuerst müssen von die aktuellen Sourcen für Windows heruntergeladen und auf der Festplatte ($DIR_SRC) entpackt werden. Wenn man zusätzlich noch durch die Sourcen des Apache Webservers debuggen will, werden weiterhin die Symbols benötigt. Diese müssen in das Hauptverzeichnis des kompilierten Apache Webservers ($DIR_BIN) entpackt werden.

Die Datei $DIR_SRCApache.dsw enthält alle Teilprojekte des Webservers und muss mit Visual Studio geöffnet werden. Falls beim Öffnen die Frage nach einer Konvertierung der Daten kommt, kann/muss dies mit Ja beantwortet werden.

Ausgehend davon, dass wir nur mod_auth_ldap patchen wollen, muss nun im Solutions Explorer das Teilprojekt mod_auth_ldap ausgewählt und die jeweiligen Änderungen in die mod_auth_ldap.c eingetragen werden. Mit einem Rechtsklick auf mod_auth_ldap > Build wird nun das Modul erstellt. Die .so-Datei lässt sich jetzt unter $DIR_SRCmodulesexperimental[Debug|Release] ($MOD_AL) finden. Weiterhin ist die $DIR_SRCmodulesexperimentalDebugmod_auth_ldap.pdb ($DEBUG_AL) wichtig.

Der Apache muss nun als Dienst beendet werden (net stop apache2), danach muss $MOD_AL und $DEBUG_AL nach $DIR_BINmodules kopiert (vorher Sicherung des Originals erstellen!) und Apache auf der Kommandozeile ($DIR_BINbinapache.exe) gestartet werden. Dies ist nötig, damit Visual Studio sich an den Apache-Prozess hängen kann. Wird der Apache als Dienst ausgeführt, ist dies nicht ohne Weiteres möglich.

Sobald der Webserver läuft, kann im Visual Studio unter Debug > Attach to Process die Apache-Prozesse ausgewählt werden. Beim Hit eines Breakpoints in der mod_auth_ldap.c stoppt der Apache die Ausführung.

Hier die Hinweise im Überblick:

  • $DIR_SRCApache.dsw als Projekt öffnen und nicht $DIR_SRCmodulesexperimentalmod_auth_ldap.dsw, da man bei letzterem zu viele Einstellungen ändern muss.
  • Apache.exe als normalen Prozess und nicht als Dienst starten, da sich sonst der Debugger nicht nutzen lässt.
  • Neben der .so-Datei muss auch die zugehörige .pdb-Datei in $DIR_BINmodules kopiert werden.

VirtualBox: Cursor wird zweimal angezeigt

Auf meinem Server läuft die aktuelle VirtualBox-Version und als Gast ein Windows Server 2003.
Von Anfang an hatte ich beim Verbinden via RDP über das VirtualBox-RDP-Gateway das Problem, dass in dem Screen zwei Cursor der Maus angezeigt wurden. Besonders problematisch ist dabei, dass ich die Ränder nicht erreichen konnte, da z.B. des rechten Randes der rechte Cursor außerhalb des RDP-Clients (Gnome-RDP) war und somit die Mausbewegungen sich auf mein Notebook und nicht mehr auf die RDP-Session bezogen.

Die Lösung des Problems ist an sich relativ simpel: Im VirtualBox-Gast muss unter Systemsteuerung > Maus > Zeigeroptionen die Option Zeigebeschleunigung verbessern deaktiviert werden.