back to the tech wip: currently figuring out how to use the state parameter to stop csrf attacks, without storing stuff on the backend to verify it hasn't changed, also without accidentally inviting tampering and replay attacks
i think i can just stick a random number in there, "sign" it with an hmac, store the hmac in cookies, check that against state when it comes back
"don't roll your own crypto" but ya'll didn't roll it for me so guess what
(cue ridin' by chamillionaire)
december adventure, wip:
to do:
i must be getting deep into it, just learned that this issue i'm struggling with is not my own fuckup, it's a bug in haproxy that's causing responses to fail in glitchy ways when a jwt signature doesn't validate
haproxy devs know about it and fixed it but the patch hasn't been backported to various versions yet
https://github.com/haproxy/haproxy/commit/46b1fec0e9a6afe2c12fd4dff7c8a0d788aa6dd4
my workaround for now is going to be only attempt jwt validation when the keys match
random achievement: got my travel router set up as a proper travel router
updated openwrt, installed travelmate. now my partner and i can use our phones and laptops together on the hotel wireless without paying exorbitant additional-device fees (not that we ever did that) and have high-quality file transfers between our own devices
there's not enough room on it to install tailscale so maybe it's time to more seriously consider zerotier or a manual wireguard setup
my workaround for the haproxy issue upthread ๐งตโ๏ธ doesn't work great because google and probably other identity providers rotate their certificates frequently
instead of building a giant contraption to keep haproxy config updated with multiple configuration lines for every cert i might need, i'm trying to do what people used to do before haproxy grew a jwt_verify builtin: do it with a lua plugin ๐
part of me gets excited about it like
what other clever hacks could i do with a lil lua plugin to haproxy!
openresty pretty famously implements an entire web platform in what was probably intended to be a little lua extension for nginx
then on top of that web frameworks like lapis exist which let you code your web thing in lua, moonscript (kinda coffeescriptish) or fennel (lisp!)
https://openresty.org/en/
https://leafo.net/lapis/
https://fennel-lang.org/
a high quality mufo recently mentioned caddy so i looked and gosh
caddy (w/plugins) has a lot of things i stalled out trying to make happen with haproxy+lua+lighttpd:
but i agree that the glossy marketing website is sus. some exec is going to spring a trap as soon as it's popular
caddy is golang which i've been stubbornly avoiding learning for as long as it has existed. i would prefer software that stands between my computer and the nasty internet to be written in rust...
but, as much as i dislike golang i think i dislike c and c++ even more
haproxy and nginx are both written in c, and i've segfaulted both with mere configuration file mistakes which makes me super nervous
so maybe i will try caddy next
oof, caddy with my selected modules eats 14% of my weak little vps's half-gig of ram. that's even chonkier than nodejs who i have already been complaining about and trying to expunge
but maybe that's fine for now since it's fast and nice and has lots of features i like
caddy's webdav + static fileserver works pretty well except that it has the same flaw nginx does: GET requests understand and behave correctly in the presence of HTTP conditional request headers like If-Match or If-Unmodified-Since, while PUT requests silently ignore those headers. which will cause lost data with concurrent edits
nbd i'll just write my own simple tiny PUT handler as a fastcgi i guess since that's all i wanted out of webdav really
recently learned that debian has a software repo explicitly for installing recent versions of haproxy. so i could get one where the bug mentioned upthread is fixed
burned up a ridiculous amount of time troubleshooting a "file not found" error in my config, when i should have stopped relying on docs and read the source. because the haproxy docs and the error message is mistaken:
(contd)
jwt_verify(alg, key): ... the key parameter should either hold a secret or a path to a public certificate
no, it wants the public key extracted from a certificate, not the certificate itself. gotta do this:
openssl x509 -noout -pubkey < cert.pem > pubkey.pem
also you can only have one key per file so it's on you to match the id in the jwt to the file holding the corresponding key
today i learned that if you are reverse-proxying :80 and :443 with PROXY protocol to a caddy set up like this...
{
servers {
listener_wrappers {
proxy_protocol {
allow ...
}
tls
}
}
}
then, in addition to your https site definitions, you also have to toss this line in there to make proxy_protocol apply to the automatic http->https redirect that caddy sets up
:80 { }
https://caddyserver.com/docs/caddyfile/options#:~:text=unless%20you%20explicitly%20declare
but with this figured out, i now have an ipv6 vm that can still serve up its websites to people stuck on ipv4-only networks! without paying for an ipv4 address allocation! ๐ฅณ
next, to see if a prosody xmpp server and a coturn turn/stun server will work just as happily as the webserver does within this setup
๐ค turn and stun are mechanisms to help ipv4 clients behind nats talk to each other directly, or failing that, proxy their traffic to each other
nats are pretty much only for ipv4 clients. if they have an ipv6 address is probably isn't nat'd
so it probably doesn't make sense to imagine how to run a stun/turn server on an ipv6-only vm
the appropriate place for it to live is probably alongside the sniproxy doing ip4->ip6 reverse proxying
possible workarounds:
today i learned firefox's network.dns.preferIPv6 is false by default :C
๐ค that setting fixes mine but how can i trick other people's browsers on dual-stack networks into preferring ipv6, instead of unnecessarily using the shared ipv4->v6 proxy my host generously provides?
first software deployed to the beefy new vps is TiddlyPWA, and it is pretty great, and easier to install than i thought it would be. going to use it as a lab notebook and planner for the rest of the things i want to deploy
i was originally reluctant to use it because it doesn't seem like it would handle multiplayer -- multiple people working on the same page at the same time -- very well. but for now i'm the only user and it's great
a small tiddlypwa continues to work great, even on my mobile device on random networks on the other side of the planet. a far better experience than my big tiddlywiki5 instance.
deno (and node) are both chunkier than i'd like but the utility tiddlypwa provides outweighs that. a problem for later.
try it out! support the author!
setting StateDirectory=foo in a systemd unit makes it create the directory /var/lib/foo and set $STATE_DIRECTORY to that
https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=
$STATE_DIRECTORY will expand in your Exec= declaration but not in e.g. Environment=
so i can't say
Environment=DB_FILENAME=${STATE_DIRECTORY}/database.sqlite3
...
Exec=/usr/bin/command
instead i have toExec=env DB_FILENAME=${STATE_DIRECTORY}/database.sqlite3 /usr/bin/command
is there a prettier way?
is there a prettier way?
there is!
StateDirectory=%N
Environment=DB_FILENAME=%S/%N/database.sqlite3
setting up xmpp service on an ipv6-only vm with a graciously provided sniproxy to reverse-proxy ipv4 traffic to it
xmpp seems fine. i think my fantastic vps will let me forward those ports but even if not you can make xmpp share http(s) ports with a webserver with some hacks
but if i want to do voice and video, i'll need stun/turn to help ipv4 users
stun seems fine. client connects to it, server says "you appear to me to be (address):(port)," done.
turn however...
turn is for when no clever way can be found to connect clients directly to each other; they both connect to a turn server which just proxies: it shovels data back and forth to each client
even though my host would probably grant a request to proxy traffic through their ip4->ip6 machine to my turn service, which would proxy it again, that seems wasteful and squandering of a currently free community resource. i think i will build this out pretending that i can't do that
i'm not sure if there's any need for stun or turn with ipv6 clients, but otoh ipv6 nats are possible
like when your isp assigns you a /64 but you want to set up several subnets
think i'll rely on the reverse proxy to enable xmpp for ipv4-only users, and just say that voice and video is unavailable to them. the only real users of my xmpp server are my immediate family, and if both happen to be on an ip4-only network and need voice/video, they can get on the vpn
i got a ipv6-only vm from my sweet hosting provider
they gave me a /56 worth of ipv6 address space to play in. woah.
said my vm is currently using only the first /64 of it.
my vm's address is (prefix)::1/64, amazing!
so uh
how do i plug servers and containers into the rest of my available space? do i have to request each address get added to a table somewhere? (no)
(to be continued. but i think i did it, and understand it now!) ๐
(i might do this as a blog instead)
woo! connected to a test instance of prosody xmpp on port 443 (https) using xmpp's direct-tls protocol
which means
there's still different ways i can think of to wire all this together, wondering if any would be better
other ways i could wire it up:
instead of using a separate ip address so it and caddy can both listen on port 443, i could have caddy reverse proxy to it
might need to put it behind a proxy anyway because it might not handle PROXY protocol from sniproxy
might need to put it behind a proxy anyway so iocaine can slap the llm scrapers that try it
maybe run it in a container and figure out how to get those their own ip address
wow incus (anti-ubuntu fork of lxd) and its web ui is pretty slick
also libvirt and virt-manager connected to lxc offers the ability to create an application container or an operating system container
(compared to incus which says application containers require docker?)
this feels like a deep rabbit hole, hope i can get grips on it soon
all right incus there you go, a whole-ass lvm volume group all to yourself, let's see what you do with it
also: learning wtf a network bridge is and how to use one ๐งโ๐๐ instead of the usual winging it with vague guesswork and assumptions from context
is xmpp's direct-tls protocol (usually on port 5223) the same as its unencrypted protocol (usually port 5222) wrapped in tls? same as imaps and pops and https? so could i terminate the tls with haproxy and reverse proxy to an unencrypted xmpp server?
the protocol is all spec'd in RFCs for anybody to look at but they don't wanna get in my brain
also, aw, the wikipedia article for xmpp describes as an example a transport for icq, rip https://en.wikipedia.org/wiki/XMPP
the docs don't reveal the info i want, and i don't want to try reading reams of source code in an unfamiliar language right now, so i'll set up an experiment and see how it behaves i guess
(the only activity that ever feels slightly close to doing science in my field of software-jiggling)
my ipv4-only client
-> ipv4-to-ipv6 sniproxy port 443
-> ipv6-only vm
-> haproxy to conditionally unwrap proxy protocol
-> prosody xmpp server
... experiment is working โจ๐คฉโจ
calling it now: even though haproxy has lots of sharp edges, i like it, or its configuration mechanism, way more than caddy's
i think i'm going to be stuck using both for a while
migrating xmpp services from my old vps to my colocataires vm is the last thing remaining to do before i'm able to delete the old account (and stop paying for it)
(dreamcompute hasn't been bad, but i like colocataires way better)
now that i've proven to myself that it can work over port 443 and ipv6-only, it's time to configure it properly
next: see if i can move the service over without xmpp clients complaining
but first, sleep ๐ด
all the clients we usually use on android and linux are now connecting to my new xmpp server at colocataires, with no settings changes, on the https port so it looks like website traffic ๐ฎ
i don't have stun/turn turned back on yet, so voice and video calls probably won't work just yet
i don't have the conversations.js web client set back up yet but that's mostly for emergency use
this may be success enough to decommission the old servers! ๐
https://conversejs.org/ is back up on my domain and working just fine ๐
old dreamcompute vps is turned off, sitting there just in case for a bit, then i can delete my account ๐
(i don't hate dreamcompute but i like https://colocataires.dev way better)
think i'm just gonna leave stun/turn not running for now. if both parties are on ipv6-capable networks, calls should work. let's see how often that's an issue
if i want to set up stun/turn, i should abandon my somewhat irrational ipv6-purist intentions and pay the loonie for an ipv4 address
if i'm gonna do that then maybe i can keep almost all of my vm ipv6-only, except for one container that runs coturn?
if i'm gonna do that then maybe i can figure out how to make that container, that only does whatismyipaddress and proxy video calls, shareable with my datacenter neighbors 
my prosody xmpp setup in its new server mostly works great (assuming ipv6 capable network) but somewhere i've introduced a timeout that closes the connection after a uniform number of seconds
pretty sure it has something to do with haproxy, though from a skim of the docs these timeouts are supposed to apply to the initial connection setup, not inactivity
also after a chat with someone more knowledgeable i think i'm resigned to eventually acquire that ipv4 address
i think i might have fixed haproxy closing the socket on my long-lived idle xmpp connections by setting timeout tunnel 1h
i'll check again in several hours to be sure
wish i knew more precisely why this fixes the issue. are clients and/or the server sending keepalive messages more often than 1h but less often than 10m? is the tcp keepalive stuff not being used? someday perhaps but more likely i'll leave it unexamined as long as it works
recent impulses have been like
"this is too long for toots i should blog about it"
"but i don't want to put anything new or deploy a new website until i have something installed to block the scrapers like iocaine"
"so let's install it"
"ehh not enough brain rn, maybe next time"
so i set up some rules to block a good portion of bots (until they smarten up)
which frees me up to actually post some blog ๐
i'll install iocaine properly after that
i want to set up a photo storage server
photoprism seems like a good browsing interface but what i'm more concerned about rn is the upload
so a client on each android phone that backs up photos to the server
but i want to be able to turn the server off for a while, as a normal/expected thing one does, and not have the clients moan about it. they should just retry occasionally until the server comes back online
anybody have a setup like this running already?
musing about how to do high(ish)-availability systems on the cheap, goblin style
...
but wait i have some tradeoffs that might enable some tricks:
so in this specific case i think i could do client-side js failover. maybe even a service worker?
wait, how often does the whole region disappear anyway?
that was never a concern multiple employers ago when i got to help out at the datacenter
they did redundant everything inside the rack, regular cable-yank failover tests and everything, but no geographical redundancy iirc
maybe i'll inquire about a vm on another host within the same rack when i get closer to dragging clients on board and just forget about higher availability than that for now
embarrassed to admit that i've today taken one halfhearted step toward learning wtf snmp is by way of (re)reading the rrdtool tutorial
no, not smtp the email sending thing. snmp the monitoring of hardware status thing
all because i want to put up some pretty charts of computer doing inscrutable computer thing
(accuracy? that's like number seven or twelve down the list of nice-to-haves)
well, actually,
my ipv4-only client
-> colocataires' ipv4-to-ipv6 sniproxy on port 443
-> my ipv6-only vm
-> haproxy to unwrap proxy protocol
-> prosody xmpp server
... experiment is not working โจ๐โจ
so:
did it never work and i mistakenly thought that it did?
or
did it work at first but i broke it?
an easy fix would be to get an ipv4 address which obviates the need for sniproxy. but dammit before i do that i want answers: is this setup possible? if so, what'd i mess up?
(maniacal cackling)
i have finally got iocaine installed. wasn't even hard, just needed to sit down and do the steps and brain is real good at not that sometimes
hooked it up to the apt-installable anarchism faq for its markov corpus and the biggest canadian flavored apt-installable wordlist i could get
feels good. like the invulnerability you get from your favorite winter gloves and jacket before going out to play in the blizzard
now it's safe to blog again ๐
i um only just now noticed that the apt-installable anarchism faq, in uncompressed markdown format, which i fed to iocaine for its markov corpus,
is twelve megabytes. of text.
almost 1.9 million words.
iocaine seems to be doing just fine so far
accidentally set caddy to syslog every request sent to iocaine 3 and oh gosh my website is pumping so much poison markov trash into chatgpt and claude rn ๐ ๐
and it's using less cpu and memory than systemd-journald to do so
might need to look into setting bandwidth limiters on this thing
i'm still casting around for anti-cloud(flare) mechanisms of regional failover. like if the cable to the datacenter i use gets cut, or there's political upheaval, how to automatically shunt traffic to a different datacenter faster than a dns update would propagate through caches
i'm vaguely aware of this technology called anycast but i don't know much
https://grebedoc.dev/ uses https://rage4.com/ to do it
yeah eat it, ai scraper assholes
(gradually improving my monitoring, iocaine stats newly added to my collectd/rrdtool dashboard)
tiddlywiki doesn't come with a basic to-do feature, to make checkboxes and tick them off without having to tediously edit the page and type some [x]s
but it does have a plugin mechanism. found two plugins (both by the same author) that do checklists: Kara and Todolist
installation instructions made me nervous though, since i'm using tiddlyPWA that is rather different on the backend...
i haven't put any rate limiters on here yet (i definitely will), but seems like claude and chatgpt limit themselves to 25 requests per second to my websites. i wonder how they picked that number, and if they'll ramp it up. and if i ratelimit, will they send more requests from other ip addresses. etc.
feels so good to know these assholes' language models are chugging down low-effort ungrammatical poison after ignoring my robots.txt
up front: cloudflare and aws are non options
still trying to figure out how to shunt traffic to a backup vm elsewhere if my nearby vm faceplants
seems like my options are:
for now i'm experimenting with https://bunny.net, whom i haven't heard bad things about but they're in the middle just like cf ๐
don't want to send all traffic through a load balancing proxy, expensive and another single point of failure
actually, not as expensive as i was afraid of, and if they're using anycast to give their dns redundancy that's good enough
their being able to snoop on unencrypted traffic is the bigger concern
/24 for IPv4 or a /48 for IPv6, and you can only do anycast on the entire block at once. (You can do whatever you want when routing inside of your network, but you could already receive the packet and do that anyway).RE: https://tiny.tilde.website/@pho4cexa/115472629866780053
@algernon debian has a few other apt-installable pieces of literature that might also be suitable as corpora
@glyph (if i understand what you're asking) yeah my home isp is ipv6-enabled and works well with my xmpp setup. but when i'm visiting aging relatives abroad one of the networks involved in the call are often natted ipv4-only. and i hear most of canada's major residential ISPs are ipv4-only too?
top priority is to avoid hearing from spouse while abroad, "i tried to voice-call you and it didn't work, let's go back to using google meet" ๐ฌ
@glyph part of this story is i'm kindof weaseling out of needing an ipv4 address for some things because my vps host provides an ipv4-to-ipv6 sniproxy for tcp ports 80, 443, and one or two others. for websites mostly
so the part of my brain that thinks working within constraints is interesting wants to try to wedge stun/turn in there and hope tcp/tls-only mode is good enough for clients
while the reasonable part wants to just get the ipv4 allocation already
@glyph absolutely that's what i'm expecting to have to deal with, but next trip isn't for several months at least so i have time to tinker
even with an ipv4 address on my old vps, the call quality was never amazing, and it sometimes took several seconds to connect after picking up
didn't have a lot of tools and expertise last trip to really diagnose it. that a call connected was good enough at the time; easier to notice a ringtone than a little "message" boop