[Prunked.Net] Continuous Integration – Teil 4 – Nexus-Installation und -Konfiguration

Die einzige benötigte Abhängigkeit von Nexus, ein Java JDK, haben wir bereits in Teil 2 dieser Reihe installiert und können wir damit überspringen. Zur Installation von Nexus laden wir uns zunächst das aktuellste .tar.gz-Archiv herunter und entpacken es an einem entsprechend geeigneten Ort.

sudo su
cd /usr/local/
NEXUS_ARCHIVE=$(wget -nv --content-disposition https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-latest-bundle.tar.gz 2>&1 | awk '{print substr($6,2,length($6)-2);}')
NEXUS_DIR=$(echo | awk -v NEXUS_ARCHIVE="$NEXUS_ARCHIVE" '{print substr(NEXUS_ARCHIVE,0,length(NEXUS_ARCHIVE)-13);}')
tar -xvzf $NEXUS_ARCHIVE
ln -s $NEXUS_DIR nexus

Danach fügen wir über

echo "NEXUS_HOME=\"/usr/local/nexus\"" >> /etc/environment
source /etc/environment

das Nexus-Home-Verzeichnis zu den Umgebungsvariablen hinzu und lesen letztere neu ein.

Da und damit Nexus nicht unter Root laufen soll, legen wir uns einen neuen Benutzer an:

useradd nexus

Damit Nexus-Benutzer auch auf die von ihm benötigten Ordner und Dateien zugreifen kann, müssen wir ihm noch die Rechte dazu geben:

chown -R nexus:nexus nexus $NEXUS_DIR sonatype-work/nexus

Nun müssen wir Nexus-Startup-Script noch beibringen, unter welchen Benutzer es laufen soll. Zusätzlich konfigurieren in diesem auch gleich das Nexus-Home-Verzeichnis (ist für den nächsten Schritt zur Konfiguration als Service wichtig, also machen wir es direkt). Dazu

nano $NEXUS_DIR/bin/nexus

ausführen. Über STRG+W suchen wir nach NEXUS_HOME= und setzen den Wert auf „/usr/local/nexus“. Danach suchen wir nach #RUN_AS_USER=, entfernen das Kommentarzeichen und setzen den Wert auf „nexus“. Die beiden Zeilen sollten danach so aussehen:

NEXUS_HOME="/usr/local/nexus"
RUN_AS_USER="nexus"

Ein kleiner Test-Start von Nexus kann nicht schaden und sollte ohne größere Fehler klappen:

$NEXUS_DIR/bin/nexus console

Nach kurzer Zeit sollte Nexus auf IP:8081/nexus verfügbar sein (Benutzername: admin, Passwort: admin123).

Als nächstes richten wir Nexus als Service ein, damit er bei einem Neustart mitgestartet wird. Dazu beenden wir den Konsolenmodus mittels STRG+C und führen folgendes aus:

cd /etc/init.d/
cp $NEXUS_HOME/bin/nexus .
chmod 755 nexus
chown root nexus
update-rc.d nexus defaults
service nexus start

Jetzt sollte noch die Checkliste nach der Installation (Post-Install Checklist) im Handbuch durchgelesen und durchgeführt werden (wobei der Punkt Configuring Nexus as a Service übersprungen werden kann, da wir diesen bereits vollzogen haben).

Danach ist die Installation von Nexus abgeschlossen. Die weitere Konfiguration geschieht über das Web-Interface.

Im Web-Interface als admin eingeloggt, klicken wir in Liste links unter Administration auf Server. Im sich öffnenden Konfigurationsdialog unter Security Settings wählen wir aus der Liste der Available Realms den Eintrag NuGet API-Key Realm aus, fügen ihn der Liste der Selected Realms hinzu und klicken auf Save.

Danach gehen wir in der linken Menüliste unter Repositories/Views auf Repositories. Hier sind bereits einige Einträge hinterlegt; für den späteren Verlauf legen wir uns über den Button Add… noch folgende zusätzliche Repositories an:

TypeRepository IDRepository NameProviderRemote Storage Location
proxynuget-galleryNuGet GalleryNuGethttps://www.nuget.org/api/v2
hostednuget-internal-releasesNuGet Internal Releases FeedNuGet
hostednuget-internal-snapshotsNuGet Internal Snapshots FeedNuGet

