Introducing GitTruckin: Truck Management Software Built by a Fleet That Uses It

We’re proud to introduce GitTruckin, the newest member of the Matavesi International family. It started as the dispatch and trip paperwork system for our own trucks at iLandClearing, and it grew into a full truck management system any trucking company can use.

Why We Built It

Small fleets end up juggling a dispatch whiteboard, a spreadsheet for driver pay, an ELD portal, a folder of rate confirmations, a stack of paper trip reports and a separate bookkeeping program. GitTruckin puts all of that in one place that works on a phone in the cab and on a desk in the office.

On the Road

  • Dispatch and trip reports: loads with ordered stops. Drivers work each pickup and delivery right from the trip report, and photos and paperwork are combined into one PDF and emailed to the office and the broker.
  • Truck-safe routes: routes planned for the rig’s size, the flattest way first with a second option, an “avoid tolls” choice, and routing around weigh stations. Drivers can re-plan from where the truck is.
  • Scale houses: every weigh station on the route shows on the map, plus CAT and truck stop scales, and drivers can add ones that are missing.
  • Fuel stop planner: uses each truck’s tank size to plan stops at Pilot, Flying J and One9, ranked by price after state fuel tax.
  • Reads your paperwork: upload a rate confirmation and GitTruckin fills in the route’s stops and details for you.
  • ELD and IFTA: connects to Motive and BlueInk for live truck positions, hours of service and IFTA mileage. See the IFTA software guide.

In the Office

  • Invoices you get paid on faster: freight invoices with receivables aging, an “overdue after” setting, and online payment by ACH or card right from the invoice.
  • Books built in: bank statement import with matching and splitting, your own expense and income categories, profit and loss, purchases and depreciation, insurance, a tax summary, QuickBooks and Quicken export, and a read-only feed for your accountant.
  • Driver pay and owner-operators: driver settlements, plus owner-operator pay that takes back fuel, ELD, insurance and maintenance on their own units. Owner-operators see their own trucks’ costs.
  • Customers and brokers: click any customer or broker to see its full history, with dated notes on customers and invoices.
  • Fleet upkeep: fluids, filters and tires for every truck, trailer and piece of equipment, maintenance reminders by miles, hours or days, cost per mile, and drug and alcohol testing records.
  • Load board: brokers post loads, carriers book them, and a load agent ranks open loads for each truck.

Pricing

Plans are priced by fleet size, starting at $49 a month for 1 to 10 trucks, with two months free on a yearly plan. Books is an optional add-on, and brokers have their own plan at $49 a month. Every company starts with a free trial.

Try It

Head over to gittruckin.com to start your free trial. Curious how it was built? Read Harlan’s notes on designing GitTruckin.

Introducing Whatcha Got: Scan Your Pantry, Cook What You Have

Meet Whatcha Got, a new app from Matavesi International that answers the nightly question: what’s for dinner with what’s already in the house?

How It Works

  • Scan to stock up: point your phone camera at a barcode and the item goes into your pantry with its nutrition facts. No barcode? Snap a photo and the app figures out what it is.
  • Use it before you lose it: every item gets an estimated expiration date, and a use-first list shows what to cook before it spoils.
  • Recipes from your pantry: get recipe ideas built from what you have. Cooking a recipe takes its ingredients out of the pantry for you.
  • Plan your week in one tap: the Magic Week button fills every empty day from what’s in your pantry, using food that’s about to expire first and skipping anything on your family’s allergy or diet list, then puts whatever is still missing on the shopping list. Tap any planned meal to open its recipe.
  • Save family recipes: photograph a cookbook page or a recipe card, or import a recipe from a link.
  • Shop a little healthier: shopping mode shows a health card for each item (sugar, salt, fat and how processed it is) with healthier swaps, and the shopping list can go straight to Instacart.
  • One pantry for the whole family: invite the household with a code, so everyone scans into the same pantry and shopping list. The Help tour walks new family members through it.

Free Through 2026

Whatcha Got is free to use through the end of 2026. It works in any browser and installs to the home screen on iPhone and Android, with nothing to download from an app store.

Try It

Open ohphokya.com on your phone, make an account, and scan your first can. Want the story behind it? Read how Harlan built Whatcha Got.

Jenkins Build Script for Multi-Project .NET Solutions (PowerShell)

When a Visual Studio solution (.sln) contains several projects, it helps to have Jenkins build each project on its own. This PowerShell build script builds a single .NET project (.csproj) within a solution: it restores, cleans, builds and publishes the project, then creates a .nuspec and packs it into a NuGet package with nuget.exe.

Like my Jenkins NuGet package build script, it reads the Jenkins WORKSPACE and JOB_NAME environment variables plus VERSION and SLN_NAME job parameters, so the Jenkins job name should match the project name. Replace the NuGet path, server URL and API key placeholders with your own.

Write-Host "This script is for building a single project (.csproj) within a Solution (.sln)"
Write-Host "and is a .NET Application using this specific build script"

# Print environment details
Write-Host "VERSION                : $ENV:VERSION"
Write-Host "WORK SPACE PATH        : $ENV:WORKSPACE"
$version = "$ENV:VERSION"

