前言

最开始的想法是,如果仅用一个树莓派只做一个pi-hole 会不会太浪费了,这么大一个树莓派,那么多的端口,可以做的东西很多,至少还能承担起一个内网导航的功能吧。

于是乎有了这篇文章。

正文

我们这里的想法是,导航页用80端口,然后pi-hole走子路径(Restful 格式),我们只要反向代理pi-hole的管理页面即可

1. Pi-hole的web端口改至8081

因为现在的80端口被pihole-FTL占着,我们需要把它改到8081,然后把80让给我们的导航页面。

# 1) 备份配置
sudo cp /etc/pihole/pihole.toml /etc/pihole/pihole.toml.bak

# 2) 编辑 pihole.toml
sudo vim /etc/pihole/pihole.toml

在文件中找到[webserver] 中的port(注意要用引号,只用8081 会不识别并且重置回默认值。)

[webserver]
port = "8081"

保存后重启:

sudo systemctl restart pihole-FTL

快速自测(Raspberry Pi上):

curl -I http://127.0.0.1:8081/admin/ | head -n1
# 期望:HTTP/1.1 200 OK 或 302

成功:

2. 安装 并 配置nginx(占80端口,反代到8081)

2.1 安装nginx

sudo apt update
sudo apt install -y nginx

2.2 建立导航页面

导航页面放在 /var/www/html/index.html index.html代码如下(这个只是一个例子,完全可以建立一个不一样的 index.html 页面):

<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>内网导航</title>
  <style>
    body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;background:#0f172a;color:#e5e7eb}
    .wrap{max-width:900px;margin:6rem auto;padding:0 1rem}
    h1{font-size:2rem;margin:0 0 1.25rem}
    .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}
    a.card{display:block;padding:18px;border-radius:14px;background:#111827;text-decoration:none;color:#e5e7eb;border:1px solid #1f2937}
    a.card:hover{border-color:#334155;background:#0b1220}
    .muted{color:#94a3b8;font-size:.9rem;margin:.5rem 0 0}
  </style>
</head>
<body>
  <div class="wrap">
    <h1>🧭 我的内网导航</h1>
    <div class="grid">
      <a class="card" href="/pihole/"><b>Pi-hole 控制台</b><div class="muted">/pihole/</div></a>
      <a class="card" href="http://192.168.1.1/"><b>路由器</b><div class="muted">192.168.1.1</div></a>
      <a class="card" href="http:/192.168.1.1/cu.html"><b>路由器(超级管理员)</b><div class="muted">192.168.1.1/cu.html</div></a>
    </div>
  </div>
</body>
</html>

2.3 建立nginx站点配置(反代 /admin /api -> 8081的 /admin 和 /api)

这里我们需要精确地代理/admin 和 /api 因为,pihole的web容器端写的就是/admin 我们如果用其他子标签的话,会404,nginx配置页面放在 /etc/nginx/sites-available/home.lan 这也是我们的主页在内网中的域名:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name home.lan 192.168.1.50;

    root /var/www/html;
    index index.html;

    # 把 /admin 重定向到 /admin/(补斜杠,避免静态资源相对路径问题)
    location = /admin { return 301 /admin/; }
    # 反向代理到 Pi-hole 内置 Web 的 /admin/
    location /admin/ {
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # 去掉 /pihole/ 前缀再转发到 /admin/
        proxy_pass http://127.0.0.1:8081/admin/;
        # 避免错误的自动重定向回根
        proxy_redirect off;
    }

    # 把 /api 重定向到 /api/(补斜杠,避免静态资源相对路径问题)
    location = /api{ return 301 /api/; }
    # 反向代理到 Pi-hole 内置 Web 的 /api/
    location /api/ {
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # 去掉 /pihole/ 前缀再转发到 /api/
        proxy_pass http://127.0.0.1:8081/api/;
        # 避免错误的自动重定向回根
        proxy_redirect off;
    }

    # 可选:把根路径 404 变更为导航页(通常不需要,因为已经有 index)
    error_page 404 =200 /index.html;
}

2.4 启用 并 重载

sudo ln -sf /etc/nginx/sites-available/home.lan /etc/nginx/sites-enabled/home.lan
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx

2.5 健康检查

现在我们就可以测试一下了,对于树莓派我们可以测试:

# 树莓派本机:
curl -I http://127.0.0.1/ | head -n1          # 期望 200
curl -I http://127.0.0.1/admin/ | head -n1    # 期望 200 或 302

成功!(admin 302 Found 大概就是因为登陆要密码的原因,我猜测):

对于局域网的电脑,我们可以测试:

# 局域网电脑:
nslookup home.lan    # 应该解析到 192.168.1.50

成功!

3. 页面展示

这就是暂时的内网导航页面啦:

总结

就是酱紫!现在对于nginx的配置,也越来越了解了,想当年4年前创建halo的时候,对于nginx完全的,百分百的复制,完全不知道是在说什么东西呢...

参考

[1] ChatGPT
[2] 自己

立志做一个有趣的碳水化合物。