Running an ASP.NET Core 2.0 app on Raspbian Stretch Linux on a Raspberry Pi with HTTPS

Today’s challenge: Serve a public API over HTTPS from a Raspberry Pi. I’ll follow up with an article about containerising the app and running it from docker on the Pi.

This article is a fast-paced guide to getting started without stopping to dwell on the details.

Some details will be mopped up in the last section for those wanting to know more.

Prepare the Pi

On your development machine (you won’t need to interact with the Pi directly, so no 2nd keyboard or monitor required):

  • Grab an 8Gb or larger microSD card and use Etcher to flash the Raspbian Lite image to the card.
  • Create an empty file in the root of the microSD card called “ssh”, with no extension, this will enable ssh on Raspbian.
  • Put the microSD card in the Pi, plug in a network cable and then plug in the power
  • After a minute attempt to ping the pi:
ping raspberrypi
  • If you get a response, ssh into the pi from a Bash shell (on Windows, you can use the bash shell that comes with Git):
ssh pi@raspberrypi
  • The “pi@” means you’re logging in as the “pi” user account. The default password is “raspberry”.

Installing the .NET Core prerequisites

This bit looks hard but is quite easy (thanks Dave).

At the ssh prompt, install the .NET dependencies by running each of the following commands (you can copy and paste these commands straight into bash):

sudo apt-get install curl libunwind8 gettext
curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/release/2.0.0/dotnet-runtime-latest-linux-arm.tar.gz
sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
sudo ln -s /opt/dotnet/dotnet /usr/local/bin

you can check if the .NET Core runtime has been installed by running:

dotnet --help

You should now see some the runtime command line options.

Configuring the App

If you don’t already have an ASP.NET Core app:

  • Download the SDK for your platform (Mac, Linux, Windows) from https://dot.net and install it
  • Make a new directory and navigate to that directory at the command line.
  • Run:
dotnet new react

By default, a new ASP.NET Core application will be set to only listen to requests only from the TCP/IP loopback address (127.0.0.1 or localhost), so:

Open up Program.cs in your ASP.NET Core app and change the BuildWebHost method to add the following:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(options => {
            options.Listen(System.Net.IPAddress.Any,
                5000,
                listenOptions => {
                    listenOptions.UseHttps("raspberrypi.pfx", "<your-password>");
                }
            );
        })
        .UseStartup<Startup>()
        .Build();

This means that when the app runs on the Pi it will accept requests to port 5000 from external clients.

Please note, Kestrel is not a supported edge server, it is designed to run behind a reverse proxy such as nginx, Apache HTTP Server or Microsoft IIS when exposed to the outside world. Read and understand this before you open up your Pi to the big bad interwebs.

Deploying the App to the Pi

I’m not offering DevOps perfection here, I’m afraid we’re just going to FTP the app across to the pi. But first we need to compile the app so it works with the Raspberry Pi’s low-power ARM processor.

On your development machine, drop to the command line, navigate to your project directory and publish your app so it works on Raspbian by executing the following command:

dotnet publish -r linux-arm

This creates a bin/Debug/netcoreapp2.0/linux-arm/publish directory that contains the binaries for your ASP.NET Core app.

Grab your favourite FTP client. If you don’t have one, FileZilla will do the trick.

Connect your FTP client to your Pi by entering the following details:

Host: raspberrypi
Username: pi
Password: raspberry
Port: 22

The FTP client should show you the directory structure on the Pi. Copy the contents of your linux-arm/publish directory to any path on the pi (I chose /home/pi/piservice/) using the FTP client.

HTTPS

We’re going to use a self-signed certificate to show HTTPS is possible. In a real-world scenario you’d sign a relatively short-lived RSA keypair with a certificate signed by a trusted root cert (and also, you’d probably not use a Raspberry Pi and publicly-exposed Kestrel Web Server to run your services, but hey ho).

SSH into your Pi again and run the following command to create a public and private key pair that will be valid for a year.

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

Next, generate a .PFX file from the two generated PEM files (thanks to Pete S Kelly):

openssl pkcs12 -export -out raspberrypi.pfx -inkey key.pem -in cert.pem

This creates the “raspberrypi.pfx” file that your ASP.NET Core app now refers to in Program.cs.

Running the app

At the SSH prompt, tell the .NET Core runtime on teh pito start your app:

dotnet <yourappname>.dll

<yourappname> will be the name of the project you created if you used Visual Studio, or the name of directory you created that you ran dotnet new in. Typically this will be something like HelloWorld.dll or Acme.Web.dll, etc.

