From bc2f0fcb81276b5f11cbba1672d494d5f212dff6 Mon Sep 17 00:00:00 2001 From: saji Date: Sun, 20 Apr 2025 09:56:54 -0500 Subject: [PATCH] fixup content, add callout shortcode --- content/blog/beets-soulseek.md | 1 + .../hacking-hikmicro-pt1/hacking-hikmicro.md | 23 ++--- content/blog/nix-unprivileged-deployments.md | 74 +++++++++------ content/blog/zig-is-dark-souls/index.md | 1 - eleventy.config.js | 8 ++ package.nix | 26 ++++++ public/css/index.css | 89 +++++++++++++++++-- styles/config/vocabularies/Base/accept.txt | 3 + 8 files changed, 179 insertions(+), 46 deletions(-) create mode 100644 package.nix diff --git a/content/blog/beets-soulseek.md b/content/blog/beets-soulseek.md index c249a4b..1ef497e 100644 --- a/content/blog/beets-soulseek.md +++ b/content/blog/beets-soulseek.md @@ -1,4 +1,5 @@ --- title: Beets and Soulseek Or, How I Learned to Give Up and Love The Hoard date: 2025-02-03 +draft: true --- diff --git a/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md b/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md index 27e1c96..80a1fe9 100644 --- a/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md +++ b/content/blog/hacking-hikmicro-pt1/hacking-hikmicro.md @@ -1,14 +1,14 @@ --- title: Reversing an image format date: 2025-01-15 -tags: reverse-engineering, hacking-hikmicro +tags: [reverse-engineering, hacking-hikmicro] +drafts: true --- This post is the first in a series on reverse engineering binary file formats using an array of tools, mainly to serve as insight into how to approach these kinds of challenges as they can be daunting. Part one focuses on the image format. - # Introduction *[ITAR]: International Traffic in Arms Regulations @@ -17,18 +17,21 @@ These arrays are higher resolution and faster framerates than what can reasonabl to low competition and ITAR restrictions. Most popular are the low-cost modules by Infiray, which provides whitelabel solutions to a host of other companies (TOPDON, Vevor, HTI, UNI-T) to relabel and sell under their own name. They come in two major form factors: Phone add-on and gun-grip unit. Existing work has documented and reverse-engineered the phone communication protocols, -but +but -I've been burned once by the phone-dongle style before with Seek Thermal. Simply put, the pace of smartphones is longer than -the target lifespan of these products. Therefore I wanted one that could be used in a dedicated fashion. The PC +I got burned once by the phone-dongle style before with Seek Thermal. Simply put, the pace of smartphones is longer than +the target lifespan of these products. This time, I wanted one that was standalone. The PC connectivity was still important to me, since there are certain operations that can only be done with access to raw data, like Lock-In Thermography. -For that reason, the Hikmicro line of portable imagers interested me. It's more expensive than the whitelabel Infiray -products, but offers some pretty nice looking PC software and uses a Radiometric JPEG image format for data. -Live USB is advertized and it supposedly also delivers radiometry over the USB (!). This is on -top of being a standalone unit so you don't need to use an odd phone app. However this choice seems less popular on forums -and there is no reverse engineering project that exists already, so we'll have to start from scratch. +For that reason, the Hikmicro line of portable imagers interested me. It's more +expensive than the whitelabel Infiray products, but offers some pretty nice +looking PC software and uses a Radiometric JPEG image format for data.They +advertise Live USB video and it supposedly also delivers radiometry over the +USB (!). This is on top of being a standalone unit so you don't need to use an +odd phone app. However this choice seems less popular on forums and there is no +reverse engineering project that exists already, so we'll have to start from +scratch. # Getting the picture diff --git a/content/blog/nix-unprivileged-deployments.md b/content/blog/nix-unprivileged-deployments.md index 35d6c88..92ec517 100644 --- a/content/blog/nix-unprivileged-deployments.md +++ b/content/blog/nix-unprivileged-deployments.md @@ -4,13 +4,16 @@ date: 2025-04-17 tags: NixOS --- -Note: this post assumes familiarity with the Nix Ecosystem. +{% callout %} +This post assumes familiarity with the Nix ecosystem. +{% endcallout %} Nix and NixOS make managing servers much easier than bespoke scripts or complex Ansible playbooks. While I don't think NixOS is ready for personal computers, it absolutely makes sense on less dynamic devices like servers or embedded-ish machines. + We can use NixOS and nixpkgs to derive a fully defined operating system and services. Then, we can: @@ -19,7 +22,7 @@ Then, we can: - push the new configuration to a remote server using [deploy-rs]() The latter is interesting. With a bit of setup, we can do GitOps with rollback -and push-deployments. `deploy-rs` is a glorified `nix copy` with some extra magic +and push-deployments. `deploy-rs` is like `nix profile` with helper scripts to "activate" the copied closure. Activation typically means running `home-manager switch` or switching the NixOS profile. @@ -37,46 +40,60 @@ And then have `nginx` use `/home/blog/_site/` as the site root. This works, but Other users have tied their blog to the NixOS system-level configuration, like [this user](https://jeancharles.quillet.org/posts/2023-08-01-Deploying-a-static-website-with-nix.html). While I think this is a good solution, it has the issue of relying on root access for updating the site. To me, this feels excessive. I should be able to deploy my site from a lesser-privileged user. +This method also ties sysadmin-tasks to our blog, which isn't keeping our concerns separate. # Scaffolding the Solution Let's recap: 1. Build the site using a nix derivation -2. Copy the derivation to a server using a locked down non-root account. -3. Create well-known path that points to the latest version of the site in the nix store. -4. Configure `nginx` to serve from this well known path. +2. Configure `nginx` to serve from a well-known path (`/var/lib/site/public`) +3. Copy the derivation to a server using a locked down non-root account. +4. Symlink `/var/lib/site/public` to our static site in the nix store. I'll do it manually to get an idea of how it should work. ## nix build blog -I build my blog using [11ty](https://www.11ty.dev), and I use `npm run build` to generate -the static sources. Nix supports building npm-like packages with `buildNpmPackage`, which -uses a [Fixed-output derivation](https://nix.dev/manual/nix/2.28/store/derivation/outputs/content-address#fixed) -to store the dependencies of the project. Then, for the `installPhase`, we just copy the built contents -to `$out`. I need to add `vips` and `pkg-config` as well because 11ty processes my images. +I build my blog using [11ty](https://www.11ty.dev), and I use `npm run build` +to generate the static sources. Nix supports building npm-like packages with +`buildNpmPackage`. This uses a [Fixed-output +derivation](https://nix.dev/manual/nix/2.28/store/derivation/outputs/content-address#fixed) +to store the dependencies of the project if it is stored elsewhere, but I found +a better method that imports the `package.lock` directly. Then, for the +`installPhase`, we just copy the built contents to `$out`. I need to add `vips` +and `pkg-config` as well because 11ty processes my images. You should add any +other tools you'd need to build your site. The end result looks like this: ```nix -default = pkgs.buildNpmPackage { +{ + nodejs, + pkg-config, + buildNpmPackage, + importNpmLock, + vips, +}: buildNpmPackage { name = "myblog"; version = "unstable"; - buildInputs = with pkgs; [ + buildInputs = [ nodejs vips ]; - nativeBuildInputs = with pkgs; [ + nativeBuildInputs = [ pkg-config ]; - npmDepsHash = "sha256-Q7rhCjAPPn44DyUZ/uoD+7o4XH33IATfL+v1azEhuW0="; + npmDeps = importNpmLock { + npmRoot = ./.; + }; + npmConfigHook = importNpmLock.npmConfigHook; src = ./.; installPhase = '' mkdir -p $out/public - cp -ar _site/ $out/public + cp -ar _site/* $out/public/ ''; -}; +} ``` Then, running `nix build` I get my site files in `result/public`, which is what we want. @@ -109,9 +126,14 @@ module that will set this up: # TODO: write this ``` + +Now we have a scoped user, with an ssh key authorized. It needs a shell so we can actually log +in remotely. The last step is creating that symlink. This is where the concept of "activation" comes into play. -For NixOS, `deploy-rs` activation just calls `switch-to-configuration` to make the system change the profile. -We can effectively do whatever we want here. + + +For NixOS, `deploy-rs` activation just calls `switch-to-configuration` to make +the system change the profile. We can effectively do whatever we want here. Reading the [custom activator](https://github.com/serokell/deploy-rs/blob/aa07eb05537d4cd025e2310397a6adcedfe72c76/flake.nix#L58C13-L96C17) source: ```nix @@ -172,8 +194,9 @@ ln -sn $PROFILE/public /var/lib/static-site/public Then when deploying with `deploy-rs`: -``` -error: cannot add path '/nix/store/2sad737aglfzmil72phv0j8s34zzmvzi-myblog' because it lacks a signature by a trusted key +```bash +error: cannot add path '/nix/store/2sad737aglfzmil72phv0j8s34zzmvzi-myblog' +because it lacks a signature by a trusted key ``` Drat. This makes sense though, since it would be a bit dangerous to allow any old user write access to @@ -182,17 +205,14 @@ the nix store. We have two options: 1. Make `static-site` a trusted user 2. Create a trusted keypair to sign our closure when it's built. -Pick your poison - the keypair mechanism is slightly more secure. +Pick your poison - the keypair mechanism is more secure, as it means that +the `static-site` user can't upload arbitrary packages. I just want to get this working, so I made `static-site` a trusted user. Note that if you wanted to use the keypair instead, `deploy-rs` has a [secret environment variable](https://github.com/serokell/deploy-rs/blob/aa07eb05537d4cd025e2310397a6adcedfe72c76/src/push.rs#L131) called `LOCAL_KEY` which is a file that contains the signing key. +Regardless of the outcome you choose, when you re-deploy, it should work properly. - - - - - - +Let's follow the symlink. diff --git a/content/blog/zig-is-dark-souls/index.md b/content/blog/zig-is-dark-souls/index.md index dd888af..3e3adf2 100644 --- a/content/blog/zig-is-dark-souls/index.md +++ b/content/blog/zig-is-dark-souls/index.md @@ -1,4 +1,3 @@ - --- title: Zig is Dark Souls description: This is both good and bad. diff --git a/eleventy.config.js b/eleventy.config.js index 473102d..8345e0d 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -145,6 +145,14 @@ export default async function (eleventyConfig) { //eleventyConfig.addPairedShortcode("section", async (content, transition = "none") => { // return `
${mdIt.renderInline(content)}
`; //}) + // + // Paired shortcode for callout + eleventyConfig.addPairedShortcode("callout", function(content) { + // The 'content' variable holds the text/HTML placed between + // {% callout %} and {% endcallout %} + // We wrap it with our div structure. + return `
${content}
`; + }); // Features to make your build faster (when you need them) diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..7124b12 --- /dev/null +++ b/package.nix @@ -0,0 +1,26 @@ +{ + nodejs, + pkg-config, + buildNpmPackage, + importNpmLock, + vips, +}: buildNpmPackage { + name = "myblog"; + version = "unstable"; + buildInputs = [ + nodejs + vips + ]; + nativeBuildInputs = [ + pkg-config + ]; + npmDeps = importNpmLock { + npmRoot = ./.; + }; + npmConfigHook = importNpmLock.npmConfigHook; + src = ./.; + installPhase = '' + mkdir -p $out/public + cp -ar _site/* $out/public/ + ''; +} diff --git a/public/css/index.css b/public/css/index.css index 05d185c..342282f 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -7,16 +7,41 @@ /* Theme colors */ :root { + + --color-black: #000000; + --color-black-bright: #5a4e51; + + --color-red: #cf5080; + --color-red-bright: #e26b95; + + --color-green: #7b8d39; + --color-green-bright: #8fa445; + + --color-yellow: #b57235; + --color-yellow-bright: #cf8544; + + --color-blue: #3c8cbf; + --color-blue-bright: #4fa1d7; + + --color-magenta: #9468d8; + --color-magenta-bright: #a782e5; + + --color-cyan: #a782e5; + --color-cyan-bright: #47ac9b; + + --color-white: #c2bdbd; + --color-white-bright: #ffffff; + --color-gray-20: #e0e0e0; --color-gray-50: #C0C0C0; --color-gray-90: #333; - --background-color: #fff; + --background-color: var(--color-white); --text-color: var(--color-gray-90); - --text-color-link: #082840; - --text-color-link-active: #5f2b48; - --text-color-link-visited: #17050F; + --text-color-link: var(--color-cyan); + --text-color-link-active: var(--color-cyan-bright); + --text-color-link-visited: var(--color-cyan); --syntax-tab-size: 2; } @@ -26,13 +51,16 @@ --color-gray-20: #e0e0e0; --color-gray-50: #C0C0C0; --color-gray-90: #dad8d8; + --background-color: var(--color-black); /* --text-color is assigned to --color-gray-_ above */ - --text-color-link: #1493fb; - --text-color-link-active: #6969f7; - --text-color-link-visited: #a6a6f8; + /* --text-color-link: #1493fb; */ + /* --text-color-link-active: #6969f7; */ + /* --text-color-link-visited: #a6a6f8; */ + --text-color-link: var(--color-cyan); + --text-color-link-active: var(--color-cyan-bright); + --text-color-link-visited: var(--color-cyan); - --background-color: #15202b; } } @@ -145,6 +173,9 @@ pre:not([class*="language-"]) { } code { word-break: break-all; + + color: var(--color-black); + background-color: var(--color-white); } /* Header */ @@ -277,3 +308,45 @@ h1, h2, h3 { font-family: WO3; letter-spacing: .1rem; } + + +/* Callout styles */ + +.callout { + padding: 2em; /* Adjust padding as needed */ + position: relative; /* Needed for positioning pseudo-elements */ + border: none; /* Ensure no default border */ + margin: 1em 0; /* Add some margin for spacing */ + overflow: hidden; /* Prevents pseudo-elements from causing scrollbars if they slightly exceed bounds */ +} + +.callout p { + margin: 0; /* Remove default paragraph margin inside callout */ +} + +/* Top-left corner bracket */ +.callout::before { + content: ''; + position: absolute; + top: 0.5em; /* Adjust position */ + left: 0.5em; /* Adjust position */ + width: 1.5em; /* Adjust size */ + height: 1.5em; /* Adjust size */ + border-top: 3px solid #ffffff; /* White border, adjust thickness */ + border-left: 3px solid #ffffff; /* White border, adjust thickness */ + box-sizing: border-box; +} + +/* Bottom-right corner bracket */ +.callout::after { + content: ''; + position: absolute; + bottom: 0.5em; /* Adjust position */ + right: 0.5em; /* Adjust position */ + width: 1.5em; /* Adjust size */ + height: 1.5em; /* Adjust size */ + border-bottom: 3px solid #ffffff; /* White border, adjust thickness */ + border-right: 3px solid #ffffff; /* White border, adjust thickness */ + box-sizing: border-box; +} + diff --git a/styles/config/vocabularies/Base/accept.txt b/styles/config/vocabularies/Base/accept.txt index 03ac90e..8c8bee2 100644 --- a/styles/config/vocabularies/Base/accept.txt +++ b/styles/config/vocabularies/Base/accept.txt @@ -21,3 +21,6 @@ nixpkgs? NixOS keypair + +whitelabel +