Skip Navigation

InitialsDiceBearhttps://github.com/dicebear/dicebearhttps://creativecommons.org/publicdomain/zero/1.0/„Initials” (https://github.com/dicebear/dicebear) by „DiceBear”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/)L
Posts
4
Comments
237
Joined
3 yr. ago

  • There are business, technical, and UI/UX reasons for having a client. The business case is that it clearly demarcates the service they're selling, because it must be installed and isn't built-in (eg Firefox VPN). The act of having the user do something means that for a brief moment, they have to concentrate on the product. Consumers have this tendency to value things higher if they were involved in its success, such as when building flat-pack furniture.

    The technical side is that while a VPN is indeed just a tube that transports packets securely to the VPN servers, the fact is that there are so many ways for this to go wrong. For example, leaking DNS requests is a way to throw the confidentiality guarantee* of a VPN out the window. As can Happy Eyeballs, where the same HTTP request is sent by both Legacy IP and by IPv6; if both aren't sent through the tunnel, confidentiality is lost.

    To deal with this, the client can implement mitigations, such as setting a different DNS nameserver, as well as the (IMO exceedingly inappropriate) measure of disability IPv6 outright. These are not functions which the built-in VPN client in the OS would necessarily do, although some OS network managers genuinely will do a good job. But even more important than applying mitigations is to check for leaks! The client app can run periodic tests to make sure DNS or IP packets are always going down the tunnel, such as by checking destinations that only exist through the tunnel. Failure to pass this test should throw up huge warnings that the user's confidentiality may be imperiled. This is table stakes for a retail VPN service in 2026.

    Finally, UI/UX for a VPN requires that the whole thing be easy: users want to browse the web, download ... uh... Linux ISOs, and go about their life with a VPN that Just Works (tm). Most people do not want to copy a Wireguard config into the OS using a terminal. A VPN service should have broad appeal, since the fear mongering advertising suggests it's a product that everyone online should use.

    At bottom, we can say that "retail VPNs" really do need a client app. But for technically minded folks, a Wireguard config would be enough, because the endpoints would also be configured to route solely down the tunnel. Or even use an isolated netif, in the case of Linux namespaces, which is IMO quite clever.

  • Another word of caution: bisection will have a rough time navigating around merge commits, because those introduce nonlinear "forks in the road" that also tend to be introducing large, possibly-breaking, non-trivial changes. But if your workflow is already avoiding merge commits except when necessary, then the drawbacks are minimized.

    Yet another reason to prefer linear history in Git whenever possible, because bisect will work more predictably.

    That said, if you're needing to use automatic bisection very often, this may point to a lack of a CI pipeline to validate commits automatically. After all, if a broken change is flagged before you notice, then you wouldn't need to bisect because the system has identified the faulty commit.

  • Would cert-manager for Kubernetes be approximately what you're looking for? In that particular case, it's a service that runs in a K8s cluster, that can auto-request CSRs and send them to Lets Encrypt using one of the challenge types. It takes care of managing the returned certificates, such as renewing them before expiration and registering the private keys within the K8s key store.

    I presume that you're not already using K8s, so maybe that project will help you find the keywords to describe the sort of certificate manager that you want.

  • If you're already using Debian on desktop, then Debian on a VPS makes sense from a maintenance perspective: you only have to track one set of security updates. When there's suddenly a critical update for some vulnerability, you can update both at once because it's the same upstream repos. Whereas with Ubuntu on your VPS, you'd have to be mindful to make sure to check back when the same vulnerability is patched there.

    Do not underestimate the effort to upkeeping a server, and do try to unify your procedures so you're spending less time doing the necessary things, and more time building up your self hosting stack.

  • Deleted

    Permanently Deleted

    Jump
  • I vaguely recall seeing (what I hope was) a joke where the C preprocessor allowed the use of Old English in lieu of the typical keywords. I can't seem to find it right now.

  • Deleted

    Permanently Deleted

    Jump
  • I'm surprised they don't lock some things behind account logins. Is it that hard to decide what would be acceptable to no longer serve without an account?

    From this most recent event, such a policy would probably need to be proposed and voted on, if the voting members of Codeberg want it that way.

    The way I read their post, it's doing double duty: the first is the announcement of the ToS changes. The second is laying out their overall position, because -- by their own words -- LLMs are controversial and with this announcement, they are pushed into a discussion where not everyone is on the same page. Should the LLM problem continue to get worse for Codeberg, their post is fair warning that future measures might be proposed and voted on. No one should believe that the two ToS changes alone have fully mitigated the LLM problem for Codeberg.

    And I think that goes exactly to their point about communities: Codeberg fosters human communities, unlike LLMs that embody nothing, and GitHub that is commercial with a free tier. If something is going to change, it will be by community discussion and decision. In that sense, their radical transparency is exceptional.

  • I'll offer a comparison not yet mentioned in the context of hosting software, but which should sound familiar in the social media context: moderation is hard at scale.

    By every metric of scale, Codeberg is a competitor to the behemoth that is GitHub. And that means they have to contend with tough choices, such as who and what to host on their servers, no different than BlueSky, Facebook, and the individual instances of the Fediverse. And to be clear, Codeberg has always been limited to FOSS projects anyway, so nobody can genuinely argue that limits weren't in the cards.

    The distinction is that less alike Meta, and more alike with the Fediverse, Codeberg takes no hostages: people with obvious AI repos (or even marginal repos, given the possible ambiguity) are free to take their code and leave. Yes, they have to rebuild their CI pipelines, but that's always required for any platform, including self hosting.

    The fact is that Codeberg is a centralized entity that needs to (try to) make consistent policy. In this case, they have a concern about copyright and nothing anyone says can magically dematerialize that risk. If their new policy is not agreeable, then decentralized self hosting is probably the only way forward. But that was always an option with ForgeJo and federation.

    And indeed, folks moving from GitHub or elsewhere are not exactly without fair warning that they might have to migrate again; we've not reached a utopia yet.

  • By what criteria do you say that? You might be right, but without any qualification for how one might be better than another, it's as useful as saying "purple is better than yellow".

    But ultimately, you're looking for a moderation paradigm and don't owe me or anyone else a criteria or explanation for what you ultimately choose. It merely means that the question as posed is unanswerable, no different than "why is green the best color?".

  • "best" is relative, and while moderation can achieve a great deal of success on a smaller scale, it's proven to be extremely tricky at large scale. Mike Masnick of TechDirt (and on the BlueSky board of directors) has documented this rather well, using some very notable case studies.

    For example, moderation is both necessary and complex (Twitter post buyout): https://www.techdirt.com/2022/11/02/hey-elon-let-me-help-you-speed-run-the-content-moderation-learning-curve/

    Decentralized moderation like Mastodon is good (by blocking Gab from the get-go) but requires active coordination from federated operators: https://www.techdirt.com/2019/07/16/gab-mastodon-challenges-content-moderation-more-distributed-social-network/

    At a slightly larger scale, volunteer moderators can be overburdened and lead to adverse infrastructure shutdowns (Parler getting bumped for violating AWS policies): https://www.techdirt.com/2021/01/13/parlers-laughably-bad-antitrust-lawsuit-against-amazon/

    My point with these examples is that a moderation system solely based on volunteer effort can be: 1) overwhelmed, 2) manipulated, or 3) antithetical to the purposes of the community and/or platform. There is no magic moderation system that will be 100% effective for your environment at all times.

  • in doing preparatory refactoring, adding the feature, adding tests, and his can be easier to review because the scope of each commit is smaller.

    This is the use-case I hadn't considered. And it makes sense now that I think of it. Though I personally haven't come across it, since I don't typically work on multiple, cascaded features at a time. Most of my work as been with waterfall models, so I can understand that other approaches may indeed have cascading features in parallel.

    Thanks!

  • TIL git history.

    That said, I'm trying to figure out what the target workflow is, specifically for the "autorebases all your branches to match" functionality. Assuming we are not talking about rewriting published history -- and nobody should ever really be doing that anyway, when multiple commiters are using the same branch -- I presume this is a situation where the dev has multiple, unpushed features that are WIP, each in their own local branch and building on each other. The trouble I'm having is the number of commits per feature.

    If the number of commits per feature is 1, then that means each branch just has one commit that its dependent branch doesn't have. What is the point of the branch then? Just have a single WIP branch and keep building a linear commit history. If you need to give someone one of the features, then give them the commit which inplemtns that feature and nothing afterwards.

    If the number of commits per feature is >1, then this is certainly more difficult to work with, and the appeal of git history starts to shine when dealing with WIP commirs. But why is the dev in this situation, where they're building multiple dependent features but they're none are fully complete yet? Because if they were complete, then I presume the dev should squash the commits so the number of commits per completes feature is 1.

    My current thought is that having >1 commits to implement a single feature is a transient condition, and good practice is to get to 1 commit per feature. Is there something I'm missing?

  • This blog post is a wandering train of thought on the topic of what tools are and why it matters to be even slightly more mature in how we think about them.

    That's the second sentence, and it's fairly clear that the author means to start the discussion of the titular topic, not to conclusively explore every ail of AI. Of which there are many, yet enumerated.

    Some people call this "food for thought"; I would agree.

  • Deleted

    Permanently Deleted

    Jump
  • Deleted

    Permanently Deleted

    Jump
  • I would say that the crucial pillars of embedded work are: mastery of C, computer architecture, and data transfer. I say this because most embedded challenges can be framed in (and often are written in) the C language. The same problem-solving approach for C is very similar to solving problems in a microcontroller. I put specific focus on pointer arithmetic and alignment, because although higher level languages take care of these things automatically, it has to be handled eventually at the lower levels, usually by the embedded engineer.

    For everything that isn't C, the next set of challenges are in integration: rarely does a microcontroller run on its own. It might coexist with a host computer, have its own serial interfaces or other peripherals, access memories or sensors through complex buses, and some even have a quantity of DDR (with all its required supports). I don't think it's absolutely necessary to enter the field knowing the ins-and-outs of ARM's AXI bus or how PCI/PCIe transactions propagate through a tree. But knowing the inspirations for commonplace things like Virtual Memory, IOMMU, DMAs, and memory bus width, those are foundational.

    Finally, there's always data transfer. Some data here needs to go over there. This can include actual networking protocols (eg TCP/IP, WiFi, ZigBee) but can also be point to point (I2C, RS232). This is probably the part where people entering the field have to be generalists: there are just so many different ways to transfer data that it's basically impossible to study them all in advance. Instead, some things are common to all transfers: a specification of the start and end of the payload, why headers or sync patterns are used, error correction, medium arbitration, reliability guarantees (if any), and API considerations (eg conformity to BSD sockets).

    To be abundantly clear, embedded is very hardware oriented. In my time, I've seen a lot of Electrical Engineers and even Mechanical Engineers successfully make the leap over to embedded software, because they already have the ability to efficiently absorb knowledge from data sheets and specification documents, and will work within the absolute limits given. If there is the aptitude to dive very deep into the details, to find truth where everyone else sees "magic", then embedded will not be too difficult.

  • Deleted

    Permanently Deleted

    Jump
  • I'm an embedded software engineer, and IMO embedded software has the benefit and curse of being not-very-sexy, in comparison to web developers or database engineers or backend engineers. That is to say, it's really easy for front-end engineers to describe their work, because it'll be something that people have seen (eg a website, or a service like Netflix). And even for backend engineers, they can analogize to fields that are well-known, such as administration or utilities (ie everything goes to poo if the sewers fail).

    But embedded engineering is a tough one to explain, and that also means prospective employers might not even know that they need an embedded engineer for their Whizz Bang 3000. It's not at all intuitive to most folks that there's a separate set of skills necessary to program a screen-less, keyboard-less, network-less tiny CPU that might not even run an OS.

    On the flip side, it means that the job is fairly specialized and thus valuable. Most software engineers could probably figure out how to program a microcontroller using C, but the most talented embedded engineers can achieve the same in the smallest memory footprint, thus saving hardware costs. To shave off $1 off the cost of a product that will sell hundreds of thousands, that's something that companies will pay for.

    Embedded is diametrically opposite of application development: basically everything is under constraints (eg RAM, CPU time, I/O, interfaces) and we just have to deal with it. At its core, the occupation seeks to do the most number of things with the fewest resources. Not everyone has to skills to optimize this hard, to strip down software to only its abject requirements.

    I can't speak as to what any particular job markets looks like right now for embedded engineers. But given that the need for embedded software does not ramp up during hype cycles, I think it tends to be a fairly stable occupation. The trick is that it's not a huge market everywhere, so moving for work might be necessary.

    TL;DR: embedded software is a small but stable occupation, IMO.

  • What is the absolute simplest way to accomplish this?

    < gets on soap box>

    The absolute simplest way is to use IPv6: on your Debian machine, assign multiple IPv6 addresses, one for each service you want to expose to your LAN. There's no penalty with having a dozen v6 addresses.

    Although you have those addresses, your machine generally uses just a single one for its own outbound and inbound traffic. For each service, you would edit their config so that they bind to a specific IPv6 address. Finally, you would configure an AAAA entry in DNS so that your chosen subdomain will point to the IPv6 address in question.

    As an example, suppose you had three different web servers running Nginx, currently on port 80, 8081, and 42069. What you would change is the server config for each server instance, adidng the IPv6 address as part of the "listen" directive. Since each instance is now bound to a different IP address, nginx can now listen to the conventional port 80 and n'ary will the three collide. In other software, the configuration option you're looking for is the "bind address". By binding each app to its own IP, it will only respond if you send a request to that IP (or DNS name, which translates to an IP); this conveniently makes debugging really easy.

    For a home network, you might have a single /64 IPv6 subnet. But that still means you literally have billions upon billions of addresses to use before you ever run out. And as you've recognized, using DNS names to identify services is a lot easier and intuitive than using port numbers. It also neatly avoids the need to memorize IPv6 addresses, because that's never been necessary: we have DNS.

    If your ISP won't give you IPv6, you can still use locally-assigned private ranges, known as ULA, and this works because your services are contained to your LAN. Best practice is to randomly generate a subnet then use it.

    < gets off soap box>

  • Melodic dubstep when I'm debugging, metalcore when I'm developing new code.

    I can't do lyrics when I'm working with GDB, and the gutteral screams help me maintain my composure as I quietly swear at the prior maintainers for leaving me with a poor foundation for my new code.

  • TUI users have much less tolerance for "lag"

    In a lot of ways, I think software that harkens back to an older era understood the assignment exceptional well: when you're working on a glass TTY attached to a 9600 baud modem via a microwave network to the university computer in the next state over, the latency from the connection itself was pretty bad. So to then have inefficient software that "lags" would be intolerable.

    Fast forward to the present day, with broadband and 1 ms latency, it's less of a concern, sure. But good software remains good software, even if the environment has improved. And for some, my work often travels with me aboard the train, where the congested 4G backhaul really makes me appreciate the miserly bandwidth of vim and SSH.

    I also find myself reconfiguring systems that only have no editor installed except VI (and sed, lol) due to disk constraints. So while the command set is grossly reduced from vim, they have similar commands and workflows that I can maintain proficiency even in these sparse environments.

    "Lowest common denominator" software definitely has its use-cases.