.
Anmeldung | Registrieren | Hilfe

.NET-Blogs Archiv Juni 2015

HSTS auf einer Azure Web App erzwingen

30.06.2015 23:51:00 | Jürgen Gutsch

Das ist ein Nachtrag zu dem Beitrag HTTPS auf einer Azure Web App erzwingen.

Was ist HSTS?

Bei HSTS (HTTP Strict Transport Security) handelt es sich um eine Technik um einen Browser zu zwingen eine Web-Applikation / Website nur mir HTTPS aufzurufen.

Dabei wird ein weiterer HTTP Header vom Server an den Browser gesendet, der diesen Mitteilt, dass die aktuelle Domain (und ggf. Sub-Domains) für einen bestimmten Zeitraum nur per HTTPS aufgerufen werden soll und nicht per HTTP. Diese Domain wird dann – mit dem entsprechenden Verfallsdatum – in einer List im Browser mitgeführt.

Das heißt, wenn ein User die URL ohne HTTPS eingibt, weiß der Browser dass diese Website immer mit HTTPS aufrufen soll. Das gilt auch für Aufrufe aus den Bookmarks heraus. Das heißt konkret, die angefragte Website muss vom Browser im angegebenen Zeitraum zwingend mit HTTPS aufgerufen werden. Sollte das nicht der Fall sein (durch eine Man-in-the-Middle-Attake) soll der Browser eine Fehlermeldungen anzeigen und es darf nicht auf die Website zugegriffen werden.

Diese Technik wurde bereits Ende 2012 als RFC 6797 vom IETF veröffentlicht. Scheinbar stammen die ersten Ideen dazu sogar schon von 2010, bzw. 2009. Allerdings wurde das Thema leider erst jetzt in den letzten Monaten aktuell und nach und nach in den Browsern verbaut.

Der HSTS-Header könnte wie folgt aussehen:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Mit diesem Header wird der Cache für ein Jahr und für alle Subdomains vorgehalten. “includeSubDomains” macht nur Sinn, wenn tatsächlich alle Sub-Domains per HTTPS aufgerufen werden sollen. Sobald man HSTS aktiviert, sollte man sich also absolut sicher sein, dass man komplett auf das alte HTTP verzichtet. Ist die Domain einmal in der HSTS  Liste der Browser enthalten, kann sie bis zum Ablaufdatum nicht mehr per HTTP aufgerufen werden. Das löschen von Einträgen aus dieser Liste ist nicht möglich.

Was allerdings möglich ist, ist das sog. Preloadig: Das ist ein weiteres Feature von HSTS, dass es den Browsern ermöglicht Domains in die Liste aufzunehmen, die er nicht zuvor besucht hat. Abgesehen davon, dass jeder Browserhersteller selber eine gefüllte Liste mit – aus seiner Sicht – wichtigen Websites mitbringt, kann man über eine spezielle Website die Liste selber mit eigenen Einträgen füllen, ohne dass man die Websites vorher besucht haben muss. Dadurch muss der erste Request nicht über eine unverschlüsselte Verbindung gehen.

Im Moment unterstützen alle neuen Browser HSTS, der IE ab Version 11 ebenso. Microsoft Edge soll HSTS ebenfalls unterstützen. Browser die HSTS nicht unterstützen ignorieren den Header und fahren aber nicht unsicherer als mit bisherigen HTTPS Anfragen.

Wie am eigenen Server einrichten?

Die OWASP nennt eine weitere Variante über ein Open Source IIS Module, die ich nicht getestet habe.

Wie auch im letzten Beitrag zum Thema HTTPS, kann die Einstellung auch in den Rewrite Rules in der Web.Config vorgenommen werden. Das heißt, auch diesmal ist es nicht nur für Azure sondern für alle IIS machbar:

<rewrite>
  <rules>
    <rule name="HTTPS_301_Redirect" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="^OFF$" />
        <add input="{SERVER_NAME}" matchType="Pattern" pattern="^localhost$" negate="true" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
    </rule>
  </rules>
  <outboundRules>
    <rule name="Add_HSTS_Header" preCondition="USING_HTTPS" patternSyntax="Wildcard">
      <match serverVariable="RESPONSE_Strict-Transport-Security" pattern="*" />
      <action type="Rewrite" value="max-age=31536000" />
    </rule>
    <preConditions>
      <preCondition name="USING_HTTPS">
        <add input="{HTTPS}" pattern="^ON$" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

Hier wird wie im letzten Beitrag ein permanentes Redirect auf HTTPS gemacht und in den outboundRules wird der HSTS-Header gesetzt, wenn es sich um eine HTTPS Verbindung handelt.

Die OWASP beschreibt HSTS auf folgender Seite: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security

HTTP Sniffer Part 6: Der komplette Sniffer in der Übersicht

30.06.2015 01:12:00 | Jürgen Gutsch

Inhalt

Der Sniffer in der Übersicht:

Folgende CodeMap zeigt die Abhängigkeiten der wichtigsten Komponenten:

Classes

Hier ist zu sehen, wie eine Komponente nach der anderen abgearbeitet wird. Die Komponenten rufen sich nacheinander auf. Den ganzen Weg über wird der ClientStream – der NetworkStream zwischen Browser und unserem Proxy – von einer Komponente zur nächsten mitgegeben, damit die letzte im der Kette die Daten vom RemoteStream – der NetworkStream zwischen Proxy und entfernten Server – direkt an den Browser gesendet werden können.

Folgendes Flussdiagram veranschaulicht die einfache Kommunikation im Falle einer HTTP-Verbindung:

HTTP

Wie bereits im letzten Teil beschrieben ist die Kommunikation im Falle einer HTTPS Verbindung etwas komplexer. Wir müssen zuerst eine saubere HTTPS-Verbindung mit dem Client aufbauen, damit es auf dem Browser nicht zu unschönen Meldungen kommt, außerdem verlangt der Browser nach einer sicheren Verbindung. Anschließend müssen die Antworten auch wieder verschlüsselt an den Client übertragen werden. Dafür müssen die entsprechenden Zertifikate erstellt und registriert werden:

 

HTTPS

Es ist nicht viel Code, der für einen einfachen Proxy wie diesen nötig ist. Allerdings enthält er außer Logging noch keine weiteren Funktionen, sondern gibt die Daten direkt weiter.

Um eine wirkungsvolle Kinderschutzsoftware mit diesem Proxy zu generieren, müssen einige konfigurierbare Filter implementiert werden, wie z. B: URL-Filter, Schlagwortfilter, eventuell Bilder- und Video-Filter.

Neue Standards wie HTTP/2, dessen Neuerungen, sowie HSTS sind ebenfalls noch nicht berücksichtigt. Ich kann mit vorstellen, das HTTP/2 und HSTS genau solche Szenarien erschweren soll. Dieser Proxy muss nun also noch kompatibel zu den neuen Standards gemacht werden.

Wer in den aktuelle Code schauen möchte kann das nun endlich unter https://github.com/JuergenGutsch/async-proxy tun. Der Proxy ist unter MIT Lizenz gestellt. Wer möchte darf sich an der Weiterentwicklung beteiligen. Ich freue mich über jeden PullRequest :) Das Ziel soll sein, eine freie Kinderschutzsoftware und/oder einen Sniffer für Entwicklungszwecke wie eben Fiddler zu erstellen.

ALM Days 2016 – Deine Themen?

26.06.2015 14:27:29 | Christian Binder

Der Sommer bringt uns den TFS 2015, der aus meiner Sicht wirkliche viele Bereiche signifikant erweitert und so die Engineering Plattform vor allem viel offener und erweiterbarer gestaltet. Ein weiterer Schritt zu einer Engineering Plattform, die auch Heterogene Teams optimal unterstützt, um den DevOps LifeCycle zu realisieren. Auf den ALM Days 2015 hatten wir Anfang des Jahres schon mal einen ersten Ausblick gegeben (Videos) und seitdem hat sich auch noch einiges getan – siehe Feature Timeline. Für die ALM Days 2016 habe ich mir daher schon die ersten Gedanken zum Design gemacht und wie immer interessiert mich, welche Themen für Euch besonders wichtig sind. Wer also ein Thema hat, dass er besonders spanned findet, kann mir gerne hier seine Idee zukommen lassen. Den Termin werden wir sobald er fixiert ist bekannt geben. Für alle Sommerurlauber wie mich, wünsche ich gutes Wetter Smile 

Chris

ASP.NET 5 Console Application

26.06.2015 07:45:00 | Jürgen Gutsch

Der Titel ist interessant, nicht war? Was zum Geier ist eine ASP.NET 5 Console Application?

Der Name ist genauso irreführend, wie das Thema interessant ist. Lange war mit nicht klar, was dieser neue Projekttyp überhaupt sein sollte.

