0%

Nginx-frp-web

项目启发

之前是有进行过博客的搭建的,但是由于水平以及各种原因基本未进行过更新,最近偶然间刷到了关于VPS的推荐,于是就一狠心入手了一个,既然钱都交了,不拿来搭点东西总觉得对不起花出去的一百大洋,而刚巧自己也一直有随便写点什么的更更博客的想法,毕竟大学四年过去了总有点什么能拿的出手的东西可写的,于是就有了本篇项目

服务器配置介绍

服务器是某毛子服务器,回国线路cn,稳定200ms延迟,访问速度只能算勉强说的过去,512mb内存,200mb带宽,rmb140/年,只能说除了价格基本没有什么很大的优势了?而且最难受的一点是他的200mb带宽是共享带宽,服务器是通过PVE虚拟化出来的机器,高峰期的ssh卡顿难受地令人发指,不过在价格面前还是忍了,如果不是不是原账户退款,可能就没有这篇文章了

本地服务器,n2840小主机,4g内存,64g存储,单百兆网口,这个配置在现在看来肯定是不太够用,但是用来搭建一些好玩的项目肯定是绰绰有余的,大家也可以用手里的NAS,软路由之类的高性能小主机,然后下面开始进入正题,在这里我想先通过内网穿透开始,说一说我们是怎么通过公网IP访问内网服务的。

闲聊到此结束,我是分割线


内网穿透

关于内网穿透网上已经有很多讲解了,也有很多现成的方案,在这里我选择的是frp一个轻量,易用,高性能的内网穿透服务,官方文档关于参数的讲解已经有很多了,如果想要了解更多可以去官网查看,在这里我们仅对我们使用到的参数进行简单讲述。

以下是内网穿透成功正常运行所需要的必须文件

1
2
3
4
5
6
7
8
9
# 服务器端
frps frps.ini
# 本地端
frpc frpc.ini

# .ini储存我们的配置文件
# 剩下的一个为可执行文件,记得下载对应系统架构的文件。
# 举例:todo

关于服务的运行也很简单,只需要一行命令

1
2
3
4
5
6
# 此处为相对路径,需要在该文件夹下
sudo ./frps -c ./frps.ini
sudo ./frpc -c ./frpc.ini

# 可以通过screen或者
# systemctl配置为service (推荐)后台运行

frps.ini配置

这部分的配置十分简单,我们只需要配置frp需要监听的端口

1
2
3
4
5
6
7
8
vhost_http_port #http协议端口,此处建议选取非80端口
vhost_https_port #https协议端口,此处建议选取非443端口
bind_port #client服务监听端口

#dashboard相关配置(可选)
dashboard_port
dashboard_user
dashboard_pwd

值得注意的是,我们这里的http https并不是我们网页访问的端口,而是我们之后nginx 服务器转发的端口,因此我们在这里选择不常用的8080 4443 端口

frpc.ini配置

client服务监听端口,这里是我们远程服务器与本地服务器唯一的连接通道,需要和frpc.ini中的配置保持一致,这里贴出我的部分frpc.ini文件,水平受限仅作参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 链接需要的默认配置,其中鉴权方式可选
[common]
server_addr = 46.29.163.133
server_port = 7000
connect_server_local_ip = 8888
authentication_method = token
token = changetoyourownpsd

#你自己的网页配置,不同的配置需要不同的命名
[web]
type = http
local_port = 22300 //访问的端口号,这个参数与你远程服务器端nginx配置有关。
subdomain = web
use_encryption = true
use_compression = true

[web2]
[blog]
type = http
local_port = 4000
custom_domains = yourdomain.com
use_encryption = true
use_compression = true

nginx

Nginx是一款轻量级的web服务器,反向代理服务器以及电子邮件(IMAP/POP3)代理服务器。我们主要需要使用的就是nginx反向代理

1
2
3
4
5
6
7
8
9
# nginx的使用非常简单,常用到命令如下:
nginx -s stop #快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
nginx -s quit #平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload #因改变了Nginx相关配置,需要重新加载配置而重载。
nginx -s reopen #重新打开日志文件。
nginx -c filename #为 Nginx 指定一个配置文件,来代替缺省的。
nginx -t #不运行,仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
nginx -v #显示 nginx 的版本。
nginx -V #显示 nginx 的版本,编译器版本和配置参数。

HTTP反向代理

这一部分我们只是进行简单的说明,都2023年不会还有人在用传统HTTP协议建站吧

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#运行用户
#user somebody;

#启动进程,通常设置成和cpu的数量相等
worker_processes 1;

#全局错误日志
error_log home/jaimevan/Tools/nginx-1.10.1/logs/error.log;
error_log home/jaimevan/Tools/nginx-1.10.1/logs/notice.log notice;
error_log home/jaimevan/Tools/nginx-1.10.1/logs/info.log info;

#PID文件,记录当前启动的nginx的进程ID
pid D:/Tools/nginx-1.10.1/logs/nginx.pid;

#工作模式及连接数上限
events {
worker_connections 1024;
}

