Using Jest with CDK tests

We use Siteimprove to crawl some of our web properties and we also protect those same properties with an AWS Web Application Firewall (WAF). To be on the safe side, we’re going to add Siteimprove’s IPs to an allowlist. We have to extend our WAF definition to include an IPSet and then also extend our test coverage.

That’s a lot of IPs

Siteimprove has 86 crawler IPs. First things first, we create a separate siteimprove.ts file to contain all the IPs:

Read More

Tests and tags in CDK

I manage a bunch of redirected subdomains. We use these with third-party applications, where the application lives at some non-Lafayette URL and we want a clean, simple Lafayette URL for our users. We call these vanity plates, and at the architectural level they’re pretty simple: a Cloudfront distribution with a certificate and LambdaEdge function to handle the redirection. We monitor the state of the redirection with a Synthetic Canary.

A small challenge is that we like to have lifecycle rules on all our S3 buckets. With the above stack we actually have three buckets:

  1. The logging bucket for the Cloudfront distribution
  2. An empty S3 bucket that serves as the unused target for the Cloudfront distribution
  3. The artifacts bucket for the Synthetic Canary.

Read More

Solving php-fpm-socket-helper: No such file or directory

I was running through a helpful DigitalOcean guide on getting multiple PHP-FPM versions configured on a Debian installation. Nothing too complex, but I’m usually doing this on RedHat derivatives so I appreciated the hand-holding. At the end of it the PHP-FPM service stubbornly refused to start correctly and I encountered an error that I hadn’t seen before:

1
Jun 01 19:45:07 XXXXXXX systemd[22426]: php7.2-fpm.service: Failed at step EXEC spawning /usr/lib/php/php-fpm-socket-helper: No such file or directory

Sure enough, no such file. Googling the error didn’t turn up much. More surprisingly I tried using apt-file to identify the provider of the file, and came up empty. I ran across a very old page that suggested php-common (a version-independent package) might provide the file. That package was already installed, but outdated, so I updated it…and the file was created and PHP-FPM was working again.

Read More

Thoughts on the June 2021 LANTA changes

The Lehigh and Northampton Transportation Authority (LANTA) is making a number of changes to its routes, effective June 21, 2021. At first glance, these don’t look like cuts so much as refactoring. I’m going to focus on the changes within Easton:

  • West Ward, Northampton Street: routes 101 and 216 replace 106 and 220. There’s still a one-seat ride to Nazareth Commons and downtown Bethlehem, but we lose Allentown. However, 101 does appear to have a timed transfer with the 107 in Bethlehem for Allentown service, and the 107/220 are on an every half-hour schedule between the two. 101/216 are both hourly as before, with a 15/45 separation inbound and every 30 minutes outbound. The latter is a real improvement over the current schedule, where the 106 and 220 leave Easton six minutes apart.
  • West Ward, Lehigh / Washington: the re-routed 106 and 220 replace the 216 and 101, respectively. The 106 follows the old 216 route to 18th, but then turns north to sere Nazareth Commons / Northampton Crossings. The 220 follows Freemansburg to Emrick, then rejoins its old route at the William Penn Park & Ride. Outbound separation is 20/40, inbound is half-hourly to hourly, as the 106 is on a ninety-minute frequency inbound only. Again, this is something of an improvement; the current frequency is 50/10 outbound and half-hourly inbound.
  • College Hill / South Easton: the 214 is extended into South Easton, replacing the 106 and 216 which now terminate downtown. The 214 does a circle in South Easton to cover both routes. The old 214 schedule was bizarre, with no relationship to any clockface. The new one is hourly between Easton Food Market and Forks Plaza South, with additional rush-hour service offest by a half-hour to Cattel / High for Lafayette College. Connection from incoming buses to/from the 214 should be half-hourly or better; it’s not clear if there’s a recommended pairing. This is a massive improvement on the previous service offering, as far as College Hill is concerned.

I’m curious to see how this affects food access. The 214 will still hit the Giant in Forks Township and the Easton Food Market and the 106 / 216 the stores out at Nazareth Highway / PA-33. That still leaves the Giant in Palmer Town Center without direct service, and for the Aldi and Lidil on Freemansburg you’re relying on the 220, with uneven timekeeping as it comes from Allentown. I think the lack of bus access to Hugh Moore Park and the National Canal Museum remains a growth opportunity, but the roads in West Easton are a rat’s nest. Route 507, a demand response service, covers it at present.