Eine in der Console gehostete ASP.NET 5 Applikation ist es definitiv nicht, mit ASP.NET hat dieser Projekttyp ebenfalls wenig zu tun.

Genau gesagt, handelt es sich um eine einfache Console Application die mit .NET Core läuft und dabei auch die Vorteile der neuen .NET Core Projekte beinhaltet:

  • .NET Core
  • CoreCLR
  • project.json
  • .NET Utilities (dnx)

Gebrauchen kann man diese Art der Console Application natürlich ebenso unter Linux und MacOS, aber natürlich am besten auf IoT-Geräten, sowie für Aufgaben ohne UI z. B. in Docker Containern.

Gestartet werden diese Console Applications wie ASP.NET 5 webs:

[code language="JScript"]> dnvm install latest
> dnu restore
> dnx . ConsoleApp1[/code]

Das dnx Command muss natürlich in der project.json deviniert sein:

"commands": {
  "ConsoleApp1" : "ConsoleApp1 a b c d e f"
},

In meinem kleinen Test-Projekt habe ich die Argumente “a b c d e f” angehängt die ich dann entsprechend ausgebe:

public void Main(string[] args)
{
    Console.WriteLine("{0} - {1} - {2} - {3} - {4} - {5}", args);
    Console.ReadKey();
}

image

Für kommende Spielereien mit meinem Raspberry PI wird dieser Projekttyp nun die erste Wahl sein.

Video zum Windows 10 Developer Readiness Screencast auf Channel 9 online

24.06.2015 13:10:44 | Andre Kraemer

Am 8. Juni hatte ich die Freude gemeinsam mit meinen MVP Kollegen Thomas Mutzl und Christian Nagel einen Screencast über die Entwicklung für Windows 10 / die Universal Windows Plattform durchzuführen. Im Rahmen einer weltweiten MVP Initiative berichteten wir in gut 2,5 h darüber, welche Idee hinter der Windows Universal Plattform steckt, welche Änderungen es für XAML Entwickler geben wird und wie ich meine App darauf vorbereiten kann, auf mehreren Endgerätetypen zu laufen.

Seit kurzem ist die Aufnahme des Screencasts nun auf Channel 9 online. Wer also keine Gelegenheit hatte, den Vortrag live zu verfolgen, kann sich nun bequem die Aufnahme ansehen.

Ich selbst habe über das Thema Adaptive UI und Adaptive Code gesprochen. Dieser Teil startet bei ca. 1:42 h. Den Demo Code werde ich in Kürze auf GitHub veröffentlichen.

Und nun: Viel Spaß beim Ansehen!

Video zum Windows 10 Developer Readiness Screencast auf Channel 9 online

24.06.2015 12:10:44 | Andre Kraemer

Am 8. Juni hatte ich die Freude gemeinsam mit meinen MVP Kollegen Thomas Mutzl und Christian Nagel einen Screencast über die Entwicklung für Windows 10 / die Universal Windows Plattform durchzuführen. Im Rahmen einer weltweiten MVP Initiative berichteten wir in gut 2,5 h darüber, welche Idee hinter der Windows Universal Plattform steckt, welche Änderungen es für XAML Entwickler geben wird und wie ich meine App darauf vorbereiten kann, auf mehreren Endgerätetypen zu laufen.

Seit kurzem ist die Aufnahme des Screencasts nun auf Channel 9 online. Wer also keine Gelegenheit hatte, den Vortrag live zu verfolgen, kann sich nun bequem die Aufnahme ansehen.

Ich selbst habe über das Thema Adaptive UI und Adaptive Code gesprochen. Dieser Teil startet bei ca. 1:42 h. Den Demo Code werde ich in Kürze auf GitHub veröffentlichen.

Und nun: Viel Spaß beim Ansehen!

Video zum Windows 10 Developer Readiness Screencast auf Channel 9 online

24.06.2015 12:10:44 | Andre Kraemer

Am 8. Juni hatte ich die Freude gemeinsam mit meinen MVP Kollegen Thomas Mutzl und Christian Nagel einen Screencast über die Entwicklung für Windows 10 / die Universal Windows Plattform durchzuführen. Im Rahmen einer weltweiten MVP Initiative berichteten wir in gut 2,5 h darüber, welche Idee hinter der Windows Universal Plattform steckt, welche Änderungen es für XAML Entwickler geben wird und wie ich meine App darauf vorbereiten kann, auf mehreren Endgerätetypen zu laufen.

Seit kurzem ist die Aufnahme des Screencasts nun auf Channel 9 online. Wer also keine Gelegenheit hatte, den Vortrag live zu verfolgen, kann sich nun bequem die Aufnahme ansehen.

Ich selbst habe über das Thema Adaptive UI und Adaptive Code gesprochen. Dieser Teil startet bei ca. 1:42 h. Den Demo Code werde ich in Kürze auf GitHub veröffentlichen.

Und nun: Viel Spaß beim Ansehen!

RetroGames e.V. in Karlsruhe

23.06.2015 18:56:00 | Daniel Springwald

If it´s saturday night and you are in germany near Karlsruhe, don´t miss to visit the arcade videogames museum of retrogames e.v..


For only a small entrance fee you can play nearly 50 original arcade and pinball machines as long as you want.

My first visit to the museum was really fantastic and lot of fun.


The machines are lovingly restored and most fully functional.


There are all important games of arcade history like Donkey Kong, Pong, Pacman etc.. and newer games like Street Fighter, Star Wars or Tron Legacy.


For more information visit http://www.retrogames.info/

HTTP Sniffer Part 5: SSL ent- und verschlüsseln

22.06.2015 01:07:00 | Jürgen Gutsch

Inhalt

Generell

In diesem Teil geht es um das ent- und verschlüsseln der zuletzt beschriebenen Streams in Falle einer SSL Verbindung.

Dieser Teil ist der kritischste Teil dieser Serie, im Sinne von “ich bin mir nicht sicher, ob ich das veröffentlichen soll, oder nicht.” Einerseits ist dieses Vorgehen sicherheitstechnisch nicht ganz ohne, allerdings ein bekanntes Verfahren das auch von Fiddler verwendet wird.

Was meine ich?

Wenn der Sniffer in einer eingehenden Anfrage erkennt, dass es sich um HTTPS Verbindung handelt (HTTP Verb “CONNECT”) dann muss der Proxy auch ein passendes Zertifikat bereitstellen.

Die Remote-Verbindung dagegen ist einfach, denn hier ist der Sniffer ein Client, der sich wie ein Browser verhält und die Daten anhand des öffentlichen Schlüssels wieder entschlüsseln kann.

Für die Client-Verbindung muss der Sniffer ein Zertifikat bereitstellen das auch noch vertrauenswürdig ist, um die Benutzer nicht mit Meldungen und Hinweisen des Browsers zu verunsichern. Der Sniffer erstellt also on-the-fly bei jedem HTTPS Request ein – für den angefragten Remote-Host – passendes SSL Zertifikat. Getrustet wird dieses Zertifikat mit einem Root-Zertifikat, das auf dem System im Certificate Store abgelegt wird.

Die Installation des Root-Zertifikats benötigt – zum Glück – Admin-Rechte.
Wehe dem, der UAC abgestellt hat.

Auf diese Art haben wir keine SSL Fehler im Browser, haben uns aber zwischen den Client und den Remote-Server gesetzt und die HTTPS Verbindung unterbrochen um mit zu lesen.

Wie sieht das aus?

Sobald wir nun eine CONECT Anfrage erhalten, Antworten wir dem Client und sagen ihm das alles in bester Ordnung ist:

var connectStreamWriter = new StreamWriter(state.ClientStream);
connectStreamWriter.WriteLine("HTTP/1.0 200 Connection established");
connectStreamWriter.WriteLine("Timestamp: {0}", DateTime.Now);
connectStreamWriter.WriteLine("Proxy-agent: GOS Proxy Service");
connectStreamWriter.WriteLine();
connectStreamWriter.Flush();

Ist die Antwort abgeschickt, kann der ClientStream in einen SslStream gesteckt werden (der Einfachheit halber wieder ohne Fehlerbehandlung und Logging):

var sslStream = new SslStream(state.ClientStream, false);
var certProvider = new CertificateProvider();

bool created;
var certificate = certProvider.LoadOrCreateCertificate(state.RemoteHost, out created);
sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, true);

var nstate = new ClientConnectionState
{
    Session = state.Session,
    Client = state.Client,
    ClientStream = sslStream,
    ClientStreamBase = (NetworkStream)state.ClientStream,
    Buffer = new byte[Globals.BufferSize],
    MessageStream = new MemoryStream(),
    IsSsl = true,
};

sslStream.BeginRead(nstate.Buffer, 0, nstate.Buffer.Length, ReadFromClient.Run, nstate);