http{
server{
listen 80; # 此处选择80端口
servername httpweb.com
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_set_header Host $host;
proxy_set_header X-Forwarder-For $remote_addr;


location / {
proxy_pass http://120.0.0.1:8080 #传回frp监听的http端口
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
}

HTTPS反向代理

对于HTTPS协议,与http协议最大的不同是其是经过了TLS/SSL协议构建的可加密传输,可身份认证的网络协议,我们如果想要构建我们的https网站,我们首先需要进行SSL证书的申请,这一步我们可以放到下一步进行说明,在这里我们先对HTTPS协议的反向代理参数进行说明。一般情况我们可以将https请求代理到我们已有的http服务的端口上,在这里即我们frp监听的http端口,后续由frp穿透到本地的http server,相关配置如下

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
server{
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate your_cert_path;
ssl_certificate_key your_key_path;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

值得注意的是如果本地的web服务依托于https协议,例如docker的一个管理面板portainer,我们就需要将https请求转发到frp监听的https端口上,此时的配置略有不同

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
32
server{
listen 443 ssl;
server_name your_domain;
ssl_certificate your_cert_path;
ssl_certificate_key your_key_path;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

location / {
proxy_pass https://yourpath:4433;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2;
proxy_ssl_session_reuse off;
proxy_ssl_name $proxy_host;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

此处关键配置是代理SSL相关配置。

HTTP跳转

此时我们已经有了我们的https服务器,再能够正常访问我们的http页面未免有点太不优雅,此时我们可以在nginx的http配置加上一行

1
2
3
4
5
server {
listen 80;
server_name example.com;
return 301 https://example.com;
}

SSL证书

我们已经有了我们的服务正在监听我们的443端口,但是我们此时并没有ssl证书,如果访问https页面会提示我们证书与网站不符合,拒绝访问,这时候我们就需要申请我们网站的ssl证书,在这里我们可以使用Let·s Encrypt申请我们免费的SSL证书。具体使用细节可以去官网详细了解,在这里我们仅提供使用certbot在命令行申请ssl证书几条简单命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装snap
sudo apt update
sudo apt install snapd

# 更新snap
sudo snap install core; sudo snap refresh core

# 安装certbot
sudo snap install --classic certbot

# 添加超链接
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 为网站添加证书
sudo certbot certonly --webroot -d example.com -d www.example.com

当然你还可以通过–manual插件申请支持通配符的SSL证书

1
certbot certonly --preferred-challenges dns --manual  -d *.example.com

根绝提示,为我们的网站加上SSL证书,我们只需要将上述nginx的配置文件的your_cert_path和your_key_path替换为我们自己的目录。
完成之后现在我们已经有了服务器端http https的监听端口,以及我们域名的SSL证书,并且有了将本地服务内网穿透到服务器端的frp,当我们访问域名地址的时候,我们可以看到frp not found的报错页面
现在我们缺少并需要的就是本地的web服务,在这里我们以一个简单的web服务为例,介绍一下如何快速通过docker构建我们的web项目。

docker构建Flare导航页

关于docker的安装具体可以见官网页,在这里我提供几个Ubuntu的安装指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 安装必要软件包
sudo apt update
sudo apt install \
ca-certificates \
curl \
gnupg \
lsb-release

# 添加docker官方GPG key,网络问题自行解决
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加docker软件源
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

此时docker compose已经作为插件安装在我们的系统,在真正使用docker之前,强烈建议你修改docker配置,限制docker日志大小

1
2
3
4
5
// 存放位置/etc/docker/daemon.json
{
"log-driver":"json-file",
"log-opts": {"max-size":"20m", "max-file":"3"}
}

重启docker,关于systemctl,如果不了解的读者,强烈建议学习一下,这是服务器运维还有基本Linux知识必须掌握的一个部分

1
sudo systemctl restart docker

当我们完成了所有的准备工作,我们就可以开始用docker 快速安装我们的
web应用了,首先在用户根目录下创建/docker_img/的目录,用于集中存放我们的docker镜像,然后创建/flare/目录,创建docker-compose.yml,并编辑,根据自己需求修改,详细介绍可见原搭建地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '3.6'

services:
flare:
image: soulteary/flare
restart: always
# 默认无需添加任何参数,如有特殊需求
# 可阅读文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md
command: flare
# 启用账号登录模式
# command: flare --nologin=0
# environment:
# 如需开启用户登录模式,需要先设置 `nologin` 启动参数为 `0`
# 如开启 `nologin`,未设置 FLARE_USER,则默认用户为 `flare`
# - FLARE_USER=flare
# 指定你自己的账号密码,如未设置 `FLARE_USER`,则会默认生成密码并展示在应用启动日志中
# - FLARE_PASS=your_password
# 是否开启“使用向导”,访问 `/guide`
# - FLARE_GUIDE=1
ports:
- 5005:5005
volumes:
- ./app:/app

进行到这里我们的工作基本完成,最后只需要在终端执行一行代码,就可以看到我们的日志输出了

1
sudo docker compose up -d

这时候我们如果执行

1
sudo docker ps

就可以看到我们的flare页面正在执行了,此时访问我们的域名就可以看到一个简易优雅的导航页面了,当然在这里我只是提供了一个简单的例子,具体怎么实现,用来实现哪些好玩的应用,还需要对上述配置进行大量的扩展和修改。我们的https请求经过nginx的反向代理,由frp转到本地服务器从而访问我们本地服务器的web应用,web的数据均储存在本地,远程服务器只负责数据的转发