本文同步发布于我的个人博客:https://sunjx97.github.io/
前言
自从入坑 NAS 以来,(黑)群晖一直都是我文件存储管理的得力助手。但随着我的圈内吹水日益熟练学习和理解不断加深,黑裙已不能满足我的需求。如今,是时候告别(黑)群晖,往更专业的自建服务器方向发展了。其中关键的一步,便是找到能方便替换群晖反向代理服务的开源项目,而 nginx proxy manager 给了我一个很好的选择。
nginx proxy manager介绍
nginx proxy manager 能让我们轻松地转发到在家里或其他地方运行的网站,包括免费的 SSL,而不需要对 Nginx 或 Let's Encrypt 了解太多。便捷直观的 web 页面管理和操作无疑大大简化了一般 nginx 反代服务的步骤。
docker 安装 nginx proxy manager
推荐使用 docker-compose 安装
version: "3"
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Uncomment the next line if you uncomment anything in the section
# environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
浏览器输入【docker主机ip:81】,成功进入 web 页面,初次登录使用邮箱:admin@example.com,密码:changeme。

登录进去后会让你设置管理员的用户名(Full Name),昵称(Nickname)和邮箱。

接下来设置密码,旧密码即预设密码 changeme。

至此,nginx proxy manager 初始化完成。
使用nginx proxy manager实现反向代理
登录进入主面版,点击 Proxy Hosts 转到反向代理设置界面。

点击 Add Proxy Host,添加一个反向代理。

在 Details 页面,Domain Names 填写你的域名,Scheme 填写反代对象的协议(http/https),Forward Hostname/IP 填写反代对象的地址,Forward Port 填写反代对象的端口号。

如果有 https 加密需求,转到 SSL 页面,将 SSL Certificate 选择为你申请的证书,建议勾选 SSL Force(强制 SSL)。

点击保存,在反向代理页面可以看到刚刚设置的反向代理。

测试相应网站,反代成功。
SSL证书申请
HTTP-01 验证方式
最简单常规的 SSL 证书申请方式,如果你的主机可以放行 80 端口(如在各大公有云处购买的主机),推荐使用这种方式。我这边没有虚拟主机,家用 80 端口也被封锁了,所以也没用过这种方式,姑且放在这里给大家参考_(:3」∠)_
转到反代编辑页面,在 SSL 页面选择 Request a new SSL Certificate,建议勾选 SSL Force(强制 SSL),打开勾选 I Agree to the Let's Encrypt Terms of Service 同意 Let's Encrypt 相关条款,点击保存。

可以看到反代已自动申请 SSL 证书,可以通过 https 访问了。证书有效期 3 个月,到期会自动续期。
DNS-01 验证方式
因为国内 ISP 一般都封锁了 80 端口,所以 HTTP-01 验证方式大概率在家庭自建服务器的情况下不会成功。作为替代,我们可以选择使用 DNS-01 的验证方式来申请 SSL 证书。相较于 HTTP-01,DNS-01 可以申请[支持通配符的域名证书](https://letsencrypt.org/zh-cn/docs/challenge-types/),也算弥补了其操作繁琐的缺点。这里以 DNSPOD 和 Cloudflare 为例:
DNSPOD
1. 申请 api key
首先登录 DNSPOD 控制台,在右上角找到 API 密钥 项。

转到 DNSPod Token 页面,点击创建密钥。

设置密钥名称

查看并保存ID和Token项,这里的内容只会显示一次,一定要保存好。

已经能在总览看到相关 API 已申请成功。

2. 配置 nginx proxy manager 并申请 SSL 证书
点击 SSL Certificates,转到 SSL Certificates 页面;再点击右上角 Add SSL Certificate,选择 Let's Encrypt。

如下图,Domain names 填写自己的域名,Email Address for Let's Encrypt 填写自己的邮箱。
打开 Use a DNS Challenge,DNS Provider 选择 DNSPod,将dns_dnspod_email 中的 DNSPOD-API-REQUIRES-A-VALID-EMAIL 替换为 DNSPod 的邮箱,dns_dnspod_api_token 中的 DNSPOD-API-TOKEN 替换为【id,token】的形式(即在上一步申请得到的id和token),注意不要删掉英文双引号,且 id 与 token 用英文逗号连接。
勾选 I Agree to the Let's Encrypt Terms of Service 同意 Let's Encrypt 相关条款,点击保存。

可以看到 SSL 证书已经申请完成,有效期 3 个月,到期会自动续期。

CloudFlare
1. 获取 api key
打开[个人资料 - API 令牌](https://dash.cloudflare.com/profile/api-tokens),找到 API 密钥,查看并复制 Global API Key。
2. 配置 nginx proxy manager 并申请 SSL 证书
同上,不过要将申请信息进行替换(初始的只有 api token 的形式申请会有问题)。something@hotmail.com 替换为 cloudflare 的邮箱,0123456789abcdef0123456789abcdef01234567 替换为上面得到的 Global API Key。
# Cloudflare API token
dns_cloudflare_email = something@hotmail.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567
附录:需要开启 Websockets Support 的应用/网站
Proxmox VE:不开启会导致 novnc 连接错误
jlesage/jdownloader-2:不开启会无法进入 webui 管理页面
truenas:不开启会导致 webui 无法登录
portainer/portainer-ce:不开启无法对容器使用 console
参考资料
Nginx Proxy Manager https://nginxproxymanager.com/guide/#project-goal
验证方式 - Let’s Encrypt https://letsencrypt.org/zh-cn/docs/challenge-types/
【Docker系列】一个反向代理神器——Nginx Proxy Manager https://www.bilibili.com/video/BV1Gg411w7kQ
【Docker系列】一个反向代理神器——Nginx Proxy Manager https://blog.laoda.de/archives/nginxproxymanager
certbot dns插件 https://www.jianshu.com/p/659dc904967f