Der SslStream kann nun benutzt werden um Anfragen entschlüsselt zu lesen und Antworten zu schreiben und zu verschlüsseln. Der ClientStream kann nun nicht mehr direkt gelesen und geschrieben werden, sondern eben nur noch über diesen SslStream. Also, alles was wir schreiben wird verschlüsselt an den Client übertragen und alles was wir vom Client lesen wird vorher entschlüsselt.

Ab jetzt beginnt der Prozess wieder beim anfänglichen einlesen des ClientStreams, denn der nächste Request des Clients wird mit den Standard-Verben (GET, POST, etc.) beginnen. In dem neuen ClientConnectionState wird nun der SslStream als ClientStream weitergeführt (siehe HTTP Sniffer Part 4: Streams optimal verarbeiten).

Die Zertifikate

Die Zertifikate werden über eine Hilfsklasse namens CertificateProvider erstellt. Diese wiederum nutzt die MakeCert.exe – die ins Ausführungsverzeichnis gelegt wird – um die nötigen Zertifikate in einem separaten Prozess zu erstellen und im Certificate Store des Systems abzulegen oder um diese dort auszulesen und für die SslStreams zurückzugeben.

Schaut euch dafür am besten den Code direkt auf GitHub an.

Die Remote-Seite

Für die Anfrage an den Server, wird ebenfalls ein SslStream benutzt, wenn es sich um eine HTTPS-Anfrage handelt, allerdings ist die Behandlung wesentlich einfacher, da wir keine Zertifikate explizit behandeln müssen. Die Methode AuthenticateAsClient übernimmt fas für uns und entschlüsselt den Stream mit dem öffentlichen Schlüssel.

var remoteStreamBase = state.RemoteClient.GetStream();
Stream remoteStream = remoteStreamBase;

if (state.IsSsl)
{
    var sslStream = new SslStream(remoteStream, false);
    sslStream.AuthenticateAsClient(state.RemoteHost);

    remoteStream = sslStream;
}

Nun wird der remoteStream genutzt, um wie gewohnt mit dem Stream zu senden und zu empfangen.

Im nächsten Teil sehen wir wie der Prozess als ganzes aufgebaut ist.

Dependency Injection in ASP.NET MVC 6 Views

18.06.2015 01:39:00 | Jürgen Gutsch

Nicht genug, dass Dependency Injection nun ein durchgehendes Konzept in ASP.NET 5 ist, nun lassen sich auch Services direkt in die Views injizieren. Wie das aussieht?

Ganz einfach :)

Erstellen wir spaßeshalber eine einfache Klasse, die uns eine Liste mit Ländern (vom Type Country) liefert und nennen diese CoutryService. Erstellen wir parallel ein Interface mit dem Namen ICountryservice:

public class CountryService : ICountryService
{
    public IEnumerable<Country> All()
    {
        return new List<Country>
        {
            new Country {Code = "DE", Name = "Deutschland" },
            new Country {Code = "FR", Name = "Frankreich" },
            new Country {Code = "CH", Name = "Schweiz" },
            new Country {Code = "IT", Name = "Italien" },
            new Country {Code = "DK", Name = "Dänemark" }
        };
    }
}

public interface ICountryService
{
    IEnumerable<Country> All();
}

public class Country
{
    public string Code { get; internal set; }
    public string Name { get; internal set; }
}

Diesen CountryService müssen wir nun dem DI Container hinzufügen. Das passiert in der Startup.cs in der Methode ConfigureServices:

services.AddTransient<ICountryService, CountryService>();

Diese Zeile mappt das Interface ICountryService auf die Implementation CountryService. Transient meint in diesem Fall, dass jedes Mal eine neue Instanz von CountryService erstellt wird, wenn wir nach der Implementation von ICountryService fragen. Das ist für diesen Fall absolut in Ordnung.

Nun können wir überall eine Instanz des Coutryservices erhalten. Wie bereits bekannt ist, natürlich auch im Controller per Constructor Injection:

public class HomeController : Controller
{
    private readonly ICountryService _countryService;

    public HomeController(ICountryService countryService)
    {
        _countryService = countryService;
    }
    // …
}

Und neu in ASP.NET MVC 6 auch in den Views.

Folgende Zeile definiert die Injection per Razor-Syntax in der View:

@inject DiViews.Services.ICountryService countryService;

Der erste Teil des @inject legt das Interface fest. Hier wird der komplette Namespace angegeben, sofern kein @using definiert ist und der zweite Wert ist der Name der Variablen, welche die Instanz hält. also analog zur Contructor Injection weiter oben.

Anschließend kann die Instanz wie gewohnt verwendet werden:

@if (countryService.All().Any())
{
    <ul>
        @foreach (var country in countryService.All().OrderBy(x => x.Name))
        {
            <p>@country.Name (@country.Code)</p>
        }
    </ul>
}

Alternativ würden sich auch Select-Boxen füllen lassen oder was auch immer:

@Html.DropDownList("Coutries", countryService.All()
    .OrderBy(x => x.Name)
    .Select(x => new SelectListItem
    {
        Text = x.Name,
        Value = x.Code
    }))

Für was ist das gut?

Eigentlich wird das recht schnell klar: Mit dieser Technik lassen sich z. b. Lookup-Daten einfacher und sauberer in die View bringen als über den ViewBack oder über das Model, bei typisierten Views. Somit wird das Model sauberer und schlanker und die Nutzung des ViewBacks wird reduziert. Die Actions übermitteln nur noch die Daten, die wirklich dynamisch ausgegeben werden sollen. Aus meiner Sicht wird diese Technik auch die Controller um einiges übersichtlicher machen, weil eben diese Lookup-Werte nicht mit ermittelt und zurückgegeben werden müssen.

Da Dependency Injection überall funktioniert, könnte man nun z. B. auch wiederverwendbare TagHelper für Lookup-Werte schreiben.

ASP.NET MVC Web kontinuierlich nach Azure ausliefern mit Jenkins und FAKE

17.06.2015 01:28:00 | Jürgen Gutsch

Vorab

Für ein aktuelles Projekt ist es nötig, schnell auf reale Umgebungen auszuliefern. In einen Fall soll der Entwicklungsstand (DEV) auf eine Instanz ausgeliefert werden, in der wir Entwickler nochmals testen und ggf. debuggen können und im nächsten Fall soll ein Zwischenstand (QS, mit fertigen Features) zum Testen und für Kundenabnahmen auf eine weitere Instanz ausgeliefert werden. Im letzten Fall, soll der abgenommene Stand (PROD) auf das Produktiv-System ausgeliefert werden.

Es soll allerdings nicht nur ausgeliefert werden. Sowohl die Website als auch drum herum entstandene Projekte sollen auch gebaut und anschließend getestet werden.

Wir haben hier drei - nahezu identische – Deployments auf fast identische Umgebungen. Die unterschiede sind minimal:

  • DEV:
    • voll automatisiert
    • baut im Debug-Modus
  • QS:
    • voll automatisiert
    • baut im Release-Modus
  • PROD:
    • automatischer Build
    • manueller Build-Trigger
    • baut im Release-Modus

Die Versionierung lasse ich in diesem Beitrag mal aus.

Die ersten beiden Builds laufen nach dem Commit in den entsprechenden Branch. Der letzte Build wird manuell angestoßen, wenn die Features getestet und abgenommen sind und dieser Stand in den master-Branch comittet sind.

Alternativ zu den Varianten mit Visual Studio Online die aktuelle überall beschrieben sind, stelle ich hier eine andere, offenere und – aus meiner Sicht – leichtgewichtigere  Variante vor.

Jenkins

Als Build-Server dient eine Jenkins-Installation auf einer VM auf Azure. Dort sind drei Build-Jobs angelegt, von denen zwei auf Änderungen im entsprechenden Branches im Git-Repository reagieren und einer auf den manuellen Start wartet.

Jenkins ist ein sehr Leichtgewichtiger und schneller Build-Server, den ich schon seit Ewigkeiten (Noch unter dem Namen Hudson) eingesetzt habe. Die UI ist zwar nicht sehr hübsch, allerdings ist er leicht zu bedienen und schnell installiert. Für Windows gibt es einen kompletten Installer von Bitnami, für alle denen selbst die manuelle Installation noch zu schwer ist ;-)

Alle Build-Jobs ziehen sich den aktuellen Stand des jeweiligen Branches und rufen ein FAKE-Skript mit Parametern auf. Die Parameter sind unter anderem:

  • Build-Nummer
  • Build-Configuration (debug oder release)
  • Name der entsprechenden Azure Deployment Configuration
  • Das Publish-Passwort

FAKE hatte ich in einem separaten Beitrag kurz vorgestellt und kommt bei mir in privaten Projekten immer zum Einsatz. Im Geschäft ist dies der erste Einsatz von FAKE. Ich gehe hier nur auf den Deploiyment Teil in FAKE ein, nicht auf die Konfiguration des Builds und der Tests, da das nicht sehr von dem abweicht, was in der Dokumentation zu FAKE steht. Die Reihenfolge (Konfigurieren, Bauen, Testen und Ausliefern) ist eh klar.

