The brilliance of the McMaster-Carr website is best appreciated when viewed alongside the print version of the McMaster-Carr catalog. As a child, I literally grew up on that bright yellow book, since my parents used it as my booster seat for the kitchen table. It is a thick tome, second only to the thinner Grainger catalog, which became the next booster seat after a few years.
- Posts
- 4
- Comments
- 237
- Joined
- 3 yr. ago
- Posts
- 4
- Comments
- 237
- Joined
- 3 yr. ago
TIL finite state transducers. The BurntSushi blog post is now in my browser tab queue. Thanks!
This blog post comes to me at an interesting time, for I've been gathering info to rebuild my router using FreeBSD. Specifically, I bought a hard-copy of The Book Of PF, 4th Edition, for configuring PF for routing and firewalling. Like with all good firewalls, the PF rulesets start with blocking all traffic. But unlike the VyOS-based rules used by my outgoing Ubiquiti router, PF does not implicitly include rules for common use-cases, such as enabling hairpin NAT for Legacy IP. Nor does the syntax assume that rules are only for inbound, as the shortest syntax will actually apply a rule in both directions on every interface.
To that end, one of the tenants for configuring a PF firewall is to also filter outbound traffic, as a matter of: 1) asserting control over the network, and 2) implementing the principle of least privilege. I can reasonably accept that my home's guest WiFi network should be fairly free flowing for outbound traffic, but that shouldn't apply to my IoT VLAN. Quite frankly, my IoT VLAN only allows outbound connections to four specific NTP servers hosted by ntp.org, because my thermostat has a badly-designed real-time clock and I refuse to allow network access for devices that historically never needed it.
Before containers, firewalls implemented the DMZ idea, where any host that runs an externally-accessible service would be within the DMZ, to prevent infiltrating the broader LAN if something goes wrong. Your solution achieves a sort-of DMZ, but does it at the Docker host. Whereas a true DMZ would segment the rest of your network off, so as to further reduce risk, since iptables is the only line of defense.
That said, zooming out, this caught my attention:
The breaking point came when I wanted to host Gemini FastAPI, a project that wraps Google’s internal Gemini API into an OpenAI-compatible interface, useful for using your Gemini Pro subscription outside Google’s walled garden. The catch: it needs your browser cookies, which means full access to your Google account.
The very premise of Gemini FastAPI seems flawed to me, if it's trying to create a wrapper when Google clearly does not want that to exist. The challenges that you observed, such as the brittleness of IP allowlists, would suggest to me that the overall endeavor is going to be brittle, by Google's design.
To be clear, that doesn't mean you shouldn't pursue this, in the same way that yt-dlp exists for the legitimate use for accessing YouTube. But what both yt-dlp and Gemini FastAPI will never escape is that they only exist because Google hasn't cracked down on it further. When every indication is showing that this is the road with even more trouble beyond the next curve, is this what you want to invest time and effort into? There are other platforms and protocols that replace YouTube, or at least minimize one's dependency on a clearly antagonistic host.
At bottom, I think the question is whether connecting to Gemini is really worth all of this trouble, when they evidently don't want you to do this, and it adds yet another dependency upon Google. Even if you believe Google is 100% benevolent and their lack of a built-in support for using Gemini externally is just a minor oversight, you will have to pick which services you will base your own infrastructure upon. This is, after all, c/selfhosted.
- JumpRemoved
Use Protocols, Not Services
The premise is good, but the linked article is too short to explain why protocols encourage decentralization, which protects against authoritarism, censorship, and promotes bona-fide free speech (not to be confused with "BuH mAh FrEe SpEeCH!" morons that only like free speech when it agrees with them and don't when it doesn't).
For a more lengthy discussion, which includes Internet history, the legacy of the USA's Section 230 of the CDA and how that impacts the modern web, and what precisely a protocol should avoid doing to successfully achieve the goal of practical decentralization, Mike Masnick's 2019 paper "Protocols, not Platforms" is particular apt.
Yes, I know I've mentioned him a number of times in my comments, but there aren't too many people who are abreast of technologcal history, the legal framework surrounding the internet, and are skilled writers to condense into words the necessary clarity upon which to build an internet that works for everyone, not just the rich or few.
As a note, BlueSky was directly inspired by his paper and he now sits on the board of BlueSky. Is that antithetical to his 2019 paper? I don't think so, since commercial success of a protocol is how it has staying power: Amazon's S3 API, email's SMTP, and QUIC are all examples of protocols where everyone benefits by their ubiquity, but they had to be commercialized first, by the likes of AWS, AOL and CompuServe, and Google. BlueSky's opponent is not another protocol like ActivityPub, but rather they challenge the platform formerly known as Twitter. The very existence of a bridge between the ATmosphere and the Fediverse proves that platforms are the real enemy, and we all need to keep that in mind.
No enemies to the left.
Your understanding is not wrong, but "within namespaces" is doing a lot of the heavy lifting. After all, there isn't just one namespace but many simultaneous namespaces at play. A process namespace is where process IDs (PIDs) begin from 1 and fork()'d processes are assigned incrementing PIDs. These values are meaningless outside of the namespace, and might even get mapped to different values in the parent namespace. A process namespace gives the appearance that the process with PID 1 is the init process, which is customarily the first userspace process started once the kernel is running.
There are also network namespaces, where network interfaces (netif) can be switched (Layer 2) or routed (Layer 3), independent of what the global/default/parent network namespace is doing. This gives the appearance that all the network configuration is wholly independent, and allows neat things like crafting specialty routing (eg Kubernetes overlay networks).
Then there are user namespaces, where the root user has the appearance of total authority, and normal users can be created, but these are entirely distinct from the global/default/parent users and groups on the machine. This pairs well with filesystem namespaces, where a sub-tree of the real filesystem is treated as though it is a full tree, which allows the namespaced users to do standard manipulations like changing file ownership or permissions. This is essentially what UNIX chroot() does, but IIRC, chroot() did not also create user namespaces.
Taken together, namespaces in Linux are less about isolation -- although they certainly work for that -- and more about abstracting everything else in userspace away: no need to deal with other people's processes, netifs, files. It's like having the whole machine to yourself. In the history of computer science, isolation is often achieved precisely by making everything else invisible and out of the way. Virtual Memory did that, as did x86 Protected Mode, as did Virtual Machines. And so too does namespacing. Containers are the result of namespacing all the key kernel interfaces.
Perhaps the crucial thing then is what interfaces aren't namespaced. In Linux, a big one is device drivers. Folks that want to share a USB TV capture card or a PCIe GPU or even a sub-NIC using SR-IOV, will find that /dev files are not namespaces. They exist in the global space and aren't isolated. So the only thing that can be done is to pretend to "move" the device file into a container, with everyone else promising not to try using that device anyway. This is not isolation because accidental or malicious action will break it. To do "device isolation" would require every driver to be namespace aware, so that it could treat requests from two different namespaces as distinct. That does not exist at all in Linux, and such low-level work continues to be difficult with containers, often surprising people that think that Linux containers are complete abstractions. They are not.
There are terminology issues here, both in the Lemmy post title, in the article body, and in the article's TL;DR. Basically, nothing is internally consistent except maybe the OCI Runtime spec itself, although its terminological relevancy is a separate issue.
Lemmy title: Containers are not Linux containers
Article title: What Is a Standard Container: Diving Into the OCI Runtime Spec
Both titles imply the existence of non-Linux containers, yet only the latter actually describes the contents of the article, specifically naming the "other" type of container, being "Standard Containers" defined by the OCI Runtime spec. As a title, I greatly prefer the latter, whereas the former is unnecessarily antagonistic.
That aside, the article could really be helped by a central glossary section, as it refers to all of these as containers, without prefacing that these can all validly be called "containers":
- OCI-compliant containers
- Standard containers
- Linux containers
- Docker containers
- Kata VM-based containers
- Other VM-based containers that have been deprecated
If the goal was to distinguish what each of these mean, the article doesn't do that great of a job, other than to say "these exist and aren't Linux containers, except Linux containers are obviously Linux containers".
Reframing what I think the article tried to convey, while borrowing some terminology from C++/Python, the OCI Runtime specification defines an Abstract Base Class known as a Standard Container. A Standard Container supports the most minimal functions of starting and stopping an execution runtime. For Linux, FreeBSD, Kata, etc, those containers are subclasses of the Standard Container.
For the most part, unless your containerized application is purely computational and has zero dependencies upon the OS, your container will be one of the subclasses. There are essentially zero practical container images that can meet the zero-dependency requirements of being a Standard Container. So while it's true that any runtime capable of running the container subclasses could also run a Standard Container, it is of little value in production. Hence why I assert that it's an abstract base class: it cannot really be instantiated in real life.
This is the reality of containers: none can abstract away an application's dependency upon the OS. The container will still rely upon Win32 calls, POSIX calls, /proc, BSD sockets, or whatever else. So necessarily, all practical containers need a kernel layer. Even the case of Kata's VM-based containers just mean that the kernel is included within the container. Portability in this context just means that the kernel version can change beneath, but you cannot take a Linux container and run it on FreeBSD, not without shims and other runtime kludges.
The Linux kernel itself doesn't really express an opinion -- it's a kernel, it enables you to do most things -- but it's Docker itself that imposes an opinion. And I say this after Docker Engine has basically delegated the runtime to containerd. At bottom, Docker has some serious baggage that needs to eventually be addressed, chiefly IMO the sorry state of networking.
What was done to make Docker usable initially has reared its ugly head a decade later, such as a focus on only supporting Legacy IP and NAT, with very little regard for IPv6. For example, Docker does do IPv6 today but only with NAT66 and zero support for DHCP6-PD upstream routing. This makes it incompatible to how actual v6 networks are set up, where NAT is neither desirable nor necessary. Docker's idea of networking is so very 1990s that it's genuinely stifling any improvements beyond the server/client TCP/UDP model.
All the meanwhile, Kubernetes is built atop sensible networking on Linux, and the BSDs have had solid networking primitives for decades. Linux is not the problem, IPv6 is not the problem, BSD is not the problem; it's just Docker being stuck because of a lack of vision and too many users dependent on the existing behavior.
Credit where it's due, Docker images defined as files and stores as artifacts in a central repository are a genuine innovation, and that's precisely what BSD Bastille brings to BSD jails. So in 2026, where the OCI specification has genericized Docker images, anything that's Docker-specific is slowly losing relevance.
The short answer is that Linux did not approach namespacing from a holistic view, but rather introduced each one at the time when they were deemed useful individually or necessary. Meanwhile, the BSDs looked at what they had from UNIX (ie chroot) and then thought about the fullest logical extent of that idea. And in doing so, looked at every kernel interface and added support to namespace (or jail) them all.
Sure, BSD jails have had their own bugs over the years, but as a design, it's an incredible testament to building a framework that was ahead of its time by focusing on the fundamentals.
To be clear, there are sometimes use-cases where Docker containers are ran without creating separate namespaces (eg sharing the host's network namespace) but it's rarer than the equivalent in BSD jails, where it's a neutral choices between isolate or reuse namespaces. In that sense, Docker is lightly opinionated into defaulting to all-isolation and makes it hard to remove all the layers, if that's your jam.
Setting aside the Forgejo issues for a moment, I can't quite see the logic behind the author's description of a "carrot disclosure".
As written, it's a third option for disclosure, beyond 1) coordinated disclosure (often 90 days for the vendor to fix things) or 2) full disclosure (immediately going public, esp when the vulnerability is believed to be actively exploited). But what the author describes as the carrot is to publish only the output of a proof-of-concept, and then the onus is on the vendor to figure out both the vulnerability and the fixes.
This seems wildly irresponsible to me, to put the effort into writing a working PoC but then to willfully withhold it, so as to basically force the vendor into a wild goose chase. And that's the best case scenario, when the PoC is actually legit. At worst, it's a DoS against a vendor (causing them to re-audit code to find a bug that doesn't actually exist, eg hallucinated AI slop) or is a form of defamation to scare users away.
Then there's the issue of when it's not a "vendor" per-se but a group of volunteers of an open-source project, which I will distinguish from commercial vendors as "maintainers". Is it ethical to withhold an already-written PoC from FOSS maintainers, whom often do not have the material capabilities to do a full-scale audit when given basically no clues?
To be clear, I'm not a security researcher and have done zero disclosures of any form. But if I ever ran a project and received a so-called carrot disclosure, why shouldn't I immediately call their bluff and treat it as full-disclosure? This situation seems like Schrodinger's Cat, where the only way to rip away the uncertainty is to throw open the box. Worse case, the project suffers the reputational hit for having a legit vulnerability. But best case, the vulnerability is non-existent. But what this supposed "third way" purports to do is no different than sowing the seeds of fear, uncertainty, and doubt amongst users. Someone tell me how this isn't one step away from extortion.
I think game theory would say that any and all recipients of "carrot" disclosures should always call the bluff, immediately and vocally. I don't see any way for such disclosures to be anything but unnecessarily antagonistic. I refuse to credit the term with any legitimacy.
For pointers in particular, this seems like a good starting point: https://sites.cs.ucsb.edu/~mikec/cs16/misc/ptrtut12/pointers.htm
As for compiling for old C/C++ versions, fortunately most compilers can be set to restrict what standard they will compile for. So you could turn the compiler all the way back to something like C99 and it should work, although you'll have to avoid using modern syntax.
That said, with regards to compiling for an old platform, be advised that complete and functional toolchains will be harder to come across. They may not even work anymore, if they haven't been upkept. That's another complexity that you may have to deal with, and it will no doubt be aggravating, than working with a modern platform but limiting yourself to only older C/C++ standards and graphics libraries.
Basically, the starting effort is quite high for developing for older targets. Be certain that this is the direction you want to start with.
For my information, what does TLV stand for? I imagine it's an acronym about repeat business, but I can't parse it. Total Lifetime Value? Tag Length Value?
This distinction is both illogical and ahistorical. Python is a scripting language that has a compiler. Indeed, any scripting language can be translated into a compilable language and then compiled, a process called transpiling.
There's also Java, which definitely compiles down to bytecode, but for a machine which physically doesn't exist. The Java Virtual Machine is an emulator that runs on supported hardware, in order to execute Java programs. Since the Java compiler does not produce, say, x86 assembly, your definition would assert that Java is not a compiled language, despite obviously having a compiler.
As an exercise for everyone else, also have a look at Lisp, a very-clear programing language with a compiler, but some specially-built machines were constructed that optimized for Lisp programs, with hardware support to do checks that would take longer on other architectures.
- JumpDeleted
Permanently Deleted
Citation needed
- JumpDeleted
Permanently Deleted
Code has never been able to be copyrighted. You cant copyright a for loop. I cant create a car class that has properties like make, model, year and copywrite it. Thats never been a thing. Thats why projects are copyrighted. An entire piece of work.
Every single complete sentence in this quote is factually wrong, under both USA copyright law and international copyright law.
Copyright accrues the moment that some work is rendered into a fixed format, such as a sheet of paper but also includes a computer text file. Writing a "for" loop as a homework assignment does create copyright. Ten students writing their homework all create their own copyright, even if the result is coincidentally identical. This isn't even a point of serious doubt in the law: copyright is very much an exercise of provenance, not of bitwise comparisons.
From when a work is created, every transformation, edit, or addition must all occur within the parameters of some sort of license from the copyright owner, or else an infringement has occurred.
Two people may stand at the same position at the foot of Mt Whitney in California and set up their own camera, one after another, on the same tripod to take the same frame of the scenery. And under copyright law, each owns the copyright to their own photo. One may decide to sell their photo and copyright to an East Coast newspaper, while the other has theirs committed to canvas. The newspaper may not assert a copyright claim against the canvas owner, and the canvas owner cannot assert a claim against the newspaper.
Please be considerate: how would anyone know that you meant your last post? Why not the last post on c/programming? If you're asking a question, please try to make it easy for people to answer. A link is easy to add and avoids ambiguity.
When you say "the last post", please link to it since different people have wildly different client settings that may not show every community's posts in an adjacent fashion.
Glad to see this! And thanks for getting back to me.
Btw, is there a presence for the project on Mastodon? I'd like to follow along on new stuff in this space. Or even an RSS feed that can be pulled by a bot on Mastodon?
Seems like that'd be a good match for this place: https://www.bbc.com/travel/article/20260402-the-floridian-beach-town-that-looks-like-santorini
I only discovered "sink plungers" in the last year, and they've been remarkably effective for my uses. What usually ends up happening is that the blockage is brought up into the sink, at which point I vacuum it out with a wet-dry vacuum.
To be effective, the emergency drain hole of the sink needs to be plugged first, and then the plunger can do its work. Note: things will get gross and messy. Don't attempt if there is still drain cleaner in the pipes, since it will spray out.
There are subscription costs for homelabbing?