Nach Anlegen der Repositories findet ihr unter dem Reiter NuGet die jeweilige URL, unter der das Repository erreichbar ist sowie ggf. den API Key, über den das NuGet Package gepusht werden kann. Wichtig sind diese Informationen für die Konfiguration des Paketmanagers im Visual Studio oder von NuGet im Jenkins.

Damit ist auch die Erstkonfiguration von Nexus abgeschlossen.

[Prunked.Net] Continuous Integration – Teil 3 – GitLab-Installation und -Konfiguration

Die Installation von GitLab ist mit den Omnibus Packages sehr einfach geworden. Wir wechseln zunächst wieder über

sudo su

zu Root und installieren über

apt-get -y install curl openssh-server ca-certificates postfix

die benötigten Abgängigkeiten (Wenn Postfix installiert wird, entweder selbst konfigurieren oder einfach den Standard Internet Site mit Hostnamen beibehalten). Danach installieren wir über

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash
apt-get -y install gitlab-ce

GitLab selbst. Nun noch die Konfiguration über

gitlab-ctl reconfigure

durchführen, und wir haben auf einem vorkonfigurierten nginx-Server auf Port 80 eine lauffähige GitLab-Instanz (Benutzername: root, Passwort: 5iveL!fe). Anmelden, Passwort ändern, erneut anmelden, anschauen und freuen. 😉

Als Vorbereitung für den später zu installierenden Jenkins können wir bereits jetzt einen entsprechenden Deploy Key in GitLab hinterlegen. Wechselt dazu mit angemeldetem Benutzer in die Admin area (die drei Zahnräder in der Leiste oben rechts) und hier über die Menüleiste links in die Deploy Keys. Über den Button New Deploy Key könnt ihr nun einen neuen SSH Public Key hinzufügen.

Für Informationen zum Erzeugen eines neuen SSH-Key-Paares bitte den Link beim Hinzufügen des neuen Deploy Keys beachten.

Windows-Benutzer können zur Erzeugung z.B. puttygen nutzen. (Achtung: Hierbei dann den generierten Public Key aus der Textbox kopieren und in GitLab einfügen; den Inhalt der Datei des gespeicherten Public Keys nimmt GitLab nicht an!) Keys speichern nicht vergessen!!! (Private Key bitte an einem sicheren Ort aufbewahren!!!)

Nun könnt ihr nach Herzenslust GitLab erforschen, neue Gruppen und Projekte erstellen, Benutzer hinzufügen etc. Viel Spaß dabei! 😉

[Prunked.Net] Continuous Integration – Teil 2 – OS-Installation

Installiert wird die Server-Edition von Ubuntu 14.04.2 LTS.

Nach dem Booten von CD/DVD wählen wir zunächst die gewünschte Sprache aus (English). Nun wählen wir noch nach Wunsch über F4 die Optionen aus (Install a minimal virtual machine). Danach auf Install Ubuntu Server, und los geht’s 😉

Als nächstes wählen wir die Sprache, in der das Setup durchgeführt wird (English). Ist diese gewählt, führt uns der nächste Schritt zur Auswahl des Standorts (other -> Europe -> Germany). Als nächstes wählen wir die gewünschte Lokalisierung (en_US.UTF-8).

