Klice/homepki

GitHub: Klice/homepki

一个可自托管的轻量级私有 TLS 证书颁发机构,通过浏览器界面为内网服务和 Tailscale 节点签发、轮换与吊销自签名证书。

Stars: 0 | Forks: 0

# homepki 一个小型的、可自托管的 **web app**,用于运行你自己的私有 TLS 证书颁发机构。签发、轮换、吊销和下载证书; 配置部署目标;管理密码短语 —— **所有操作都在 浏览器中完成**。无需安装 `homepki` CLI:只需一个 Docker 容器 即可运行服务器并提供 UI。 ![homepki web UI](https://static.pigsec.cn/wp-content/uploads/repos/cas/67/67af325fb0221f041dd82cb54a6a57714e49dcc7d41b782770d402f90d9e4954.png) ## 为什么你可能需要它 **这个项目存在的原因:为 [Tailscale](https://tailscale.com/) 节点提供 HTTPS。** 如果你给你的 tailnet 机器起了像 `nas`、 `media` 或 `pi.tail-scale.ts.net` 这样友好的名称,Let's Encrypt 帮不上忙 —— 这些 名称不在公共 DNS 中。但是一旦你在每台 设备上信任了 homepki root,你的 tailnet 上的每个内部服务都会获得真正的 HTTPS,而没有 浏览器警告,并且证书使用你的设备实际 响应的任何名称:简短的 MagicDNS 名称、`*.lan` 别名、原始 tailnet IP。 同样的问题也出现在普通家庭实验室中 —— 位于 `nas.lan` 的 NAS, 位于 `192.168.x.x` 的路由器管理页面、Home Assistant 盒子、 自托管的 Git 服务器。Let's Encrypt 不会签发,浏览器警告很快就会让人厌烦, 而从博客文章中复制过来的 `openssl` 咒语很容易出岔子。 homepki 为你提供了缺失的中间环节: - 一个你在设备上信任一次的 **root CA**。 - 用于单个服务的 **Leaf certs**,带有正确的 SAN(`nas.lan`、 `192.168.1.10`、MagicDNS 名称)和你真正可以 轮换的短生命周期。 - **部署目标** 会将证书和密钥存放到 nginx / Caddy / haproxy 预期的磁盘路径上,之后还可以选择为你运行 `nginx -s reload`。 - 内置于每个证书中的 **公共 CRL endpoint**,这样当你吊销 证书时,你信任的设备就能真正获知。 - 使用你选择的密码短语进行静态加密。锁定应用后, 内存中的密钥会被擦除;磁盘上的私钥将变得不可读,直到 你再次解锁。 它故意做得很小:一个二进制文件、一个 SQLite 文件、一个操作者。没有 ACME 服务器,没有多租户 CA 仪表板。如果你需要这些,请使用 [step-ca](https://github.com/smallstep/certificates) 或 [EJBCA](https://www.ejbca.org/)。 ## 运行它 发布的镜像位于 `ghcr.io/klice/homepki`。选择符合 你需求的标签 —— `latest` 是最新的稳定版本, `vX.Y.Z` 固定到特定版本,而 `edge` 跟随 main 分支 (最前沿,可能是未发布的)。 ### 使用 Docker 快速开始 **1. 启动容器。** ``` docker run -d \ --name homepki \ -p 8080:8080 \ -v homepki-data:/data \ -e CRL_BASE_URL=http://localhost:8080 \ ghcr.io/klice/homepki:latest ``` **2. 在浏览器中打开 web UI** 。 首次访问时,你会看到 **首次运行设置** 界面 —— 选择一个 密码短语(≥ 12 个字符)并确认它。把它记在 安全的地方;没有它,加密的密钥将无法恢复。 **3. 从仪表板中签发你的第一个证书链**:一个 root CA,然后 是一个中间 CA,最后是你想要保护的服务的 leaf certs。 所有操作都是点击式的;不需要 `openssl`。 ### 使用 Docker Compose 如果你希望它在重启后依然存活并与其他 服务共存,请将以下内容放入 `docker-compose.yml`: ``` services: homepki: image: ghcr.io/klice/homepki:latest container_name: homepki restart: unless-stopped ports: - "8080:8080" volumes: - homepki-data:/data environment: # Required. Base URL clients use to fetch CRLs — baked into every # cert at issuance, so it must be reachable by the devices that will # verify those certs. http://localhost:8080 is fine if you only use # them on the host running homepki; otherwise use the address other # machines on your network see this service at. CRL_BASE_URL: http://homepki.lan:8080 # Address the HTTP server binds to inside the container. The image # always exposes 8080; change this only if you remap ports. # CM_LISTEN_ADDR: ":8080" # Where the SQLite database lives inside the container. The image # already declares /data as a volume; mount yours there. # CM_DATA_DIR: "/data" # If set, the app auto-unlocks at startup using this passphrase. # Convenient for unattended boxes; less secure than typing it into # the unlock screen each time. Leave unset to require manual unlock. # CM_PASSPHRASE: "" # Auto-lock after this many minutes of inactivity. Unset / 0 means # the app stays unlocked until you click Lock or restart it. # CM_AUTO_LOCK_MINUTES: "0" # Log format. "json" is friendlier for log shippers; "text" for tailing. # CM_LOG_FORMAT: "json" # UID/GID the homepki process drops to inside the container. The # entrypoint runs as root, recreates the homepki user at these # IDs, chowns /data, and then exec's the binary as that user. # Defaults to 1000:1000. Set PUID=99 PGID=100 on Unraid so the # appdata share's default ownership Just Works. # PUID: "1000" # PGID: "1000" volumes: homepki-data: ``` 然后: ``` docker compose up -d ``` 与单纯的 Docker 路径相同:在浏览器中打开 即可访问 web UI。 ### 在你的设备上信任 root CA 一旦你签发了 root CA,从其详情页面下载 `cert.pem` 并 将其添加到每台设备的信任存储中。以下是一些常见的: - **Linux (Debian/Ubuntu):** 将文件复制到 `/usr/local/share/ca-certificates/homepki-root.crt` 并运行 `sudo update-ca-certificates`。 - **macOS:** 双击 `.crt` 文件 → 钥匙串访问 → 将 *使用此证书时* 设置为 *始终信任*。 - **Windows:** 双击 → *安装证书* → *本地计算机* → *将所有证书放入* → *受信任的根证书颁发机构*。 - **Firefox:** 有自己的存储。*设置 → 隐私与安全 → 证书 → 查看证书 → 证书颁发机构 → 导入*。 - **Android / iOS:** 查阅适用于你版本的 *安装用户证书*; 现代 Android 会将用户安装的 root 视为值得警告,除非 你已经 root。 之后,homepki 在该 root 下签发的每个证书都将被信任,而不会出现警告。 ## 配置 所有配置均通过环境变量完成。 | 变量 | 默认值 | 作用 | | ----------------------- | ---------------- | ----------------------------------------------------------- | | `CRL_BASE_URL` | *必填* | 客户端用于获取 CRL 的 Base URL。内置于每个签发的证书中。 | | `CM_LISTEN_ADDR` | `:8080` | HTTP 服务器绑定的地址。 | | `CM_DATA_DIR` | `/data` | SQLite 数据库所在的路径。在此处挂载卷。 | | `CM_PASSPHRASE` | *未设置* | 如果设置,应用会在启动时自动解锁。对于无人值守的机器很方便;但不如每次在 UI 中输入密码短语安全。 | | `CM_AUTO_LOCK_MINUTES` | *未设置* | 在此分钟数不活动后自动锁定。未设置 / `0` 则禁用。 | | `CM_LOG_FORMAT` | `json` | `json` 或 `text`。 | ## 备份 停止容器并复制数据目录: ``` docker stop homepki cp -r /var/lib/docker/volumes/homepki-data/_data ~/homepki-backup docker start homepki ``` 或者,在运行期间使用 SQLite 的在线备份: ``` docker exec -it homepki \ sh -c 'sqlite3 /data/homepki.db ".backup /data/backup.db"' docker cp homepki:/data/backup.db ~/homepki-backup.db docker exec -it homepki rm /data/backup.db ``` 备份是一个常规的 SQLite 文件;恢复方法是停止容器, 替换该文件,然后再次启动它。 ## 将其置于反向代理之后 容器在 `:8080` 上使用纯 HTTP。大多数操作者会希望在前面有一个 终止 TLS 的反向代理 —— 并且它提供的证书当然 可以是由 homepki 自己签发的。nginx、Caddy、 Traefik 或 haproxy 中的任何一个都可以正常工作;homepki 本身并不在乎。 如果你的反向代理位于不同的主机上,请将 `CRL_BASE_URL` 指向 客户端将看到的 **公共** URL,而不是 `http://localhost:8080`。 ## 局限性 —— homepki 不是什么 - **不是 ACME 服务器。** 它不会响应 `acme.sh` 或 `certbot` 来签发证书;操作者(你)需要点击按钮。 - **不是多租户的。** 一个操作者、一个密码短语、一个 CA 层次结构。 - **v1 中没有 JSON / REST API。** 浏览器和 `curl` 使用相同的 HTML endpoint。证书 / 密钥 / CRL 下载是直接的 PEM/DER 响应,因此编写自动续期脚本很简单 —— 只是不是通过 单独的 API 表面。 ## 对于开发者 如果你想阅读设计或做出贡献,规范位于 [docs/](docs/): | 文档 | 阅读目的 | | --- | --- | | [SPEC.md](docs/SPEC.md) | 产品表面、技术栈、部署形态、环境变量。从这里开始。 | | [LIFECYCLE.md](docs/LIFECYCLE.md) | 锁定/解锁、KEK→DEK 密钥加密设计、轮换、吊销、CRL 重新生成。 | | [STORAGE.md](docs/STORAGE.md) | SQLite schema、迁移、事务、备份。 | | [API.md](docs/API.md) | 路由、请求/响应形态、状态码、幂等性。 | | [COLD_ROOTS.md](docs/COLD_ROOTS.md) | 在可移动数据库中冷存储根密钥的 v2 设计。 | 包含一个 devcontainer;在 VS Code 中使用 Dev Containers 扩展打开代码库即可获得一个可用的构建。`make help` 列出了 常见的开发者目标。 ## 许可证 [MIT](LICENSE)。
标签:CA, Docker, EVTX分析, TCP SYN 扫描, TLS证书, Web UI, 安全防御评估, 日志审计, 自托管, 请求拦截, 运维工具