If all has been successful you’ll see the following echoed in your SSH session on the Pi:

pi@raspberrypi:~/piservice $ dotnet src.dll
Hosting environment: Production
Content root path: /home/pi/piservice
Now listening on: https://0.0.0.0:5000
Application started. Press Ctrl+C to shut down.

(My emphasis). From your development machine you should now be able to begin making requests to your app hosted on the Pi, https://raspberrypi:5000/

You will get errors about the certificate being untrusted, this is expected as your development machine has no reason to trust the little $30 computer, but you can skip past them – or read the final section of Peter Kelly’s article to learn how to trust the Pi’s self-signed certificate.

Making it Public

This is where things turn a bit vague as it’s up to you how you set up your network.

At the most basic level you need to tell your router to send traffic to port 5000 on your Pi. This usually involves adding a Port-Forwarding Rule. You’ll need to know your Pi’s IP address to set up the rule, so it makes sense to either give the Pi a static DHCP lease. Please refer to your router’s user guide for specific information.

To call your Pi from the outside world you’ll need your router’s public IP address – of course it’s best if this is static, ask your ISP if this is an option – and then you can set up a domain name to point to this IP address.

You can get a proper SSL certificate for your domain name from LetsEncrypt, or any other certificate provider.

Note: You’ll get SSL certificate errors when using a self-signed certificate, and browsers may stop allowing access to sites where the certificate doesn’t match the public domain name.

Follow Up

I’ll follow up soon with an article on containerising the ASP.NET Core app and running it on Docker on the Pi.

 

aspnetcore.dll failed to load. The data is the error

This morning, while trying to debug our big ol’ web project in Visual Studio 2015 I encountered a problem – it held me up for a while so I wanted to quickly blog about the solution in case it hits you too. When hitting F5 to start debugging, Chrome launched but then immediately Visual Studio detached from IIS Express and showed the following error:

A process with the ID of <id> is not running

True enough, IIS Express wasn’t running…

Open Wide and Say ‘Ahh!’, Mr Windows

I ran a Repair on IIS Express 10.0 in case it was an issue with that, or the self-signed SSL certificate it uses to host web projects over a secure connection…. but still had the same problem.

I then created a brand new ASP.NET MVC 5 project and hit F5… but that ran fine. Hmm, curious. That let me know IIS Express was fundamentally OK, and the issue lay with the big ol’ web project.

Microsoft are usually pretty good at logging when things go wrong so I fired up eventvwr, the Windows Event Viewer, and saw the following  error being thrown by IIS Express:

The Module DLL C:\Program Files (x86)\Microsoft Web Tools\AspNetCoreModule\aspnetcore.dll failed to load. The data is the error

Strange… We don’t have any ASP.NET Core projects in that solution so why aspnetcore.dll is being loaded was beyond me. Furthermore, that path didn’t exist on my disk. Continue Reading “aspnetcore.dll failed to load. The data is the error”

Things I learned at my last job

Today I closed a chapter in my life. After nearly 4 years tenure at a company I wanted to reflect on the things I learned over that time.

I have been very lucky to have a few excellent – world-class even – mentors here who have taught me things that will stay with me for the rest of my life, and I wanted to share the reflection process with you in the hope you gain something valuable too.

Individual Success Isn’t Success

For a long, long time I  adopted the ‘aircraft oxygen mask’ approach to my career: I’ll get to where I want to be first, then I’ll help others. This company has taught me that isn’t the right thing to do.

ubuntumeme

My thinking was always “I’ll be in a better position to help others” once I hit my objectives, but that simply doesn’t work in practice: without respectful, cooperative development across your team(s), you risk yourself hitting your goals at all, and if you haven’t helped others hit theirs too, nobody wins.

Dare I use the management-bullshit-bingo term ‘synergy’?

My current role here is a technical leadership role – that means I don’t have people reporting to me but I do have authority over technology direction and a remit to ensure conceptual integrity of the solution. I have led project teams before, I have even run small businesses before, but being a leader in a larger company was new to me when I began this chapter of my life, and I wanted to be good at it.

I’ve seen all the memes about the difference between a boss and a leader but for some reason I struggled to enact the differences. However, after some time spent being (in retrospect) a terrible boss, some sage advice from one of those mentors made everything ‘click’, and I was given the mental tools to develop the techniques required to become a good leader instead. (Note, a good mentor won’t give you the answer, but the means of finding it on your own!).

boss-vs-leader

“Take people with you.”