Der Aufruf des FAKE-Scripts in Jenkins erfolgt über ein Batch-Task, Hier wird ebenfalls nur ein Batch-Script aufgerufen, das – bevor das FAKE-Skript gestartet wird – FAKE aktualisiert, in dem es die aktuellen NuGet Packages zieht. War das update erfolgreich wird das FAKE-Script wie folgt aufgerufen:

CI\build.bat bn=%BUILD_NUMBER% conf=Debug pubprofile="MyMvcProject - Web Deploy.pubxml" pubpwd=%PUBLISH_PASSWORDD%

Deployment mit FAKE

Die Auslieferung war etwas Tricky, wir mussten zuerst herausfinden, wie das mit MS-Build gelöst werden kann. Am Ende war es klar: Wir mussten die Web App nochmals bauen mit den Targets Publish und der Angabe der Azure Deployment Configurations. Also ein Web-Deployment direkt auf die Azure Web App.

Wir haben im FAKE-Script wieder einen MsBuild Aufruf, diesmal mit den erwähnten zusätzlichen Parametern:

let setParamsWeb = [
        "DebugSymbols", "True"
        "Configuration", buildConf
        "Platform", "Any CPU"
        "PublishProfile", publishProfile
        "DeployOnBuild", "true"
        "Password", publishPassword
        "AllowUntrustedCertificate", "true"
        "IgnoreDatabaseSettingOutOfSync", "true"
]

// Publish the application
Target "PackageApp" (fun _ –>
    MSBuild buildDir "Build" setParamsWeb ["MySolution/MyMvcProject/MyMvcProject.csproj"]
      |> Log "AppBuild-Output: "
)

Fazit

Im Grunde war es das auch schon. Dieses Setup ist schnell aufgesetzt, einfach zu warten und läuft auch relativ schnell durch. Das Continuous Deployment an sich ist also angenehm leichtgewichtig. Projektverantwortliche und Kunden können schnell auf den aktuellen Stand schauen und schnell Feedback geben. Was im aktuellen Projekt hervorragend funktioniert hat.

Nach Möglichkeit sollte dieses Setup nun in allen zukünftigen .NET-Projekten genutzt werden. Durch FAKE spart man sich eine übermäßige Konfiguration im Jenkins und kann den gesamten Build- und Deployment-Prozess bequem im Visual Studio bearbeiten. Beim nächsten Commit in den jeweiligen Branch wird das FAKE-Script sofort angewendet.

Kostenlose Performance Sprechstunde mit André Krämer auf der Developer Week 2015

16.06.2015 22:12:39 | Andre Kraemer

Am 17. Juni 2015 werde ich deswegen während der Mittagspause der Developer Week einen Kurzvortrag über drei typische Performance Probleme halten. Anschließend haben wir noch ca. 15 Minuten für Fragen und Antworten zu konkreten Performance Problemen, ehe die Sessions wieder starten.

Kostenlose Performance Sprechstunde mit André Krämer auf der Developer Week 2015

16.06.2015 22:12:39 | Andre Kraemer

Die Anwendung ist viel zu langsam!

Diesen Satz möchte wohl kein Entwickler gerne von seinen Kunden oder Anwendern hören.

Am 17. Juni 2015 werde ich deswegen während der Mittagspause der Developer Week einen Kurzvortrag über drei typische Performance Probleme halten. Anschließend haben wir noch ca. 15 Minuten für Fragen und Antworten zu konkreten Performance Problemen, ehe die Sessions wieder starten.

Jeder Besucher der DWX ist herzlich willkommen, mich am Stand von Redgate zu besuchen und seine Fragen mitzubringen.

Kostenlose .NET Performance Sprechstunde mit Andre Kraemer auf der Developer Week 2015

HTTP Sniffer Part 3: Der TcpListener

15.06.2015 01:37:00 | Jürgen Gutsch

Inhalt

Zu allererst:

Dieser Sniffer kann über die Console und über einen Windows-Service gestartet werden. Während der Entwicklung empfiehlt sich der Start über die Konsole. Dafür sollten die Startparameter in den Projekteigenschaften unter Debug festgelegt werden:

image

In der Program.cs werden als erste diese Parameter mit den Mono.Options ausgelesen und validiert:

IPAddress ip = null;
int port = 0;

var p = new OptionSet()
    .Add("a|address=", v => ip = IPAddress.Parse(v))
    .Add("p|port=", v => port = int.Parse(v));

p.Parse(args);

Im Anschluss erfolgt der Aufruf der Klasse Proxy, die auch vom Windows-Service aufgerufen wird:

var proxy = new Proxy
{
    ListenToIp = ip,
    ListenOnPort = port
};
proxy.Start();

In der Klasse Proxy sitzt nun der TcpListener.

Der Einfachheit halber lasse ich in den folgenden Code-Beispielen das Logging weg. Der Logger ist hier eine eigene kleine Implementation um in eine Textdatei und in das Windows Event Log zu schreiben.

Der TcpListener

Der TcpListener aus dem Namespace System.Net.Sockets, hängt sich an die angegebenen IP-Adresse und den angegebenen Port und lauscht auf eingehende Anfragen. Das ist unser Einstiegspunkt. Hier kommen die Requests rein, die wir filtern bzw. mitlesen wollen.

In folgenden Beispiel ist die komplette Klasse Proxy zu sehen.

public class Proxy
{
    private TcpListener _tcpListener;
    public IPAddress ListenToIp { get; set; }
    public int ListenOnPort { get; set; }
       
    public void Start()
    {
        Stop();
        ServicePointManager.ServerCertificateValidationCallback +=
            (sender, certificate, chain, policyErrors) => true;

        _tcpListener = new TcpListener(ListenToIp, ListenOnPort);
        _tcpListener.Start();

        _tcpListener.BeginAcceptTcpClient(AcceptTcpClient.Run, _tcpListener);
    }
       
    public void Stop()
    {
        if (_tcpListener != null)
        {
            _tcpListener.Stop();
        }
        _tcpListener = null;
    }
}

Das erste was hier beim Start gemacht wird, ist einen eventuell laufenden TcpListener zu stoppen, um Konflikte zu vermeiden, wenn bereits eine Instanz auf den angegebenen Port lauscht.

Im zweiten Schritt deaktivieren wir die Server Zertifikat Validierung, um auch Antworten von Servern mit nicht validen Zertifikaten verarbeiten zu können.

Nun wird eine neue Instanz eines TcpListeners mit der IP-Adresse und der Portnummer erstellt und gestartet. Die nächste Zeile repräsentiert die komplette asynchrone Verarbeitung in dieser Bibliothek. Der Aufruf von BeginAcceptTcpClient lässt den TcpListener auf den nächsten eingehenden Request reagieren und einen TcpClient erstellen. Diesem Aufruf übergeben wir den Zeiger auf den Handler und den aktuellen TcpListener als AsyncState-Variable.

Der Handler ist die statische Methode Run in der Klasse AcceptTcpClient. Auch diese Klasse ist angenehm klein. Sie erzeugt einen TcpClient, lässt den TcpListener wieder weiter lauschen und delegiert weiter um die Streams zu bearbeiten:

Der TpListener wird aus den AsyncState ausgelesen. In der ersten Zeile innerhalb des Try-Blockes wird dann mit dem Aufruf EndAcceptTcpClient der TcpClient geladen, mit dem wir nun weiter arbeiten werden. Ganz am Ende der Methode Run, wird wieder die Methode BeginAcceptTcpClient des TcpListeners aufgerufen – wie in der Klasse Proxy – um auf die nächste eingehende Anfrage reagieren zu können. Das ist schon die ganze direkte Verwendung des TcpListeners:

public class AcceptTcpClient
{
    public static void Run(IAsyncResult result)
    {
        if (result.IsCompleted == false || !(result.AsyncState is TcpListener))
        {
            return;
        } 
       
        var tcpListener = result.AsyncState as TcpListener;

        try
        {
            var tcpClient = tcpListener.EndAcceptTcpClient(result);

            tcpClient.ReceiveBufferSize = Globals.BufferSize;
            tcpClient.SendBufferSize = Globals.BufferSize;

            var clientStream = tcpClient.GetStream();

            var state = new ClientConnectionState
                {
                    Session = new RequestSession(),
                    Client = tcpClient,
                    ClientStream = clientStream,
                    ClientStreamBase = clientStream,
                    Buffer = new byte[Globals.BufferSize],
                    MessageStream = new MemoryStream(),
                    IsSsl = false
                };

            clientStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadFromClient.Run, state);
        }
        catch(Exception ex)
        {
            Logger.Log("Error while attempting to complete async connection.");
            Logger.Log(ex);
        }

