TLS has forever played a very large part in securing internet communications. Secure Socket Layer (SSL) filled this space prior to TLS coming to the fore.
In today’s article, I’m going to walk through an exercise of mTLS which is just an extension of TLS.
CA
First of all, we need a certificate authority (CA) that both the client and the server will trust. We generate these using openssl.
This now puts a private key in ca.key and a certificate in ca.crt on our filesystem. We can inspect these a little further with the following.
Looking at the output, we see some interesting things about our CA certificate. Most importantly the X509v3 Basic Constraints value is set CA:TRUE, telling us that this certificate can be used to sign other certificates (like CA certificates can).
Server
The server now needs a key and certificate. Key generation is simple, as usual:
We need to create a certificate that has been signed by our CA. This means we need to generate a certificate signing request, which is then used to produce the signed certificate.
This gives us a signing request for the domain of localhost as mentioned in the -subj parameter. This signing request now gets used by the CA to generate the certificate.
Inspecting the server certificate, you can see that it’s quite a bit simpler than the CA certificate. We’re only able to use this certificate for the subject that we nominated; localhost.
Client
The generation of the client certificates is very much the same as the server.
The subject in this case is my-client.
The -CAcreateserial number also ensures that we have unique serial numbers between the server and client certificates. Again, this can be verified when you inspect the certificate.
Only the last segment was incremented here. You get the idea though. Unique.
Appliation
Now, we setup a basic node.js server that requires mTLS.
Most important here is that the server’s options specify rejectUnauthorized as well as requestCert. This will force the mTLS feedback look back to the client.
A curl request now verifies that the solution is secured by this system of certificates.
The client’s key, certificate, and the ca cert accompany a successful request. A request in any other format simply fails as the authentication requirements have not been met.
In networking, a port is assigned as a logical entity that a socket is established on. These sockets are owned by processes in your operation system. From time to time, it can be unclear which process owns which socket (or who is hogging which port).
In today’s article, I’ll take you through a few techniques on finding out who is hanging onto particular ports.
netstat
netstat is a general purpose network utility that will tell you about activity within your network interfaces.
If you can not find netstat installed on your system, you can normally get it from the net-tools package.
The following command will give you a breakdown of processes listening on port 8080, as an example:
An important message appears here. “Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.”. There will be processes invisible to you unless you run this command as root.
Breaking down the netstat invocation:
l will only show listening sockets
t will only show tcp connections
n will show numerical addresses
p will show you the PID
You can see above, that no process is shown. Re-running this command as root:
lsof
lsof will give you a list of open files on the system. Remember, sockets are just files. By using -i we can filter the list down to those that match on an internet address.
fuser
fuser is a program that has overlapping responsibilities with the likes of lsof.
fuser — list process IDs of all processes that have one or more files open
You can filter the list down directly with the command:
This gives us a PID to work with. Again, note this is run as root. Now all we need to do is to tranform this PID into a process name. We can use ps to finish the job.
PostgreSQL is a very popular relational database which has quite a few different data access libraries available for the Haskell programming language.
Today’s article aims to get you up and running, executing queries against PostgreSQL from your Haskell environment with the least amount of hassle.
postgresql-simple
The first library that we’ll go through is postgresql-simple. This library has a very basic interface, and is really simple to get up an running.
A mid-level client library for the PostgreSQL database, aimed at ease of use and high performance.
Prerequisites
Before you get started though, you’ll need libpq installed.
Now you’re ready to develop.
You’ll need to add a dependency on the postgresql-simple library to your application. The following code will then allow you to connect to your PostgreSQL database, and ru a simple command.
Hello, Postgres!
When your application successfully builds and executes, you should be met with the following output:
Walking through this code quickly, we first enable OverloadedStrings so that we can specify our Query values as literal strings.
In order to connect to Postgres, we use a ConnectInfo value which is filled out for us via defaultConnectInfo. We just override those values for our examples. I’m running PostgreSQL in a docker container, therefore I’ve got my docker network address.
The localPG value is now used to connect to the Postgres database. The conn value will be referred to after successful connection to send instructions to.
Finally, we run our query SELECT 1 + 1 using the query_ function. conn is passed to refer to the connecion to execute this query on.
With this basic code, we can start to build on some examples.
Retrieve a specific record
In the Hello, World example above, we were adding two static values to return another value. As exampeles get more complex, we need to give the library more information about the data that we’re working with. Int is very well known already, and already has mechanisms to deal with it (along with other basic data types).
In the client database table we have a list of names and ids. We can create a function to retrieve the name of a client, given an id:
The Query template passed in makes use of the ? character to specify where substitutions will be put. Note the use of query rather than query_. In this case, query also accepts a Tuple containing all of the values for substitution.
Using the FromRow type class, our code can define a much stronger API. We can actually retrieve client rows from the database and convert them into Client values.
We need FromRow first:
The Client data type needs definition now. It’s how we’ll refer to a client within our Haskell program:
The Client data type now gets a FromRow instance, which allows postgresql-simple to use it.
In order of the fields definitions, we give fromRow definition. The retrieveClient function only changes to broaden its query, and change its return type!
Create a new record
When creating data, you can use the function execute. The execute function is all about execution of the query without any return value.
Extending our API, we can make a createClient function; but with a twist. We’ll also return the generated identifier (because of the id field).
We need a definition for Int64. This is what the underlying SERIAL in PostgreSQL will translate to inside of your Haskell application.
We can now use createClient to setup an interface of sorts fo users to enter information.
We’ve created a data creation interface now.
Update an existing record
When it comes to updating data, we don’t expect much back in return aside from the number of records affected by the instruction. The execute function does exactly this. By measuring the return, we can convert the row count into a success/fail style message. I’ve simply encoded this as a boolean here.
Destroying records
Finally, destroying information out of the database will look a lot like the update.
execute providing the affected count allows us to perform the post-execution validation again.
Summary
There’s some basic operations to get up and running using postgresql-simple. Really looks like you can prototype software all the way through to writing fully blown applications with it.
Sometimes it can be useful to capture information about your environment at build time, and have this information injected into the binary that you’re building. Some examples centre around versioning, where it might make sense to capture git commit hashes or build serials.
An example program
Two variables in this module gitCommit, and buildSerial are going to hold some version information for us. Running this program yields some rather uninteresting results.
-X switch
While building a program, you can use the -X linker switch which will allow you to supply information into module variables from the build process.
We can obtain the latest build hash using git with the following:
We can even synthesize a build number involving the date, perhaps?
Using the -ldflags switch, we can now specify these at the console.
Closing up
Now that we have a binary built, it’s had its build information applied - these variables now magically receive these values.
Remember, these switches can be buried behid a Makefile also, so you don’t need to be typing these things over and over.
Sometimes you may need to investigate the contents of binary files. Simply using cat to view these details in your terminal can have all sorts of random effects due to control characters, etc. The utility hexdump allows you to look at the contents of these files in a sane way.
From the hexdump manpage:
display file contents in hexadecimal, decimal, octal, or ascii
In today’s article, we’ll walk through some example usages of this utiltiy.
Examples
For all of these examples, we’ll be using a 256 byte file of random binary. I generated this data on my system with the following command:
The initial view of this data now looks like this:
Formatting
Now things get interesting. The -e switch of the hexdump command allows us to specify a format string that controls the output to the terminal.
Using _a[dox] we can control how that offset down the left hand side looks. %07_ax pads the offset with a width of 7. 16/1 "%_p" will print 16 bytes using _p which prints using the default character set. The output of which looks like this:
Anytime this format encounters a non-printable character, a . is put in its place.
Builtin
-v -C gives a side-by-side of hex values along with the printable characters: