OSO Minecraft Community IAAS and Website

Introduction

I initiated OSO to delve into game server hosting and type-1 hypervisors. My journey began with setting up a Minecraft server network featuring a proxy system, allowing players to seamlessly move between different Minecraft worlds through portals. As I refined my skills in Minecraft server configuration, I expanded my efforts to support the community by offering private server hosting as an educational project. This initiative involved a nominal fee to cover electrical and bandwidth costs and allowed me to manage services for over 300 users. The project's initial website was a static page hosted on an Ubuntu server managed via Apache, while OSO's Minecraft server network operated on separate Ubuntu server VMs. My ultimate goal was to create an intuitive control panel for private server hosting clients, providing them with VM access within my server cluster to manage files and gain console access through a web browser, eliminating the need for additional software.

Features

Security

The site implemented multiple security measures to protect user data. I set up a TLS certificate validated by Let's Encrypt to ensure secure communication. Passwords were hashed and salted to prevent them from being stored in plaintext, enhancing security against potential breaches. Additionally, the site employed session management to verify that sessions remained active and valid, preventing unauthorized access.

Console Access

Users are provided console access via NoVNC, an open-source VNC project. Proxmox employs NoVNC as an option for console access to VMs hosted on its hypervisor. Virtual Network Computing (VNC) is a desktop-sharing system that uses the remote frame buffer (RFB) protocol to enable remote system access through a browser. The OSO site leverages the Proxmox REST API to provide console-level access to private servers.

Special thanks to Dmitri Agababaev for his GitHub project - ProxmoxVE_API_php, which demonstrates the use of the Proxmox REST API for NoVNC connections and for his assistance via email.

// ------------------------------------------------------------------------------
//  © Copyright (с) 2020
//  Author: Dmitri Agababaev, d.agababaev@duncat.net
//
//  Redistributions and use of source code, with or without modification, are
//  permitted that retain the above copyright notice
//
//  License: MIT
// ------------------------------------------------------------------------------
public function noVNC($node, $vmid) {
    $conf = $this->post("/nodes/{$node}/qemu/{$vmid}vncproxy", [
        'websocket' => 1
    ]);
    $websock = $this->get("/nodes/{$node}/qemu/{$vmid}vncwebsocket", [
        'vncticket' => $this->ticket,
        'port'      => $conf['port']
    ]);
    setcookie('PVEAuthCookie', $this->ticket , 0, '/',$_SERVER['HTTP_HOST'], false);
    $src = "https://{$this->hostname}:{$this->port}/console=kvm&novnc=1&node={$node}&resize=scale&vmid{$vmid}&path=api2/json";
    $src .= "/nodes/{$node}/qemu/{$vmid}/vncwebsocketport/".$conf['port'];
    return $src;
}

File Access

For file management on the servers, I implemented File Browser, which allows users to modify, delete, and upload files within a specified directory through a web interface. The interface is akin to Dropbox, Google Drive, and OneDrive. The software was installed on each VM, with encrypted communication via TLS.

<table>
    <tr>
        <th style="padding:10px">
            <form method="post">
                <div class="Dcontainer">
                    <input style="background-image: url('/assets/images/terminal.png'); background-color: #272426; background-repeat: no-repeat; border-radius: 15px; background-size:95%; width: 70px; height:70px;" type="submit" name="terminal" class="button" value="" />
                </div>
            </form>
        </th>
        <?php 
            $sql = "SELECT * FROM users WHERE user_id='".$_SESSION['user_id']."';";
            $result = mysqli_query($cake, $sql);
            $resultCheck = mysqli_num_rows($result);
            if ($resultCheck > 0) {
                $row = mysqli_fetch_assoc($result);
                $url = $row['FileTransfer'];

                echo "<style>.fileImageButton {background-image: url('/assets/images/folder.png'); background-color: #272426; background-repeat: no-repeat; border-radius: 15px; background-size:100%; width: 70px; height:70px;}</style>";
                echo "<th style='padding:10px'><a href = '".$url."' target='_blank' rel='noopener'><input class='fileImageButton' type='submit' name='files' class='button' value='' /></a></th>";
            }
        ?>
    </tr>
</table>

Maintenance Calendar

To keep users informed about scheduled downtime, I integrated a calendar into the panel, linked to the OSO Google Calendar.

<div class="col">
    <iframe src="https://calendar.google.com/calendar/embed?height=600&amp;wkst=1&amp;bgcolor=%238E24AA&amp;ctz=America%2FNew_York&amp;src=bG4wODBlbjVqZzQyaWlkZzN0cmIwYzdocGNAZ3JvdXAuY29t&amp;color=%23F6BF26&amp;color=%230B80A3&amp;showTitle=0&amp;showNav=1&amp;showDate=1&amp;showPrint=0&amp;showTabs=1&amp;showCalendars=1&amp;showTz=1" style="border-width:0" width="100%" height="375" frameborder="0" scrolling="no"></iframe>
    <center><h4 style="padding-top: 5px; color:#f2f2f2; font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;">Maintenance Schedule</h4></center>
</div>

Discord Integration

To facilitate communication among users, I integrated the OSO Discord channel into the panel using Discord's widget.

<div class="col">
    <widgetbot server="7889655012744232" channel="801234342348980235" width="100%" height="375"></widgetbot>
    <script src="https://cdn.jsdelivr.net/npm/@widgetbot/html-embed"></script>
    <center><h4 style="padding-top: 5px; color:#f2f2f2; font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;">Chat With Us</h4></center>
</div>

Sources: