dimidotdev/logline

GitHub: dimidotdev/logline

Logline 是一个安全优先的多云日志访问控制台,通过本地云模拟器实现可复现的跨 AWS、Azure 和 GCP 日志发现与下载体验。

Stars: 0 | Forks: 0

# Logline Logline 是一个安全的 backend-for-frontend 和操作控制台,用于跨云服务提供商发现和下载日志对象。其本地环境完全可复现,且不需要个人云账户。 该演示针对本地模拟器运行 AWS S3、Azure Blob Storage 和 Google Cloud Storage 适配器。它只需一条命令即可植入代表性日志、启动 Java API 并运行 React 应用程序。 ## 快速开始 ### 前置条件 - Docker 及 Docker Compose v2 无需在本地安装 Java、Maven、Node.js 或云 CLI。 ``` docker compose up --build --wait ``` 首次构建会下载提供商 SDK 和模拟器镜像,可能需要几分钟;后续构建将重用 Docker 和 Maven 缓存。 打开 [http://localhost:3000](http://localhost:3000)。 | 角色 | 用户名 | 密码 | 权限 | | --- | --- | --- | --- | | Viewer | `viewer` | `viewer123` | 列出并下载日志 | | Administrator | `admin` | `admin123` | Viewer 权限,外加临时链接 | 使用以下命令停止应用程序并删除其确定性演示数据: ``` docker compose down --volumes ``` 上述所有凭据均为有意公开的本地演示值。绝不可在此 Compose 环境之外重用。 ## 用户旅程 1. 使用其中一个明确标识的本地配置文件登录。 2. 选择加入白名单的 AWS、Azure 或 GCP 源。 3. 检查对象计数、数据量、时间线、类型分布,以及根据当前结果集计算的确定性操作洞察。 4. 按 prefix 过滤,使用对 URL 和界面隐藏的不透明 continuation cursor 进行分页,并下载已授权的对象。BFF 通过一个有限的 executor 流式传输提供商字节。 5. 作为管理员,请求一个短期的 AWS 预签名 URL。 该界面包括响应式导航、深色和浅色主题、可访问的加载/错误/空状态,以及每个提供商的明确能力指示器。 它基于 shadcn/ui Base UI + Lyra 预设 `b3Rq8QyAs`,并使用了 JetBrains Mono 和 Hugeicons,然后添加了专门构建的炭灰色视觉系统:方形几何图形、中性表面,以及专用于状态和交互强调的酸橙色。 ### 工作界面 以下屏幕截图捕获自已植入数据的模拟器上的容器化应用程序。 #### 安全登录 ![Logline 安全登录](https://static.pigsec.cn/wp-content/uploads/repos/cas/30/3098a5339779d317c6c431fb41e771d6f34526b02b757ebf62f0c189e5e7fc0f.png) #### 多云日志控制室 ![Logline 仪表板显示确定性指标和云日志对象](https://static.pigsec.cn/wp-content/uploads/repos/cas/5c/5c7a497099c88d7e3092cbef8b4d1dd53f971158ab03b69a42c6a81a4a2f7614.png) #### 管理员临时链接流程 ![创建临时 AWS 链接后的 Logline 管理员页面](https://static.pigsec.cn/wp-content/uploads/repos/cas/25/2599804ada4989b439059df57d67011f895d4dde06adc4c9a90be47377504590.png) ## 架构 ``` flowchart LR Browser[React operations console] -->|same-origin /api| Nginx[Nginx] Nginx --> API[Spring Boot BFF] API --> Auth[Session + CSRF + RBAC] API --> Port[Object storage port] Port --> S3[AWS SDK adapter] Port --> Azure[Azure SDK adapter] Port --> GCS[GCP SDK adapter] S3 --> LocalStack[(LocalStack S3)] Azure --> Azurite[(Azurite)] GCS --> FakeGCS[(fake-gcs-server)] ``` 浏览器选择的是受信任的 `sourceId`,而不是原始 endpoint 或凭据。服务器将该标识符解析为已列入白名单的提供商、bucket/container 和 prefix。提供商 SDK 类型保留在其各自的 adapter 内部。 | 提供商 | 本地实现 | 列出 | 下载 | 临时链接 | | --- | --- | :---: | :---: | :---: | | AWS S3 | LocalStack | 是 | 是 | 是,预签名 GET | | Azure Blob Storage | Azurite | 是 | 是 | 未提供 | | Google Cloud Storage | fake-gcs-server | 是 | 是 | 未提供 | 临时链接支持被建模为一种能力,而不是假装每个提供商和模拟器都具有相同的行为。 ## 安全模型 - Spring Security 将经过身份验证的会话存储在 HttpOnly、SameSite cookie 中。 - 登录、登出和临时链接操作需要 CSRF token。 - 浏览器仅持久化非敏感的用户元数据,并在释放受保护的路由之前始终重新验证会话。 - 后端角色具有权威性:`VIEWER` 可以列出/下载,`ADMIN` 还可以发布临时链接。 - 源和 prefix 是服务器端白名单。在进行任何 SDK 调用之前,都会验证对象键。 - 下载通过有限的异步执行、安全的 content disposition 和 private/no-store 缓存进行流式传输。 - 签名链接的生命周期被限制在 60-3,600 秒内,并且会首先验证对象是否存在。 - Java runtime 使用专用的非特权用户。其他容器保留其上游镜像默认值;除了浏览器端签名 URL 所需的 LocalStack loopback 端口外,模拟器端口均被隔离。 - 宿主机云凭据永远不会被本地 Compose 环境继承。 - Nginx 应用本地登录限制,并在超出限制时返回带有 `Retry-After` 的 RFC Problem Details。 LocalStack endpoint 有意仅在开发者的 loopback 接口上可访问,因为预签名 URL 直接从对象存储下载数据。 它包含伪造的植入数据,不是生产环境的安全边界。 对于公共部署,请使用 TLS,设置 `SESSION_COOKIE_SECURE=true`,用组织的身份提供商替换演示用户,应用网关速率限制,并使用真正的机密管理。内存中的 HTTP 会话在水平扩展之前还需要共享会话存储或无状态设计。 ## API 示例 这些示例使用前端源,因为 Nginx 同时公开了 API 和 UI。 ### 建立 CSRF 状态并登录 ``` curl --silent --cookie-jar cookies.txt \ http://localhost:3000/api/v1/auth/csrf ``` 从响应中复制 `csrfToken`: ``` { "csrfToken": "", "headerName": "X-CSRF-Token", "parameterName": "_csrf" } ``` ``` curl --silent \ --cookie cookies.txt \ --cookie-jar cookies.txt \ --header 'Content-Type: application/json' \ --header 'X-CSRF-Token: ' \ --data '{"username":"admin","password":"admin123"}' \ http://localhost:3000/api/v1/auth/login ``` 登录会轮换 CSRF token 并返回经过身份验证的身份: ``` { "user": { "username": "admin", "roles": ["ADMIN"] }, "csrf": { "csrfToken": "", "headerName": "X-CSRF-Token", "parameterName": "_csrf" } } ``` ### 列出已配置的源 ``` curl --silent --cookie cookies.txt \ http://localhost:3000/api/v1/sources ``` 以下响应经过了精简;运行中的本地环境会返回 AWS、Azure 和 GCP 条目。 ``` { "items": [ { "id": "aws-audit", "name": "AWS audit logs", "provider": "AWS", "capabilities": { "list": true, "download": true, "temporaryLink": true } } ] } ``` ### 列出并下载日志 ``` curl --silent --cookie cookies.txt \ 'http://localhost:3000/api/v1/sources/aws-audit/logs?limit=25&prefix=2026/07' curl --cookie cookies.txt --remote-header-name --remote-name \ 'http://localhost:3000/api/v1/sources/aws-audit/logs/download?key=logs%2F2026%2F07%2F23%2Fapi-002.log' ``` 精简的列表响应如下所示: ``` { "items": [ { "key": "logs/2026/07/23/api-002.log", "size": 282, "lastModified": "2026-07-23T21:15:00Z", "etag": "" } ], "nextCursor": null } ``` 当存在另一个提供商页面时,列表响应包含 `items` 和不透明的 `nextCursor`。 ### 请求 AWS 临时链接 使用登录时返回的已轮换的 CSRF 值,或再次调用 `/api/v1/auth/csrf`。 ``` curl --silent \ --cookie cookies.txt \ --header 'Content-Type: application/json' \ --header 'X-CSRF-Token: ' \ --data '{"key":"logs/2026/07/23/api-002.log","expiresIn":300}' \ http://localhost:3000/api/v1/sources/aws-audit/logs/temporary-link ``` ``` { "url": "http://localhost:4566/demo-aws-logs/...?X-Amz-Signature=...", "expiresAt": "2026-07-24T02:15:00Z" } ``` 错误遵循 RFC Problem Details (`application/problem+json`)。 ## 开发 ### 后端检查 Java 21 是编译和 runtime 目标。 ``` cd backend ./mvnw verify ./mvnw spring-boot:run ``` ### 前端检查 ``` cd frontend npm ci npm run lint npm test npm run build npm run dev ``` 在本地开发期间,Vite 会将 `/api` 代理到 `http://localhost:8080`。 这些命令对于隔离检查和迭代非常有用。包含功能的三个提供商环境、植入的数据和演示身份通过 Compose 快速启动;在该拓扑结构中,后端有意不向宿主机公开。 ## 配置 默认的 Compose 环境是刻意自包含的。相关的后端设置包括: - `APP_DEMO_SEED` 和 `APP_DEMO_USERS_ENABLED` - `DEMO_*` 源和用户设置 - `AWS_ENDPOINT`、`AWS_PUBLIC_ENDPOINT`、`AWS_REGION` 和 `AWS_PATH_STYLE_ACCESS` - `AZURE_STORAGE_CONNECTION_STRING` - `GCS_ENDPOINT` 和 `GCS_PROJECT_ID` - `SESSION_COOKIE_SECURE` 当提供真实的、最小权限凭据和适当的公共签名 endpoint 时,AWS adapter 也可以与 AWS S3 或兼容 S3 的 endpoint 一起使用。 本地模拟器验证的是契约和可复现性,而不是完整的云行为或服务级别保证。 ## 质量关卡 GitHub Actions 执行后端验证、前端 runtime 依赖审计、lint/test/build、Compose 配置验证以及完整的容器化用户旅程。在本地,相同的检查通过上述 Maven 和 npm 脚本运行。 在 `docker compose up --build --wait` 之后,使用以下命令验证完整的容器化旅程: ``` ./scripts/smoke-test.sh ``` 冒烟测试会登录,从所有三个提供商处列出并下载植入的数据,跟随 AWS 预签名 URL,并验证 viewer 无法创建该 URL。 重要决策以简短的 ADR 形式记录在 [`docs/decisions`](docs/decisions) 中,包括多云边界、本地模拟和浏览器会话策略。透明的 AI 辅助工作流及其人工审查政策记录在 [`docs/ai-assisted-engineering.md`](docs/ai-assisted-engineering.md) 中。 ## 仓库结构 ``` backend/ Java 21 / Spring Boot BFF frontend/ React / TypeScript operations console docs/decisions/ Architecture decision records .github/workflows/ CI quality gates compose.yaml One-command local cloud environment scripts/ End-to-end smoke test ```
标签:Docker Compose, OISF, React, Syscalls, 多云管理, 日志管理, 版权保护, 自动化攻击, 请求拦截, 运维控制台