Hi everyone! We had to go back to the drawing board for a while, but it's finally time to give this another shot. Please check out my patreon campaign - and don't forget to sign up and share!
ARCHIVE NOTICE
My website can still be found at industrialcuriosity.com, but I have not been posting on this blog as I've been primarily focused on therightstuff.medium.com - please head over there and take a look!
Tuesday, 16 October 2018
Friday, 17 August 2018
self-signed localhost ssl certificate on windows (for dummies)
[THIS ARTICLE IS OBSOLETE: you'll find better ones here and here]
today i needed to self-sign certificates, and while there are good guides available they make a lot of assumptions or use complicated tools. here's what i figured out this morning after a long struggle with scripts that windows doesn't like:
1. install openssh for windows, and make sure to remember where the installation directory is. there are a number of options available from the openssl wiki, shining light productions' version is the most official. download the default build (the larger installation file) paying attention to whether your system is 32-bit or 64-bit.
2. install babun (bash and zsh on windows for people who don't want to micromanage their software)
3. using babun, change to the openssl bin directory. run the following command from letsencrypt:
openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <( printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
once installed in your app you'll be able to access with http or https - your browser will warn you that the certificate isn't signed but it's yours, so just accept it and get back to work!
Saturday, 11 August 2018
IIS Rewrite Rules Regex
I'm not sure why it's so hard to find clear examples of the not-quite-regex regex that the IIS Url Rewrite module implements for its rewrite rules. Here are three things that I've wasted time figuring out.
1. Rewrite actions use regex matched groups by referencing {R:<group number>} eg. {R:1}
2. The order of the rules is critical, rewrites are then re-matched from scratch.
3. To prevent matches beginning with a word, use "^((?!theword).*)"
1. Rewrite actions use regex matched groups by referencing {R:<group number>} eg. {R:1}
2. The order of the rules is critical, rewrites are then re-matched from scratch.
3. To prevent matches beginning with a word, use "^((?!theword).*)"
Friday, 20 April 2018
Sale!
Sale! The Kindle edition of my children's book, "Life is but a Dream" is now on sale for just a dollar. Please support me with a review!
https://www.amazon.ca/Life-but-Dream-fisher-king-ebook/dp/B075W3ZQYL/
https://www.amazon.ca/Life-but-Dream-fisher-king-ebook/dp/B075W3ZQYL/
Wednesday, 28 March 2018
Azure Key Vault in C# for Dummies
There's a vast amount of documentation available, but all of it assumes a lot of prior knowledge or very particular use cases. Here's a simple and straightforward guide to creating and using a service principal for an Azure Key Vault so that your secrets can be managed programmatically.
Please note: I'm excited because I've finally managed to authenticate using a secret, it's probably more secure to use certificates but I'll get to that another time.
Step 1: Registered App
Under Azure Active Directory in the Azure Portal, select App registrations.
Add a New application registration, the application type being Web app / API and the Sign-on URL anything being any valid URL (just the format, it doesn't have to exist). If the name you enter isn't simple to remember then it would be a good idea to take a note of it for step 2.
Take note of the Application ID as that will be your Client ID for authentication, then select the Keys blade under Settings. Enter a Key description (preferably indicating the user or application that will be using this key), select a duration and Save. Immediately store the resulting value somewhere safe as it will never be displayed again.
I recommend adding yourself as an owner on the Owners blade (also under Settings), whatever else this may be good for it'll let you see the app registration immediately on the App registrations blade without having to select "All apps".
Step 2: Key Vault permissions
Open the Key Vault in the Azure Portal and select the Access policies blade under Settings. Click Add New and click on Select principal - you'll have to enter the full name of the registered app you created in the previous step in the search box before it'll show up, at which point you'll be able to select it.
You can either select an appropriate template from the top dropdown or choose Key, Secret or Certificate permissions manually. Don't worry about Authorized application at this stage.
IMPORTANT: pressing the OK button will add your new policy to the list, but it will not be saved! Be sure to click Save before continuing.
Step 3: Accessing the Key Vault from your Code
There are many different ways to authenticate, most of them obscure and undocumented. This is the simplest method, I've put the credentials in the code for clarity but I have faith that you'll store them somewhere more intelligent. Never store credentials in the codebase. Seriously. Just don't.
Please note: I'm excited because I've finally managed to authenticate using a secret, it's probably more secure to use certificates but I'll get to that another time.
Step 1: Registered App
Under Azure Active Directory in the Azure Portal, select App registrations.
Add a New application registration, the application type being Web app / API and the Sign-on URL anything being any valid URL (just the format, it doesn't have to exist). If the name you enter isn't simple to remember then it would be a good idea to take a note of it for step 2.
Take note of the Application ID as that will be your Client ID for authentication, then select the Keys blade under Settings. Enter a Key description (preferably indicating the user or application that will be using this key), select a duration and Save. Immediately store the resulting value somewhere safe as it will never be displayed again.
I recommend adding yourself as an owner on the Owners blade (also under Settings), whatever else this may be good for it'll let you see the app registration immediately on the App registrations blade without having to select "All apps".
Step 2: Key Vault permissions
Open the Key Vault in the Azure Portal and select the Access policies blade under Settings. Click Add New and click on Select principal - you'll have to enter the full name of the registered app you created in the previous step in the search box before it'll show up, at which point you'll be able to select it.
You can either select an appropriate template from the top dropdown or choose Key, Secret or Certificate permissions manually. Don't worry about Authorized application at this stage.
IMPORTANT: pressing the OK button will add your new policy to the list, but it will not be saved! Be sure to click Save before continuing.
Step 3: Accessing the Key Vault from your Code
There are many different ways to authenticate, most of them obscure and undocumented. This is the simplest method, I've put the credentials in the code for clarity but I have faith that you'll store them somewhere more intelligent. Never store credentials in the codebase. Seriously. Just don't.
Monday, 5 March 2018
Let's Encrypt site deletion (Apache on Ubuntu)
Let's Encrypt is brilliant, but why site deletion makes things so complicated is beyond me. I had a bunch of sites running on Apache that Let's Encrypt automagically generated certificates for, which was fine right up until I needed to make one of them unavailable. What follows are the instructions for regenerating the certificates quickly and (relatively) painlessly.
- Ensure that Apache site configurations are removed from
/etc/apache2/sites-enabled
- Move unwanted site configurations from
/etc/apache2/sites-available to a backup location if needed
- Remove all certificate files from
/etc/letsencrypt/archive/
/etc/letsencrypt/live/
/etc/letsencrypt/renewal/
- Restart Apache
service apache2 restart
- Run letsencrypt
Sunday, 19 November 2017
'How to create an Azure SQL Database programmatically' with less frustration
Microsoft's devs have done yet another "almost-but-not-quite-great" job with their sample code for creating an Azure database programmatically.
In addition to the headache of setting up an Azure subscription and Azure Active Directory correctly, it took a silly amount of investigation and trial and error before I could figure out what values the code was expecting as the variable names (almost predictably) don't match their counterparts as displayed in the Azure portal.
In addition to the headache of setting up an Azure subscription and Azure Active Directory correctly, it took a silly amount of investigation and trial and error before I could figure out what values the code was expecting as the variable names (almost predictably) don't match their counterparts as displayed in the Azure portal.
- Instructions:
- Follow the instructions from the original code's page up to item 4 ("Add your variables to the program")
- Replace Program.cs with my modified code.
- Follow the instructions in the 4th item, using the modified code's documentation in case of confusion or ambiguity.
Sunday, 5 November 2017
Online JSON / CSV Converter
I needed a good JSON / CSV converter and couldn't find one, so I made one: Online JSON / CSV Converter
Wednesday, 4 October 2017
C# / OpenSSH RSA Encryption made easy
[EDIT: please see C# / OPENSSH RSA ENCRYPTION MADE EVEN EASIER]
The struggle to uncover the secrets of importing from and export to OpenSSH keys with Microsoft's .NET RSACryptoServiceProvider is real. It's possible but not practical to do this without BouncyCastle, which may or may not be well-documented (navigating their website is far from a joyful experience), but after trawling the web and playing around I've created the following gists that should be of assistance to anyone who needs to do this in a straightforward manner.
And if you want to share RSA keys between JavaScript and .NET platforms, well, you're going to need to do this.
Import and export RSA Keys between C# and PEM format using BouncyCastle
And just because the actual encryption and decryption are always annoying:
Simple RSA Encryption to and Decryption from Base64 encoded strings in C#
The struggle to uncover the secrets of importing from and export to OpenSSH keys with Microsoft's .NET RSACryptoServiceProvider is real. It's possible but not practical to do this without BouncyCastle, which may or may not be well-documented (navigating their website is far from a joyful experience), but after trawling the web and playing around I've created the following gists that should be of assistance to anyone who needs to do this in a straightforward manner.
And if you want to share RSA keys between JavaScript and .NET platforms, well, you're going to need to do this.
Import and export RSA Keys between C# and PEM format using BouncyCastle
And just because the actual encryption and decryption are always annoying:
Simple RSA Encryption to and Decryption from Base64 encoded strings in C#
Friday, 12 May 2017
connecting node.js to the azure table storage emulator
Once again, solid software is rendered useless by a lack of documentation. I've just wasted way too much time connecting my node app to an emulated table, so I'm going to spell it out for you so that you don't have to do the same.
- The npm azure-storage package instructions are found here, the emulator software is found here and the storage explorer is found here.
- Once the emulator has been installed, you'll need to start it. The init operation worked fine for me (I'm running SQL Server 2012 Express anyway), but the start operation failed and it took a while to realize that ports 10000 - 10002 (or is that 3?) need to be available; the software blocking could be anywhere from backup software or bittorrent to malware.
Good to know.
There doesn't appear to be any way to customize the ports used. - To verify that your emulator is running correctly, connect using the storage explorer.
- Select "Use a storage account name and key"
- Set the account name and authentication key (see point 6 below)
- Set the storage endpoints domain to "Other" with a value of 127.0.0.1
- Select "Use HTTP"
- The emulator runs on http NOT https, which shouldn't affect you once you've got your connection configured correctly. For some people the authentication requires setting your system time to UTC / GMT, for others it's setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0; the latter can be done in node.js with
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
- There are two ways to instantiate a table service object. Assuming
var azure = require('azure-storage');var tableSvc = azure.createTableService(account, key, '127.0.0.1:10002');
orprocess.env.AZURE_STORAGE_ACCOUNT = account; process.env.AZURE_STORAGE_ACCESS_KEY = key; process.env.AZURE_STORAGE_CONNECTION_STRING = connectionString; var tableSvc = azure.createTableService();
- The account name, authentication key and connection string are public, invariable and for emulation purposes only:
Account name: devstoreaccount1
Authentication Key:
Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
Connection String: UseDevelopmentStorage=true
Sunday, 23 April 2017
How to code Entity Framework programmable migrations
The internets are eerily quiet when it comes to running Entity Framework's migrations through code, which is odd because Entity Framework's Code First migrations are extremely powerful and calling them (or rolling them back) through the code seems an obvious choice to someone like me, who prefers to reduce the amount of complexity for the poor IT people handling deployment.
(And for poor me, too, I'm very lazy and I like being able to just press a button to make magic happen.)
The most important quirk of running migrations programmatically that you'll need to know before we begin is that the DbMigrator class, for reasons unclear, requires the Entity Framework Configuration class but uses it in a way that's incompatible with the Update-Database and Add-Migration scripts, even after manually configuring the ContextType and ContextKey properties. We'll set those anyway for consistency, but no matter where you store your migrations and however diligently you inform the DbMigrator (the MigrationsDirectory property was ignored too) you're going to be stuck with automatic migrations. And while we're fiddling with the Configuration class, be sure to make the internal Configuration class public.
Automatic migrations ignore the explicit migration files and detect changes between the context's models and the database. As with the Update-Database script, the database will be created if it hasn't been already. It will not function reliably unless the AutomaticMigrationDataLossAllowed property is set to true, and you'll also need to update the OnModelCreating method of your context class to allow for database calls when the models are out of sync to give you a chance to run the migrations:
Migrating up and down
Using automatic migrations to update your database is great, but what do you do if you need to roll back? DbMigrator requires a migration name to update to, and unlike the case with explicit migrations, the migration name is not established by the developer but is unique to the database in question.
Fortunately, the DbMigrator includes the GetDatabaseMigrations method, which returns a list of applied migrations; so while you won't be able to roll back to a predefined named state, you will be able to roll back to a previously run migration. Here it is important to note that the order of the migrations returned is not guaranteed, but the names begin with a timestamp so they're not too difficult to sort.
So rolling back the first of that list is as simple as
Seeding
Seeding must be performed manually after calling DbMigrator.Update(). The Configuration class' Seed method is protected, so add the following wrapper method to your Configuration class
and call it once the migration is complete.
(And for poor me, too, I'm very lazy and I like being able to just press a button to make magic happen.)
The most important quirk of running migrations programmatically that you'll need to know before we begin is that the DbMigrator class, for reasons unclear, requires the Entity Framework Configuration class but uses it in a way that's incompatible with the Update-Database and Add-Migration scripts, even after manually configuring the ContextType and ContextKey properties. We'll set those anyway for consistency, but no matter where you store your migrations and however diligently you inform the DbMigrator (the MigrationsDirectory property was ignored too) you're going to be stuck with automatic migrations. And while we're fiddling with the Configuration class, be sure to make the internal Configuration class public.
Automatic migrations ignore the explicit migration files and detect changes between the context's models and the database. As with the Update-Database script, the database will be created if it hasn't been already. It will not function reliably unless the AutomaticMigrationDataLossAllowed property is set to true, and you'll also need to update the OnModelCreating method of your context class to allow for database calls when the models are out of sync to give you a chance to run the migrations:
Migrating up and down
Using automatic migrations to update your database is great, but what do you do if you need to roll back? DbMigrator requires a migration name to update to, and unlike the case with explicit migrations, the migration name is not established by the developer but is unique to the database in question.
Fortunately, the DbMigrator includes the GetDatabaseMigrations method, which returns a list of applied migrations; so while you won't be able to roll back to a predefined named state, you will be able to roll back to a previously run migration. Here it is important to note that the order of the migrations returned is not guaranteed, but the names begin with a timestamp so they're not too difficult to sort.
So rolling back the first of that list is as simple as
Seeding
Seeding must be performed manually after calling DbMigrator.Update(). The Configuration class' Seed method is protected, so add the following wrapper method to your Configuration class
and call it once the migration is complete.
Subscribe to:
Posts (Atom)
Labels
algorithms
(2)
art
(2)
automation
(8)
aws
(4)
azure
(2)
bamboo
(1)
banking
(2)
blockchain
(1)
books
(5)
c#
(7)
cloud
(4)
collaboration
(5)
comics
(3)
comments
(4)
communication
(6)
crypto
(1)
data ownership
(1)
database
(5)
deployment
(10)
design
(3)
design patterns
(2)
development
(32)
devops
(5)
documentation
(16)
dynamodb
(1)
encryption
(6)
formatting
(4)
git
(1)
golang
(1)
google
(1)
hiring
(1)
html5
(5)
iis
(1)
installation
(5)
integration
(2)
interfaces
(2)
java
(1)
javascript
(11)
lambda
(2)
linux
(5)
mysql
(1)
node.js
(7)
open source
(15)
plugins
(3)
privacy
(2)
processes
(2)
promotions
(1)
python
(4)
readability
(3)
recruitment
(1)
regex
(2)
reviews
(1)
security
(13)
self-publishing
(2)
shakespeare
(3)
sql server
(1)
tattoos
(2)
tools
(21)
user experience
(1)
version control
(3)
virtualization
(1)