So what does that look like in practice? Last year I was offered the chance to travel to our American HQ to present some new work to 1,500 customers. ‘Prestigious’ isn’t even close – this is a huge event, so compelling that our customers pay us to listen to our plans and roadmap. The trip dripped with a significant amount of attached ‘kudos’ and the opportunity to rub shoulders with the highest of the high in the business. Not only that – the opportunity to ask probing questions to 1,500 customers about our technology direction is such a rare occurrence it was unmissable. The old me would have started packing immediately. Continue Reading “Things I learned at my last job”

Introducing QuickModules for ASP.NET MVC

INTERNET ALL THE THINGS!
Do what he says! He has a giant cotton bud in his hand!

Like you I often spend my weekends writing REST APIs for fun. And like you I am often frustrated by the amount of server-side code I need to write just to expose some data to JavaScript. Boilerplate, boilerplate, boilerplate. Ugh! So this weekend, in between bouts of erratic and unsatisfying jetlag-sleep, I decided to try and simplify the task of exposing an API to JavaScript. Introducing “QuickModules for ASP.NET MVC”, available now as a NuGet package!

QuickModules

QuickModules provides you with a basic, modular framework for hanging API endpoints from. Internally using the Managed Extensibility Framework (MEF) to load modules, QuickModules gives you the ability to build encapsulated CRUD services without needing to write, or understand, the usual plumbing.

Consumer Experience

