Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 80 additions & 80 deletions .promo_web/src/generated/site-data.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"generatedAt": "2026-06-10T09:00:14.690Z",
"generatedAt": "2026-06-19T18:05:15.920Z",
"requirements": {
"maxLab": {
"memory": 2048,
Expand All @@ -14,127 +14,127 @@
},
"labs": [
{
"id": "nginx-bad-gateway",
"title": "Nginx Bad Gateway",
"summary": "Scenario The monitoring team has alerted us that the company's main landing page is down, showing a \"502 Bad Gateway\" error.",
"category": "web",
"difficulty": "beginner",
"labId": "nginx-bad-gateway",
"updatedAt": "2026-06-10T09:00:13.093Z",
"id": "time-drift-broken",
"title": "Time Drift Breaks TLS and Package Operations",
"summary": "Scenario A maintenance script stopped refreshing packages after the machine's clock drifted far into the past.",
"category": "linux",
"difficulty": "intermediate",
"labId": "time-drift-broken",
"updatedAt": "2026-06-19T18:05:15.908Z",
"commit": "",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/nginx-bad-gateway",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/time-drift-broken",
"resources": {
"memory": 1024,
"cpu": 1,
"disk": 10
}
},
{
"id": "ca-certificates-missing",
"title": "HTTPS Downloads Fail Because CA Certificates Are Missing",
"summary": "Scenario A bootstrap service is supposed to download and install a tiny internal package from a local HTTPS endpoint.",
"id": "rsyslog-forwarding-broken",
"title": "Rsyslog Remote Forwarding Not Working",
"summary": "Scenario Local logs are written normally, but they never reach the central collector.",
"category": "linux",
"difficulty": "intermediate",
"labId": "ca-certificates-missing",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/ca-certificates-missing",
"difficulty": "advanced",
"labId": "rsyslog-forwarding-broken",
"updatedAt": "2026-06-19T18:05:15.817Z",
"commit": "",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/rsyslog-forwarding-broken",
"resources": {
"memory": 1024,
"cpu": 1,
"disk": 10
}
},
{
"id": "cron-broken",
"title": "Cron Job Never Executes",
"summary": "Scenario A system administrator configured a cron job to run a cleanup script /opt/cleanup.sh every minute.",
"category": "linux",
"difficulty": "beginner",
"labId": "cron-broken",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/cron-broken",
"id": "compose-service-dns-breaks-after-rename",
"title": "Compose Service DNS Breaks After Rename",
"summary": "Scenario A Compose-based proxy still references an old backend hostname after the service was renamed.",
"category": "docker",
"difficulty": "intermediate",
"labId": "compose-service-dns-breaks-after-rename",
"updatedAt": "2026-06-11T07:08:39Z",
"commit": "401e96d5c6abece75cc8c03ae4e3e4978b9f1ad1",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/compose-service-dns-breaks-after-rename",
"resources": {
"memory": 1024,
"cpu": 1,
"memory": 2048,
"cpu": 2,
"disk": 10
}
},
{
"id": "dns-broken",
"title": "DNS Resolution Failure",
"summary": "Scenario A teammate changed DNS settings on this server.",
"category": "linux",
"id": "docker-entrypoint-flags",
"title": "Container Entrypoint Uses Wrong Command Flags",
"summary": "Scenario A container image builds, but the application exits right away because the default command still uses an obsolete flag name.",
"category": "docker",
"difficulty": "beginner",
"labId": "dns-broken",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/dns-broken",
"labId": "docker-entrypoint-flags",
"updatedAt": "2026-06-11T07:08:39Z",
"commit": "401e96d5c6abece75cc8c03ae4e3e4978b9f1ad1",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/docker-entrypoint-flags",
"resources": {
"memory": 1024,
"cpu": 1,
"memory": 2048,
"cpu": 2,
"disk": 10
}
},
{
"id": "docker-broken",
"title": "Docker Daemon Crash",
"summary": "Scenario A developer was trying to configure the Docker daemon to use a custom data root (/var/lib/docker_custom), but something went wrong and now the docker service refuses to st",
"category": "containers",
"difficulty": "advanced",
"labId": "docker-broken",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/docker-broken",
"id": "docker-loopback-bind",
"title": "Container Port Binds Only to Loopback",
"summary": "Scenario The container starts, but the Open Port path cannot reach it because the service only listens on localhost inside the container.",
"category": "docker",
"difficulty": "intermediate",
"labId": "docker-loopback-bind",
"updatedAt": "2026-06-11T07:08:39Z",
"commit": "401e96d5c6abece75cc8c03ae4e3e4978b9f1ad1",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/docker-loopback-bind",
"resources": {
"memory": 1024,
"cpu": 1,
"memory": 2048,
"cpu": 2,
"disk": 10
}
},
{
"id": "docker-restart-loop",
"title": "Container Restart Loop",
"summary": "Scenario A web application container web-app has been deployed on this server.",
"category": "containers",
"id": "docker-multi-stage-copy-path",
"title": "Docker Multi-Stage COPY Path",
"summary": "Scenario A container image stopped building after a refactor changed the artifact path in a multi-stage Dockerfile.",
"category": "docker",
"difficulty": "intermediate",
"labId": "docker-restart-loop",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/docker-restart-loop",
"labId": "docker-multi-stage-copy-path",
"updatedAt": "2026-06-11T07:08:39Z",
"commit": "401e96d5c6abece75cc8c03ae4e3e4978b9f1ad1",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/docker-multi-stage-copy-path",
"resources": {
"memory": 1024,
"cpu": 1,
"memory": 2048,
"cpu": 2,
"disk": 10
}
},
{
"id": "fstab-broken",
"title": "Filesystem Missing After Reboot",
"summary": "Scenario A teammate configured a secondary storage volume (modeled as /opt/data.img) to automatically mount at /mnt/data on boot.",
"category": "linux",
"difficulty": "intermediate",
"labId": "fstab-broken",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/fstab-broken",
"id": "mysql-max-connections",
"title": "MySQL Max Connections Too Low",
"summary": "Scenario The application team reports that their service is frequently crashing with \"Too many connections\" errors from the MySQL database during peak traffic.",
"category": "database",
"difficulty": "advanced",
"labId": "mysql-max-connections",
"updatedAt": "2026-06-11T10:34:25+05:30",
"commit": "b808c27234405689f673dc646fedd176d90cdc4c",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/mysql-max-connections",
"resources": {
"memory": 1024,
"cpu": 1,
"disk": 10
"memory": 2048,
"cpu": 2,
"disk": 20
}
},
{
"id": "full-disk",
"title": "The Full Filesystem",
"summary": "Scenario A critical service on this system has failed to start or is operating extremely slowly.",
"category": "linux",
"difficulty": "beginner",
"labId": "full-disk",
"updatedAt": "2026-06-10T13:36:17+05:30",
"commit": "620c6961a1686b5117c37f67ea7fa6d31814bfac",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/full-disk",
"id": "nginx-rate-limiting",
"title": "Nginx Aggressive Rate Limiting",
"summary": "Scenario Users are reporting that the /api/ endpoint of our web application is intermittently failing with 429 Too Many Requests errors, even when they aren't sending many requests",
"category": "web",
"difficulty": "advanced",
"labId": "nginx-rate-limiting",
"updatedAt": "2026-06-11T10:34:25+05:30",
"commit": "b808c27234405689f673dc646fedd176d90cdc4c",
"url": "https://github.com/HimanM/BrokenOps/tree/main/labs/nginx-rate-limiting",
"resources": {
"memory": 1024,
"cpu": 1,
Expand Down
31 changes: 31 additions & 0 deletions labs/rsyslog-forwarding-broken/cloud-init.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#cloud-config
packages:
- rsyslog
- socat
write_files:
- path: /etc/systemd/system/collector.service
owner: root:root
permissions: '0644'
content: |
[Unit]
Description=BrokenOps syslog collector
After=network.target

[Service]
ExecStart=/usr/bin/socat -u TCP-LISTEN:1514,reuseaddr,fork OPEN:/var/log/collector.log,append
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target
- path: /etc/rsyslog.d/50-forward.conf
owner: root:root
permissions: '0644'
content: |
*.* @127.0.0.1:1514
runcmd:
- systemctl daemon-reload
- touch /var/log/collector.log
- systemctl enable --now collector.service
- systemctl enable --now rsyslog
- systemctl restart rsyslog
25 changes: 25 additions & 0 deletions labs/rsyslog-forwarding-broken/lab.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
id: rsyslog-forwarding-broken
name: Rsyslog Remote Forwarding Not Working
category: linux
difficulty: advanced
vm:
name: rsyslog-lab
image: ubuntu-24.04-base.qcow2
cpu: 1
memory: 1024
disk: 10G
cloud_init: cloud-init.yaml
verify_script: verify.sh
description:
summary: "Local logs are written, but they never reach the remote collector."
story: "A systems administrator set up remote log forwarding so the local server can ship syslog events to a central collector. The collector is running, but forwarded messages never arrive. Fix the rsyslog forwarding rule so remote logs are delivered again."
objectives:
- Inspect the rsyslog forwarding configuration
- Find why messages are not reaching the collector
- Fix the forwarding protocol or endpoint and confirm receipt on the collector
- Ensure rsyslog remains healthy after the change
tags:
- linux
- rsyslog
- logging
- networking
19 changes: 19 additions & 0 deletions labs/rsyslog-forwarding-broken/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Scenario

Local logs are written normally, but they never reach the central collector. The collector service is up, yet forwarded syslog messages are missing.

Fix the forwarding rule so the remote collector receives the logs again.

### Objective

1. Inspect the rsyslog forwarding configuration.
2. Identify why messages are not reaching the collector.
3. Fix the forwarding protocol or endpoint and confirm receipt on the collector.
4. Verify rsyslog remains healthy after the change.

### Useful Commands

- `systemctl status rsyslog`
- `rsyslogd -N1`
- `cat /etc/rsyslog.d/50-forward.conf`
- `logger -t brokenops-rsyslog "test message"`
31 changes: 31 additions & 0 deletions labs/rsyslog-forwarding-broken/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
### The Issue

The forwarding rule used the wrong transport. The collector listens on TCP, but the rsyslog rule was sending UDP packets, so the messages never arrived.

### Step-by-Step Fix

1. **Inspect the forwarding rule**:
```bash
cat /etc/rsyslog.d/50-forward.conf
```
You should see a single `@` in the forwarding target.

2. **Validate the configuration**:
```bash
sudo rsyslogd -N1
```
That confirms the syntax is valid, but it does not guarantee the collector will receive the message.

3. **Switch the rule to TCP forwarding**:
Change the rule to use a double `@@`:
```bash
sudo sh -c 'printf "*.* @@127.0.0.1:1514\n" > /etc/rsyslog.d/50-forward.conf'
sudo systemctl restart rsyslog
```

4. **Send a test log message**:
```bash
logger -t brokenops-rsyslog "rsyslog forwarding test"
tail -n 20 /var/log/collector.log
```
Once the transport matches the collector, the message shows up in the log file.
8 changes: 8 additions & 0 deletions labs/rsyslog-forwarding-broken/solution.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -euo pipefail

cat > /etc/rsyslog.d/50-forward.conf <<'EOF'
*.* @@127.0.0.1:1514
EOF

systemctl restart rsyslog
32 changes: 32 additions & 0 deletions labs/rsyslog-forwarding-broken/verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
set -euo pipefail

LOG_FILE=/var/log/collector.log
TEST_TAG=brokenops-rsyslog
TEST_MESSAGE="rsyslog forwarding test $(date -Is)"

if ! systemctl is-active --quiet rsyslog; then
echo "FAILURE: rsyslog is not running."
exit 1
fi

if ! rsyslogd -N1 >/tmp/rsyslog-syntax.log 2>&1; then
cat /tmp/rsyslog-syntax.log
echo "FAILURE: rsyslog configuration still has syntax errors."
exit 1
fi

logger -t "$TEST_TAG" "$TEST_MESSAGE"
sleep 2

if [ ! -f "$LOG_FILE" ]; then
echo "FAILURE: The collector log was not created."
exit 1
fi

if ! grep -q "$TEST_TAG" "$LOG_FILE" || ! grep -q "$TEST_MESSAGE" "$LOG_FILE"; then
echo "FAILURE: The forwarded log message never reached the collector."
exit 1
fi

echo "SUCCESS: rsyslog forwards messages to the remote collector successfully."
Loading
Loading