前期准备(默认你已经具备)
- 如果你的内网nas使用的是群晖系统,则一定要先干掉系统自带的的nginx
- 一个合法的域名。(本文均使用www.rikinyoung.com示例)
- 公网服务器,无需高配。
- 你的内网nas。(后文均使用docker安装所用项目)
- 均能使用ssh连接上述两台实例。
- 文中代码块出现的中文部分,均需根据读者情况自行修改。
- 会使用命令行等方式安装和启动docker镜像。
打通公网
1. 安装 frps
在公网服务器中安装frps,ssh登录公网服务器,创建frps目录:
mkdir /usr/local/frps && cd /usr/local/frps在frp的官方仓库中找到对应系统的tar包,以笔者为例,get下来:
wget https://github.com/fatedier/frp/releases/download/v0.65.0/**frp_0.65.0_linux_arm64**.tar.gz && tar -xzvf **frp_0.65.0_linux_arm64**.tar.gz我们只用到其中的fprs,提取出来:
mv ./**frp_0.65.0_linux_arm64**/frps ./ && mv ./**frp_0.65.0_linux_arm64**/frps.toml ./然后就可以把其他的删了。
2. 配置 frps
不同版本的frp,其配置文件的书写差距较大,笔者安装的为最新版本的frps,使用toml格式的配置文件,下列仅供参考:
#监听端口和域名
bindPort = frp监听端口
#webui面板端口,可选
[webServer]
addr = "127.0.0.1"
port = 7500
user = "账户名"
password = "账户密码"
#身份验证
[auth]
method = "token"
token = "你的frp密钥"3. 使用 systemd 管理 frps 服务
安装systemd:(如果没有)
# 使用 yum 安装 systemd(CentOS/RHEL)
yum install systemd
# 使用 apt 安装 systemd(Debian/Ubuntu)
apt install systemd创建 frps.service 文件:
vim /etc/systemd/system/frps.service写入内容:
[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /usr/local/frp/frps -c /usr/local/frp/frps.toml
[Install]
WantedBy = multi-user.target启动frps:
sudo systemctl start frps设置frps开机自启动:
sudo systemctl enable frps至此公网服务器的任务完成。
4. 安装 frpc
在内网nas上安装frpc,使用镜像snowdreamtech/frpc,网络使用host模式,映射容器路径/etc/frp,将下述toml文件放进去。
我知道你还没有安装ss服务,先配置了再说。
# 服务端连接配置
serverAddr = "你的公网服务器ip地址"
serverPort = frp监听端口
[auth]
method = "token"
token = "你的frp密钥"
# 映射 ss
proxies
name = "ss"
type = "tcp"
localIP = "你的NAS的ip"
localPort = ss监听端口(尽量大一点)
remotePort = ss监听端口(可以与上述端口不同,笔者建议保持一致)启动frpc,不出所料你应该能在frps的webui中看到已经成功打通ss监听端口。
需要注意的是,不要忘记在公网服务器上打开防火墙端口!,包括frp的监听端口和ss监听端口。
5. 安装 ss
不作详细展开,使用**teddysun/shadowsocks-rust**镜像,host网络安装,映射容器路径/etc/**shadowsocks-rust**/config.json对应下述json文件。注意映射路径和镜像名的对应关系。
{
"server": "::",
"server_port": ss监听端口(尽量大一点),
"password": "ss的连接密钥",
"method": "2022-blake3-aes-128-gcm",
"dns": "你的NAS的ip",
"mode": "tcp_and_udp"
}启动ss,后续再配置相关代理。
注意,ss的连接密钥需要在终端中使用openssl rand -base64 16命令生成,自己填则会报错。
值得一提的是,如果读者使用的加密方式为aes-256-gcm,则需要将上述命令的16改为32。
打通内网
1. 安装 Caddy
群晖系统请确认已经干掉自带的nginx。
创建名为caddy的docker网络:
docker network create -d bridge caddy进入你的docker目录,克隆Caddy仓库:
git clone https://github.com/Xm798/docker-caddy.git更改docker-compose文件,以下供参考:
services:
caddy:
container_name: caddy
image: xm798/caddy:latest
user: 1026:100
extra_hosts:
- "host.docker.internal:host-gateway"
dns:
- 8.8.8.8
- 1.1.1.1
- 1.0.0.1
- 223.5.5.5
- 119.29.29.29
networks:
- caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfiles:/etc/caddy
- ./data:/data
- ./config:/config
- ./log:/log
- ./srv:/srv
restart: always
networks:
caddy:
external: true使用上述配置文件后,Caddy后续配置可用host.docker.internal代替Nas的ip。
创建映射所需的目录:
mkdir data config log srvdocker,启动!
docker compose up -d
#群晖环境使用:
docker-compose up -d2. 配置 Caddy
启动过一次后,编辑 Caddyfiles 目录下 Caddyfile 文件,在第一个花括号内,添加你正在使用的 DNS 提供商的信息,为后续自动申请 SSL 证书做准备:阿里云:
{
http_port 80
https_port 443
email 你的阿里云登录账户
acme_dns alidns {
access_key_id "密钥id"
access_key_secret "登录密钥"
}
}Cloudflare:
{
http_port 80
https_port 443
email user@example.com
acme_dns cloudflare "你CF的token"
}DNSPOD:
{
http_port 80
https_port 443
email user@example.com
acme_dns dnspod "你的id,你的token"
}务必确认使用的Caddy镜像中,包含你使用的DNS服务商的对应插件,否则Caddy将无法启动。
3. 配置Caddy反代服务
在Caddyfiles 目录下新建后缀名为Caddyfile的文件,例如反代https下群晖的DSM,并忽略证书验证,新建nas.Caddyfile:
nas.rikinyoung.com {
reverse_proxy {
to https://host.docker.internal:5001
transport http {
tls
tls_insecure_skip_verify
}
}
}是不是很简单?来点进阶的,记得我们刚刚创建了名为caddy的docker网络吗?
将需要反代的容器全都放进caddy网络内,则可以不映射服务端口,在docker网络内部直接通过Caddy反代访问服务。如果不理解docker网络的话,听着可能有些绕,我们以emby举例:
emby.rikinyoung.com {
reverse_proxy http://emby:8096
#此时可以使用容器名:端口号的方式
}将emby加入到caddy网络中,此时尽管8096端口没有映射,依然可以访问!
这样做的好处是不暴露容器端口,相对更加安全。
对这部分感兴趣的话,可以学习了解下docker网络的工作原理,官方文档事无巨细。笔者的docker知识基本全是在官方文档学的
当然,你也可以像nginx那样把静态网页托管给Caddy,它的srv路径相当于nginx的www,例如:
home.rikinyoung.com {
root * /srv/homepage
file_server
}这样在内网环境下访问home.rikinyoung.com会进入homepage页面。
修改Caddyfile文件后使用下列命令重载配置:
docker exec -w /etc/caddy caddy sh -c "caddy fmt --overwrite && caddy reload"4. 安装 adguard
adguard在这里只负责改写DNS,且只改内网Nas的DNS,这样才能正确通过上述的域名和子域名访问对应服务。
以下compose文件供参考:
services:
adguardhome:
image: adguard/adguardhome:latest
container_name: adguard
network_mode: host
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
environment:
- PUID=1026
- PGID=100
- TZ=Asia/Shanghai
logging:
driver: "json-file"
options:
max-file: "10"
max-size: 10m
restart: always
dns:
- 223.5.5.5
- 119.29.29.29访问你的nas的ip:3000进入adguard的安装页面,将网页管理也就是webui的端口配置为3000,设置帐号密码。
安装完成后使用ctrl F5的组合键刷新网页,否则可能无法登录。
5. 配置 adguard
建议将内网服务托管到子域名,而不要占用根域名。
登录成功后点击过滤器-DNS重写-添加DNS重写,将泛域名*.rikinyoung.com重写到你的Nas的ip。
至此所有准备都已经完成~
配置代理
在你的神秘软件中,添加自己的节点,切换为全局模式进行测试,添加格式为:
proxies:
- name: 节点名
type: ss
server: www.rikinyoung.com
port: ss监听端口(尽量大一点)
password: ss的连接密钥
udp: true
cipher: 2022-blake3-aes-128-gcm若此时成功访问home.rikinyoung.com进入homepage页面,或是访问nas.rikinyoung.com进入DSM,则恭喜你,欢迎回家!
覆写代理
上述的回家方式限制居多,包括但不限于无法正常访问其他页面,无法访问某些“不存在的页面”。
若直接写入订阅中,订阅的频繁更新则会覆盖配置,笔者也不止一个订阅,非常的不现实。
但是如果你的神秘软件有覆写功能,建议将节点写到全局覆写中。
以下仅供参考!
+proxies:
- name: 节点名
type: ss
server: www.rikinyoung.com
port: ss监听端口(尽量大一点)
password: ss的连接密钥
udp: true
cipher: 2022-blake3-aes-128-gcm
+proxy-groups:
- name: 内网
type: select
proxies:
- 节点名
+rules:
- DOMAIN,www.rikinyoung.com,DIRECT
- DOMAIN,static.rikinyoung.com,DIRECT
- DOMAIN-SUFFIX,rikinyoung.com,内网实现只在访问内网服务的时候流量走代理,而访问博客、博客的静态资源等其他流量照常。
直连规则需配置在内网规则前,靠前的规则会覆盖靠后的规则。
顺带的,可以在公网服务器上,把rikinyoung.com不用的子域名统统重定向到根域名,这样无论公网怎么访问,都会跳转到笔者的博客页面。
原理
启动神秘软件后,主机访问内网服务.rikinyoung.com时流量会走代理,也就是frp映射出来的ss端口,ss将流量转发到Nas,因为Nas收到的是域名,会查询DNS找对应的ip,而DNS被adguard改写了,找到的是Caddy,通过Caddy反代访问实际服务,藉此通过域名实现了公网访问内网服务。
一环扣一环,环环相扣,一人一句docker码头nb来!