Read More

Engine change at New Haven

Beginning with a round-trip to Brattleboro, Vermont, in March 2013 for HighEdWeb New England, I made at least one round-trip on the Vermonter every year between 2013 and 2017, and then two more in 2019. I’ve logged 3,033 miles since 2013. I’ve made a couple of firsts aboard it as well: my first trip east of New York on the Northeast Corridor, and my first trip east of Springfield on CSX’s Boston Subdivision.

The Vermonter makes a daily run from Washington, DC, to St. Albans, Vermont, just shy of the Canadian border. It uses Amtrak’s Northeast Corridor from Washington, DC, to New Haven, Connecticut (via New York City), then turns north to follow the Connecticut River through Springfield, Massachusetts, into Vermont. I’ve never been further north than Bellows Falls, Vermont; normally I don’t even take it into Vermont. I’ve also never taken it west of New York, not that there’s a reason to.

The Vermonter has some unusual features. Up until the end of 2014, it made a backup move at Palmer, east of Springfield, to continue north toward Vermont. This took a good twenty minutes as the Vermonter pulled past the crossing the connecting track, stopped, the crew manually threw a switch, then reversed direction. It’s a J-turn, but on a railroad. The state acquisition of the Connecticut River Line, completed at the end of 2014, eliminated this operation, though for good measure the Vermonter still backs in and out of Springfield Union Station.

Read More

Circling Deerfield Park

A man is a very small thing, and the night is very large and full of wonders

Lord DunsanyPlays of Gods and Men

I’m back visiting my parents in Mt. Pleasant, Michigan, where I grew up and spent the first 18 years of my life. Mt. Pleasant is a small place. Even now, the permanent population is about 26,000. Central Michigan University, when it’s in session, adds another 20,000. It’s not even 8 square miles. A man can walk from Pickard Road, at the northern edge, to Broomfield in the south, in under an hour. Growing up, it didn’t seem that way. I counted it as a major achievement when I first bicycled to the southern edge of CMU’s campus. As we get older the familiar shrinks even as the unfamiliar expands.

Deerfield Park is one of several parks on the Chippewa River, which runs through the county and city. It’s about five miles west of town, a stone’s throw though it didn’t seem that way once. It’s a little under two miles north-south and a little under a mile across at its widest point, though in that space are a multitude of trails, campsites, a generous sledding hill less dangerous than Mission Creek, and no fewer than four crossings of the river. In my memory, there was always a bridge that was hard to find, hidden away off the beaten path. Today, with clear skies and time to kill, I resolved to find all four bridges and settle the matter.

Read More

Apache and HTTP/2 on AWS

I’ve spent the last few months building up a generic highly-available EC2 stack for our various on-premises applications. We’re using Apache as the webserver on EC2 since that’s what we’re familiar with. An interesting wrinkle is that, out-of-the-box, cURL and Safari didn’t work with WordPress running on this stack. cURL would return this cryptic error message:

curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

Safari refused to render the page at all, with this equally (un)helpful message:

Read More

Using TLS-ALPN-01 on a Raspberry PI

I'll always read ALPN as Alpine

I run Nextcloud on my Raspberry PI and I have a certificate from Let’s Encrypt on it. I set this up a couple years ago with certbot and it’s been fine. I don’t expose port 80 in my environment so I’ve relied on the TLS-SNI-01 challenge using the certbot client which ships on Raspbian Jessie.

TLS-SNI-01 is now end-of-life because of security vulnerabilities so I needed to find an alternative. There are a couple different challenge methods available. Let’s Encrypt’s cerbot supports two:

Read More

Node on RHEL7

In August 2017 we implemented Swarthmore College’s PDF accessibility tool for Moodle. This required us to stand up a Node.js application, which was a new experience for us. Our environment was RHEL7, and our preferred web server Apache.

Application deployment

We followed our usual Capistrano principles for deploying the application. We created a simple project with all the Capistrano configuration and then mounted the Swarthmore project as a git submodule in a top-level directory named public. We configured the Capistrano npm module to use public as its working directory to ensure that the various node modules are installed on deployment.

Read More