As a software developer, and a human (vaguely), I like an easy life, so I’m all about the consumer experience when publishing code or frameworks (see my JavaScript business-object CRUD framework at http://richstokoe.github.io).

In order to ease any concerns you may have I will run through all the steps required (there are very few) to get QuickModules into your MVC application.

Step 0: Open Visual Studio (Duh!)

Step 1: Create a new MVC project

quickmodules_1

 

Step 2: Choose an Empty, Basic, Internet, Intranet or SPA template (actually, any will do, but these make the most sense)

quickmodules_2

 

Step 3: Notice how barren your project is without QuickModules. 🙁 (I’ve chosen a Basic template here)

quickmodules_3

 

Step 4: Install QuickModules using NuGet: Right-click on the References node in your Solution Explorer tree and click on “Manage NuGet Packages”:

quickmodules_4

 

Step 5: Search for “QuickModules” and choose “Install”. (Don’t worry if the details and version numbers look a little different on your PC, this is a screenshot of an early work-in-progress package).

quickmodules_5

 

That’s it! Hit F5 to run your application. If you’ve chosen an Empty or Basic template you’ll probably get a 404 Not Found error. Try navigating to the sample “Nearby Restaurants” module by adding /QM/Get?ActivityType=NearbyRestaurants to your URL (QM being shorthand for QuickModules of course!).

You should see a list of food places from The Simpsons as a wonderful, unformatted, JSON object array, ready to be consumed by your JavaScript:

quickmodules_7

 

But Wait There’s More!

Built into the framework (and optionally supported by your modules) is paging, and filtering. All for the low, low price of $9.95.  (Just kidding, it’s free). Use the LINQ-style Skip and Take arguments to control paging:

quickmodules_8

 

And use the Filter argument to narrow the result set down:

quickmodules_9 Continue Reading “Introducing QuickModules for ASP.NET MVC”

Learn to Code (An Intermission): Code.org

The founders of Facebook, Microsoft, Dropbox, Twitter and many more top tech companies have provided their voices and recognisable fizzogs to this latest video from Code.org. Code.org promotes the principle that nobody is born with the ability to code, or play basketball, or drive a racing car: it is a learned skill. The biggest hurdle is that first step overcoming the apprehension of the unknown. That’s something that all of these people have done. From humble beginnings and all that jazz…

 

Oracle Appeals Google’s Java Win. What’s next for Dalvik?

Larry Ellison points finger at Larry Page. Shakes it. Offers cookie. Redundantly.

This week, Oracle appealed Google’s win at the patent trial over the Java application programming interface (API) being used in the Android operating system.

In a new document published this week (PDF), Oracle’s lawyers start by introducing a character called Ann Droid. And then tell a story about Ann ripping off Harry Potter: The Order of the Phoenix. Quite strange, but hilarious to think of a serious legal department putting this into such an important document:

 

Ann Droid wants to publish a bestseller. So she sits down with an advance copy of Harry Potter and the Order of the Phoenix—the fifth book—and proceeds to transcribe.

She verbatim copies all the chapter titles—from Chapter 1 (“Dudley Demented”) to Chapter 38 (“The Second War Begins”). She copies verbatim the topic sentences of each paragraph, starting from the first (highly descriptive) one and continuing, in order, to the last, simple one (“Harry nodded.”). She then paraphrases the rest of each paragraph. She rushes the competing version to press before the original under the title: Ann Droid’s Harry Potter 5.0. The knockoff flies off the shelves. J.K. Rowling sues for copyright infringement.

Ann’s defenses: “But I wrote most of the words from scratch. Besides, this was fair use, because I copied only the portions necessary to tap into the Harry Potter fan base.”

Obviously, the defenses would fail.

Defendant Google Inc. has copied a blockbuster literary work just as surely, and as improperly, as Ann Droid—and has offered the same defenses.

Continue Reading “Oracle Appeals Google’s Java Win. What’s next for Dalvik?”

Learn to Code: Chapter 2 – Black Tie Function

She only wants you for your brain…

This is the third part of my Learn to Code series. The previous part is here: Chapter 1 – Meet Bob.

 

See Bob. See Bob Run. Run Bob, Run!

We last spoke about making Bob run 5 miles. We were going to do that by performing an action – a “function” in programmer parlance – called “run”, and give the number 5 (meaning the miles he is to run) to the function. We do that like this:

bob.run(5);

 

The problem is, we haven’t said what “run” actually means or does. Later we’ll use code that already exists but this time it’s all up to us. We’re going to have to write this “run” function ourselves. Again, this is a very easy thing to do once you understand the pattern you use.

function (miles) {
}

 

Here we say we want to create a “function” and that the function will take some information in brackets that we can refer to by the name “miles”. You see, when information (such as the number 5) is “passed” into the function, it is important that we can get to it because we can use it to change how the function operates. You can write a function once, but pass different things to it each time and it will behave differently every time. That is the real beauty of programming.

You will notice there aren’t any semi-colons in the bit of code above, this is because we are using a pattern that the computer will understand – those curly brackets (called “braces”) tell the computer when you’re starting and stopping to describe your function. However, when we write code inside those braces, we still must use semi-colons to differentiate one .

The devil is very much in the details when programming. Different programming languages have different requirements for WHERE those curly braces go. Sometimes they should be on the same line as the start of your function, and sometimes they go on the next line down. Like this:

function (miles)
{
}

 

But the language we are learning needs them to be on the same line as the word “function”.

Here’s an example of combining curly braces and semi-colons. Gosh it’s getting complicated… but stick with it, this is as complex as it gets. let’s write some code inside the function that uses that number 5 that was passed in, which we can refer to as “miles”:

function (miles) {
    return miles + miles;
}

 

This is now a fully-functioning function. If you’ll pardon the pun. Although… not a particularly useful one. Yet.  Continue Reading “Learn to Code: Chapter 2 – Black Tie Function”

Learn to Code: Chapter 1 – Meet Bob

You understand that, right?

This is the second part of a series of articles called Learn to Code. Click here to go to Chapter 0, “Wax on, Wax off”.

 

Learn to Code

Well done. You’re now a World class programmer! And you’ve been given a brief  by your customer who wants you to write some software for them. The following sentence is the first line of their brief to you:

“Bob is a man. He is 30 years old. He can run 5 miles.”

What a peculiar start!! But bear with me. Remember, in order to start programming, we have to fully understand the real-world thing we are transforming into some computer code. Let’s take that sentence apart and write some bullet points about what we know about Bob:

  • Bob is a “something”.  A real thing. A proper object.
  • That thing is categorised as a “man” (whatever that is).
  • Bob has something called an “age”. The value of his “age” thing is “30”.
  • Bob can perform an action known as “running”.
  • Bob can do that action for “5 miles”.

 

Sorry for all the quotation marks and playing-dumb, but all will become clear as we move through this lesson.

Like pretty much anything in the universe, Bob can be defined by a set of “properties” (like his age, height, inside leg measurement) and the actions that he can perform (like “run”). In proper programming, we call these “properties”, “properties” (hahaha, surprise! I slipped a programming term into your vocabulary!). Slightly more complex, we call the actions he is capable of performing, “methods” or “functions”, depending on which programming “language” you’re using. We’ll use the term “functions” to start with because the first programming language you’ll use demands this terminology.

The programming language we’ll start with also prefers things to start with a lowercase letter. For now, just accept that, we’ll cover why later. Let’s start by creating Bob in code.  Continue Reading “Learn to Code: Chapter 1 – Meet Bob”