        // auf den nächsten Client warten und reagieren
        tcpListener.BeginAcceptTcpClient(AcceptTcpClient.Run, tcpListener);
    }
}

Der TcpClient wird nun so Konfiguriert, dass er mit der selben Puffergröße arbeitet, wie wir das das mit den Streams tun werden. 20 KB haben sich als optimale Größe herausgestellt. in der Regel wird man mit dem Wert etwas herum spielen werden. In diesem Fall müssen wir aber sicherstellen, dass der TcpCLient, die Leitungskapazität und unsere Stream-Behandlung einigermaßen gleich schnell abläuft.

Den Stream den wir hier vom TcpClient bekommen nennen wir nun den clientStream, da er die Verbindung mit dem Client offen hält.

Auch jetzt müssen wir asynchron weiterarbeiten. um den aktuellen Thread nicht zu blocken und vor allem, um Speicher-schonend weiter zu arbeiten. Wir rufen nun also die Methode BeginRead des clientStreams auf, erzeugen dafür eine Klasse ClientConnectionState die wir als AsyncState an den Aufruf übergeben. Ebenso nutzen wir den definierten Byte-Array-Puffer unseres ClientConnectionState, um Blockweise aus dem Stream zu lesen. Die statische Handler-Methode Run in der Klasse ReadFromClient wird nun so oft aufgerufen, bis der Stream zu Ende gelesen ist. Es werden also immer 20 KB ausgelesen und per ClientConnectionState an den Handler übergeben.

Alle Streams werden auf diese Art behandelt. So erreichen wir einen gleichmäßigen und Speicher-schonenden Datenfluss und können mehrere Anfragen parallel behandeln. Mehr dazu im nächsten Teil mit dem Thema: Streams optimal verarbeiten.

Pound and Varnish Cache + SSL (Https Port 443) on IIS/Nginx

14.06.2015 08:02:00 | Andreas Mehl

1. Install and configure Pound

Varnish isn't listening on port 443 and doesn’t handle SSL traffic. 

So if you want an SSL-encrypted web site to be cached with Varnish, 

you need to intercept and decrypt the SSL traffic before it gets passed to Varnish, with a utility like the Pound reverse proxy and load balancer.

 

Since we only need Pound to decrypt SSL traffic, we’ll set it up to listen on port 443 and pass to Varnish on port 80.

 

Install pound

$ apt-get install pound

 

Set Pound to start on system boot (in /etc/default/pound):

startup=1

 

Edit your Pound configuration (/etc/pound/pound.cfg):

 

ListenHTTPS

        Address 0.0.0.0  

        Port 443

        Cert "/etc/ssl/private/myserverdomain.pem"

        HeadRemove "X-Forwarded-Proto"

        AddHeader "X-Forwarded-Proto: https"

        Service

                BackEnd

                        Address 0.0.0.0

                        Port 80

                End

        End

End

 

The Cert directive points to your web site’s certificate for decrypting SSL traffic, and the “BackEnd” 

points to the address and port where Varnish is listening. 

Thus, SSL traffic goes from 443 (Pound) to 0.0.0.0:80 (Varnish) to Backend 192.168.0.1:8080 (Nginx or IIS). 

We also add an HTTP header to indicate that we’re forwarding SSL traffic.

 

Configure varnish

Set up Varnish to listen for HTTP traffic on port 80

DAEMON_OPTS="-a :80 \

             -T localhost:6082 \

             -f /etc/varnish/default.vcl \

             -S /etc/varnish/secret \

             -s malloc,256m"

 

2. SSL (Https - Port 443)

to get the cert (pem file) for pound you have to do following:

Create Free SSL certificate from StartCom StartSSL

Anyone looking for a free alternative that is accepted without confirmation of the client, should take a look at StartSSL.

This offer with StartCom StartSSL Free to create an SSL certificate for a year, which is entirely free.

You will receive for the top level domain and a subdomain encrypted for free.

Steps:

1.

First, we need to invest in the somewhat confusing website StartSSL an account.

This we can accomplish in the Control Panel with the button sign up.

Then we need to specify our address, telephone number and email address.

2.

After logging we receive via email a code that we need to specify the page to submit the registration,

to complete this. Then the address data are checked by an employee.

This may take several hours depending on the time of day. When the test is complete and the data has been accepted,

obtained a second e-mail with an activation link that we have to click and, in this another code, which is included in the email

enter.

3.

Now we need to Generate Private Key Generate a certificate in the next step, with the browser at StartSSL in

can log created account. The default 2048 bit is fine, so we proceed by clicking Continue and then

can install the certificate.

4.

Having signup now done, we can go in the Control Panel of the Validation Wizard StartSSL tab.

There we select Domain Name Validation and enter the next step, the domain to which we want to create an SSL certificate.

In the third step, we must choose which of the three standard e-mail addresses, a verification code is sent.

Once we receive the code by e-mail, we have to enter the last step on the website of StartSSL.

 

This is necessary because StartSSL must verify that the domain for which we later create an SSL certificate really belongs to us.

 

5.

Created account and domain verified. Now all preparatory steps are done and we can to generate an SSL certificate

pass. For this we select the tab Certificates Wizard and there choose the type of SSL certificate that we would like to exhibit.

The steps are exemplary declared a Web server SSL / TLS Certificate, which we need for a Web server IIS or nginx.

6.

First, we have to generate a private key. However, the private key is a key which should not be published,

this is why we should not on the website, but produce itself.

 

Using Microsoft IIS to Generate CSR and Private Key

How to generate a CSR in Microsoft IIS

 

  1. Click Start, then Administrative Tools, then Internet Information Services (IIS) Manager.
  2. Click on the server name.
  3. From the center menu, double-click the "Server Certificates" button in the "Security" section (it is near the bottom of the menu). 
  4. Next, from the "Actions" menu (on the right), click on "Create Certificate Request." This will open the Request Certificate wizard.
  5. In the "Distinguished Name Properties" window, enter the information as follows:
  6. Common Name - The name through which the certificate will be accessed (usually the fully-qualified domain name, e.g., www.domain.com or mail.domain.com).
  7. Organization - The legally registered name of your organization/company.
  8. Organizational unit - The name of your department within the organization (frequently this entry will be listed as "IT," "Web Security," or is simply left blank).
  9. City/locality - The city in which your organization is located.
  10. State/province - The state in which your organization is located.
  11. Click Next.
  12. In the "Cryptographic Service Provider Properties" window, leave both settings at their defaults (Microsoft RSA SChannel and 4096) and then click next.
  13. Enter a filename for your CSR file. 
  14. Remember the filename that you choose and the location to which you save it. You will need to open this file as a text file and copy the entire body of it (including the Begin and End Certificate Request tags) into the online order process when prompted

 

Get Private Key

To get the private key on Microsoft IIS follow these instructions:

 

  1. From your server, go to Start > Run and enter mmc in the text box. Click on the OK button.
  2. From the Microsoft Management Console (MMC) menu bar, select Console > Add/Remove Snap-in.
  3. Click on the Add button. Select Certificates from the list of snap-ins and then click on the Add button.
  4. Select the Computer account option. Click on the Next button.
  5. Select the Local computer (the computer this console is running on) option. Click on the Finish button.
  6. Click on the Close  button on the snap-in list window. Click on the OK button on the Add/Remove Snap-in window.
  7. Click on Certificates from the left pane. Look for a folder called REQUEST or "Certificate Enrollment Request> Certificates
  8. Select the private key that you wish to backup. Right click on the file and choose > All Tasks > Export 
  9. The certificate export wizard will start, please click  Next  to continue. In the next window select Yes, export the private key and click Next 
  10. Leave the default settings selected and click Next.
  11. Set a password on the private key backup file and click  Next 
  12. Click on Browse and select a location where you want to save the private key Backup file to and then click Next to continue. By default the file will be saved with a .pfx extension. 
  13. Click  Finish, to complete the export process

 

Convert to RSA Private Key Format

The private key is backed up as a '.pfx' file, which stands for Personal Information Exchange.

To convert it to RSA Private Key format supported by inSync:

1. Download and install latest version of OpenSSL for windows from http://www.slproweb.com/products/Win32OpenSSL.html.

2. Open command prompt, navigate to C:\OpenSSL-Win32\bin>, and run the following commands.

Set OPENSSL_CONF=c:\openssl-win32\bin\openssl.cfg 

openssl pkcs12 -in filename.pfx -nocerts -out key.pem

openssl rsa -in key.pem -out myserver.key

3. The private key will be saved as 'myserver.key'.

4. Carefully protect the private key. Be sure to backup the private key, as there is no means to recover it, should it be lost.

 

On the website of StartSSL we click Skip and are then prompted to enter the Certificate Request.

To do this we simply copy the contents of .csr in the specified field.

 

7.

In the next step, we need to select one of the previously verified domains for which we want to create an SSL certificate.

We must now specify a subdomain, which will also be supported by the certificate.