Einen Schritt weiter verneinen wir die Frage, ob das Tastaturlayout erkannt werden soll, und wählen über die darauf folgenden Bildschirme unser gewünschtes Layout aus (German -> German – German (dead grave acute).

Sind mehrere Netzwerkschnittstellen in eurem System vorhanden, könnt ihr nun auswählen, welche primär genutzt werden soll (euer späteres eth0).

Nach Angabe von Hostname, vollständiger Name eines neuen Benutzers, Benutzername, Paswort und Passwortbestätigung, Verschlüsselung des Benutzerverzeichnisses, Bestätigung oder Korrektur der erkannten Zeitzone können wir nun unsere Festplatte nach unseren Wünschen partitionieren (Guided – use entire disk -> Auswahl der Festplatte -> Yes).

Wir werden noch nach einem evtl. vorhandenen HTTP-Proxy gefragt. Wer keinen hat, kann den Eintrag einfach leer lassen, ansonsten müsst ihr entsprechend die URL eintragen. Mit Continue geht es weiter.

Der nächste Bildschirm fragt ab, ob ihr automatische Updates zulassen wollt (No automatic updates). Zusätzlich zur Ubuntu-Installation könnt ihr auswählen, welche Pakete nachinstalliert werden sollen ([OpenSSH server]).

Als letztes werden wir noch gefragt, ob wir den Bootloader in den MBR der Festplatte installieren wollen (Yes). Danach sind wir mit der Installation durch und können über Continue das erste Mal in unser neues System booten.

Meldet euch nun mit dem Benutzernamen und Passwort, die ihr gewählt habt, an. Ein ifconfig später haben wir die IP-Adresse heraus und können nach Bedarf alle folgenden Schritte per SSH weitermachen.

Die nächsten Schritte benötigen zumeist Root-Rechte, wechseln wir also über

sudo su

zu diesem.

Hinweis: Solltet ihr beabsichtigen, Mono unter Linux nutzen zu wollen, empfiehlt es sich, als nächstes die Installationsquelle des Mono-Project über

apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list

einzubinden. Bei mir bestand zu einem späteren Zeitpunkt immer das Problem, das ich mich in einer „Dependency Hell “ (sprich: für Mono benötigte Abhängigkeiten konnten nicht korrekt aufgelöst und installiert werden) befand.

Bringen wir als nächstes unser System auf den aktuellen Stand.

apt-get -y update
apt-get -y upgrade
apt-get -y dist-upgrade

Zusätzlich sollten wir noch ein paar weitere benötigte Pakete wie z.B. nano, wgetgit, default-jdk und mono-complete über

apt-get -y install nano wget git default-jdk mono-complete

installieren. Fügen wir nun JAVA_HOME zu den Umgebungsvariablen hinzu und lesen letztere neu ein:

echo "JAVA_HOME=\"/usr/lib/jvm/default-java\"" >> /etc/environment
source /etc/environment

Ein abschließendes

reboot

und die Grundinstallation des Systems abgeschlossen.

[NuGet] ASP.NET MVC and TinyMCE 4.0

Hi there!

Today, i published some updated package for ASP.NET MVC TinyMCE 4.0 integration (based on http://www.tugberkugurlu.com/archive/tinymce-html-text-editior-and-asp-net-mvc-setting-it-up-has-become-easy-with-nuget).

Following packages are available:

Hope these packages will help on integrating TinyMCE 4.0 in your existing ASP.NET MVC solution.

[IIS 7.x] PKI-Authentifizierung

Um den IIS 7.x für eine starke Authentifizierung mittels PKI einzurichten, sind folgende Schritte notwendig:

  1. Das Feature Authentifizierung über Clientzertifikatzuordnung (Windows 7) bzw. Clientzertifikatszuordnung-Authentifizierung (Windows Server 2008 R2) installieren. Dies geschieht unter Windows 7 über Systemsteuerung->Programme und Funktionen->Windows-Funktionen aktivieren oder deaktivieren->Internetinformationsdienste->WWW-Dienste->Sicherheit->Authentifizierung über Clientzertifikatzuordnung, unter Windows Server 2008 R2 über Server-Manager->Rollen->Webserver (IIS)->Rollendienst hinzufügen->Webserver->Sicherheit->Clientzertifikatszuordnung-Authentifizierung„.
  2. Nachdem das Feature erfolgreich installiert wurde, den Internetinformationsdienste (IIS)-Manager öffnen und den Server auswählen. Hier muss in der Ansicht „Features“ unter Authentifizierung die Option Active Directory-Clientzertifikatauthentifizierung aktiviert werden.
  3. Unter Sites die gewünschte Website auswählen und mittels Kontextmenü Bindungen bearbeiten… wählen. Es muss zwingend eine Bindung vom Typ https mit einem gültigen Zertifikat existieren. Es ist zwar empfehlenswert, alle anderen Bindungen zu entfernen, jedoch nicht unbedingt notwendig (falls z.B. noch andere Applikationen ohne PKI-Authentifizierung in der Website laufen).
  4. Innerhalb der Website die gewünschte Applikation auswählen und in der Ansicht „Features“ unter Authentifizierung alle verfügbaren Optionen deaktivieren. Sie werden beim Mapping des Client-Zertifikats auf den Windows-Account nicht mehr gebraucht.
  5. Ebenfalls der Ansicht „Features“ müssen unter SSL-Einstellungen die Optionen SSL erforderlich und Clientzertifikate: Erforderlich aktiviert werden.

Nun ruft man nun die gewünschte Applikation auf. Sollte nur ein passendes Client-Zertifikat im Benutzerzertifikatsspeicher vorhanden sein, wird dieses automatisch angezogen. Andernfalls erscheint ein Auswahldialog mit den verfügbaren Client-Zertifikaten.

[ASP.NET MVC 3] elmah Integration

Abend liebe Leute 😉

Seit einiger Zeit entwickle ich nun schon verschiedene Intranetapplikationen unter Einsatz des ASP.NET MVC 3 Frameworks. Und da wir alle nur Menschen sind, machen wir bekanntlich auch Fehler…

Am Schlimmsten ist es dann, vom Kunden zu hören „Geht nicht!“. Als Entwickler ist man dann immer froh über Mitarbeit. Als zusätzliche Hilfe möchte ich euch heute zeigen, wie man elmah (Error Logging Modules and Handlers) in seine MVC-Applikation einbindet und konfiguriert.

Als erstes ladet ihr euch die Binaries unter dem oben angegebenen Link herunter (aktuell zum Zeitpunkt des Blogposts: v1.2 SP1). Entpackt diese in euer Libs-Verzeichnis eurer Solution (oder wo auch immer ihr die hinpackt 😉 ).

Fügt nun in eurem MVC-Projekt einen Verweis auf die Elmah.dll hinzu.

Folgendes in die web.config hinzufügen:


<configuration>

    <configSections>

        ...

        <sectionGroup name="elmah">

            <section name="errorLog" type="Elmah.ErrorLogSectionHandler, Elmah" requirePermission="false" />

            <section name="errorFilter" type="Elmah.ErrorFilterSectionHandler, Elmah" requirePermission="false" />

            <section name="security" type="Elmah.SecuritySectionHandler, Elmah" requirePermission="false" />

        </sectionGroup>

    </configSections>

    <elmah>

        <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/Logs/Elmah" />

        <!-- Achtung! Erlauben des Remotezugriffs erfolgt auf eigene Gefahr! -->

        <!-- Infos: http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html -->

        <!--<security allowRemoteAccess="1" />-->

    </elmah>

    ...

    <!-- für IIS < 7 -->

    <system.web>

        ...

        <httpHandlers>

            ...

            <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

        </httpHandlers>

        <httpModules>

            ...

            <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />

        </httpModules>

    </system.web>

    <!-- für IIS >= 7 -->

    <system.webServer>

        ...

        <handlers>

            ...

            <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

        </handlers>

        <modules runAllManagedModulesForAllRequests="true">

            ...

            <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />

        </modules>

    </system.web>

</configuration>

Wir sind nun fast fertig 😉 Wir legen uns nun noch einen eigenen ExceptionFilter an (unbehandelte Ausnahmen werden standardmäßig sowieso von Elmah geloggt)


using System.Web.Mvc;
using Elmah;

namespace Prunked.Net.Flt
{
    public class ElmahErrorFilter : IExceptionFilter
    {
        #region IExceptionFilter Members

        public void OnException(ExceptionContext context)
        {
            if (context.ExceptionHandled)
            {
                ErrorSignal.FromCurrentContext().Raise(context.Exception);
            }
        }

        #endregion
    }
}

und registrieren diesen in unserer Applikation (dazu die Global.asax.cs öffnen)


public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new ElmahErrorFilter());
    ...
}

