笔记树莓派树莓派搭建私有Memos备忘录并实现FRP内网穿透和HTTPS访问
Carkree
本文实现了在树莓派上用Docker搭建一个Memos私有备忘录,并使用Nginx反向代理实现https访问和BasicAuth验证,以及借助公网服务器实现frp内网穿透。
前言
Memos是一个私有、轻量、开源、自托管的备忘录,适合记录各种内容。它的数据存储在本地,无需依赖第三方云服务,支持 Markdown 语法,并且可以通过 Docker 部署。Memos 还支持多平台访问,满足个人知识管理和团队协作的需求。这是它在github上的页面
FRP是一款开源、高性能的内网穿透和反向代理工具,主要用于将内网服务通过公网节点安全地暴露到外网。为实现FRP,我们需要一台公网服务器作为FRPS,树莓派作为FRPC。
我购买的是阿里云一年99元的服务器,它的缺点是带宽只有3mbps,下载速度比较慢,完全不适合将其用作NAS的内网穿透,只能用作纯文字内容(memos)。
frp的传输速率其实并不一定被服务器带宽所限制。像本文中写的这种方式确实会受到服务器带宽的影响,但如果我们将服务器作为中转,在客户端上也部署frpc,使得P2P连接被建立,这样流量就不再直接通过服务器,服务器只用于UDP打洞,传输速率也就不再受到服务器带宽的限制。这是frp提供的一种新的代理类型,被称为XTCP,这是官方文档,需要满足一些条件。
作为一个私有备忘录,我们不希望其他人访问,Basic Auth(基本认证)是一种在 HTTP 请求中提供用户名和密码的身份验证方式。首次访问受保护资源时,浏览器会弹出认证窗口,如果账号或密码错误,服务器会返回401。Basic Auth在HTTP协议中很常见,适合用于保护私有资源,但它有局限性,例如无法直接注销等。为保安全,BasicAuth必须和https配合使用,否则密码将以明文形式传输
本文实现的是以IP访问的,不包括域名。且均使用的是自签名证书,不向其他人开放服务的,有些步骤只适用于个人
(本文中树莓派的系统为Ubuntu)
一、安装Memos
可以通过Docker来安装memos(官方文档点我)
1 2 3 4 5
| docker run -d \ --name memos \ --publish 5230:5230 \ --volume ~/.memos/:/var/opt/memos \ neosmemo/memos:stable
|
顺利的话,你可以在http://IP:5230访问它了,会让你设置账号和密码。
二、通过Nginx反向代理配置https以及Basic Auth
二.1 Nginx反向代理配置https
Nginx反向代理是指客户端的请求并不直接到达后端服务器,而是先由Nginx接收,再将请求转发给后端应用。在这种情况下,客户端只与Nginx交互,让nginx把外部的请求转发到Docker容器里的服务,进而我们就可以实现https访问
首先,安装nginx
1 2
| sudo apt update sudo apt install nginx
|
首先,我们需要签发一个https证书。
(我是通过IP访问的,如果想通过域名访问那么就可能和我提供的方法有一些不一样)
先创建一个配置文件
内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no
[req_distinguished_name] C = CN ST = Beijing L = Beijing O = MyOrg OU = MyUnit CN = xx.xx.xx.xx # 这里写服务器公网IP
[v3_req] keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names
[alt_names] IP.1 = xx.xx.xx.xx # 这里填写服务器公网IP IP.2 = 192.168.x.xx # 这里填写树莓派内网IP DNS.1 = localhost
|
这里有两个alt_name同时包含树莓派内网IP和公网IP,目的是为了既可以访问内网地址也可以访问外网地址。
随后,用openssl创建自签名证书server_new.key和server_new.crt,并把这两个文件移动到/etc/nginx/certs下面,并为其赋予权限:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cd ~
openssl req -x509 -nodes -newkey rsa:2048 -keyout server_new.key -out server_new.crt -days 3650 -config san.cnf -extensions v3_req
sudo mv server_new.key /etc/nginx/certs/server_new.key
sudo mv server_new.crt /etc/nginx/certs/server_new.crt
sudo chown root:root /etc/nginx/certs/server_new.*
sudo chmod 600 /etc/nginx/certs/server_new.*
|
在/etc/nginx/sites-available/下创建一个文件,命名为memos
1
| sudo vim /etc/nginx/sites-available/memos
|
并添加如下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| server { listen 5000 ssl http2; # 监听5000端口 server_name 192.168.x.xx xxx.xxx.xxx.xxx; # 填你的IP,可以填一个内网一个公网
# 这里和下面一行是证书的路径,在上面的命令中,我把它移到了这两个目录,如果你不是,则把路径换成你自己的。 ssl_certificate /etc/nginx/certs/server_new.crt; ssl_certificate_key /etc/nginx/certs/server_new.key ;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
location / { proxy_pass http://127.0.0.1:5230;
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
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; } }
|
随后,保存关闭
检查nginx配置文件是否正确
重启nginx服务
1
| sudo systemctl reload nginx
|
顺利的话,可以在内网里通过https://192.168.x.xx:5000访问你的memos服务了
二.2 启用basic auth
memos本身已经自带了登陆界面,basic auth只是为了加一个在http层面的认证,如果觉得没必要或者麻烦,可以跳过这个步骤。
首先安装apache2-utils
1 2
| sudo apt update sudo apt install apache2-utils
|
创建一个basic auth的账号和密码
1 2
| cd ~ sudo htpasswd -c /etc/nginx/.htpasswd Your_Username
|
把Your_Username改成你想要的用户名。执行后会让你设置密码。
我们需要修改nginx的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| sudo vim /etc/nginx/sites-available/memos
# 文件内容如下,我们只需要增加两行即可
server { listen 5000 ssl http2; server_name 192.168.x.xx;
ssl_certificate /path_to_your_crt; ssl_certificate_key //path_to_your_key;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
location / { auth_basic "basicauth"; # 新增1 auth_basic_user_file /etc/nginx/.htpasswd; # 新增2
proxy_pass http://127.0.0.1:5230;
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
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; } }
|
重启nginx
1 2
| sudo nginx -t sudo systemctl reload nginx
|
顺利的话,现在访问https://192.168.x.xx:5000会弹框让你输入用户名和密码。由于刚刚设置了https,现在basic auth的传输是加密的了。
三、配置frp
Github页面
FRP官方文档
请从https://github.com/fatedier/frp/releases/下载最新版本的frp。
这里需要注意,frps和frpc的架构可能是不同的,要分别下载不同版本的。树莓派是arm64,常见的服务器架构是amd64。我就在这里浪费了很长时间
通过wget下载
1 2 3 4 5
| wget https://github.com/fatedier/frp/releases/download/v0.64.0/frp_0.64.0_linux_arm64.tar.gz # (截至文章更新时(2025年10月),frp的最新版本为0.64.0)
tar -xzf frp_0.64.0_linux_arm64.tar.gz # 解压
|
下载后有如下几个文件:frps frps.toml frpc.toml frpc。将带frps的放在公网服务器下,将带frpc的放在树莓派上。你可以分别在用户目录下面新建一个frpc或frps文件夹存放相关内容
关于frp的配置的参考文章,个人认为可以参考:
https://blog.hoshiroko.com/archives/37f497acabc8/
这是官方给的一个完整示例:
https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml
下面是我的配置文件写法。把token改成你自己的,xxx也改成你自己的路径
(可以用openssl rand -base64 12命令生成一个强token,最后一个数字代表的是长度)
这里惟需要注意的是,网上有很多配置文件的写法已经过时,注意辨别版本
1 2 3 4 5 6 7 8 9 10 11 12
| #frps.toml bindAddr = "0.0.0.0" bindPort = 7000 auth.token = "your_token"
transport.tls.certFile = "/xxx/server.crt" transport.tls.keyFile = "/xxx/server.key" transport.tls.trustedCaFile = "/xxx/ca.crt"
log.to = "/xxx/frps.log" log.level = "info" log.maxDays = 4
|
- 这三行代表启用了双向身份验证。依据文档,从 v0.50.0 开始,transport.tls.enable 的默认值将会为 true,默认开启 TLS 协议加密。如果没有配置证书,是使用随机证书来加密的,可能有被中间人攻击的风险。因此可以进行双向身份验证,实现它需要借助本地CA,因此我们需要先生成一个CA,具体过程在此省略。你完全可以选择把这三行删除,下面frps同理。
1 2 3
| transport.tls.certFile = "/xxx/server.crt" transport.tls.keyFile = "/xxx/server.key" transport.tls.trustedCaFile = "/xxx/ca.crt"
|
- token的作用是,frps会验证只有token一样的frpc才能连接它,否则在公网不是被随便连接:
1
| auth.token = “your_token”
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #frpc.toml serverAddr = "服务器公网IP" serverPort = 7000 auth.token = "your_token"
transport.tls.certFile = "/xxx/client.crt" transport.tls.keyFile = "/xxx/client.key" transport.tls.trustedCaFile = "/xxx/ca.crt"
log.to = "/home/xxx/frp/frpc.log" log.level = "info" log.maxDays = 4
[[proxies]] name = "memos-https" #随便起名 type = "tcp" localIp = "127.0.0.1" localPort = 5000 remotePort = xxxx transport.useEncryption = true transport.useCompression = true
|
1 2
| localPort = 5000 remotePort = xxxx
|
接下来,我们通过systemd来启动它以及实现开机自启
在/etc/systemd/system/下创建一个文件。
在frpc上:sudo vim /etc/systemd/system/frpc.service
添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #frpc.service
[Unit] Description = FRP Client After = network.target syslog.target Wants = network.target
[Service] Type = simple # 启动frpc的命令,需修改为您的frpc的安装路径。例如我的frpc目录是/home/username/frpc: ExecStart = /home/username/frpc -c /home/username/frp/frpc.toml
[Install] WantedBy = multi-user.target
|
在frps上:
sudo vim /etc/systemd/system/frps.service
添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #frps.service
[Unit] Description = FRP Server After = network.target syslog.target Wants = network.target
[Service] Type = simple # 启动frps的命令,需修改为您的frps的安装路径。例如我的frps目录是/root/frp: ExecStart = /root/frp/frps -c /root/frp/frps.toml
[Install] WantedBy = multi-user.target
|
保存退出后,分别执行:
1 2 3 4 5 6 7 8 9 10 11
| 在frpc上: sudo systemctl daemon-reload sudo systemctl start frpc # 启动 sudo systemctl enable frpc # 开启自启 sudo systemctl status frpc
在frps上: sudo systemctl daemon-reload sudo systemctl start frps # 启动 sudo systemctl enable frps # 开启自启 sudo systemctl status frps
|
最后记得在ufw和/或服务器安全组中启用相关端口,就可以啦φ( ̄∇ ̄o)!!!!
如有错误请指出#(投降)
本文使用CC BY-NC-SA 4.0协议进行许可