jab's blog

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

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