Normally, you should specify www At this point, if the certificate should not be issued for a specific subdomain.

Subsequently, we have to confirm our statements again. Once done, we obtain again in the browser the message that the certificate

was requested and we will be notified via email if this is issued.

8.

Do we have received the email in the Control Panel under Tool Box and then Retrieve Certificate the free SSL certificate

pick up that appears in a text box. We place its contents in a .crt file called from (should be replaced again).

9.

We now have the private key and SSL certificate. Furthermore, we still need the ca.pem and sub.class1.server.ca.pem file StartSSL,

which we can download.

 

10.

In conclusion, now we need to insert the SSL certificate Path in pound config.

 

3. Making a .pem File for SSL Certificate Installations

.pem SSL Creation Instructions

Making a .pem with the Private Key and Entire Trust Chain

Open a text editor (such as wordpad) and paste the entire body of each certificate into one text file in the following order:

 

The Private Key - your_domain_name.key

The Primary Certificate - your_domain_name.crt

The Intermediate Certificate - DigiCertCA.crt

The Root Certificate - TrustedRoot.crt

Make sure to include the beginning and end tags on each certificate. The result should look like this:

 

-----BEGIN RSA PRIVATE KEY----- 

(Your Private Key: your_domain_name.key) 

-----END RSA PRIVATE KEY----- 

-----BEGIN CERTIFICATE----- 

(Your Primary SSL certificate: your_domain_name.crt) 

-----END CERTIFICATE----- 

-----BEGIN CERTIFICATE----- 

(Your Intermediate certificate: sub.class1.server.ca.pem) 

-----END CERTIFICATE----- 

-----BEGIN CERTIFICATE----- 

(Your Root certificate: ca.pem) 

-----END CERTIFICATE-----

 

Save the combined file as your_domain_name.pem. The .pem file is now ready to use.

 

Don't forget to open 443 Port on your router and on your firewalls.

 

Done! The free SSL certificate for a domain was issued for one year and is ready for use.

Pound and Varnish Cache + SSL (Https Port 443) on IIS/Nginx

14.06.2015 08:02:00 | Andreas Mehl

1. Install and configure Pound

Varnish isn't listening on port 443 and doesn’t handle SSL traffic. 

So if you want an SSL-encrypted web site to be cached with Varnish, 

you need to intercept and decrypt the SSL traffic before it gets passed to Varnish, with a utility like the Pound reverse proxy and load balancer.

 

Since we only need Pound to decrypt SSL traffic, we’ll set it up to listen on port 443 and pass to Varnish on port 80.

 

Install pound

$ apt-get install pound

 

Set Pound to start on system boot (in /etc/default/pound):

startup=1

 

Edit your Pound configuration (/etc/pound/pound.cfg):

 

ListenHTTPS

        Address 0.0.0.0  

        Port 443

        Cert "/etc/ssl/private/myserverdomain.pem"

        HeadRemove "X-Forwarded-Proto"

        AddHeader "X-Forwarded-Proto: https"

        Service

                BackEnd

                        Address 0.0.0.0

                        Port 80

                End

        End

End

 

The Cert directive points to your web site’s certificate for decrypting SSL traffic, and the “BackEnd” 

points to the address and port where Varnish is listening. 

Thus, SSL traffic goes from 443 (Pound) to 0.0.0.0:80 (Varnish) to Backend 192.168.0.1:8080 (Nginx or IIS). 

We also add an HTTP header to indicate that we’re forwarding SSL traffic.

 

Configure varnish

Set up Varnish to listen for HTTP traffic on port 80

DAEMON_OPTS="-a :80 \

             -T localhost:6082 \

             -f /etc/varnish/default.vcl \

             -S /etc/varnish/secret \

             -s malloc,256m"

 

2. SSL (Https - Port 443)

to get the cert (pem file) for pound you have to do following:

Create Free SSL certificate from StartCom StartSSL

Anyone looking for a free alternative that is accepted without confirmation of the client, should take a look at StartSSL.

This offer with StartCom StartSSL Free to create an SSL certificate for a year, which is entirely free.

You will receive for the top level domain and a subdomain encrypted for free.

Steps:

1.

First, we need to invest in the somewhat confusing website StartSSL an account.

This we can accomplish in the Control Panel with the button sign up.

Then we need to specify our address, telephone number and email address.

2.

After logging we receive via email a code that we need to specify the page to submit the registration,

to complete this. Then the address data are checked by an employee.

This may take several hours depending on the time of day. When the test is complete and the data has been accepted,

obtained a second e-mail with an activation link that we have to click and, in this another code, which is included in the email

enter.

3.

Now we need to Generate Private Key Generate a certificate in the next step, with the browser at StartSSL in

can log created account. The default 2048 bit is fine, so we proceed by clicking Continue and then

can install the certificate.

4.

Having signup now done, we can go in the Control Panel of the Validation Wizard StartSSL tab.

There we select Domain Name Validation and enter the next step, the domain to which we want to create an SSL certificate.

In the third step, we must choose which of the three standard e-mail addresses, a verification code is sent.

Once we receive the code by e-mail, we have to enter the last step on the website of StartSSL.

 

This is necessary because StartSSL must verify that the domain for which we later create an SSL certificate really belongs to us.

 

5.

Created account and domain verified. Now all preparatory steps are done and we can to generate an SSL certificate

pass. For this we select the tab Certificates Wizard and there choose the type of SSL certificate that we would like to exhibit.

The steps are exemplary declared a Web server SSL / TLS Certificate, which we need for a Web server IIS or nginx.

6.

First, we have to generate a private key. However, the private key is a key which should not be published,

this is why we should not on the website, but produce itself.

 

Using Microsoft IIS to Generate CSR and Private Key

How to generate a CSR in Microsoft IIS

 

  1. Click Start, then Administrative Tools, then Internet Information Services (IIS) Manager.
  2. Click on the server name.
  3. From the center menu, double-click the "Server Certificates" button in the "Security" section (it is near the bottom of the menu). 
  4. Next, from the "Actions" menu (on the right), click on "Create Certificate Request." This will open the Request Certificate wizard.
  5. In the "Distinguished Name Properties" window, enter the information as follows:
  6. Common Name - The name through which the certificate will be accessed (usually the fully-qualified domain name, e.g., www.domain.com or mail.domain.com).
  7. Organization - The legally registered name of your organization/company.
  8. Organizational unit - The name of your department within the organization (frequently this entry will be listed as "IT," "Web Security," or is simply left blank).
  9. City/locality - The city in which your organization is located.
  10. State/province - The state in which your organization is located.
  11. Click Next.
  12. In the "Cryptographic Service Provider Properties" window, leave both settings at their defaults (Microsoft RSA SChannel and 4096) and then click next.
  13. Enter a filename for your CSR file. 
  14. Remember the filename that you choose and the location to which you save it. You will need to open this file as a text file and copy the entire body of it (including the Begin and End Certificate Request tags) into the online order process when prompted

 

Get Private Key

To get the private key on Microsoft IIS follow these instructions:

 

  1. From your server, go to Start > Run and enter mmc in the text box. Click on the OK button.
  2. From the Microsoft Management Console (MMC) menu bar, select Console > Add/Remove Snap-in.
  3. Click on the Add button. Select Certificates from the list of snap-ins and then click on the Add button.
  4. Select the Computer account option. Click on the Next button.
  5. Select the Local computer (the computer this console is running on) option. Click on the Finish button.
  6. Click on the Close  button on the snap-in list window. Click on the OK button on the Add/Remove Snap-in window.
  7. Click on Certificates from the left pane. Look for a folder called REQUEST or "Certificate Enrollment Request> Certificates
  8. Select the private key that you wish to backup. Right click on the file and choose > All Tasks > Export 
  9. The certificate export wizard will start, please click  Next  to continue. In the next window select Yes, export the private key and click Next 
  10. Leave the default settings selected and click Next.
  11. Set a password on the private key backup file and click  Next 
  12. Click on Browse and select a location where you want to save the private key Backup file to and then click Next to continue. By default the file will be saved with a .pfx extension. 
  13. Click  Finish, to complete the export process

 

Convert to RSA Private Key Format

The private key is backed up as a '.pfx' file, which stands for Personal Information Exchange.

To convert it to RSA Private Key format supported by inSync:

1. Download and install latest version of OpenSSL for windows from http://www.slproweb.com/products/Win32OpenSSL.html.

2. Open command prompt, navigate to C:\OpenSSL-Win32\bin>, and run the following commands.

Set OPENSSL_CONF=c:\openssl-win32\bin\openssl.cfg 

openssl pkcs12 -in filename.pfx -nocerts -out key.pem

openssl rsa -in key.pem -out myserver.key

3. The private key will be saved as 'myserver.key'.

4. Carefully protect the private key. Be sure to backup the private key, as there is no means to recover it, should it be lost.

 

