Storm Cleanup Season Is Here: Debris and Erosion Help from Palacios to Terlingua

Between hurricane season on the coast and monsoon flooding out toward Big Bend, storm damage hits the Palacios, Austin and Terlingua corridor differently depending on where you are.

If a recent storm has left your property with downed trees, washed-out roads or debris, head over to iLandClearing. They run a Kubota track steer with the equipment for both coastal debris cleanup and desert erosion control, and they know the terrain across the whole service area. Learn more in our iLandClearing introduction.

Introducing iLandClearing: Land Clearing and Property Management Services

We’re proud to announce iLandClearing, the latest addition to the Matavesi International family of companies.

What iLandClearing Does

iLandClearing helps with property and landscape management jobs big or small, from demolition to pasture management:

  • Land clearing and demolition
  • Pasture management
  • Building and maintaining trails across your property, for fun or function
  • Desert restoration and erosion control

Our Equipment

We run a 75-horsepower Kubota track steer that can work in any climate, with these attachments:

  • Rotary disk mulcher: takes down trees up to 8 inches and mows heavy grass.
  • Hydraulic auger: digs holes 8 to 12 inches in diameter and up to 8 feet deep.
  • Tree stump digger: pulls stubborn roots and pushes trees over.
  • Grapple: bundles brush and vegetation or tears down a building.
  • 74″ flat blade: general grading, moving material, or cutting a pathway.
  • Trencher: a 60″ x 6″ blade for trenches for water, sewer, electrical and data lines.
  • 74″ box blade: ripping and leveling land, great for pathways and food plots.

Schedule a Consultation

Head over to ilandclearing.com to schedule your consultation today, and see our work on the iLandClearing YouTube channel. Storm damage? Read storm cleanup season is here.

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"

Jenkins PowerShell Build Script for NuGet Packages (dotnet pack and push)

Here is a PowerShell build script for creating NuGet packages on a Jenkins server. It restores and builds a .NET solution, packs the project with dotnet pack, and pushes the package to your NuGet server.

I recently had to rewrite my build scripts when moving Jenkins from one server to another, and this time I went all out with variables. The script reads the Jenkins WORKSPACE and JOB_NAME environment variables plus VERSION and SLN_NAME job parameters. Replace the NuGet path, server URL and API key placeholders with your own. See also multi-project build scripts for Jenkins.



Write-Host "This Script is for Compiling Nuget Packages"

# 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 = $true
Write-Host "NUGET PACK             : $nugetPack"
$nugetDeploy = $true
Write-Host "NUGET DEPLOY           : $nugetDeploy"

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

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

# 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\$ENV:JOB_NAME.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 $slnPath -v q

# Run dotnet build
Write-Host "DOTNET BUILD: dotnet build $csprojectPath -c Release --version-suffix $version --verbosity quiet"
dotnet build $csprojectPath -c Release --version-suffix $version --verbosity quiet

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

# Run nuget pack
Write-Host "DOTNET BUILD: dotnet pack -c Release --no-restore -o $nugetPackageDir --version-suffix $version --verbosity quiet"
dotnet pack -c Release --no-restore -o $nugetPackageDir --version-suffix $version --verbosity quiet

# Display completed tasks
Write-Host "DOTNET BUILD: Completed Tasks"

# Define the NuGet Package Name
$NugetPackageName = "$ENV:JOB_NAME.$version.nupkg"
Write-Host "NUGET: Nuget Package Name: $NugetPackageName"

#Change to the $nugetPackageDir (ensure that we are in the NUPKG directory)
cd $nugetPackageDir
Write-Host "CURRENT PATH           : $nugetPackageDir"
  
# Push the package to the NuGet server
Write-Host "NUGET: Push "$NugetPackageName" -k $NugetServerKey -s $NugetServer"
dotnet nuget push "$NugetPackageName" -k $NugetServerKey -s $NugetServer


# Display completed tasks
Write-Host "NUGET: 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.

Stay in Terlingua, Texas: Our Favorite Ghost Town Rental Near Big Bend

We love to visit the West Texas Desert and stay with our friends in Terlingua, Texas at The Terlingua Ghostown Rentals. Right at the entrance to the Ghosttown, you’ll see https://terlinguaghosttownrentals.com/ — the staff is friendly and you’ll be close to everything the desert has to offer!

A Quick History of Terlingua

Terlingua’s name is thought to come from the Spanish phrase for “three tongues,” a nod to the mix of Native American, Spanish, and English speakers who once passed through the area. The settlement got its start as a small village along Terlingua Creek, but everything changed in the 1880s when prospectors discovered cinnabar, the mineral used to produce mercury (also known as quicksilver).

Chicago businessman Howard Perry recognized the value of the deposits and founded the Chisos Mining Company in 1903, turning Terlingua into the largest mercury-producing district in Texas. At its peak, the town supported a population in the thousands, complete with a company store, a school, and the Terlingua Cemetery that still draws visitors today. But mercury demand faded after World War II, the mine went bankrupt, and by the late 1940s most residents had moved on, leaving the town to earn its “ghost town” name.

Terlingua didn’t stay quiet forever. Starting in the 1960s and 70s, river guides, artists, and other desert-loving transplants began moving into the old ruins, restoring buildings and breathing new life into the community. Today it’s a small, tight-knit outpost known for its chili cook-offs, star parties, and a laid-back frontier spirit that still echoes its mining-camp roots.

Big Bend National Park, Just Down the Road

Terlingua sits right at the doorstep of Big Bend National Park, one of the most remote and least-visited parks in the country — and that’s part of the appeal. Established in 1944, Big Bend was the first national park in Texas and remains the only one in the country to contain an entire mountain range within its boundaries, the Chisos Mountains.

The park spans over 800,000 acres of Chihuahuan Desert along the Rio Grande, which forms the border with Mexico and has carved dramatic canyons like Santa Elena, Mariscal, and Boquillas over millions of years. Elevations swing from around 1,850 feet near the river up to over 7,800 feet at Emory Peak, which makes for wildly different landscapes and temperatures depending on where you’re standing. It’s also one of the best places in the country for stargazing, thanks to an International Dark Sky designation and some of the darkest night skies left in the lower 48.

Whether you’re here for the mining history, the hiking and canyons, or just the quiet of the desert at night, staying in Terlingua puts you close to all of it. Come visit us at Terlingua Ghostown Rentals!

GoPro Flyaround Videos: Our YouTube Feed

Here are our GoPro flyaround videos, straight from our YouTube channel.

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.