Das sollte es schon gewesen sein. Am besten schaut ihr euch das Ergebnis einfach mal in eurer Entwicklungsumgebung unter http://localhost:<PORT>/elmah.axd an…

Grüße,

prunkster / [TF2CM] prunked

[PRUNKED.NET] TF2CM Project Server…

Hallo allerseits!

Ab sofort steht unser erster TF2-Server unter 84.23.68.16:27015 bereit (Stats verfügbar unter http://stats.prunked.net). Sicherlich gibt es hier und da noch ein paar Kleinigkeiten und Tweaks, die wir vornehmen wollen…

Für Bemerkungen, Anregungen, Kritik etc. sind wir immer dankbar. Schreibt dazu doch einfach einen Kommentar unter diesem Artikel. Wir werden dann sehen, was wir umsetzen können / werden.

 

Beste Grüße,

prunkster / [TF2CM] prunked

Windows Vista / Windows Server 2008 / Windows Storage Server 2008 / Windows 7 / Windows Server 2008 R2 Multi-Installations-Stick…

„Wo ist nun wieder diese verfluchte Windows-DVD?“

Wer kennt es nicht: Der Rechner läuft nicht mehr so, wie er soll. Startet er gar nicht mehr, hat man nun zwei Möglichkeiten: Entweder ein vorhandenes und funktionsfähiges Backup wiederherstellen, oder eine Neuinstallation durchführen. Die Suche nach dem Windows-Installationsmedium steht in den meisten Fällen an…

Wer nun keine Lust hat, immer wieder die Windows-DVD zu suchen, oder das ISO neu zu brennen, für den bietet Microsoft das „Windows 7 USB/DVD Download Tool“ an, womit man sich einen bootfähigen USB-Stick erstellen und von diesem aus die Installation durchführen kann.

An sich eine ganz praktische Sache, jedoch hat diese einen aus meiner Sicht gesehen gewaltigen Nachteil: Man kann mit dieser Variante nur eine Windows-Version auf den Stick übertragen. Hat man sich daheim ein kleines Netzwerk aufgebaut, müsste man diesen für die Installation von unterschiedlichen Clients und Servern immer wieder neu beladen.

Mancher, der sich mit den neueren Version von Windows und deren Setup auskennt, wird sich nun denken: „Hey, dann pack ich halt alle Images aus der install.wim einfach in ein neues wim-File!“ Wird nur leider nichts, da noch Setup-Dateien von der DVD angezogen werden und somit die Installation zum Scheitern verurteilt ist.

Hier möchte ich euch nun einen etwas anderen Weg beschreiben, wie ihr euch einen entsprechenden Installationsstick zusammenstellen könnt. Zunächst die benötigte Software:

Als Hardware benötigt ihr:

  • einen Windows-Rechner
  • einen für eure Anforderungen entsprechend dimensionierten USB-Stick

Alles beisammen? Wunderbar, dann kann es ja losgehen 😉

Zunächst einmal schließt ihr euren USB-Stick am Rechner an, und startet das HP USB Disk Storage Format Tool als Administrator. Wählt hier euren USB-Stick aus, und wählt als „File System“  „FAT32“. „Quick Format“ für die ganz Eiligen noch aktivieren, dann auf „Start“.

Danach entpackt ihr GrubInst und startet die „grubinst_gui.exe“ als Administrator. Nach dem Start wählt ihr unter „Device Name“ den Punkt „Disk“. In der Auswahlliste müsst ihr nun euren USB-Stick auswählen (orientiert euch dabei am besten an der Größe des Sticks). Einen Klick auf „Refresh“ neben der Auswahlliste „Part List“, wählt ihr dann in der Auswahlliste selbst „Whole Disk (MBR)“. Nun sind wir nur noch ein Klick auf „Install“ von einem bootfähigen USB-Stick entfernt.

Als nächstes empfehle ich euch, eine geeignete Ordnerstruktur für die ISOs anzulegen. Die Batchfiles in diesem Artikel müsst ihr dementsprechend anpassen. Für meine Zwecke hat sich folgende Ordnerstruktur bewährt:

  • boot
    • microsoft
      • windows_7
      • windows_server_2008
      • windows_server_2008_r2
      • windows_storage_server_2008
      • windows_vista
  • imdisk
  • install
    • microsoft
      • windows_7
      • windows_server_2008
      • windows_server_2008_r2
      • windows_storage_server_2008
      • windows_vista

Nicht benötigte Windows-Ordner könnt ihr natürlich weglassen 😉

Installiert nun 7-Zip auf eurem Rechner und entpackt damit die „imdiskinst.exe“ auf euren USB-Stick in den Ordner „imdisk“.  Das WAIK ISO entpackt ihr ebenfalls mit 7-Zip auf eure Festplatte in ein temporäres Verzeichnis. Führt hier die „StartCD.exe“ aus, wählt den Menüpunkt „Windows AIK-Setup“ und folgt den weiteren Anweisungen des Assistenten.

Die nächsten Schritte sind nun für jede Windows-Version, die ihr in euren USB-Stick integrieren wollt, zu wiederholen.

Entpackt euch das Windows-ISO mittels 7-ZIP in ein temporäres Verzeichnis, Unterverzeichnis „DVD“. Löscht hier die „sourcesinstall.wim“ – wir erstellen uns ein kleines Hilfs-Boot-ISO, in dem wir die install.wim nicht brauchen.

Öffnet aus dem Startmenü eine „Microsoft Windows AIKEingabeaufforderung für Bereitstellungstools“ (als Administrator). Erstellt in eurem Temp-Verzeichnis ein neues, leeres Verzeichnis, und tippt in die Kommandozeile dann folgendes ein:

imagex /mountrw $TEMP$DVDsourcesboot.wim 2 $TEMP$$DIR$

Damit mountet ihr das zweite in der boot.wim enthaltene Image zum Schreiben in den neuen Ordner. Erstellt euch nun folgende zwei Dateien auf eurem Desktop.

Datei 1: winpeshl.ini

[LaunchApp]
AppPath = wpeinit.exe
[LaunchApps]
cmd.exe, "/q /c %SystemRoot%System32mntdrv.cmd"
%SystemDrive%setup.exe

Datei 2: mntdrv.cmd

@ECHO OFF
CLS
FOR %%i IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF EXIST %%i:nul (
  IF EXIST %%i:imdiskimdisk.inf IF EXIST %%i:imdisksetupcdrom.cmd IF EXIST %%i:imdisksetupimdisk.cmd IF EXIST %%i:installmicrosoftwindows_server_2008_r2x64.iso (
    echo Found necessary files on %%i:>>%SystemDrive%mntdrv.txt
    pushd %%i:imdisk
    echo Setting um ImDisk>>%SystemDrive%mntdrv.txt
    setupimdisk.cmd>>%SystemDrive%mntdrv.txt
    echo Setting up virtual CD/DVD drive, mounting image>>%SystemDrive%mntdrv.txt
    setupcdrom.cmd %%i:installmicrosoftwindows_server_2008_r2x64.iso>>%SystemDrive%mntdrv.txt
  )
)

Hier darauf achten, die Pfade zum ISO entsprechend anzupassen. Kopiert nun diese beiden Dateien nach „$TEMP$$DIR$WindowsSystem32“.

Hintergrund des Ganzen: Wir werden die ISOs am Ende in einem Grub-Menü einbinden. Die ISOs werden hierbei gemappt, so dass die Installation startet. Sobald aber Windows PE die Protected Mode Treiber lädt, können wir nicht mehr auf die gemappten ISOs zugreifen. Mit diesen beiden Dateien starten wir nun zuerst die „wpeinit.exe“ (übernimmt z.B. die Initialisierung von Plug & Play). Danach durchforsten wir die verfügbaren Laufwerksbuchstaben nach Anwesenheit eines Datenträgers und der Existenz der benötigten Dateien. Wurden diese gefunden, wird ImDisk geladen und das Installations-ISO in das virtuelle Laufwerk eingebunden. Abschließend wird das Windows Setup aufgerufen.

Als nächstes führt folgenden Befehl in der Kommandozeile aus:

imagex /unmount /commit $TEMP$$DIR$

Damit unmountet ihr das Image wieder und übertragt die durchgeführten Änderungen.

Nun erstellen wir uns unser Boot-ISO mit dem Befehl (wie schon im Beispiel oben für Windows Server 2008 R2 x64):

oscdimg -lLABEL -t02/15/2011 -b$TEMP$DVDbootetfsboot.com -m -u2 $TEMP$DVD $TEMP$x64.iso

Das Label könnt ihr selbst bestimmen, das Datum muss im Format „DD/MM/YYYY“ angegeben werden. Bei Windows Vista x64 ist es nötig, statt „etfsboot.com“ die „bootsect.exe“ anzugeben.

Das so erstellte ISO packt ihr nun in das entsprechende Unterverzeichnis unter „bootmicrosoft“ auf eurem USB-Stick.

Das originale Installations-ISO kopiert ihr nun in das entsprechende Unterverzeichnis unter „installmicrosoft“ auf eurem USB-Stick. Benennt es bitte entsprechend der Architektur zu „x86.iso“ oder „x64.iso“ um.

Wie oben geschrieben, müssen diese Schritte für die verschiedenen Windows-Versionen entsprechend wiederholt und angepasst werden.

Wir sind nun fast am Ziel, drei Dateien fehlen uns noch auf dem Stick. Die ersten beiden finden ihr neues Zuhause unter „imdisk“:

Datei 1: setupimdisk.cmd

rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 132 .imdisk.inf

Datei 2: setupcdrom.cmd

Set fullname=%~1
imdisk -a -f "%fullname%" -m #:

Die letzte Datei, unser Bootmenü, findet sein Ziel direkt auf dem USB-Stick:

Datei 3: menu.lst

color white/black dark-gray/light-gray white/black white/black
timeout 30
default /default

title Memtest86
find --set-root /boot/other/memtest86/mt420.iso
map /boot/other/memtest86/mt420.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Vista Setup (x86)
find --set-root /boot/microsoft/windows_vista/x86.iso
map /boot/microsoft/windows_vista/x86.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Vista Setup (x64)
find --set-root /boot/microsoft/windows_vista/x64.iso
map /boot/microsoft/windows_vista/x64.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Server 2008 Setup (x86)
find --set-root /boot/microsoft/windows_server_2008/x86.iso
map /boot/microsoft/windows_server_2008/x86.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Server 2008 Setup (x64)
find --set-root /boot/microsoft/windows_server_2008/x64.iso
map /boot/microsoft/windows_server_2008/x64.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Storage Server 2008 Setup (x86)
find --set-root /boot/microsoft/windows_storage_server_2008/x86.iso
map /boot/microsoft/windows_storage_server_2008/x86.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Storage Server 2008 Setup (x64)
find --set-root /boot/microsoft/windows_storage_server_2008/x64.iso
map /boot/microsoft/windows_storage_server_2008/x64.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows 7 Setup (x86)
find --set-root /boot/microsoft/windows_7/x86.iso
map /boot/microsoft/windows_7/x86.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows 7 Setup (x64)
find --set-root /boot/microsoft/windows_7/x64.iso
map /boot/microsoft/windows_7/x64.iso (0xff)
map --hook
chainloader (0xff)
boot

title Windows Server 2008 R2 Setup (x64)
find --set-root /boot/microsoft/windows_server_2008_r2/x64.iso
map /boot/microsoft/windows_server_2008_r2/x64.iso (0xff)
map --hook
chainloader (0xff)
boot

Die menu.lst müsst ihr natürlich entsprechend euren Vorstellungen anpassen. So braucht zum Beispiel nicht jeder noch zusätzlich Memtest86 auf dem Stick 😉

Der größte Vorteil bei dieser Methode ist: Die Installations-ISOs liegen in ihrer Originalform auf dem USB-Stick vor und können so mit einem entsprechenden Brennprogramm einfach wieder auf DVD gebrannt werden (z.B. wenn ein Freund seine DVD verloren hat, der Key aber noch vorhanden ist).

So, ich hoffe, dass ich nichts vergessen habe. Ist einiges an Gefrickel, einiges könnte man evtl. noch eleganter lösen, aber nach diesem Prinzip solltet ihr erst mal in der Lage sein, euren eigenen Multi-Installations-Stick zu erstellen.

Double-Hop, WCF-Sessions und HTTPS…

This site is under construction.

So stay tuned…

Ein neuer Tag, ein neues Projekt…

Ein Projekt mit etwas „verzwickteren“ Anforderungen…

Wer kennt es nicht: Man meldet sich an seinen Rechner an, benutzt ein Programm, und beendet es wieder. Alles ganz normal. Was zum Teil für eine Technik dahintersteckt, wird einem nicht ersichtlich. Allein so eine feine Sache wie Single Sign-On ist vielen nicht bekannt, und diejenigen, die wissen, was dahinter steckt,  möchten es nicht mehr missen.

Gut, diese Story geht noch ein bisschen darüber hinaus. Soll aber auch nicht so wichtig sein. Fangen wir am besten mal an…

Für einen Kunden sollen wir eine Software-Lösung entwickeln. Es soll dabei aus zwei Teilen bestehen: dem Webservice, der die Daten bereitstellt, und ein Client, der auf die vom Webservice bereitgestellten Daten zugreift und diese dem Benutzer präsentiert. Zusätzlich befindet sich im Hintergrund eine Datenbank, in der sich die Daten, die vom Webservice bereitgestellt werden, befinden.

Soweit alles noch kein Problem, ist ja nichts Ungewöhnliches. Das Rollen-Rechte-Konzept sieht nun vor, dass der Benutzer des Clients mittels Windows-Authentifizierung am Service angemeldet wird und die Credentials dann benutzt werden, um sich an der Datenbank selbst ebenfalls per Windows-Authentifizierung anzumelden. Man ahnt nichts Böses…

Double Hop Issue

Doch genau hier steckt der Teufel im Detail: Die Credentials müssen vom Client an den WebServer und von diesem aus an den DBServer weitergegeben werden. Befinden sich diese auf verschiedenen physikalischen Maschinen, so hat man ein Problem: das Double Hop Issue. Standardmäßig ist es nämlich nicht möglich/erlaubt, die Credentials weiterzugeben. Hierzu müssen ein paar Anforderungen an die Infrastruktur erfüllt werden:

  • Die Domäne befindet sich mindestens in der Domänenfunktionsebene Windows Server 2003
  • Benutzer melden sich mittels Windows-Authentifizierung am Webservice an
  • Autorisierte Benutzer der Datenbank werden mit der Windows-Authentifizierung eingetragen
  • Das Kerberos-Token muss vom WebServer an den DBServer weitergegeben werden (Einrichtung der Delegation)

In welcher Domänenfunktionsebene die Domäne arbeitet, lässt sich relativ schnell im MMC-SnapIn „Active Directory-Benutzer und -Computer“ herausfinden. Eigenschaften der Domäne öffnen, dort steht dann auch schon die Funktionsebene unter der Registerkarte „Allgemein“. Eventuell muss man sie noch heraufstufen; dies geschieht im Kontextmenü der Domäne.

Die Windows-Authentifizierung im IIS lässt sich unter den Eigenschaften der Website->Verzeichnissicherheit->Authentifizierung und Zugriffsteuerung aktivieren. Den anonymen Zugriff lassen wir zunächst noch aktiviert.

Die Einrichtung der Benutzer für die Datenbank erkläre ich jetzt nicht, da man hier selber entscheiden soll,  ob nun jeder Benutzer einzeln eingetragen oder man das lieber über eine eigene Gruppe, die im Active Directory hinterlegt ist, regelt.

Letzter Punkt: Einrichtung der Delegation. Damit das Kerberos-Token erfolgreich seinen Weg vom Client über den WebServer zur DB findet, müssen die „Service Principal Names“ korrekt registriert und die Delegation zwischen den einzelnen Computerkonten eingerichtet werden. Hierzu auf dem Domain Controller folgendes ausführen:

setspn -l <dbserver>

Sollte man hier Einträge nach dem Schema „MSSQLSvc/<dbserver>“ sowie „MSSQLSvc/<dbserver-fqdn>“ finden, so ist dies schon mal nicht schlecht. Ansonsten müssen diese noch über folgende Befehle registriert werden:

setspn –a MSSQLSvc/<dbserver>:<Port bzw. Name der SQL Server-Instanz>
setspn –a MSSQLSvc/<dbserver-fqdn>:<Port bzw. Name der SQL Server-Instanz>

Ist dies geschehen, machen wir uns auf und suchen das Computerkonto des Rechners, auf dem der Webservice läuft. In den Eigenschaften des Kontos wählen wir die Registerkarte „Delegation“, und wählen hier „Computer bei Delegierungen angegebener Dienste vertrauen“->“Nur Kerberos verwenden“. Unter Hinzufügen->Benutzer oder Computer geben wir nun den Rechnernamen des DBServers ein, und wählen nach einem Klick auf OK den MSSQLSvc-Eintrag aus. Ein weiterer Klick auf OK, und die Konfiguration sollte damit fertig sein.

Anpassung der WCF-Webservices

Leider habe ich die genaue Konfiguration über HTTP nicht mehr vor Augen, es soll jedoch gesagt sein, dass wir als Binding das wsHttpBinding einsetzten. Die Umstellung des Bindings auf SSL gab dann aber Probleme: Sobald wir

<wsHttpBinding><binding name="wsHttpsBinding"><security mode="Transport"><transport clientCredentialType="Windows"></security></binding></wsHttpBinding>

als bindingConfiguration der Endpoints in der web.config benutzten, schmiss uns der Service eine Fehlermeldung entgegen, dass das Binding keine Sessions unterstützt oder diese nicht richtig konfiguriert seien. Die genaue Ursache ist uns bisher noch nicht klar, da es an sich zwei verschiedene Baustellen sind.

Die Lösung brachte uns ein CustomBinding mit folgenden Parametern:

<customBinding><binding name="customHttpsBinding"><reliableSession /><httpsTransport authenticationScheme="Negotiate" /></binding></customBinding>

Was noch zu erwähnen ist: Wenn die Endpoints mittels bindingConfiguration auf HTTPS umgestellt werden, sollten/müssen die Bindings der Metadata-Exchange-Endpoints (kurz: mex) auf „mexHttpsBinding“ umgestellt werden. Hier ein kurzes Beispiel:

<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />

Dann noch unter

<behaviors><serviceBehaviors><behavior name="de.ecw.prunkster.TestService"><serviceMetadata httpsGetEnabled="true"></behavior></serviceBehaviors></behaviors>

sicherstellen, dass auch wirklich httpsGetEnabled auf true gesetzt ist. Das sollte es dann gewesen sein.