On the website of StartSSL we click Skip and are then prompted to enter the Certificate Request.

To do this we simply copy the contents of .csr in the specified field.

 

7.

In the next step, we need to select one of the previously verified domains for which we want to create an SSL certificate.

We must now specify a subdomain, which will also be supported by the certificate.

Normally, you should specify www At this point, if the certificate should not be issued for a specific subdomain.

Subsequently, we have to confirm our statements again. Once done, we obtain again in the browser the message that the certificate

was requested and we will be notified via email if this is issued.

8.

Do we have received the email in the Control Panel under Tool Box and then Retrieve Certificate the free SSL certificate

pick up that appears in a text box. We place its contents in a .crt file called from (should be replaced again).

9.

We now have the private key and SSL certificate. Furthermore, we still need the ca.pem and sub.class1.server.ca.pem file StartSSL,

which we can download.

 

10.

In conclusion, now we need to insert the SSL certificate Path in pound config.

 

3. Making a .pem File for SSL Certificate Installations

.pem SSL Creation Instructions

Making a .pem with the Private Key and Entire Trust Chain

Open a text editor (such as wordpad) and paste the entire body of each certificate into one text file in the following order:

 

The Private Key - your_domain_name.key

The Primary Certificate - your_domain_name.crt

The Intermediate Certificate - DigiCertCA.crt

The Root Certificate - TrustedRoot.crt

Make sure to include the beginning and end tags on each certificate. The result should look like this:

 

-----BEGIN RSA PRIVATE KEY----- 

(Your Private Key: your_domain_name.key) 

-----END RSA PRIVATE KEY----- 

-----BEGIN CERTIFICATE----- 

(Your Primary SSL certificate: your_domain_name.crt) 

-----END CERTIFICATE----- 

-----BEGIN CERTIFICATE----- 

(Your Intermediate certificate: sub.class1.server.ca.pem) 

-----END CERTIFICATE----- 

-----BEGIN CERTIFICATE----- 

(Your Root certificate: ca.pem) 

-----END CERTIFICATE-----

 

Save the combined file as your_domain_name.pem. The .pem file is now ready to use.

 

Don't forget to open 443 Port on your router and on your firewalls.

 

Done! The free SSL certificate for a domain was issued for one year and is ready for use.

Dependency Injection in ASP.NET MVC 6

12.06.2015 02:31:04 | Jürgen Gutsch

Schon früh war es möglich Depency Injection mit ASP.NET MVC zu nutzen. Mit jeder Version wurde es etwas einfacher machbar. ASP.NET MVC, SignalR und Web API nutzten allerdings jeweils andere Implementationen

Dependency Injection ist nun ASP.NET 5, bzw. ASP.NET MVC 6 vereinheitlicht. Der komplette ASP.NET Stack (MVC, SignalR and Web API) nutzt nun den selben DI-Container.

Wie dieser Konfiguriert wird und wie dieser Ersetzt wird, schreibt Ed Charbeneau in folgendem ausführlichen Blog Beitrag: http://developer.telerik.com/featured/dependency-injection-in-asp-net-mvc6/

HTTP Sniffer Part 2: Grundlegendes zur Funktionsweise

10.06.2015 01:07:00 | Jürgen Gutsch

Inhalt

Grundlegendes zur Funktionsweise

Sowohl Fiddler, als auch der Sniffer den ich hier beschreiben möchte, ist nichts anderes als ein Proxy Server, der Lokal auf dem Rechner läuft, dessen Traffic mitgelesen, bzw. gefiltert werden soll.

Das heißt der komplette Traffic wird umgeleitet zu diesem Proxy und dort weiterverarbeitet. Das passiert systemweit in den Proxy Einstellungen der Internet Optionen die unter anderem über den Internet Explorer erreichbar sind. Einige andere Browser nutzen eigene Proxy Einstellungen die ebenfalls entsprechend gesetzt werden müssen. Mehr dazu später im Detail.

In Richtung der Browser verhält sich dieser Sniffer wie ein Server: Er nimmt die Requests entgegen und beantwortet diese. In die andere Richtung ist dieser Sniffer ein Browser, der die Anfragen an die eigentlichen Webserver sendet und die Antworten entgegennimmt.

image

Der Proxy befindet sich also zwischen dem echten Server und dem Client. Auf die selbe Art findet übrigens auch eine Man-in-the-Middle-Attacke statt. Diesen Hinweis merken wir uns, da er später in Verbindung mit der SSL Verschlüsselung wieder wichtig wird.

Die Hauptsächliche Arbeit findet in der Mitte statt.

Wir benötigen also ein kleines Programm oder einen Service, welcher auf einem speziellen Port auf eingehenden Traffic lauscht und verarbeitet. Das könnte z. B: Port 12345 sein. Die Proxy Einstellungen müssten also wie folgt aussehen:

image

In dieser Serie gehe ich nicht darauf ein, wie die Einstellungen für alle Clients automatisch geändert werden. In diesem Fall werden die Einstellungen manuell gesetzt werden müssen. Auf diese Art kann auch ein spezieller Browser zum testen genutzt werden. Und das System bleibt wie es ist. Zum Beispiel hat Firefox eigene Proxy Einstellungen.

Geschrieben ist alles in C#. Damals .NET 4. Jetzt werde ich es mit .NET 4.6 neu aufsetzen. Die einzige externe Abhängigkeit ist Mono.Options, die ich inzwischen in jede Console App mit reinnehme.

Um jede Art von Traffic lesen zu können, vor allem um auch SSL verschlüsselten Traffic lesen und senden zu können, wird ein TcpListener verwendet (mehr dazu im nächsten Teil). Weiterhin werden wir uns -  da wir uns auf Socket-Ebene (OSI Level 5) befinden - mit den zu lesenden Protokollen auseinandersetzen müssen. In dieser Serie gehe ich der Einfachheit halber allerdings nur auf HTTP und HTTPS ein.

Dieser Sniffer arbeitet also mit NetworkStreams, die der TcpClient zur Verfügung gestellt wird. Der TcpClient wiederum wird vom TcpListener bereitgestellt, sobald sich ein Client mit dem Listener verbindet. Dieser Stream wird im weiteren Kontext von mit ClientStream genannt, da dieser die Verbindung zum Client aufrecht erhält

Um mich nun mit dem Remote Server zu verbinden, muss ich die HTTP-Header Informationen aus dem ClientStream auslesen und die IP und den Port des angefragten Remote-Host ermitteln. Mit diesen Daten kann ich dann wiederum einen TcpClient erstellen, mit dem ich eine Socket-Verbindung zum Remote-Server herstellen kann. Diese Verbindung liefert mir ebenfalls einen NetworkStream, den ich im weiteren Kontext RemoteStream nennen werde.

Das parsen des HTTP Request Headers ist recht einfach. Da dieser Zeilenweise aufgebaut ist. Ich kann also den Stream ab Position 0 zeilenweise auslesen, bis zur ersten Leerzeile ab dann folgt der Body, der erst später interessant wird.

Jeder Request beginnt mit einem HTTP Verb (GET, POST, etc.) mit einer Besonderheit: Eine Anfrage per HTTPS wird nämlich zuerst mit dem Verb CONNECT geführt. CONNECT ist im Prinzip die Anfrage um SSL Tunneling über einen Proxy zu ermöglichen. Erst wenn die CONNECT Anfrage beantwortet ist, wird die GET oder POST Anfrage per HTTPS vom Browser abgeschickt. Dieser Teil muss also gesondert behandelt werden.

Die beiden Streams ClientStream und RemoteStream werden – soweit erforderlich – permanent offen gehalten. NetworkStreams haben die Eigenschaft, dass sie sowohl ausgelesen, also auch beschrieben werden können, wobei nie beide Seiten gleichzeitig schreiben können. Man muss also warten bis eine Seite fertig ist mit schreiben.

Da der Proxy sehr performant sein sollte, ist alles asynchron aufgebaut. Sobald ein TcpClient erstellt wurde, lauscht der TcpListener schon wieder auf die nächste Verbindung. Mehrere Client- und RemoteStreams können so parallel verarbeitet werden

Die aktuelle Lösung reduziert die Netzwerk-Performance spürbar und hat sicherlich noch optimierungspotential. Allerdings ist der Performanceverlust nicht störend und man gewöhnt sich dran. Während der Entwicklungszeit damals hatte ich den Proxy als Windows Service zwei Wochen auf meiner Maschine am laufen. Eating your own dog food

Im nächsten Teil zum TcpListener zeige ich nun endlich auch etwas Code.

HTTP Sniffer Part 1

09.06.2015 01:37:00 | Jürgen Gutsch