# Define solutionName, solutionDir, projectDir, and projectName
$solutionName = $env:SLN_NAME
Write-Host "SOLUTION NAME          : $solutionName"
$solutionDir = $ENV:WORKSPACE
Write-Host "SOLUTION DIRECTORY     : $solutionDir"
$projectDir = "$ENV:WORKSPACE\$ENV:JOB_NAME"
Write-Host "PROJECT DIRECTORY      : $projectDir"
$projectName = $ENV:JOB_NAME
Write-Host "PROJECT NAME           : $ENV:JOB_NAME"

# Define flags for nuget operations (not currently utilized properly except for display)
$nugetPack = $false
Write-Host "NUGET PACK             : $nugetPack"
$nugetDeploy = $false
Write-Host "NUGET DEPLOY           : $nugetDeploy"


# Target framework (only utilized for display)
$framework = "net8.0"
Write-Host "TARGET FRAMEWORK       : $framework"

# Define NUGET paths, csproject name and directory, and NUGET Server URL and API Key
$nugetEXE = "D:\build_tools\"your nuget location"\nuget.exe"
$csprojectPath = "$projectDir\$projectName.csproj"
Write-Host "PROJECT PATH           : $csprojectPath"
$nugetPackageDir = "$solutionDir\nupkgs"
Write-Host "NUGET PACKAGE DIRECTORY: $nugetPackageDir"
$nugetPublishDir = "$solutionDir\publish"
Write-Host "NUGET PUBLISH DIRECTORY: $nugetPublishDir"
$NugetServer = "https://"your nuget package server"/nuget"
Write-Host "NUGET SERVER URL       : $NugetServer"
$NugetServerKey = "your nuget server key"
Write-Host "NUGET SERVER KEY       : $NugetServerKey"

# Clean and Create necessary directories
if (Test-Path $nugetPackageDir) {
    Write-Host "DOTNET BUILD: Delete Directory $nugetPackageDir"
    Remove-Item -Path $nugetPackageDir -Recurse -Force
}

Write-Host "DOTNET BUILD: Create Directory $nugetPackageDir"
New-Item -ItemType Directory -Force -Path $nugetPackageDir

if (Test-Path $nugetPublishDir) {
    Write-Host "DOTNET BUILD: Delete Directory $nugetPublishDir"
    Remove-Item -Path $nugetPublishDir -Recurse -Force
}

Write-Host "DOTNET BUILD: Create Directory $nugetPublishDir"
New-Item -ItemType Directory -Force -Path $nugetPublishDir

# Define the Solution location
$slnPath = "$solutionDir\$solutionName.sln"
Write-Host "Solution Path         : $slnPath"

# Run dotnet restore
Write-Host "DOTNET BUILD: dotnet restore $slnPath"
dotnet restore $projectDir

Write-Host "DOTNET BUILD: dotnet clean $projectDir --configuration Release --verbosity quiet"
dotnet clean $projectDir --configuration "Release" --verbosity quiet

# Change to the $projectDir (ensure that we are in the project directory)
cd $projectDir
Write-Host "CURRENT DIRECTORY           : $projectDir"

# Run dotnet build
Write-Host "DOTNET BUILD: dotnet build $csprojectPath --configuration Release --verbosity quiet -p:PackageVersion=$version"
dotnet build $csprojectPath --configuration "Release" --verbosity quiet -p:PackageVersion=$version

# Run dotnet publish
Write-Host "DOTNET BUILD: dotnet publish $projectDir --configuration Release --verbosity quiet -p:PackageVersion=$version --framework $framework --output $nugetPublishDir"
dotnet publish $projectDir --configuration "Release" --verbosity quiet -p:PackageVersion=$version --framework "$framework" --output $nugetPublishDir

# Change to the $nugetPublishDir (ensure that we are in the publish directory)
cd $nugetPublishDir
Write-Host "CURRENT DIRECTORY           : $nugetPublishDir"

# NuGet operations
Write-Host "DOTNET BUILD: NUGET spec $projectName"
& $nugetEXE spec $projectName

Write-Host "DOTNET BUILD: Nuget PACK $projectName.nuspec -OutputDirectory $nugetPackageDir -Version $version"
& $nugetEXE pack "$projectName.nuspec" -OutputDirectory $nugetPackageDir -Version $version

Write-Host "DOTNET BUILD: Completed Tasks"

Schannel Errors Again in 2024: A GPO Still Allowing SSL 3.0

My log server was collecting loads of Schannel errors every day, so I decided to hunt them down.

Schannel errors in the Windows event log

The Cause

It turned out that a Group Policy Object controlling Internet Options was misconfigured to allow SSL 3.0 traffic.

The Fix

Disable SSL 3.0 as shown below, either with a GPO or on each machine. That stopped the log spam. For step-by-step instructions, see disabling SSL 3.0 with Group Policy or Internet Explorer, and for an earlier Schannel fix, see Schannel fatal alert 40 and 70.

Use SSL 3.0 unchecked in Internet Options

Apache Reverse Proxy with SSL and WebSockets on RHEL/CentOS: Full Configuration

