SSO In Apache HTTPD – OAuth2

PingID is another external authentication source that looks to be replacing ADFS at work in the not-too-distant future. Unfortunately, I’ve not been able to get anyone to set up the “other side” of this authentication method … so the documentation is untested. There is an Apache Integration Kit available from PingID (https://www.pingidentity.com/en/resources/downloads/pingfederate.html). Documentation for setup is located at https://docs.pingidentity.com/bundle/pingfederate-apache-linux-ik/page/kxu1563994990311.html

Alternately, you can use OAuth2 through Apache HTTPD to authenticate users against PingID. To set up OAuth, you’ll need the mod_auth_openidc module (this is also available from the RedHat dnf repository). You’ll also need the client ID and secret that make up the OAuth2 client credentials. The full set of configuration parameters used in /etc/httpd/conf.d/auth_openidc.conf (or added to individual site-httpd.conf files) can be found at https://github.com/zmartzone/mod_auth_openidc/blob/master/auth_openidc.conf

As I am not able to register to use PingID, I am using an alternate OAUTH2 provider for authentication. The general idea should be the same for PingID – get the metadata URL, client ID, and secret added to the oidc configuration.

Setting up Google OAuth Client:

Register OAuth on Google Cloud Platform (https://console.cloud.google.com/) – Under “API & Services”, select “OAuth Consent Screen”. Build a testing app – you can use URLs that don’t go anywhere interesting, but if you want to publish the app for real usage, you’ll need real stuff.

Under “API & Services”, select “Credentials”. Select “Create Credentials” and select “OAuth Client ID”

Select the application type “Web application” and provide a name for the connection

You don’t need any authorized JS origins. Add the authorized redirect URI(s) appropriate for your host. In this case, the internal URI is my docker host, off port on 7443. The generally used URI is my reverse proxy server. I’ve had redirect URI mismatch errors when the authorized URIs don’t both include and exclude the trailing slash. Click “Create” to complete the operation.

You’ll see a client ID and secret – stash those as we’ll need to drop them into the openidc config file. Click “OK” and we’re ready to set up the web server.

Setting Up Apache HTTPD to use mod_auth_openidc

Clone the mod_auth_openidc repo (https://github.com/zmartzone/mod_auth_openidc.git) – I made one change to the Dockerfile. I’ve seen general guidance that using ENV to set DEBIAN_FRONTEND to noninteractive is not ideal, so I replaced that line with the transient form of the directive:

ARG DEBIAN_FRONTEND=noninteractive

I also changed the index.php file to

RUN echo "<html><head><title>Sample OAUTH Site</title><head><body><?php print $_SERVER['OIDC_CLAIM_email'] ; ?><pre><?php print_r(array_map(\"htmlentities\", apache_request_headers())); ?></pre><a href=\"/protected/?logout=https%3A%2F%2Fwww.rushworth.us%2Floggedout.html\">Logout</a></body></html>" > /var/www/html/protected/index.php

Build an image:

docker build -t openidc:latest .

Create an openidc.conf file on your file system. We’ll bind this file into the container so our config is in place instead of the default one. In my example, I have created “/opt/openidc.conf”. File content included below (although you’ll need to use your client ID and secret and your hostname). I’ve added a few claims so we have access to the name and email address (email address is the logon ID)

Then run a container using the image. My sandbox is fronted by a reverse proxy, so the port used doesn’t have to be well known.

docker run --name openidc -p 7443:443 -v /opt/openidc.conf:/etc/apache2/conf-available/openidc.conf -it openidc /bin/bash -c "source /etc/apache2/envvars && valgrind --leak-check=full /usr/sbin/apache2 -X"

* In my case, the docker host is not publicly available. I’ve also added the following lines to the reverse proxy at www.rushworth.us

ProxyPass /protected https://docker.rushworth.us:7443/protected
ProxyPassReverse /protected https://docker.rushworth.us:7443/protected

Access https://www.rushworth.us/protected/index.php (I haven’t published my app for Google’s review, so it’s locked down to use by registered accounts only … at this time, that’s only my ID. I can register others too.) You’ll be bounced over to Google to provide authentication, then handed back to my web server.

We can then use the OIDC_CLAIM_email — $_SERVER[‘OIDC_CLAIM_email’] – to continue in-application authorization steps (if needed).

openidc.conf content:

LogLevel auth_openidc:debug

LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so

OIDCSSLValidateServer On

OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCClientID uuid-thing.apps.googleusercontent.com
OIDCClientSecret uuid-thingU4W

OIDCCryptoPassphrase S0m3S3cr3tPhrA53
OIDCRedirectURI https://www.rushworth.us/protected
OIDCAuthNHeader X-LJR-AuthedUser
OIDCScope "openid email profile"

<Location /protected>
     AuthType openid-connect
     Require valid-user
</Location>

OIDCOAuthSSLValidateServer On
OIDCOAuthRemoteUserClaim Username

SSO In Apache HTTPD — ADFS

Active Directory Federated Services (ADFS) can be used by servers inside or outside of the company network. This makes it an especially attractive authentication option for third party companies as no B2B connectivity is required to just authenticate the user base. Many third-party vendors are starting to support ADFS authentication in their out-of-the-box solution (in which case they should be able to provide config documentation), but anything hosted on Apache HTTPD can be configured using these directions:

This configuration uses the https://github.com/UNINETT/mod_auth_mellon module — I’ve built this from the repo. Once mod_auth_mellon is installed, create a directory for the configuration

mkdir /etc/httpd/mellon

Then cd into the directory and run the config script:

/usr/libexec/mod_auth_mellon/mellon_create_metadata.sh urn:samplesite:site.example.com "https://site.example.com/auth/endpoint/"

 

You will now have three files in the config directory – an XML file along with a cert/key pair. You’ll also need the FederationMetadata.xml from the IT group – it should be

Now configure the module – e.g. a file /etc/httpd/conf.d/20-mellon.conf – with the following:

MellonCacheSize 100
MellonLockFile /var/run/mod_auth_mellon.lock
MellonPostTTL 900
MellonPostSize 1073741824
MellonPostCount 100
MellonPostDirectory "/var/cache/mod_auth_mellon_postdata"

To authenticate users through the ADFS directory, add the following to your site config

MellonEnable "auth"
Require valid-user
AuthType "Mellon"
MellonVariable "cookie" 
MellonSPPrivateKeyFile /etc/httpd/mellon/urn_samplesite_site.example.com.key
MellonSPCertFile /etc/httpd/mellon/urn_samplesite_site.example.com.cert
MellonSPMetadataFile /etc/httpd/mellon/urn_samplesite_site.example.com.xml
MellonIdPMetadataFile /etc/httpd/mellon/FederationMetadata.xml
MellonMergeEnvVars On ":"
MellonEndpointPath /auth/endpoint

 

Provide the XML file and certificate to the IT team that manages ADFS to configure the relying party trust.

Fortify on Demand Remediation: Cookie Security: Cookie not Sent Over SSL

This is another one that might be a false positive or might be legit. If you look at the documentation for PHP’s setcookie function, you will see the sixth parameter sets a restriction so cookies are only sent over secure connections. If you are not setting this restriction, the vulnerability is legitimate and you should sort that. But … if you followed PHP’s documentation and passed 1 to the parameter? FoD is falsely reporting that the parameter is not set to true.

In this case, the solution is easy enough. Change your perfectly valid 1

to say true

And voila, the vulnerability has been remediated.

Porkbun DDNS API

I’ve been working on a script that updates our host names in Porkbun, but the script had a problem with the example.com type A records. Updating host.example.com worked fine, but example.com became example.com.example.com

Now, in a Bind zone, you just fully qualify the record by post-pending the implied root dot (i.e. instead of “example.com”, you use “example.com.”, but Porkbun didn’t understand a fully qualified record. You cannot say the name is null (or “”). You cannot say the name is “example.com” or “example.com.”

In what I hope is my final iteration of the script, I now identify cases where the name matches the zone and don’t include the name parameter in the JSON data. Otherwise I include the ‘name’ as the short hostname (i.e. the fully qualified hostname minus the zone name). This appears to be working properly, so (fingers crossed, knock on wood, and all that) our ‘stuff’ won’t go offline next time our IP address changes.

2022 Seeds

We’ve saved seeds from the garden (and seeds from both ground cherries and hot peppers that we picked up at the farmers market) that will make up much of our garden this year. I purchased a bunch of flower seeds to expand the bee garden, and a few new vegetables. And I really hope to get asparagus established this year!

Seeds for Honeybees

Autumn Beauty Sunflower Seeds – XL Packet

Ballerina California Poppy Seed Mix – XL Packet

Calendula-Balls-Orange-Wildflower-Seeds

Ball’s Orange Calendula Seeds – XL Packet

Asclepias-tuberosa

Butterfly Weed Seeds – 1/4 Oz

California Giants Zinnia Seed Mix – 1/4 Lb

Globe Annual Candytuft Seeds – XL Packet

Fairy Bouquet Snapdragon Seed Mix – XL Packet

Chrysanthemum-maximum-dwarf

Dwarf Shasta Daisy Seeds – XL Packet

Swiss Giants Pansy Seed Mix – 1/4 Oz

Single-Mixed-China-Aster-Wildflower-Seeds

Single China Aster Seed Mix – XL Packet

Painted Daisy Seeds – XL Packet

Money Plant Seeds – XL Packet

Ice Plant Seed Mix – 1 Oz

McKana Giants Columbine Seed Mix – XL Packet

Gaillardia-pulchella

Indian Blanket Seeds – XL Packet

Imperial Rocket Larkspur Seed Mix – 1 Oz

Imperial Pincushion Flower Seed Mix – XL Packet

Iceland Poppy Seeds – 1 Oz

Sparky French Marigold Seed Mix – XL Packet

Asclepias-syriaca-01

Common Milkweed Seeds – 1 Oz

Seeds for Food
Sugar-Beet-Beet-Seeds

Sugar Beet Seeds

Anise-Herb-Seeds

Anise Seeds

Chioggia-Beet-01

Chioggia Beet Seeds

Easter-Egg-Radish-01

Easter Egg Radish Seeds

French-Breakfast-Radish-01

French Breakfast Radish

 

Sparkler-White-Tip-Radish-Seeds-01

Sparkler White Tip Radish

White-Icicle-Radish-01

White Icicle Radish Seeds

 

 

Hickory King Corn

Pencil Cob Corn
Triticale Winter Rye Dundale Pea
Hull-less Barley Burbank Hull-less Barley Stalks of oats stock image. Image of ripe, harvest ...

Oats

Wheat on farm field stock image. Image of agriculture ...

Wheat

German Extra Hardy Garlic

Chesnok Garlic

Music Garlic

Dutch Red Shallot

Dutch Red Shallot

 

Costco

We’d talked about joining Costco for years — a new store was built not too far from my office, and they had a membership promo. It was rather far away from our house; and, without checking it out first, hard to tell if it was a good deal. Especially without storage space for, say, a gallon of lemon juice. As we’ve been producing more at home — vegetables, meats — we’ve also gotten a lot of storage space. Loads of canning jars, chest freezers, vacuum sealer, shelves. So the idea of buying twenty pounds of apples is now appealing — can a bunch of apple sauce and apple butter 🙂

So, on Friday, we went out to Costco and got a membership. They’ve got a lot of stuff. Unfortunately, we were there about an hour before closing (why in the world would a company have limited hours on the weekend?!) and didn’t get to check out everything. Lots of electronics — a big TV that Scott would have loved to get. A couple of mesh WiFi systems. Fridges (not the one I want to get, unfortunately). And the expected huge containers of foods. Stuff I have a hard time finding in the grocery store too — they never have thick cut pork chops, so I end up getting a whole loin and cutting my own. But there were really nice 1″+ chops sitting right in a cooler. A tasty looking kale pesto. And a huge bag of frozen mango chunks (also a similarly huge bag of blueberries that I hope to not need in a year or two once our bushes start producing!). The coolest thing was that they’re loaded up with organic options (that are generally cheaper than the non-organic variety at the grocery store).

We also learned something about pickup trucks. They are great for hauling home the materials to build a chicken pasture fence. They’re great for hauling chest freezers. They are not great for bringing home groceries … I get why people have those tarp things that pull over the bed. We loaded all of the heavy (and low wind resistance) things into the truck bed, but ended up piling a bunch of lighter / breakable things in the cab with Anya.

Overall, the place seems like a score. And very much in line with my mom’s parents’ approach to living out in the country on a mountain. They’d not plan on going anywhere from October through April — stock up on food, get supplies for any winter projects, and just do their thing for six months. An approach that seems far more reasonable now that I’ve got my own couple hundred foot driveway curving up a mountainside.

Rechargeable batteries in the game camera

We tried using rechargeable batteries in our game cameras — eight batteries per camera, and we have three cameras … so it’d be nice not to throw out two dozen double-a batteries. The question, though, was how long they’d last. (Well, the first question is if they’d work at all … nuance of battery chemistry and electric production … the cheap rechargeable AA’s are lower voltage than throw away ones. But we quickly proved that the cameras would run on these batteries). We put the cameras out on October 3, and the cameras are still operational today. That’s over two weeks on a charge. We’ll see when the last videos record, but they’ve already proven to be functional for our purpose.

The first batteries to discharge stopped recording overnight 11/6 to 11/7 … 34 days on a charge. One set was still working, but we pulled them all to discharge / charge them.