Vor etwas mehr als zwei Jahren habe ich für einen zahlungsunwilligen Ex-Kunden einen TCP-Sniffer geschrieben, der in einer Kinderschutz-Software eingesetzt werden sollte. An diesen Sniffer sollten diverse Filter angehängt werden, die z. B. Textdaten nach Schlagwörtern Filtern, Bilder nach Gesichtern, nach Sex- und Gewaltszenen. Sogar Videos sollten entsprechend gefiltert werden. Der Sniffer sollte zudem SSL verschlüsselten Traffic auswerten können.

Im Grunde funktioniert er ganz ähnlich wie auch Fiddler, die Idee zur Behandlung von verschlüsselten Streams stammt tatsächlich von Fiddler. Der Unterschied ist, dass dieser Sniffer am Ende ein Filter darstellen soll, der den Traffic auch ändern kann, wenn es die Filter für erforderlich halten. Wohingegen ein Sniffer den Traffic lediglich mitließt, aber weitestgehend unberührt lässt.

Das spannende an diesem Projekt ist nicht das Sniffen selber, sondern die Arbeit mit echten Streams, um den Traffic performant zu halten. Immerhin soll der User wenig bis nichts merken, wenn er im Netz unterwegs ist. Der User wird wissen, dass ein Filter installiert ist, aber dieser Filter sollte die Surf-Experience nicht negativ beeinflussen, sonst ist der Filter schnell wieder deinstalliert oder deaktiviert.

Nun das in den letzten zwei Jahren weder der Ex-Kunde noch, irgend ein anderer ernsthaftes Interessent gezeigt hat das Stück Software komplett zu erwerben und zu verwenden, möchte ich den Bau dieses Sniffers hier im Blog dokumentieren und den Sniffer selber parallel auf Github zur Verfügung stellen. Bei diversen vertrauenswürdigen Software-Herstellern in Deutschland und der Schweiz, war zwar ein gewisses Interesse an der Software vorhanden, allerdings zogen sich die Entscheidungen sehr lange hin und die letzten Kontakte sind nun auch schon ein Jahr her. Wer weiß, vielleicht entsteht ja tatsächlich mal eine Kinderschutz-Software aus diesem Code.

Inhalt dieser Serie:

Ich hoffen mit dieser Serie auch zeigen zu können, wie man tatsächlich mit Streams umgeht, wie man Streams verschlüsseln kann und worin der Vorteil des Tcp/Ip-Listener gegenüber dem HTTP-Listener besteht. ;)

Get Windows 10 IoT Core running on the Raspberry PI 2

08.06.2015 01:11:03 | Jürgen Gutsch

Nachdem nun mehrere Monate bekannt ist, dass es ein Windows 10 Build für IoT Devices gibt und dieses nun auch schon eine Zeitlang als Preview verfügbar ist, wollte ich es selber wissen.

Vorbereitung

Ich hatte noch eine 8 GB Micro SD Karte übrig und versuchte nun einen Weg zu finden, ohne Windows 10, das “Windows 10 IoT Core” Image auf die SD Karte zu bekommen.

Der Grund warum Windows 10 benötigt wird, ist die dism.exe, die auf älteren Systemen nicht auf eine SD Karte schreiben kann. Man muss also an eine Version kommen die mit Windows 10 ausgeliefert wird. golem.de schreibt in seinem Artikel dazu, dass die neueste dism.exe mit dem Windows Assessment and Deployment Kit für Windows 10 (Windows ADK) installiert wird.

Mit diesem Hinweis konnte ich dann dem Tutorial von Microsoft weiter folgen und das Image auf die SD Karte bringen

Das die Vorbereitung nicht ganz so flüssig lief, war zu erwarten, da es Überall so beschrieben wurde.

Erster Start

Nach dem ich die Micro SD Karte in das Gerät gesteckt hatte, folgte der erste Start, bzw. der erste Hänger des Systems.

Ein Neustart brachte das System in eine Art Start-Bildschirm, dass dem von Windows 8.1/10 ähnelte, allerdings farblos und ohne die Möglichkeit diesen zu verlassen. Zwei Apps waren vorinstalliert, Allerdings war nicht auf Anhieb zu erkennen, was diese Apps tun sollten. Leider habe ich es verpasst hiervon einen Screenshot zu machen.

Ein weiterer Neustart zeigte nun endlich den Bildschirm den ich aus den zahlreichen Tutorials erwartet hatte:

image

Ein holpriger Start, für ein System das erst Mal nichts kann.

Der WLAN Dongle wurde nicht erkannt und ich musste auf ein Ethernet Kabel zurückgreifen. Die Tastatur wurde nicht erkannt, was allerdings kein großes Problem ist, das man auf dem System eh nicht viel zu schreiben hat. Wie gesagt, kann man ja erst Mal nichts machen. Das einzige was man tatsächlich direkt auf dem Gerät tun kann, ist die Einstellung der Zeitzone.

Gut, alles andere Lässt sich über die Web UI oder über Power Shell lösen, aber irgendwie hatte ich doch ein bisschen mehr erwartet.

Raspberry Pi 2 Windows 10 Web Management
(Quelle: http://www.hanselman.com/blog/SettingUpWindows10ForIoTOnYourRaspberryPi2.aspx)

Anders als bei Hanselmans Screenshot oben, ist die Web UI einfach mit der IP-Adresse oder dem Rechnernamen (Standardmäßig MINIWINPC) erreichen.
Ich werde in kürze einen eigenen Screenshot nachreichen.

Wie man sich per Power Shell verbindet zeigt unter anderem Scott Hanselman in seinem Beitrag zum Thema. Das funktionierte immerhin auf Anhieb. Allerdings bin ich kein Power Shell Mensch. Ich versuchte nun direkt den Zugriff per Browser.

Entgegen dem Artikel auf golem.de wurde ich aufgefordert ein Benutzername und ein Passwort anzugeben, um auf die UI zuzugreifen. Erstaunlich auch deshalb, weil der Zugriff per FTP anonym erfolgen kann. Scott Hanselman klärt auf: Der Benutzername ist MINIWINPC\Administrator das Passwort lautet p@ssw0rd. Leider ist auch das eine Standard-Einstellung, die sich wahrscheinlich nur per Power Shell ändern lässt.

Arbeiten mit dem Visual Studio

Nun, nachdem das System nun erstaunlicherweise irgendwie lief, wollte ich mal das Deployment einer App per Visual Studio testen. Um nicht ganz von Vorne anzufangen, habe ich mir das Repository mit den Samples von Github geladen und wollte die HelloWorld App Starten. Ohne jemals die Visual Studio Tools für Universal Apps installiert zu haben, wird das allerdings nichts. Aber auch darauf muss man erst Mal kommen, wenn man im VS beim öffnen der Samples lediglich den Hinweis erhält, dass der Projekttyp nicht geöffnet werden kann.

Beim Deployment ist ein weiterer kleiner Stolperstein eingebaut, an den man denken sollte. Man muss sich per IP-Adresse auf ein Remote Machine verbinden und muss für den Raspberry PI den Authentication Mode von Windows auf None stellen :

image

Sollte man hier versehentlich etwas falsch eingestellt haben, muss Visual Studio geschlossen werden und die *.user Datei gelöscht werden. Andernfalls versucht sich das Visual Studio permanent, entweder der falschen IP oder der falschen Authentifizierung, mit dem Gerät zu verbinden. Da der Default die Windows Authentifizierung ist, ist mir das prompt zweimal passiert und wird mir sicher auch noch öfter passieren.

Beachtet man dass alles, läuft das Deployment mit F5 allerdings erstaunlich Problemlos. Wer das Arbeiten mit Windows CE Geräten noch kennt, wird sich freuen.

Entgegen anderer Tutorials, ist der Remotedebugger standardmäßig an und ich konnte bequem von meinem Rechner aus die Apps debuggen.

Als nächste versuchte ich die Blinky App aus den Samples. Nachdem ich alles verkabelt hatte, lief auch diese App auf Anhieb.

Das macht Hoffnung für meine komplexeren Ideen.

Fazit

Trotz dieses stolpernden Starts, lief es dann gegen Ende doch erstaunlich gut. Obwohl das Betriebssystem im Vergleich zum Raspian wirklich gar nichts kann und nicht mal eine richtige UI hat, laufen die Apps auf anhieb. Raspian verwöhnt uns hier mit einem vollwertigen System auf dem Raspberry PI.

Aber wenn wir ganz ehrlich sind, benötigen wir für IoT Anwendungen auch keine UI. Wir benötigen ein System, das wir per Remote Steuern und Konfigurieren können. Wir benötigen ein System, auf das wir bequem unsere Apps deployen können und auf denen die Apps stabil laufen. Letzteres muss sich in den kommenden Wochen und Monaten noch zeigen.

Weiterhin muss das System noch endgültig fertiggestellt werden, so das möglichst viele Peripherie Geräte erkannt werden. Ich würde sehr gerne den WLAN Dongle nutzen können, um für einige Szenarien nicht noch ein weitere Kabel anhängen zu müssen.

Regeln | Impressum