Here’s the configuration I use to run Apache httpd as a reverse proxy in front of a back-end service, with SSL termination and WebSocket support, on a Red Hat-family server.

1. Load the Proxy Modules

Edit the proxy module config:

vi /etc/httpd/conf.modules.d/00-proxy.conf

Make sure these modules are loaded:

# Load necessary modules
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

# Load lbmethod modules
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so

# Load additional proxy modules
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so

2. Create the Site’s VirtualHost

Edit your site’s config file:

vi /etc/httpd/sites-enabled/service.domainname.com.conf

Replace the host name, certificate paths, and backendserverIP:portnumber with your own values. The rewrite rules send WebSocket upgrade requests to the back end over ws://; everything else goes through ProxyPass.

<VirtualHost *:443>
ServerName service.domainname.com

SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/yourcert.crt
SSLCertificateKeyFile /etc/pki/tls/private/yourprivatekey_privatekey.key
SSLCertificateChainFile /etc/pki/tls/certs/bundle.crt

RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule /(.*) "ws://backendserverIP:portnumber/$1" [P,L]

ProxyPreserveHost On
ProxyPass / http://backendserverIP:portnumber/
ProxyPassReverse / http://backendserverIP:portnumber/

ErrorLog /var/log/httpd/service.domainname.com/error.log
CustomLog /var/log/httpd/service.domainname.com/access.log combined
</VirtualHost>

3. Restart Apache

Restart httpd and test your new site. Related: Apache security headers for an A+ rating.

Apache HTTP Security Headers for an A+ Rating (WordPress .htaccess)

I went down an interesting rabbit hole after finding securityheaders.com and hstspreload.org. To get an A+ rating for my blog, I worked through all of their suggestions. I won’t detail each one, but below is the set of HTTP security headers I’ve landed on that works for my WordPress site.

Add These Headers to .htaccess

Add the following to the .htaccess file on your Apache web server (the mod_headers module must be enabled). Replace yoursite.com with your own domain.

Header set Content-Security-Policy "upgrade-insecure-requests"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set X-Xss-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin"
Header set Permissions-Policy "geolocation=self"
Header set Access-Control-Allow-Origin "https://*yoursite.com*"
Header set Cross-Origin-Embedder-Policy "unsafe-none"
Header set Cross-Origin-Opener-Policy "unsafe-none"
Header set Cross-Origin-Resource-Policy "same-site"

After saving the file, rescan your site at securityheaders.com to confirm the grade. Related: Apache reverse proxy configuration and configuring Apache mod_rewrite.

Holiday Phishing Scams: How to Spot Fake Calls and Emails

I can’t stress enough how important it is to stay vigilant over the next few months. Holiday events and social engagements will keep you distracted, and scammers count on that.

If it hasn’t started already, you’ll be bombarded with scam phone calls and emails. Please, do not respond to them. Mark them as spam or phishing, and delete them.

Scam Phone Calls

The latest phone scams are after your Social Security number, Medicaid information and credit card details. The caller usually gives a common, friendly first name like “Robin” or “John.” Hang up immediately.

Fake Invoice Emails

A common email scam looks like someone “replying” to a message and BCC’ing you with a short note like “what’s this?” or “what is this?”, with an invoice below asking for payment. Mark it as spam and delete it.

There are many variations on this theme, but they all want the same thing: your money and your personal information, which they then use to trick other people out of theirs.

Change Your Password Manager Passwords

If you use a password manager like LastPass, I strongly urge you to change all of your passwords and keep them in a different password manager, or in a notebook stored somewhere safe in your home.

Hacking is serious business, with serious consequences for anyone who isn’t careful. It’s up to every one of us to keep our organization safe.

Database CI/CD with Bitbucket, Jenkins, Octopus Deploy, Redgate and Visual Studio

The PDF below is my end-to-end documentation of a database CI/CD (continuous integration and continuous delivery) workflow. It follows a database change from Visual Studio and Redgate, through source control in Bitbucket, into a Jenkins build, and on to deployment with Octopus Deploy.

I hope it helps anyone who gets stuck the way I did while setting this up. For more on the build side, see my Jenkins NuGet package build script and multi-project build scripts for Jenkins.

How to Build a PiAware FlightAware ADS-B Receiver on a Raspberry Pi

PiAware is FlightAware’s software for turning a Raspberry Pi into an ADS-B receiver that tracks nearby aircraft and feeds the data to FlightAware. Here’s what I used to build mine.

Parts List

Install PiAware

Once you have the parts together, you have two options:

I installed it by hand, since the Pi I used also hosts this website. Related: enabling SNMP on a Raspberry Pi.

Happy New Year 2021! Using app_offline.htm for ASP.NET Maintenance Pages

Greetings, 2021! I’m in the middle of a software deployment right now, hoping adoption goes well and that everyone enjoys using the application.

Quick Tip: app_offline.htm

Here’s a basic tool I just learned: place an app_offline.htm file in the root of an ASP.NET application (ASP.NET 2.0 or later) to quickly let users know the page, or the whole app, is down for maintenance. Download my sample file below.