#+TITLE: bsd #+AUTHOR: Michał Sapka #+URL: https://michal.sapka.me/unix-history/ #+STARTUP: show2levels indent logdone #+HUGO_BASE_DIR: ~/ghq/michal.sapka.me/mms/site #+HUGO_WEIGHT: auto #+HUGO_SECTION: bsd * BSD :@bsd: :PROPERTIES: :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :primary_menu bsd :EXPORT_HUGO_MENU: :menu bsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :image_dir "bsd" :image_max_width 600 :EXPORT_HUGO_PAIRED_SHORTCODES: image :END: ** DONE Michal's Guide to BSD CLOSED: [2024-03-06 Wed 14:45] :PROPERTIES: :EXPORT_FILE_NAME: _index :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract A site dedicated to BSD family of systems :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :noreturn yes :EXPORT_HUGO_PAIRED_SHORTCODES: menu :EXPORT_HUGO_MENU: :menu bsd-null :END: #+attr_shortcode: "bsd" #+begin_menu Dune #+end_menu ** DONE Why I run a BSD on a PC :@bsd: CLOSED: [2024-05-01 Wed 21:48] :PROPERTIES: :EXPORT_FILE_NAME: why-bsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract Reasons why BSD may be the best OS for you :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :menu_item_override "Why I run BSD on a PC" :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :menu_item_override_start_li true :EXPORT_HUGO_MENU_OVERRIDE: :post "but" :END: There's multitude of Operating Systems to choose from. You may have been using something like Windows or MacOS and be perfectly happy with it. You can step up and use Linux, Haiku or even Amiga OS. So, why do I think a BSD system may be a great choice? *** Freedom The most popular systems out there are proprietary. This has the small downside of having to pay, but there's another one. Closed systems have tendency to limit the user. It's much more visible with MacOS than in Windows, but the user is always blocked from doing what the user wants to do. Are you following the product manager's ideal path? Is web browser everything you need to run? If so - getting something from Silicon Valley may enough. But a lot of us are hungry for more; we want to be in control instead of being controlled. FreeBSD and GNU/Linux give the user a huge power to adjust itself to the needs and wins. *** License One of the reasons for choosing BSD are the legals term under which all BSDs are provided - the BSD license. It differs strongly from what GNU and others propose. While also being "freedom respecting", it does not limit anyone. Want to create a closed source fork of FreeBSD and stop giving anything back after few short years? Don't want to have your hands tied by GPL? Are you Apple? Because that's how MacOS X started. BSD licenses are amongst the most liberal one. The standard "[[https://opensource.org/license/bsd-3-clause][3-Clause BSD License]]" limits only the liability of the code provider. Some say that BSD License are a problem as companies may take and never give up (like Sony did for PS4), but it's as close to the idea of "Free software" as it gets. *** No BigTech As a result of this, there is very little interference from Big Tech. While Linux is happily in bed with the likes of Microsoft, Google, who are able to steer the development, BSDs are still very much a niche and independent product. Just look at list of sponsors of [[https://www.linuxfoundation.org/about/members][Linux Foundation!]] In BSD-land we've got some big players, with Netflix being the most prominent one. But the cooperation is very much on partner terms. Netflix gives back, but it does not dictate the direction. *** A designed OS But the biggest differential factor between BSDs and GNU/Linux is the way it is structured. #+attr_shortcode: :file run-bsd.png #+attr_shortcode: :alt White, all caps "Run BSD" over black background #+attr_shortcode: :class pull-right #+attr_shortcode: :forced_width 200 #+begin_image RunBSD #+end_image In Linux, all components are designed to work together, but are completely separate. You've got the kernel, init systems, multimedia daemons, userland, bootloader, virtualization and containerization mechanisms, package managers, and so on. They are all separate projects with their own goals and are operated by separate entities. This is why we've got different Linux Distributions instead of Operating System. Everyone can take the kernel, start adding components on top of it, and a few minutes later the distrowatch is even harder to keep up with. Each BSD on the other hand is designed as single system. All components are created and developed together. Things work together perfectly, because they are designed, coded, tested and released as one. When you install any BSD you are getting the complete package. *** Build-in technology To give just two examples here: 1. OpenBSD comes with complete web stack built in. We've got a packet filter (best in class), reverse proxy and http server. We've even got a TLS certificate manager. The configuration of all those use similar format, whish is fully explained in man pages. You don't need any external packages. And the security of each of those is as high as rest of the OS. All things work together in perfect harmony, as it is designed as such. 2. FreeBSD comes with ZFS. One thing this file system provides are efficient and bullet-proof snapshots. The developers of FreeBSD used it to create the idea of boot environments - a snapshot of OS. The user can easily boot from any of those in any moment. Even the standard update process creates a new boot env, just in case something goes wrong. Such integration would be very hard to achieve without up-front design. And the list goes on: Jails, Beehive, Vnet, Dtrace, Ports system, OpenSSH, or Libre SSL. The crazy folks over at OpenBSD are even working on their own version control system called [[https://gameoftrees.org/index.html][Game of Trees]]. You can find a great deep-dive into FreeBSD tech on [[https://vermaden.wordpress.com/2020/09/07/quare-freebsd/][Vermaden's site]]. This has the added benefit of having the entire system codebase in a single place. One needs to follow only a few repositories to be up-to-date and informed. Mind you, those are /gigantic/ repositories, but if you are smart enough[fn:src] - it's there. *** Documentation Speaking of documentation, all BSDs have amazing docs. In GNU world a lot of people were discouraged from man pages, as the quality is not there. In BSD land the manuals are top-notch and are treated as integral component of each program, and therefore the OS. Just take a look at the aforementioned [[https://man.openbsd.org/httpd.conf.5][Httpd configuration]]. The man pages don't end here. You can compare how termios is described in [[https://man.freebsd.org/cgi/man.cgi?query=termios&apropos=0&sektion=4&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html][FreeBSD]] and in [[https://man7.org/linux/man-pages/man3/termios.3.html][Linux]]. Quite often I am finding that the provided offline manual are more than enough. You can also check the amazing [[https://docs.freebsd.org/en/books/handbook/][FreeBSD Guidebook.]] FreeBSD has a dedicated [[https://www.freebsd.org/internal/doceng/][Documentation Engineering Team]] and their work add immeasurable value. *** Community and culture And not only them. Occasionally when I wrote something dumb, instead of being screamed at, some maintainer reached out to me and gathered feedback or explained the thing I was missing. When the people developing the OS have such attitude, BSD community is also infected by this positivity. Yes, like everywhere, there are some bad eggs, but its nowhere near the OS wars we're seeing in GNU/Linux or proprietary systems. This may be a result of the fact, that BSD users tend to be much more experienced - it's not the type of OS which people randomly install. More often than not, using BSD is just a next phase after being involved in Linux. Also, it seems hard to be /only/ focused on BSD, so people being paid to do BSD work tend to do the same with GNU/Linux. All in all, I found the crowd to be very welcoming of new people. #+attr_shortcode: :file openbsd.png #+attr_shortcode: :alt A yellow fish named puffy over the text - OpenBSD #+attr_shortcode: :class pull-right #+attr_shortcode: :forced_width 200 #+attr_shortcode: :transparency yes #+begin_image OpenBSD #+end_image You can find amazing people over at [[https://wiki.bsd.cafe/][bsd.cafe]] or [[https://bsd.network/][bsd.network]]. The oldest public UNIX system, [[https://sdf.org/][SDF]] is running on NetBSD and quite a few of it's members are active in BSD community. There's also [[https://mwl.io][Michael W. Lucas]] who makes a living writing AMAZING technical BSD-related books. And we've got a great dedicated podcast, [[https://www.bsdnow.tv/][BSD Now]]. There's also a community bulletin board - [[https://www.unitedbsd.com/][unitedbsd]] *** POSIX and widening perspective The one thing that is not welcomed, however, is change for the sake of change. All BSDs take portability very seriously and follow POSIX closely. You won't find craziness in the base install, like ZSH or even Bash. FreeBSD only recently migrated root shell to Bourne Shell sh(1) from tsch(1). I'm sure a lot of people have never used those despite living in a POSIX-compatible (or even certified) OS. Only after daily driving BSD, I started to appreciate following POSIX and not using bashisms. *** OSes, not distributions However, one thing which took me some time to understand was: why do we have those different BSDs instead of a single one. Well, OpenBSD, FreeBSD, NetBSD, and DragonFly BSD are separate operating systems that have forked from each other[fn:hist]. They are developed separately and have separate teams. And even though the code very often migrates between them, they are not the same. Just an example: PF, the great packet filter was developed as part of OpenBSD. It was then ported to FreeBSD. It worked great, but with time, it diverged from the OpenBSD's one quite significantly, and all those changes had to be ported again, just recently. Since OpenBSD and FreeBSD grew out of Unix, they are binary compatible, but their kernels differ significantly. FreeBSD and OpenBSD have different goals, and therefore are diverging more and more. Packet Firewall needs to be fast, so it needs to interact closely with the kernel. This means that all attempts to align PF on these systems requires significant effort. Another example: ZFS. It's a staple of FreeBSD, it's integrated deeply into everything. But it was never ported to OpenBSD. In fact, it may never be forked, since it's not aligned with OpenBSD's ideology. *** Linux's software availability But what good is an OS without software? Luckly, you've most of Linux has to offer. Most popular programs are already ported, and those not may not be that difficult to port yourself. FreeBSD even comes with Linux compatibility layer called [[https://freebsdfoundation.org/blog/update-on-freebsd-foundation-investment-in-linuxulator/][Linuxulator]] Not having Microsoft or Adobe is, at least for me, meaningless. I run a FOSS software in my personal life. *** Dedicated uses-cases But why do we care about all those systems? Well, since they have different goals and visions they have different appliances where they shine. You can use any BSD on a PC (with great successes!0, but when you get comfortable with the system you may want to go deeper. FreeBSD with ZFS is a perfect system for a NAS. OpenBSD with its security focus is often used for homegrown routes (and the site is hosted on OpenBSD VM). NetBSD is known to run on anything, and therefore is often used of embedded devices - like a [[https://blog.embeddedts.com/netbsd-toaster-powered-by-the-ts-7200-arm9-sbc/][toaster]]. *** History But still share the Unix lineage and can be traced to *that huge computer in Bell Labs*. This is very personal, but for me, it was one the factors driving me towards BSD. Linux is Posix-like, so it looks like Unix, but it not one. BSD are direct descendants of Unix. This is also one the reasons BSDs follow Unix philosophy so closely. *** RunBSD Those are /mine/ reasons, but everyone has different. You can read more testimonials on [[https://runbsd.info/][RunBSD]] site, or random blogs like [[https://web.jessups.org/jhjessup/posts/2023-01-30_openbsd-laptop][Jonathan's]] or [[https://rubenerd.com/its-worth-running-a-freebsd-or-netbsd-desktop/][Ruben's]]. [fn:src] I am not; just barely licking C for now. [fn:hist] vide: [[/bsd/history][BSD History]] on this site. ** DONE BSDs may not be a system for you CLOSED: [2024-04-20 Sat 22:13] :PROPERTIES: :EXPORT_FILE_NAME: why-not-bsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract Reasons why BSD may not be the best OS for you :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :menu_item_override "perhaps you shouldn't" :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :menu_item_override_end_li true :END: Changing GNU/Linux distribution can be done on a whim, as underneath all of that you've got the same basic operating systems. With BSDs it's not the same. One should try to understand the downsides, as not to waste the next 20 years exploring an OS that simply is not a good fit. *** Hardware All BSD are much less popular than GNU/Linux[fn:otheros], and with this comes the most pressing downsides. The support from hardware vendors is, at the very least, problematic. You will have problems with recently released components; most likely your WiFi card will not work. Your graphic card may have drivers, but they may work much slower. One needs to deeply examine hardware at hand and make sure it is supported by the chosen OS. As an example, my laptop has an NVIDIA card hardwired to HDMI-out, so if I want to use an external monitor, I need to use this card. While this works on FreeBSD, there is no support on OpenBSD. Another example would be the Intel wireless NIC which I had to physically replace[fn:tp] to not get constant Kernel Panics. It goes without saying that power management is also a problem, but it's a problem on GNU/Linux as well. The lackluster support from vendors is handled by volunteers who try to reverse-engineer the hardware. And here comes another problem - it's *very* hard to back port anything from GNU/Linux kernel. There is a huge difference between what GPL and BSD license allows. And even if that wasn't the problem, the GNU/Linux driver land is full of closed blobs. You could have thought that if something is supported there, it has a beautiful open-sourced drivers. Nothing further from the truth. Ever wondered why GNU's GUIX doesn't support Nvidia? That's because the drivers are provided as blobs, and therefore closed-source. As a result, the work needed for BSD support is difficult and slow[fn:gnukernel][fn:closedlicense]. *** Software availability But let's assume this is not a problem in your case. You have been blessed by the Gods of Hardware Support. You've installed the system: your GPU is calculating pixels, your air is full of bits and waves. Next step? Software! And hello to another problem: software support. Most popular software is not compiled against BSD operating systems. VS Code? Steam? Microsoft Office? Firefox? Those programs may be essential for your work or evening. /BSDs on desktop/ crowd is not significantly large enough for companies to want to deal with us. We are not completely lost here, as BSD is POSIX-compliant, so it's possible to compile everything that's running on GNU/Linux. It requires changes and a bit of luck[fn:ports] but any open-source application can be run. Unfortunately, since we are not using GNU/Linux, all hacks that make software run fast there may now work here, or even create huge problems. Firefox on FreeBSD is a huge pile of patches layered over each other. I have no idea how much work is required to support it, but it's somewhere between "big" and "have mercy". About that closed-source ones? No Office for you. *** Help Let's once again allow our imagination run wild and assume all software you use is there, but you have a problem. You try to Kagi[fn:kagi] it and nothing. Nada. GNU/Linux has plethora of sites, blogs, and vlogs. Any problem you may encounter, someone else already solved and documented. In BSD you are expected to read the manual. But wait, you may ask, RTFM? That's rude! It is, however, true. Since all BSDs have best in class documentation, it is assumed that you will look for help there first. This also means that trivial problems may not ever find themselves a subject of any blog post. Unfortunately, non-trivial ones are also often not documented. The community is friendly and will help you, but you need to do the homework. Since the community is small, it may take some time/luck, but someone will help you help yourself. When GUN/Linux may be used by someone who has zero knowledge about the inner workings of the OS, BSD will not be so kind. Notice how I, like a gentleman, always mention GNU when mentioning Linux? Well, BSD teaches you why you should. Since BSD and Linux use different userland software, they are not compatible. And while yes, basic usages of such programs like ls, cat, awk is the same, GNU likes to add a lot of custom extensions. You can assume that *only POSIX* requirements are met. As a result you will find answers for your question on the interwebs which will not work for you, as they are written for GNU-flavored tooling. Unfortunately, POSIX is a weapon for a more civilized age. Folks these days assume /a lot/ and BSDs don't even come with ZSH out of the box. Ever used the basic /Shell/? Too bad, as /Shell/ is what you should assume in all your scripts. *** Pce of change Next: do you like to call yourself an /early adopter/? Being in the /bleeding edge/ is what gets you going? BSD are evolving slowly by design. If something works, let's leave it alone. That's the mantra. GNU/Linux is changing rapidly - Pipewire, Wayland, SystemD. Even good old /ifconfig/ is being deprecated. At the same time BSDs still use technology from decades ago[fn:slow]. There was never a need to replace them, so no one did it. *** It's Linux, right? And lastly, prepare for a lot of raised brows. Younger folks may have never even heard of BSD. Rocking their MacBooks they don't know (nor care) about its FreeBSD roots. Very few people I have contact in the meatsphere have ever seen a BSD system, and it's not that easy to explain that it's not Linux. You can think of the problems as something one may have had trying to run RedHat on a computer with a winmodem back in 1999. It's not an OS that gets out of the way allowing you to get stuff done. You need to /enjoy/ making it work for you. Otherwise, all you will find is annoyance and a swift OS change. [fn:otheros] I won't even mention proprietary OS, as they are irrelevant here. [fn:tp] I tried to record my fight with having my Thinkpad working under FreeBSD [[https://michal.sapka.me/bsd/thinkpad/][here]]. [fn:gnukernel] I won't pretend to understand it, but as to the best of my knowledge: those closed blobs are part of Linux kernel. They are not strictly /drivers/, as drivers are how the OS communicated with the device. Instead, they are /firmware/ which run on the device itself. Both of those parts need to work together as to not fry the device. [fn:closedlicense] As a sidenote: having /closed/ standards is my definition of a dick move. Not only the way the device is hidden, but also how something like WiFI is. It's very hard to read the exact spec of modern WiFi standard, and it's most definitely illegal to use that knowledge without a paying a crazy amount of money. [fn:ports] BSDs have collection of such converted software called /ports/. They are supported by volunteers, so your mileage may vary. [fn:kagi] Are people still using Google? [fn:slow] Not going on breakneck speed is one of huge driving factors towards BSD. It's a good thing, I promise! ** OpenBSD :PROPERTIES: :EXPORT_HUGO_MENU: :menu bsd :parent "openbsd" :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :primary_menu bsd :END: *** DONE OpenBSD webstack: Relayd, Httpd and Acme-client CLOSED: [2023-07-19 Mon 19:08] :PROPERTIES: :EXPORT_FILE_NAME: open-bsd-web-stack :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How to setup the web server stack work? :EXPORT_HUGO_MENU_OVERRIDE: :identifier "obsdweb" :name "Webstack: Relayd, Httpd and Acme-Client" :END: OpenBSD comes with three great tools out of the box: - httpd(8) - an HTTP daemon - relayd(8) - a relay daemon - acme-client(1) - a client for Automatic Certificate Management Environment (ACME) With those free things, we can serve static webpages over TLS. While you most likely already use [[https://www.nginx.com/][NGINX]] or [[https://httpd.apache.org/][Apache]][fn:win], those solutions are complex. They work amazingly in enterprise environments where you have people with doctorates in NGINX configuration, but most real-world examples don't need that complexity. A static blog most likely doesn't. Let's set it up. Due to security concerns, OpenBSD comes with doas(1) instead of sudo(1). Copy `/etc/examples/doas.conf` file to `/etc/doas.conf`. For all intends, and purposes, from now on doas(1) will work the same as sudo(1). When the system boots for the very first time, ports 80 and 443 are closed, and only the SSH port is open. This alone was a nice surprise for me. But it gets better: since all utilities are part of the OSes, they work together perfectly. Assuming your domain is already pointing at the correct IPs, let's start listening for unencrypted HTTP traffic. I will use "michal.sapka.me" as the domain in all examples. First, Open =/etc/httpd.conf= in your favorite editor and add #+begin_src shell server "michal.sapka.me" { listen on * port 80 root "/htdocs/michal-sapka-me" } #+end_src Then create a simple HTML file under =/var/www/htdocs/michal-sapka-me/index.html=. Httpd(8) works chrooted to /var/www/, so it threats this directory as root. This makes the "root" option shorter to write, but it also means that the process doesn't have access to anything outside of /var/www/. Even if an attacker can break in via the daemon, he will be locked in the www folder, so there is no risk to the rest of the system. As I said, OpenBSD is secure by default[fn:nginx-sec]. All we need to do now it to enable the daemon via the handy rcctl(8) tool. #+begin_src shell $ doas rcctl enable httpd #+end_src and to start it #+begin_src shell $ doas rcctl start httpd #+end_src And boom. Opening http://michal.sapka.me shows on our site both on IPv4 and IPv6. One thing to note here is the limitation of up to HTTP 1.1. HTTP 2 is not yet supported. Let's add TLS, so we have this cute lock icon. For this, we will request a certificate from [[https://letsencrypt.org/][Let's Encrypt]] using acme-client(1). If you used certbot, this will look familiar - just tidier. First, let's add config to =/etc/acme-client.conf= #+begin_src shell -n authority letsencrypt { api url "https://acme-v02.api.letsencrypt.org/directory" account key "/etc/acme/letsencrypt-privkey.pem" } authority letsencrypt-staging { api url "https://acme-staging.api.letsencrypt.org/directory" account key "/etc/acme/letsencrypt-staging-privkey.pem" } domain michal.sapka.me { domain key "/etc/ssl/private/michal.sapka.me.key" domain full chain certificate "/etc/ssl/michal.sapka.me.crt" sign with letsencrypt } #+end_src Lines 1-9 tell our acme-client(1) how to talk with Let's Encrypt, while lines 11-15 allow us to request a certificate for our domain. OpenBSD comes preconfigured for Let's Encrypt, so we just enable provided settings. Nice! Next, we need to allow Let's Encrypt challenges. Acme-client(1) will manage all required files, and Let's Encrypt can read them via httpd(8). Again, like cogs in a well-oiled machine. By default, acme-client(1) will write to =/var/www/acme=, so we need to redirect =/.well-known/acme-challenge/*= there. Let's change our =httpd.conf=: #+begin_src shell server "michal.sapka.me" { listen on * port 80 root "/htdocs/michal-sapka-me" location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } } #+end_src We can now either restart httpd(8) or reload it. Let's for the latter. #+begin_src shell $ doas rcctl reload httpd #+end_src Now we can request the certificates #+begin_src shell $ doas rcctl reload httpd $ doas acme-client -v michal.sapka.me #+end_src OpenBSDs supplied tools don't print unnecessary information to the user, so we add the =-v= to see what's happening. Assuming everything went fine, let's start serving the page with TLS! For this, we will use relayd(8). We could use only httpd(8), but moving it one layer up is easier. Relayd(8) also gives us nice options for changing headers or moving some locations to a different process, like we will do with Plaroxy soon. This also shows us the big difference between this simple solution and NGINX: while NGINX shovels everything into one process and config, OpenBSD splits it into narrow focus areas. Let's open =/etc/relayd.conf= and add: #+begin_src shell -n table { 127.0.0.1 } http protocol "https" { tls keypair "michal.sapka.me" match request quick header "Host" value "michal.sapka.me" forward to } relay "https" { listen on 0.0.0.0 port 443 tls protocol https forward to port 8080 } relay "https6" { listen on :: port 443 tls protocol https forward to port 8080 } #+end_src Now, I won't go into much detail here, but what happens here is: 1. We create two relays, one for ipv4 and one for ipv6. One relay can listen on a single port for given IP. Each relay uses protocol "https" to modify and steer the request to a given process. 2. Both relays set up forwarding to httpd (IP taken from the table on the head of the file) on port 8080. 3. https protocol adds a TLS key pair for the session. We've got the files from Let's Encrypt in the step above. 4. We then test each request, and if the host matches "michal.sapka.me" it will be forwarded to httpd(8). You can also see that relayd(8) can listen on a given IP or all IPs (:: in case of IPv6) But our httpd(8) listens only on port 80! Let's fix that by changing the `httpd.conf` file: #+begin_src shell server "michal.sapka.me" { listen on * port 8080 #+end_src We also need to redirect HTTP to HTTPS. Since we use Relayd(8) only for HTTPS, this will be done in httpd(8). Let's add a second server to our `httpd.conf`: #+begin_src shell server "michal.sapka.me" { listen on * port 80 location * { block return 301 "https://$HTTP_HOST$REQUEST_URI" } } #+end_src Now, when the user enters the site, the flow will look like: 1. httpd(8) will respond to :80 requests and return a 301 redirect to HTTPS 2. relayd(8) will catch the request to :443 and forward it on port :8080 to httpd(8) 3. httpd(8) will serve our site and pass the response to relayd(8) again 4. relayd(8) can modify headers before returning the response to the client. Talking about modifying headers, let's apply some extra security! We can expand our https protocol with the following: #+begin_src shell # Return HTTP/HTML error pages to the client return error match request header set "X-Forwarded-For" value "$REMOTE_ADDR" match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT" match response header remove "Server" match response header append "Strict-Transport-Security" value "max-age=31536000; includeSubDomains" match response header append "X-Frame-Options" value "SAMEORIGIN" match response header append "X-XSS-Protection" value "1; mode=block" match response header append "X-Content-Type-Options" value "nosniff" match response header append "Referrer-Policy" value "strict-origin" match response header append "Content-Security-Policy" value "default-src https:; style-src 'self' \ 'unsafe-inline'; font-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'" match response header append "Permissions-Policy" value "accelerometer=(), camera=(), \ geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" # set recommended tcp options tcp { nodelay, sack, socket buffer 65536, backlog 100 } # set up certs tls { no tlsv1.0, ciphers "HIGH:!aNULL:!SSLv3:!DSS:!ECDSA:!RSA:-ECDH:ECDHE:+SHA384:+SHA256" } #+end_src I won't discuss details here as each header has a dedicated MDM webdoc. Most of the headers here are considered a standard. Besides adding headers, we configure TLS here, disabling weak ciphers and old TLS versions and adding some standard config. Lastly, we can automate refreshing the certificate via cron(8): #+begin_src shell 0~59 0~23 * * 1 acme-client michal.sapka.me && rcctl reload relayd #+end_src It looks almost like a normal cron. The "0~59" and "0~29" parts are unique to OpenBSD: Cron(8) will evenly split all tasks between specified time boxes so that no two jobs run simultaneously. We now have created a fully working web server without any 3rd party packages. All OpenBSD provided, all secure, all simple, all cool as ice. To further your knowledge, you can challenge the assumption that BSD has the best doc and read man pages for =httpd.conf(5)=, =relayd.conf(5)=, and =acme-client.conf(5)=. I also can't recommend enough "Httpd and Relayd Mastery" by Michael W. Lucas[fn:mwl2] [fn:nginx-sec] The ports collection of OpenBSD contains a fork of NGINX with a similar security treatment. [fn:mwl2] yeah, the one from the top of this article. He's a household name and a staple of the BSD community. I'm primarily a software engineer, and all this sysadmin thing I am doing is a side quest for me. His books make it so much easier. I've already read four of his books, and I will read more as they are amazing. Even a dense person like yours truly comes out smarter after the lecture. While I'm not a [Full Michael](https://www.tiltedwindmillpress.com/product/full-michael-2023-06/) kind of person, it seems my library will soon have a very strong representation of his. [fn:win] because there is no fourth way. Please repeat after me: there is no webserver in Windows. *** DONE OpenBSD: Blocking bad bots using Relayd CLOSED: [2023-12-11 Mon 19:08] :PROPERTIES: :EXPORT_FILE_NAME: blocking-bad-bots-openbsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How do I fight bad crawlers? :EXPORT_HUGO_MENU_OVERRIDE: :parent "obsdweb" :name "Blocking bad bots using Relayd" :END: The bane of existence for most of small pages: web crawlers. They create most traffic this site sees and makes my [[https://michal.sapka.me/site/info/#site-stats][site stats]] overly optimistic. We can go with [[https://en.wikipedia.org/wiki/Robots_Exclusion_Protocol][robots.txt]], but what if it's not enough? I can tell a valuable bot to not index some part of my site, but: a) some bots ignore it b) what if I don't want some bots to even have the chance to ask? Get that SEO scanning and LLM training out of here! **** Blocking crawlers The rest of this guide assumes webstack: Relayd and Httpd. Relayd is great and since it works on higher level than pf, we can read headers. Luckily, those crawlers send usable "User-Agents" which we can block. First, let's see who uses my site the most. Assuming you use "forwarded"[fn:log-style] style for logs, we can do: #+begin_src shell awk -F '"' '{print $6}' | sort | uniq -c | sort# #+end_src Then we need to manually select agents we want to block. It won't be easy, as the strings are long and contain a lot of unnecessary information - which includes plain lies. You need to define which part of the full User-Agent is common and can be used for blocking. Then we can create block rules in a Relayd protocol. Relayd doesn't use regexp, and instead allows using case-sensitive Lua globs. Stars will match everything. #+begin_src shell block request method "GET" header "User-Agent" value "**" #+end_src Remember that config assumes last-one-wins, so the block rules should be the last matching. I just put those end the end of my config. You can create a `block quick...` rule if you want - it will short-circuit the entire protocol. Therefore, my "https" protocol now has a series of blocks: #+begin_src shell http protocol "https" { # most of the procol omitted block request method "GET" header "User-Agent" value "*Bytespider*" block request method "GET" header "User-Agent" value "*ahrefs*" block request method "GET" header "User-Agent" value "*censys*" block request method "GET" header "User-Agent" value "*commoncrawl*" block request method "GET" header "User-Agent" value "*dataforseo*" block request method "GET" header "User-Agent" value "*mj12*" block request method "GET" header "User-Agent" value "*semrush*" block request method "GET" header "User-Agent" value "*webmeup*" block request method "GET" header "User-Agent" value "*zoominfo*" } #+end_src (usage of globs was proposed to me on [OpenBSD mailing list](https://marc.info/?l=openbsd-misc&m=170206886109953&w=2) [fn:log-style]: vide https://man.openbsd.org/httpd.conf.5#style *** DONE OpenBSD: Forwarding requests from Relayd to a custom webserver CLOSED: [2023-07-19 Mon 19:30] :PROPERTIES: :EXPORT_FILE_NAME: relayd-custom-webserver :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How to forward request to webserver? :EXPORT_HUGO_MENU_OVERRIDE: :parent "obsdweb" :name "Forwarding requests from Relayd to a custom webserver" :END: One thing that OpenBSD doesn't provide (yet?) is an HTTP proxy. I use [[https://plausible.io/][[Plausible]][fn:nope] for basic visitor analytics [fn:privacy] here, and one of the cool things you can do is to break all adblockers via serving Plausible from my own domain[fn:adblock] After two evenings of failed attempts, I reminded myself that I am a programmer, and I wrote one myself. You can find it on my [no longer available]. It was a great learning exercise and a chance to touch Golang[fn:ruby] for the first time. Assuming you have it running (it works on my machine!), let's adjust our relayd(8). Plaprox listens on port 9090, and we want to relay all requests to =/js/script.js= there. Let's add it to our relays in =relayd.conf=: #+begin_src shell -n table { 127.0.0.1 } http protocol "https" { # all our previous content omitted match request quick path "/js/script.js" forward to match request quick path "/api/event" forward to } relay "https" { listen on 0.0.0.0 port 443 tls protocol https forward to port 8080 forward to port 9090 } relay "https6" { listen on :: port 443 tls protocol https forward to port 8080 forward to port 9090 } #+end_src You can also move the port number to a table. Remember that in Relayd(8) last one wins. We already have a match for the domain and added another matcher for the path. The request will be forwarded to the last marching matcher - so we put our new matchers at the end of the protocol definition. **** Updates 2023-07-28: remove wrong information abot PF. 2023-07-30: fix invalid cron format 2023-12-12: extracted to a dedicated article [fn:privacy] Yes, I want to know what people are reading! For details, refer to my [[https://michal.sapka.me/about/#privacy-policy][two sence long privacy policy]]. [fn:nope] [[https://michal.sapka.me/site/updates/2023/removed-plausible/][this is no longer the case]] [fn:adblock] yes, it's a dick move. But my reasoning was simple: Plausible gathers so little information that the harm is almost nonexistent, and I really want to know what people are reading. [fn:ruby] I am a Ruby developer by trade and heart, but I will try anything that is not an IDE-driven language. LSP for Java/Scala is still a joke, and I refuse to pollute my system with Intellij. [[https://go.dev/][Go][, on the other hand, is a modern language designed for humans. I am not good at it, but I am infinitetly[fn:infinit] better than a week ago. [fn:infinit] Any positive number would be infinite progress compared to zero, or as an old wise man once said: "to have a nickel and to not a nickel is already two nickles". ** FreeBSD *** Personal use :PROPERTIES: :EXPORT_HUGO_MENU: :menu bsd :parent "freebsd-personal" :END: **** DONE Switching between WiFi and Ethernet on FreeBSD CLOSED: [2024-10-26 Sat 20:11] :PROPERTIES: :EXPORT_FILE_NAME: switching-wifi-eth :EXPORT_HUGO_MENU_OVERRIDE: :name "Switching between WiFI and Ethernet" :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How to handle multiple network interfaces? :END: *The problem*: I have a laptop with built-in WiFi. Say what you will about WiFi, it's always better to use the good, old cable connection. I have bought myself a cheap, USB Ethernet adapter (Reltek) which is perfectly detected by FreeBSD, as per =ifconfig(8)=: #+begin_src shell name: "aa" ue0: flags=1008843 metric 0 mtu 1500 options=68009b ether c8:4d:44:20:6a:1b inet 10.0.7.197 netmask 0xfffff800 broadcast 10.0.7.255 media: Ethernet autoselect (1000baseT ) status: active nd6 options=29 #+end_src However, I don't want to remove the WiFi card, but FreeBSD insists on using it for all outgoing connections. ***** Pre-requisites What we need to know: - names of devices (from =ifconfig(8)=). In my case, WiFi is =wlan0= while the Eth dongle is =ue0= - default route (from =netstat(1)=): #+begin_src shell netstat -rn | grep default #+end_src Write down the IP shown, in my case it's =10.0.1.1=. ***** Netif Netif is FreeBSD's way to manage network devices. We will can disable WiFi: #+begin_src shell service netif stop wlan0 #+end_src And ensure the dongle (ue0) is enabled: #+begin_src shell service netif restart ue0 #+end_src At this point your WiFi is no longer enabled, and all traffic should go through Ethernet. If everything works fine - you're done. ***** Default route Disabling a network interface removes its routes. If you can't reach any location (try =ping(8)=) it may be that you are lacking default route. We can check it via: #+begin_src shell netstat -rn | grep default #+end_src If nothing is returned, your computer does't know to reach other machines. Luckily, we can re-add it. Remember the address from earlier? #+begin_src shell route add default 10.0.1.1 #+end_src Now everything should work fine! ***** Alternatives As per FreeBSD Guide, you can also try [[https://docs.freebsd.org/en/books/handbook/advanced-networking/#network-aggregation][link aggregation]]. *** DONE FreeBSD: examples of Jail usage CLOSED: [2023-12-01 Mon 21:29] :PROPERTIES: :EXPORT_FILE_NAME: jails-usage-examples :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How can we use FreeBSD Jails? :EXPORT_HUGO_MENU_OVERRIDE: :name "Some examples of using Jails" :END: Creating Jails in FreeBSD is very easy. It takes few minutes to follow the [[https://docs.freebsd.org/en/books/handbook/jails/][official handbook]] and voilà! We've a dedicated container. But what can we do with it? A very common use pattern on FreeBSD desktop is to use Jails to encapsulate dependencies, so they don't pollute the main OS. Don't want that pesky Pyton? Straight to Jail. Java? Straight to jail! *** Simple jail - Ltex-Ls I am not a native speaker, so my English skills are far from perfect. My terrible typing skills don't add anything good into the mix. Therefore, I am in need of a good grammar and spell checker. There is Grammarly, but it's closed source and cloud based. We don't want that. Luckily an alternative exist - [[https://languagetool.org/][LanguageTool]]. It is quite good and can run locally! I use it via an LSP - [[https://valentjn.github.io/ltex/ltex-ls/installation.html][Ltex-Ls]]. Technically it's aimed at Latex, but it can work with any filetype. The problem with ltex-ls is that is runs on JVM. I really don't need that on my system. Let's lock it in a jail and allow our NeoVim[^lsp] to use it. [^lsp]: I can, of course, run in any other editor which supports the LSP standard, be it Emacs or some bad one. First, let's create a Jail and call it `ltex`. For now we can allow it access to the internet, as we will download some files. #+begin_src shell ltex { ip4 = inherit; interface = em0; } #+end_src We will remove network access after we are done with the setup. We don't want any of our writings to leak to the web. Then, let's log into the jail #+begin_src shell doas jexec ltex /bin/sh #+end_src and add the dreaded java #+begin_src shell pkg install openjdk-jre #+end_src then, let's fetch our latex-ls #+begin_src shell cd /root wget https://github.com/valentjn/ltex-ls/releases/download/16.0.0/ltex-ls-16.0.0.tar.gz tar -xvf ltex-ls-16.0.0.tar.gz #+end_src for ease of use, let's remove the version number from the directory #+begin_src shell mv ltex-ls-16.0.0/ ltex #+end_src And our jail is ready, so let's leave it (either `exit` or the good, old Ctrl+d). We can now open our nvim config file. This is not a guide about this part, so let's just assume you have LSP and LSP-Config intalled. Our config will look like this: #+begin_src lua lspconfig.ltex.setup{ on_attach = on_attach, cmd = { "doas", "jexec", "ltex", "/root/ltex/bin/ltex-ls" }, -- rest of config omitted } #+end_src Notice, that we now run the command as root inside the Jail. It would make sense to allow passwordless-doas to our user due to `doas`. I will update this guide if I figure out if we can commit this security nightmare here. But let's go a step further. Ltex-Ls allows to use machine learning based grammar check based on ngram data. We can add it to our jail. Let's log back in #+begin_src shell doas jexec ltex /bin/sh #+end_src Next we need to fetch the ngram data (you can find it on [[https://dev.languagetool.org/finding-errors-using-n-gram-data.html][LanguageTool website]]. We need to have a `ngrams` folder which contains `en` (as the language shortcut). The ngrams should be inside the `en`. I propose you move the files to `/var/ngrams/en` inside the Jail. We can now tell `NeoVim` to inform the `ltex-ls` runtime to use the ngrams. #+begin_src lua -- our old config lspconfig.ltex.setup{ on_attach = on_attach, cmd = { "doas", "jexec", "ltex", "/root/ltex/bin/ltex-ls" }, -- ngram settings added settings = { ltex = { additionalRules = { languageModel = '/var/ngrams/', }, }, }, -- rest of config still omitted #+end_src Note that we instructed the LSP to use =/var/ngrams= folder. For program running inside a Jail, the Jail is full system. Even though we can access the ngram data on the host OS under =/jail/containers/ltex/var/ngrams= (depending on your config), for Jail, the =/jail/containers/ltex/= prefix doesn't exist as it points to root for the jail. We can now remove networking from the jail, so our Jail config just defines the existence of the jail #+begin_src shell ltex { } #+end_src And boom. We've got machine language grammar checking which is completely offline and does not pollute our primary system. Our tinfoil friends will be proud of us. [this article will be expanded with more examples in the near future] ** Thinkpad :@bsd: :PROPERTIES: :EXPORT_HUGO_SECTION: bsd/thinkpad :EXPORT_HUGO_MENU: :menu bsd-thinkpad :END: *** DONE FreeBSD on Thinkpad X1 Extreme G2 CLOSED: [2024-04-10 Wed 22:42] :PROPERTIES: :EXPORT_FILE_NAME: _index :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract My my laptop on FreeBSD :EXPORT_HUGO_PAIRED_SHORTCODES: menu :EXPORT_HUGO_MENU: :menu bsd :parent freebsd :name "Thinkpad X1 Extreme G2 support" :END: This is my personal machine, where I run FreeBSD-release daily. **** Current status of components: | Name | Comment | Status | |--------------------+--------------------------------------------------------+----------------------------| | Audio | | works | | Intel GPU | switching doesn't work. You either use Intel or Nvidia | works | | Nvidia GPU | " | | | Bluetooth | never tried | unsupported | | Camera | | works | | Ethernet | | works | | Fingerprint sensor | | not tested | | Fn Keys | | works | | HDMI | | works | | Hibernate | works is done to address | unsupported | | SD card reader | | not tested | | Suspend | | works | | Touchpad | | works | | Trackpoint | | works | | USB-C | | works | | USB | | works | | WiFi | a lot of problems | technically works[fn:wifi] | [fn:wifi] I have replaced my WiFi card **** Articles Some articles I've written about trying to get it to a usable state: #+attr_shortcode: "bsd-thinkpad" #+begin_menu History of BSD #+end_menu *** DONE FreeBSD: Review of Thinkpad Extreme G2 CLOSED: [2023-02-25 Mon 22:30] :PROPERTIES: :EXPORT_FILE_NAME: freebsd-on-thinkpad-x1-extreme-g2 :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract it works, but there are drawbacks :EXPORT_HUGO_MENU_OVERRIDE: :name "Impressions, Instalation and problems" :END: My wife got a new computer, so I can easily break my laptop whenever I want - so it's time for FreeBSD! *All this applies to FreeBSD 13.1 at the time of publishing. I'll add links to any additions and errata in the future* **** Installation The installation process is great. It's more involved than something like Fedora, and some concepts were foreign to me. [[https://docs.freebsd.org/en/books/handbook/bsdinstall/][Handbook's chapter on installation]] guided me through every step, so there were no problems. Within 15 mins of booting from the USB Drive, I had a working hardened system running on an encrypted ZFS drive with wireless networking and essential services configured. #+attr_shortcode: :file freebsd-setup-fs.png #+attr_shortcode: :alt White, all caps "Run BSD" over black background #+attr_shortcode: :class centered #+attr_shortcode: :source https://docs.freebsd.org/en/books/handbook/bsdinstall/ #+begin_image Partitioning #+end_image Many things worked out of the box, but not all of them. **** Hardware Setting X-Org was a breeze. Nvidia drivers are [[https://docs.freebsd.org/en/books/handbook/x11/#x-configuration-nvidia][available and ready to go]] no additional configuration is necessary. (update: I was wrong, but it is fixed now) Sound, of all things, work out of the box. Unfortunately, it doesn't auto-switch to headphone output, but there is [[https://freebsdfoundation.org/freebsd-project/resourcesold/audio-on-freebsd/][a known way to do this]] via device hints. The integrated camera also works after running =webcamd -d ugen0.2 -i 0 -v 0=. Tested via =pwcview=. My laptop uses AX200 wireless card, which is [[https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244261][not yet fully supported by the system]]. It is recognized and works, but only up to WiFi 3 (g). I'd be ok with WiFi 4(n), but the driver is not ready, and WiFi 5 (AC) [[https://wiki.freebsd.org/WiFi/80211ac][is not supported by the OS]] at all. Funny enough, it [[https://man.openbsd.org/man4/iwx.4][seems to be supported by OpenBD]]. I have yet to learn how different BSDs intertwine and different. FreeBSD is supposed to be more user-friendly, but it seems not to be the case here. Work on [[https://wiki.freebsd.org/WiFi/Iwlwifi][fully supporting]] the card is already planned, but I have no idea when I can expect results. From what I've learned, the team can't reuse code from Linux due to licensing incompatibilities between [[https://www.gnu.org/licenses/gpl-3.0.html][GPL]] and [[https://docs.freebsd.org/en/articles/license-guide/][BSD license]] [update: there are more problems]. #+attr_shortcode: :file freebsd-beastie.png #+attr_shortcode: :alt White, all caps "Run BSD" over black background #+attr_shortcode: :class pull-right #+attr_shortcode: :forced_width 150 #+attr_shortcode: :src https://docs.freebsd.org/en/books/handbook/bsdinstall/ #+attr_shortcode: :transparency yes #+begin_image FreeBSD Beastie #+end_image This is one of the few instances when I am rethinking my life choices, and I would love to be able to help with C code. Also, Bluetooth on this card is not supported, and there is no work done to address it - but luckily, I am already de-wirelessing my life. USB devices are detected automatically and mostly work. However, my monitor (Dell P2723QE) has an integrated 1000Base-T ethernet connection, but on FreeBSD, only 100Base-T worked. Another problem is Suspend/Resume. I can easily [[https://wiki.freebsd.org/SuspendResume][suspend]] the device, but after resuming it, the screen is still black. This seems to be a known problem across different OSes for this laptop and has some [[https://www.thinkwiki.org/wiki/Problem_with_display_remaining_black_after_resume#Solution_for_ThinkPads_with_Intel_Extreme_Graphics_2][known warkarounds]] for Linux, but I have no idea how to apply them to BSD. [update: there is a fix working] The biggest problem here is battery drain. I have =power= enabled, but =acpinfo= reports about over 1% per minute. I was getting about the same drain on Arch Linux, but Manajaro acted much better. I have not tested the fingerprint reader as I've never used it. **** Conclusion My ThinkPad is far from being a brick under FreeBSD. It is, however, severely hindered. I plan to fix the memory drain and allow for a resume after suspension. This will make it a proper laptop again, as there are always USB dongles when faster WiFi is needed. Dongle town, however, is not what I want in the long term, and I'll need to follow the progress of the driver implementation closely. It seems that for a desktop computer everything would work. I'm falling in love with the system and its simplicity and logic. So even if I fail at fixing the above, I'll try to stick with it. And even if I get fed up with the state of hardware support, I'll keep FreeBSD as a secondary system. For personal servers, however, I see no way of abandoning BSD. **** Updates - 2023-02-27: [[/2023/fixing-resume-on-thinkpad-x1-extreme-g2-on-freebsd][Fixing resume due to graphic drivers]] - 2023-02-04: [[/2023/freebsd-configuring-nvidia-and-xorg-on-thinkpad-x1-extreme-g2][Configuring NVIDIA]]. - 2023-03-15: [[/2023/freebsd-on-modern-intel-wifi-cards-and-resume][Problems with WiFi after resume]] *** DONE FreeBSD: Fixing ThinkPad X1 Wifi CLOSED: [2023-08-03 Mon 21:40] :PROPERTIES: :EXPORT_FILE_NAME: fixing-thinkpad-x1-wifi-on-freebsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract replacing a wificard fixes everything :EXPORT_HUGO_MENU_OVERRIDE: :name "Fixing WiFi for good" :END: As much as I like FreeBSD, my laptop has mostly sat dormant for the last few weeks. It rocked an AX200, an excellent WiFi adapter unless you want to use it in FreeBSD. There were three reasons for this, with one primary cause: 1. WiFi speeds up to WiFi 2, 2. inability of the system to resume after suspend 3. occasional kernel panics Long story short[fn:wifiart], the firmware is yet to be properly reverse-engineered, and the card is still unsupported[fn:lies]. The team can't simply copy the Linux driver due to BSD/GPL license incompabilities[fn:openbsd], so the work needs to continue. Luckily, ThinkPads are still good laptops, and the card was not soldered. So, there was a way: buy a better-supported card and just replace it. Unfortunately, Lenovo is not a good company. You can't simply buy any random card matching the port and be sure it will work. The BIOS has a whitelist of supported hardware, and if it detects anything outside of this list, the machine won't boot. Lenovo's support proved itself useless. I tried to contact them and get the list of whitelisted WiFi adapters, but at first, they had no idea what am I talking about, and when we finally got on the same page, they started to ignore me. After a few nags met with silence, I just gave up and ordered a used [[https://www.intel.com/content/www/us/en/products/sku/99445/intel-wirelessac-9260/specifications.html][Intel AC 9260]]. Have I mentioned that ThinkPads are still good devices? Replacing the WiFi adapter was sparkly[fn:spark] but easy. Just pop the two antenna connectors, unscrew a single screw, remove the card, and do the same in reverse for the new one. Try to do that with a MacBook![fn:battery] #+attr_shortcode: :file intel-ac9260.jpg #+attr_shortcode: :alt Opened laptop with a screwdrive on top #+attr_shortcode: :class centered #+begin_image Sitting and working nicely #+end_image Then, with a single reinstall[^reinstall] of the system, everything started working. I'm still limited to WiFi 2, but it works over 5GHz. It's a small problem because my system can finally suspend and resume. I no longer need to power off/power on all the time because it's no longer necessary. I no longer need to be annoyed by the booting speed[fn:systemd] because it will no longer be a constant sight for me. I also have a (not backed by any analysis) feeling that the laptop runs colder. With this, I am now a two BSD[fn:golang] guy: [[/2023/moved-to-openbsd][OpenBSD]] on the server and FreeBSD on the computer. Why not go fully into one? Mostly, BSDs are cool, and it's nice to get to know each other. But also each of them has its strengths and weaknesses. OpenBSD is secure, has httpd/relayd and modern PF[fn:pf] but a smaller number of ported software, no ZFS, and finding answers on the information highway is more difficult. For a server, those are non-issues, as I have no intention of installing random crap there. But for my computer, I want to experiment more. I will break the system so ZFS will be a great addition. And having more applications ready to =pkg install= will make it this much nicer. [fn:spark] don't be a moron like me and disable the internal battery in BIOS before randomly poking the motherboard with a metal screwdriver. [fn:battery] or with battery. I'm replacing mine in a few days. If I went with Apple, I would need to go to a service station as my ungluing skills are nonexistent. [fn:wifiart] Vide [FreeBSD on modern Intel WiFi cards and resume](/2023/freebsd-on-modern-intel-wifi-cards-and-resume/) [fn:lies] technically [it is](https://wiki.freebsd.org/WiFi/Iwlwifi), but no real use case is feasable. [fn:openbsd] The OpenBSD team had no such problems, and the drivers are downloaded during installation and work out of the box. [fn:reinstall] I'm a simple bare metal guy and was toying with OpenBSD. I don't know if a reinstall would be required if I had a working FreeBSD. [fn:systemd] Which is one of the few good things about [systemd](https://michal.sapka.me/2023/systemd-is-fast/) [fn:golang] I could have learned to Go, but I chose a totally unmarketable skill for a programmer. I think it makes it even cooler. [fn:pf] I am currently reading /[[https://nostarch.com/pf3][[The Book of PF]]/ so I can have any benefit. Great book. Would recommend. *** DONE FreeBSD: Switching Between Speakers and Headphones CLOSED: [2023-03-16 Mon 23:02] :PROPERTIES: :EXPORT_FILE_NAME: switching-between-speakers-and-headphones-on-freebsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract How to change the audio sevices? :EXPORT_HUGO_MENU_OVERRIDE: :name "Switching beteen headphnes and speakers" :END: I want my laptop to switch to wired headphones when I attach them. FreeBSD has its own [[https://wiki.freebsd.org/Sound][Sound System]], so it's a great learning experience. I have yet to automate it (it is possible, but an attempt to do so forced me to do a complete rollback of the system state), but for now, this is working. First, check which audio outputs your device supports: #+begin_src shell $ cat /dev/sndstat #+end_src In the case of my ThinkPad, this returns #+begin_src shell Installed devices: pcm0: (play) pcm1: (play) pcm2: (play) pcm3: (play/rec) default pcm4: (play) No devices installed from userspace. #+end_src The ones I care about are: pcm3 - the speakers pcm4 - the headphone jack I can now easily switch between them: #+begin_src shell # enable speakers $ sysctl hw.snd.default_unit=3 # enable headphones $ sysctl hw.snd.default_unit=4 #+end_src (replace the value with the correct id from `sndstat` file.) This, however, comes with a huge caveat. Some apps (khem khem, Firefox) not native to FreeBSD come configured with PulseAudio instead of FreeBSD's Sound System. This creates a level of indirection, and changing system output may not work instantly. In the case of Firefox, I need to reload the tab. Some apps, as I've heard, require a restart. *** DONE FreeBSD: Fixing Resume on ThinkPad X1 Extreme G2 due to integrated graphic card CLOSED: [2023-03-16 Mon 23:02] :PROPERTIES: :EXPORT_FILE_NAME: fixing-resume-on-thinkpad-x1-extreme-g2-on-freebsd :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract you need to load the driver :EXPORT_HUGO_MENU_OVERRIDE: :name "Fixing resume due to Intel driver" :END: *This applies to FreeBSD 13.1* Recently I [[/2023/freebsd-on-thinkpad-x1-extreme-g2][posted]] about my problems with FreeBSD. One of them was resume. After installing FreeBSD, I was able to put my laptop to sleep via #+begin_src shell acpiconf -s 3 #+end_src And this worked fine. However, I was not able to resume it back from sleep. After pressing the power button laptop woke, but the screen was still black. I could =reboot=, and it would work, so only the screen was the problem. After asking about this on [[https://forums.freebsd.org/threads/resume-on-thinkpad-x1-extreme-g2-ends-in-black-screen.88162/][FreeBSD Forums]], [[https://forums.freebsd.org/members/bsduck.61635/][bsdduck]] and [[https://forums.freebsd.org/members/smithi.71028/][smithi]] pointed me to dedicated drivers for the integrated Intel GPU. And it worked like a charm. All I had to do was: #+begin_src shell pkg install drm-kmod sysrc -f /etc/rc.conf kld_list+=i915kms reboot #+end_src (via [[https://wiki.freebsd.org/Graphics#Intel_Integrated_Graphics_.28aka_HD_Graphics.29][FreeBSD Wiki]]). Now the computer can sleep and resume without any problems. At least when using [[https://man.freebsd.org/cgi/man.cgi?acpiconf(8)][sleep mode 3]]. The 4th doesn't work for me at all. *** DONE FreeBSD: configuring Nvidia and Xorg CLOSED: [2023-03-16 Mon 23:02] :PROPERTIES: :EXPORT_FILE_NAME: freebsd-configuring-nvidia-and-xorg-on-thinkpad-x1-extreme-g2 :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract A tutorial on making Nvidia work :EXPORT_HUGO_MENU_OVERRIDE: :name "Setting up Nvidia" :END: First, the bad news: I could not make FreeBSD work with Hybrid Graphics, so I use only the discrete one. To ensure this, open BIOS and: 1. Configuration 2. Display 3. Graphics Device 4. select `Discrete Graphics` Then, log in as root and install the drivers: #+begin_src shell pkg install nvidia-driver nvidia-xconfig #+end_src The next step is to enable the drivers. #+begin_src shell sysrc kld_list+=nvidia sysrc kld_list+=nvidia-modeset #+end_src Some people advise adding Linux (=sysrc kld_list+=linux=) to kld_list, but I got my GPU working without that. After that, either load the drivers manually or give the computer an old, good reboot. Login as root again and use the NVIDIA configurator to get Xorg configured. #+begin_src shell nvidia-xconfig #+end_src Then try starting your desktop environment, windows manager, or startx. You may be done, but I got an error about =Screen not found=. Tell Xorg where the NVIDIA GPU is if you have the same problem. Try probing the system for GPUs #+begin_src shell pciconf -l | grep vga #+end_src You will see one on more elements on the list. The critical part is in the first column, for example: #+begin_src shell vgapci0@pci0:1:0:0 #+end_src Our GPU is available under BUS 1:0:0 (we skip the first 0). You may need to try different elements from the list. #+begin_quote For PCI/AGP cards, the bus−id string has the form PCI:bus:device:function (e.g., “PCI:1:0:0” might be appropriate for an AGP card). [[https://www.x.org/releases/X11R7.7/doc/man/man5/xorg.conf.5.xhtml#heading10X][Xorg documentation]] #+end_quote Open =/etc/X11/xorg.conf=, look for =Section "Device"= and add: #+begin_src shell BusID "PCI:1:0:0" #+end_src In my case, everything worked fine after that. Notes: I learned the BUS trick from [[https://nudesystems.com/how-to-fix-no-screen-found-xorg-error-on-freebsd/][Nude Systems]]. ** Gaming :PROPERTIES: :EXPORT_HUGO_MENU: :menu bsd :parent "gaming" :EXPORT_HUGO_SECTION: bsd/freebsd-gaming :END: *** DONE ScummVM CLOSED: [2024-09-20 Fri 21:34] :PROPERTIES: :EXPORT_FILE_NAME: scummvm :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract Running old adventure games :END: [[https://www.scummvm.org/][ScummVM]] started as a way to run classic LucasArts point-and-click adventure games on modern hardware. Today is has grown to a general runner for classic adventure games. If ScummVM is supported on your OS, you have a huge selection of games to choose from - just check the [[https://www.scummvm.org/compatibility/][compatibility list]]! Luckly for us, FreeBSD has a ready port and a prebuilt package. All we need to do is to #+begin_src sh pkg install scummvm #+end_src Note, that ScummVM is not *only* a runner, but it's the best way to experience supported games. Not only does it provide a modern save system, but it also fixes all problems, like synchronization of audio/video. Since ScummVM abstracts the OS from the game, any problems you may experience should not be FreeBSD specific, so finding help should be easy. Getting the games may be problematic. Most modern remakes are not using the classic engines, so they may not work. #+attr_shortcode: :file scummvm.png #+attr_shortcode: :alt Screenshot ScummVM running Monkey Island 2 #+attr_shortcode: :class centered #+begin_image Monkey Island 2 running on ScummVM #+end_image ** Homelab :PROPERTIES: :EXPORT_HUGO_MENU: :menu bsd :parent "freebsd-homelab" :EXPORT_HUGO_SECTION: bsd/freebsd-homelab :END: *** DONE Template for jail with an external IP assigned via DHCP CLOSED: [2024-10-29 Tue 22:03] :PROPERTIES: :EXPORT_FILE_NAME: dhcp-vnet-jail :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :abstract Running old adventure games :END: The idea behind FreeBSD homelab is simple: to utilize the Jail system. Jails are great! What I want is to have jails with: - dedicated, external IP - IPs are assigned via DHCP server - I am able to access files outside if the jails I was able to achieve most of this by following [[https://docs.freebsd.org/en/books/handbook/jails/][FreeBSD handbook]], [[https://rubenerd.com/starting-with-freebsd-jails/][Rubenerd's post]], and [[https://wiki.freebsd.org/Jails][FreeBSD Wiki]], but I also received some help from different individuals whose names I can't recall. I use classic jails created from ZFS snapshots, but (as to the best of my knowledge), any jail will work with the following configuration. Unless specified, all code here goes to =/etc/jails.conf=. #+begin_src shell config1; jail1 { config2; } jail2 { config3; } #+end_src jail1 gets configured with =config1= and =config2=, while jail2 gets =config1= and =config3=. **** Jail configuration First, we start with standard configuration regarding starting, stopping and logging. Notice the =#{name}=. It's a variable which fill be filled with the name of the jail. #+begin_src shell # STARTUP/LOGGING exec.clean; exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.consolelog = "/var/log/jail_console_${name}.log"; #+end_src Then we add permissions which will enable =vnet= - the system allowing for jail to have their own, (virtual) network stack. Even though everything goes through host's network stack, for all intends and purposes we can pretend that each jail has it's own (virtual) NIC. #+begin_src shell # PERMISSIONS allow.raw_sockets; exec.clean; mount.devfs; devfs_ruleset = 5; vnet; #+end_src Note, that we need to configure this =devfs_ruleset=. Create =etc/defvs.rules=: #+begin_src shell [devfsrules_jails=5] add include $devfsrules_hide_all add include $devfsrules_unhide_basic add include $devfsrules_unhide_login add path 'bpf*' unhide #+end_src back to =jail.conf=, we set hostname and path for the container. Adjust to your liking. #+begin_src shell host.hostname = "${name}.dune.local"; path = "/usr/local/jails/containers/${name}"; #+end_src Now for the actual network configuration. We will configure for the jail system to: - create an =epair(4)= and use for network communication - destroy this =epair= upon stopping a jail #+begin_src shell $epair = "epair${id}"; $bridge = "bridge0"; vnet.interface = "${epair}b"; exec.start += "dhclient ${epair}b"; exec.prestart = "/sbin/ifconfig ${epair} create up"; exec.prestart += "/sbin/ifconfig ${epair}a up descr jail:${name}"; exec.prestart += "/sbin/ifconfig ${bridge} addm ${epair}a up"; exec.prestart += "/sbin/ifconfig ${epair}b ether ${mac}"; exec.poststop = "/sbin/ifconfig ${bridge} deletem ${epair}a"; exec.poststop += "/sbin/ifconfig ${epair}a destroy"; #+end_src For this to work, we need to create a =if_bridge(4)= on our host machine. Make sure that your =rc.conf= has: #+begin_src shell cloned_interfaces="bridge0" ifconfig_bridge0="addm em0 up" #+end_src (replace =em0= with appropriate device) Ok, now we just need to have our jail ready. First, create it as it presented in the [[https://docs.freebsd.org/en/books/handbook/jails/][FreeBSD handbook]]. Then, configure the jail: #+begin_src shell jail { $id=1; $mac="2:bf:b9:4c:4f:0b"; exec.prestart += "mount -a -F /etc/fstab.$name"; exec.poststop += "umount -a -F /etc/fstab.$name"; } #+end_src Explanations: - =$id= will be used when creating matching =epair= - =$mac= will force a given mac address for the virtual network card. This will ensure that FreeBSD won't change it, and we can assign fixed =IP= on the router level - This jail has attached network storage. You don't want the jail itself to even know what it is, so we're forcing the host to execute =/etc/fstab.$name=, and mount the shares. Note, that you need to mount the drives in directory relative to *host's* root, so something like: #+begin_src shell 10.0.1.200:/volume2/movies /usr/local/jails/containers/servarr/mnt/movies nfs rw 0 0 #+end_src (this attaches an NFS share in read-write mode) **** Putting it all together The entire =jail.conf= looks like: #+begin_src shell exec.clean; exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.consolelog = "/var/log/jail_console_${name}.log"; allow.raw_sockets; exec.clean; mount.devfs; devfs_ruleset = 5; vnet; host.hostname = "${name}.dune.local"; path = "/usr/local/jails/containers/${name}"; $epair = "epair${id}"; $bridge = "bridge0"; vnet.interface = "${epair}b"; exec.start += "dhclient ${epair}b"; exec.prestart = "/sbin/ifconfig ${epair} create up"; exec.prestart += "/sbin/ifconfig ${epair}a up descr jail:${name}"; exec.prestart += "/sbin/ifconfig ${bridge} addm ${epair}a up"; exec.prestart += "/sbin/ifconfig ${epair}b ether ${mac}"; exec.poststop = "/sbin/ifconfig ${bridge} deletem ${epair}a"; exec.poststop += "/sbin/ifconfig ${epair}a destroy"; jail { $id=1; $mac="2:bf:b9:4c:4f:0b"; exec.prestart += "mount -a -F /etc/fstab.$name"; exec.poststop += "umount -a -F /etc/fstab.$name"; } #+end_src **** Improve me Is this perfect? No! There are people doing magical things with jails. If this makes no sense to you, or if you've done it better - make sure to [[/contact][contact me]]. * WIP ** TODO OpenBSD: XMPP (Jabber) server /intro/ *** Installing prosody #+BEGIN_SRC shell pkg_install prosodyctl #+END_SRC - daemon *** Configuring DNS prosodyctl check dns *** Getting certificates - acme config (ignore makefile) - importing certificates #+BEGIN_SRC shell prosodyctl --root cert import HOSTNAME /path/to/certificates #+END_SRC *fullchain* #+BEGIN_SRC shell prosodyctl check certs #+END_SRC *** Final tests #+BEGIN_SRC shell prosodyctl check connectivity #+END_SRC *** Clients - emacs - terminal - android - ios *** Modern XMPP: