jab's blog

im jab, backend developer and enthusiast sysadmin. welcome to my blog.

These last few months I haven't been bringing my laptop to classes, mostly because it's having some problems with the keyboard and it's also kind of breaking apart (it's an old laptop), so I came up with a script to replicate some of the workflow I usually have at my desktop.

To summarize it, the key things about my setup if I had to say would be the window manager and the text editor. They are key to everything I do, so, I thought of installing them on the university's computers, which was easier than I expected

The script

This is the script:

#!/bin/bash

echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
echo 'setxkbmap us intl ctrl:nocaps' >> ~/.bashrc
echo 'alias intellij="flatpak run com.jetbrains.IntelliJ-IDEA-Ultimate"' >> ~/.bashrc

mkdir ~/.local/bin -p

git clone https://git.suckless.org/dwm --depth 1 && cd dwm && make && mv dwm ~/.local/bin
cd ~

git clone https://git.suckless.org/dmenu --depth 1 && cd dmenu && make && mv dmenu* ~/.local/bin
cd ~

git clone https://git.suckless.org/st --depth 1 && cd st && make && mv st ~/.local/bin
cd ~

echo 'PATH=$PATH:~/.local/bin exec ~/.local/bin/dwm' > ~/.xinitrc

chmod +x ~/.xinitrc

git config --global user.name jabuxas
git config --global user.email jabuxas@proton.me
git config --global credential.helper store

pkill -KILL -U $USER

# GETting
wget https://github.com/nix-community/nix-user-chroot/releases/download/1.2.2/nix-user-chroot-bin-1.2.2-x86_64-unknown-linux-musl
wget https://github.com/tectonic-typesetting/tectonic/releases/download/continuous/tectonic-0.15.0+20250221-x86_64-unknown-linux-gnu.tar.gz
git clone --depth 1 https://github.com/doomemacs/doomemacs ~/.config/emacs
git clone https://github.com/jabuxas/configs --depth 1


# tectonic
tar xvf tectonic*
mkdir ~/bin
mv tectonic bin

# nix'ing
mkdir -m 0755 ~/.nix
mv nix-user-chroot-bin-1.2.2-x86_64-unknown-linux-musl nix-user-chroot
chmod +x nix-user-chroot
/home/aluno/nix-user-chroot ~/.nix bash -c 'curl -L https://nixos.org/nix/install | sh'

echo '. /home/aluno/.nix-profile/etc/profile.d/nix.sh' >> ~/.bashrc

# chroot bypassing
/home/aluno/nix-user-chroot ~/.nix bash <<"EOT"
. .bashrc

export PATH=$PATH:~/bin

nix-env -iA nixpkgs.emacs || die "it failed bruh"

nix-env -iA nixpkgs.ripgrep

yes | ~/.config/emacs/bin/doom install

mv configs/shared/.config/doom/* ~/.config/doom/

~/.config/emacs/bin/doom sync

EOT

This script first installs dwm locally, then we install nix locally as well with nix-user-chroot to install Doom Emacs, I install tectonic and texlab because I'm just using Emacs to use ORG mode in Uni.

That's it, it took some attempts to get it right and get everything setup correctly, but in the end it was easier than expected.

written by jabuxas contact info: jabuxas@proton.me

For months, I had been trying to find a way to get sudo access on my university's lab computers. As students, we didn't have any administrative privileges—no sudo, no root, nothing. The system seemed locked down tight. Every reboot, the /home directory reset, which made it feel like the system was immutable. But something didn’t add up.

A Lucky Discovery: Docker Group

One day, while looking into the system setup, I noticed something interesting: my user was in the docker group. This caught my eye because I remembered reading in the Gentoo Wiki that having Docker access can be just as powerful as root access. This made me realize there might be a way to leverage Docker to gain the control I needed.

Researching the Possibilities

I turned to Google and started exploring what I could do with Docker access. The possibilities were huge because Docker runs containers that act like mini virtual machines, and with root privileges in the container, you have a lot of power. One guide suggested that I could spin up a Docker container running Ubuntu, and from there, I could modify system files as if I were root.

Spinning Up the Container

I quickly set up a Docker container running Ubuntu. Once inside the container, I was effectively running with root privileges inside that environment. From there, I could start poking around in the system. My goal was to modify the sudoers file—the file that controls who has sudo access on the machine.

Editing the Sudoers File

Inside the container, I mounted the host’s file system, giving me access to crucial system files. Then, I edited the sudoers file to grant my user sudo access. To be safe, I made sure I was adding the correct syntax (myusername ALL=(ALL:ALL) ALL) to avoid locking myself out.

Once that was done, I exited the container and logged back in as my regular user. I tested sudo… and it worked! After months of trying different approaches, I finally had full administrative access.

Persistent Access Across Reboots

At first, I was worried that this was just a temporary fix, but I noticed something about the system's behavior. While the /home directory was wiped clean and restored from a tarball every time the system rebooted, the actual system files weren’t as locked down as they seemed. The changes I made to the sudoers file persisted across reboots.

This made it clear that the system wasn’t truly immutable. It just had a mechanism to reset student environments, making it look that way.

Conclusion

With Docker access, even on locked-down systems, you can do a lot more than it might seem at first glance. The experience taught me that having Docker privileges is a significant level of access, one that can lead to root-like control if used strategically.

written by jabuxas contact info: jabuxas@proton.me

Introduction

I've always wanted my own pastebin-like service, for reasons difficult to explain besides “being cool” and more importantly learning purposes, but I never got around to making it because I always thought it'd be a chore. But I can say, after making one, that it was an awesome project.

I don't think it's something that has a lot of uses for most people in the modern-day landscape, with big tech cloud services on every corner of the internet and messaging platforms having their own way of attaching things already. Nonetheless, it is very cool to just send an image with your domain name attached to it, right? Well, at least I've always wanted that.

I first learned about these when I started going to support channels, namely Gentoo Linux's. When there, users will send log outputs of programs, files, or whatever it is that they're having problems with, and that is, I think, the main use of pastebins today—at least in the IT area.

Getting Down to Actually Doing It

As I said, it took me a while to actually start writing it. I procrastinated for several reasons, but mostly because nowadays I wasn't really using IRC all that much anymore and so I had no reason to start doing it. I did try to write a basic one in Python, but that didn't go all that well, mostly because I didn't really know what I was doing and I started by tackling the most annoying things (which I'll explain later).

The push to get me started, though, was when I started getting involved in Chimera Linux's IRC channel. There was a developer there that had their own pastebin-like service, and that finally gave me the confirmation inside my head that it would be something cool to do. I asked about it to them, and they said that it was just a POST handler. Indeed, at its core, it's simply that. That sort of paved the way for me to know what I needed to search for to start doing it on my own, so after that, it was mostly just about doing it.

Writing the Server

Choosing the right language for your project can often be daunting. In my case, I opted for Go. Why? Simply because it feels right. Go, with its simplicity and efficiency, makes building HTTP servers a breeze, which is perfect for a project like this. It’s highly readable, compiles to a single binary and it's very performant. These factors made it an ideal choice for building my paste service.

The heart of the paste service is just handling HTTP POST requests. These requests contain the data that needs to be uploaded and stored, like text snippets, logs, or files. Once uploaded, the server generates a unique URL that points to the content.

Here’s a simplified version of how I handled the core functionality:

Setting Up the Server

In Go, setting up a basic HTTP server is straightforward:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/upload", uploadHandler)
    fmt.Println("Server started at :8080")
    http.ListenAndServe(":8080", nil)
}

This sets up an HTTP server listening on port 8080. Whenever a user makes a POST request to the /upload route, the server will trigger the uploadHandler function, which we’ll define next.

Handling File Uploads

To store uploaded content, we need to handle POST requests properly. Here's a basic function to do that:

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }

    file, handler, err := r.FormFile("file")
    if err != nil {
        http.Error(w, "Error retrieving the file", http.StatusBadRequest)
        return
    }
    defer file.Close()

    fmt.Fprintf(w, "Uploaded File: %v\n", handler.Filename)

    // ...
}

This handler checks if the request is a POST method, then parses the form to get the file. After retrieving the file, you can store it in a directory and return a unique URL for accessing it later

Generating the URL

Once you have the file uploaded, the next step is to generate a link to access it. This is where things can be a bit more flexible. You could store the file on your server or even upload it to a cloud service like AWS S3 if you want to get fancy. In this case, I stored the files locally and generated a simple link:

func generateLink(filename string) string {
    return fmt.Sprintf("https://yourdomain.com/uploads/%s", filename)
}

Now, when someone uploads a file, they get a URL to access it directly.

In my project I used a different format from what I'm doing here, but the gist of it is mostly the same.

Serving Uploaded Files

To serve the uploaded files, you need to create a new route that serves static content. Here’s how you can serve files from an uploads directory:

func main() {
    http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("./uploads"))))
    
    http.HandleFunc("/upload", uploadHandler)
    
    fmt.Println("Server started at :8080")
    http.ListenAndServe(":8080", nil)
}

This code ensures that any file placed in the uploads directory can be accessed via https://yourdomain.com/uploads/filename.

Lessons Learned

Building this project was a lot of fun and came with many “aha!” moments. One of the key things I learned was the importance of breaking down the problem. At first glance, creating a paste service seemed complex, but once I broke it down into handling uploads, serving files, and generating links, it became manageable.

Another big lesson was how easy Go makes it to build web servers. The standard library provides all the tools you need, without overcomplicating things. There’s no need for external frameworks (unless you want to), and that’s one of the beauties of Go—simplicity without sacrificing performance.

This project wouldn't have been possible without the many resources available out there like for example for encrypting and middleware logic that I wouldn't have known how to use without those articles. Also big thanks to the awesome Go documentation!

This is the link: https://github.com/jabuxas/abyss to my project in case you wanna check it out! I made it for myself but it has all things one would need for an awesome paste service in case you want to self-host it yourself. Thanks for reading.

written by jabuxas contact info: jabuxas@proton.me