eduolihez/eduolihez.com
GitHub: eduolihez/eduolihez.com
Astro 静态前端加自建 PHP/MySQL API 的三语个人作品集与博客系统,集成了严格的 Web 安全控制和隐私保护机制。
Stars: 0 | Forks: 0
# eduolihez.com
**Eduardo Olivares Hernández 的个人作品集** — SOC 分析师 / Blue Team
[](https://eduolihez.com)
[](https://astro.build)
[](https://www.php.net)
[](https://github.com/eduolihez/eduolihez.com/actions/workflows/codeql.yml)
[](LICENSE)
支持**西班牙语、英语和加泰罗尼亚语**的网站与作品集。前端使用 Astro 编译为静态 HTML;经常变动的内容——如项目、认证和博客——由基于 PHP 的自建 API 通过 MySQL 提供,并通过定制的后台管理面板进行管理。
该网站旨在作为一种实践演示:如果我的工作是保障他人系统的安全,那么我自己的系统至少应该经得起审查。在 **[eduolihez.com/sobre-esta-web](https://eduolihez.com/sobre-esta-web/)** 中详细说明了具体的安全控制措施及其原因。
## 架构
```
┌─ src/ Astro · compila a HTML estático ──► dist/ ──► FTP ──┐
│ │
│ ┌─────────▼────────┐
│ fetch /api/*.php ◄─────────────────────────────────────┤ CDMON · Apache │
│ │ Cloudflare/TLS │
└─ server/ PHP 8 + MySQL · API pública + /admin ─────►└─────────┬────────┘
│
┌────────▼───────┐
│ MySQL/MariaDB │
└────────────────┘
```
前端在生产环境中不需要 Node:直接上传已编译的 `dist/`。`server/` 原样上传,无需构建。由于两部分共享同一个域名,因此 API 使用相对路径调用,无需 CORS 标头。
| 层级 | 技术 |
| --- | --- |
| 前端 | Astro 7 (SSG), Tailwind CSS, TypeScript, 原生 i18n (ES/EN/CA) |
| 后端 | PHP 8 结合 PDO, MySQL/MariaDB,无框架 |
| 基础设施 | CDMON, Apache, Cloudflare, TLS |
| CI | CodeQL (JS/TS), Semgrep (PHP), Dependabot |
## 结构
| 路径 | 内容 |
| --- | --- |
| `src/` | Astro 的页面、组件、布局、静态数据和 i18n |
| `public/` | 原样提供的资源:图像、认证证书的 PDF、`robots.txt`、`security.txt` |
| `server/api/` | 只读的公共 API + 联系方式和分析端点 |
| `server/admin/` | 受会话保护的后台管理面板 |
| `server/lib/` | 共享核心:启动、HTTP helpers、上传、user-agent 解析 |
| `database/` | `schema.sql`(幂等:包含架构、迁移和初始内容)和 `clean.sql`(清空数据) |
| `scripts/` | 临时实用工具:生成图标和扩展程序的 CSS |
## 安全性
以下是已实现功能的概要。关于每一点的详细说明及原因,请参阅[该网站的技术页面](https://eduolihez.com/sobre-esta-web/)。
**前端**
- CSP 包含每次编译时重新计算的 SHA-256 哈希值;`script-src` 无 `'unsafe-inline'`。
- HSTS 设置为一年并包含 `includeSubDomains`,刻意不使用 `preload`。
- `X-Frame-Options: DENY`,COOP 和 CORP 设为 `same-origin`,限制性的 `Permissions-Policy`。
- 零第三方资源:自托管字体,无 CDN 或外部分析。
**后端与面板**
- 使用真正的预处理查询(`ATTR_EMULATE_PREPARES = false`),绝不使用字符串拼接。
- 所有表单均启用 CSRF 防护,使用 `hash_equals` 进行常量时间比较。
- 基于 IP 和时间窗口的暴力破解锁定机制。
- 登录后重新生成 ID 的会话,使用 `HttpOnly`/`Secure`/`SameSite=Lax` cookies,并设置基于不活动和绝对时间的双重过期机制。
- 登录时执行虚构的哈希验证,以确保响应时间不会暴露用户枚举信息。
- 上传文件通过真实的 MIME 类型(`finfo`)**和** `getimagesize()` 进行验证,限制尺寸、随机命名,并在目标文件夹中禁用代码执行。
- CSV 导出包含针对公式注入的防护措施。
**隐私**
- 自建分析系统,不使用 cookies,不涉及第三方。不存储 IP 地址:仅保存加盐的 SHA-256 哈希值。尊重 `Do Not Track` 请求,并通过自动清理程序限制数据保留期。
报告安全漏洞请参阅:[`SECURITY.md`](SECURITY.md) 或 [`/.well-known/security.txt`](https://eduolihez.com/.well-known/security.txt)。
## 启动说明
需要 Node 20 或更高版本。后端需要 PHP 8 和 MySQL/MariaDB 数据库。
```
npm install
npm run dev # http://localhost:4321
```
| 命令 | 功能 |
| --- | --- |
| `npm run dev` | 带热重载的开发服务器 |
| `npm run build` | 将站点编译到 `dist/` |
| `npm run preview` | 在本地提供 `dist/` 服务,以上传前进行检查 |
| `npm run icons` | 重新生成 favicons 和 PWA 图标 |
### 部署
1. `npm run build`。
2. 将 `dist/` 的**内容**上传到 Web 根目录(`public_html/`)。
3. 将 `server/` 上传到 Web 根目录,确保 API 位于 `/api/`,管理面板位于 `/admin/`。
4. 将 `server/config.example.php` 复制到 `server/config.php` 并填写凭据。此文件已包含在 `.gitignore` 中,**绝不能**上传到代码库。
5. 从 phpMyAdmin 导入 `database/schema.sql`。它是幂等的:无论是全新安装还是更新现有生产数据库都同样适用。
6. 在 `/admin/setup.php` 中创建管理员用户,并从服务器上**删除该文件**。
## 可见性与 SEO
- 统一的 JSON-LD 图谱(`Person`、`WebSite`、`ProfilePage`、`BreadcrumbList`、`FAQPage`)通过 `@id` 关联,每篇文章另有 `BlogPosting`。
- 相互关联的 `hreflang` 搭配 `x-default`,仅在存在翻译的地方声明。
- 每次编译时生成 Sitemap,包含每种语言的 `xhtml:link` 且仅保留可索引的 URL。
- 对故意移除的内容返回 `410 Gone`,对旧路由返回 `301`。
- [`/llms.txt`](https://eduolihez.com/llms.txt) 提供面向语言模型的纯文本摘要,数据源与网站相同。
- `robots.txt` 包含明确的策略:允许 AI 爬虫,屏蔽激进的商业 SEO。
## 许可证
代码采用 [MIT 许可证](LICENSE)。
个人内容——包括文本、照片、简历以及认证 PDF——不在此许可范围内,保留所有权利。您可以复用该实现代码,但不能复用其中的个人身份内容。标签:Astro, OpenVAS, PHP, 个人主页, 内容管理系统, 博客系统, 后端开发