通过frp进行内网穿透实现星露谷多人局域网联机

2021-01-05
Cover Image

本文最后更新于 天前,文中部分描述可能已经过时。

环境

星露谷游戏平台:Steam

服务器配置(服务端):Ubuntu 20.04.1 LTS x86_64(确保所需要用到的端口号全部开启)

游戏主持主机(客户端):Ubuntu 20.10 x86_64

联机测试主机:Windows 10 家庭版 x64

开始前需要了解的东西

星露谷局域网联机的端口号

我们都知道游戏多人联机是需要通过端口进行相连的,在进行内网穿透前我们需要搞清楚星露谷局域网联机的端口号是多少。

不像Terraria一样,星露谷并没有提供多人游戏的端口号,但是想获取星露谷的端口号也很简单。

netstat查看端口占用获取星露谷端口号

启动星露谷多人游戏

打开steam->打开Stardew Valley->多玩家->多人游戏->主持

在选项中找到多玩家先将服务器模式改为离线

打开终端使用netstat查看星露谷端口占用情况

1
2
3
4
$ netstat -tunlp | grep Stardew
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
udp 0 0 0.0.0.0:57560 0.0.0.0:* 56045/./StardewVall

发现星露谷开放了一个端口号为57560udp协议端口,不清楚是不是局域网游戏的端口(毕竟游戏模式是离线)

再将服务器模式改为仅朋友

再使用netstat查看星露谷端口占用情况

1
2
3
4
5
$ netstat -tunlp | grep Stardew
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
udp 0 0 0.0.0.0:24642 0.0.0.0:* 56045/./StardewVall
udp 0 0 0.0.0.0:57560 0.0.0.0:* 56045/./StardewVall

发现星露谷又开放了一个端口号为24642的udp端口(由于开启了多人游戏所以推测24642是局域网多人游戏的端口)

记住24642这个端口号,一会使用frp进行内网穿透时会用到,还有走的udp协议

什么是内网穿透(NAT穿透)

内网穿透可以说是NAT穿透,如果你在Wikipedia上搜索内网穿透的话搜索页面会被重定向到NAT穿透,那么什么是NAT

NAT

NAT即(Network Address Translation)中文译为网络地址转换。是在计算机网络中是一种在IP数据包通过路由器或防火墙时重写来源IP地址或目的IP地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有IP地址访问互联网的私有网络中。它是一个方便且得到了广泛应用的技术。当然,NAT也让主机之间的通信变得复杂,导致了通信效率的降低。

基本网络地址转换(Basic NAT)

这一种也可称作NAT或“静态NAT”,在RFC 2663中提供了信息。它在技术上比较简单,仅支持地址转换,不支持端口映射。Basic NAT要求对每一个当前连接都要对应一个公网IP地址,因此要维护一个公网的地址池。宽带(broadband)路由器通常使用这种方式来允许一台指定的设备去管理所有的外部链接,甚至当路由器本身只有一个可用外部IP时也如此,这台路由器有时也被标记为DMZ主机。由于改变了IP源地址,在重新封装数据包时候必须重新计算校验和,网络层以上的只要涉及到IP地址的头部校验和都要重新计算。

Basic NAT要维护一个无端口号NAT表,结构如下:

内网IP 外网IP
192.168.1.55 219.152.168.222
192.168.1.59 219.152.168.223
192.168.1.155 219.152.168.224
网络地址端口转换(NAPT)

这种方式支持端口的映射,并允许多台主机共享一个公网IP地址。支持端口转换的NAT又可以分为两类:源地址转换和目的地址转换。前一种情形下发起连接的计算机的IP地址将会被重写,使得内网主机发出的数据包能够到达外网主机。后一种情况下被连接计算机的IP地址将被重写,使得外网主机发出的数据包能够到达内网主机。实际上,以上两种方式通常会一起被使用以支持双向通信。

NAPT维护一个带有IP以及端口号的NAT表,结构如下:

内网IP 外网IP
192.168.1.55:5566 219.152.168.222:9200
192.168.1.59:80 219.152.168.223:9201
192.168.1.155:4465 219.152.168.224:9202

现在你应经知道了NAT可以转换IP地址和IP地址及其端口了,通过上述所说NAT这些功能所实现的技术可称之为内网穿透了。那么如何实现内网穿透?我们需要使用的是一款基于Go语言编写的开源软件frp

frp使用

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

下载

在frp的github仓库release页面找到对应的客户端和服务端版本进行下载

解压

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ tar -zxvf frp_0.34.3_linux_amd64.tar.gz
frp_0.34.3_linux_amd64/
frp_0.34.3_linux_amd64/frps
frp_0.34.3_linux_amd64/frps.ini
frp_0.34.3_linux_amd64/LICENSE
frp_0.34.3_linux_amd64/frpc.ini
frp_0.34.3_linux_amd64/frps_full.ini
frp_0.34.3_linux_amd64/frpc_full.ini
frp_0.34.3_linux_amd64/systemd/
frp_0.34.3_linux_amd64/systemd/frps@.service
frp_0.34.3_linux_amd64/systemd/frpc@.service
frp_0.34.3_linux_amd64/systemd/frpc.service
frp_0.34.3_linux_amd64/systemd/frps.service
frp_0.34.3_linux_amd64/frpc

你会发现存在着frps和frpc这两类文件分别是服务端文件(frpServer)和客户端文件(frpClient)

服务端文件一览

服务端完整所需的文件是这样的

1
2
3
4
5
6
7
8
9
$ tree
.
├── frps
├── frps.ini
└── systemd
├── frps.service
└── frps@.service

1 directory, 5 files

客户端文件一览

客户端完整所需的文件是这样的

1
2
3
4
5
6
7
8
9
$ tree
.
├── frpc
├── frpc.ini
└── systemd
├── frpc.service
└── frpc@.service

1 directory, 5 files

将服务端文件通过scp命令上传至服务器,客户端文件通过cp保存到本地。

配置

服务端配置

通过vim打开frps.ini

1
2
[common]
bind_port = 7000

添加tokendashboard_portdashboard_userdashboard_pwd参数

frps.ini参数说明
参数 说明
bind_port frp服务端与客户端访问绑定端口
token 访问验证令牌需要服务端与客户端一致(安全性建议添加)
dashboard_port frp的仪表盘网页界面(可不选)
dashboard_user frp的仪表盘网页登陆用户名界面(可不选)
dashboard_pwd frp的仪表盘网页登陆密码界面(可不选)

添加参数后的frps.ini

1
2
3
4
5
6
[common]
bind_port = 7000
token = example_token
dashboard_port = 7500
dashboard_user = example_user
dashboard_pwd = example_password

客户端配置

通过vim打开frpc.ini

1
2
3
4
5
6
7
8
9
[common]
server_addr = 127.0.0.1
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
  1. 修改common项中server_addr参数,并添加token参数(应与服务端token保持一致),删除ssh所有的参数
  2. 添加stardewValleytype参数为tcplocal_ip参数为127.0.0.1local_port参数为24642remote_port参数为24642
frpc.ini参数说明
参数 说明
server_addr frp服务端ip地址
server_port frp客户端与服务端访问绑定端口
token 访问验证令牌需要服务端与客户端一致(安全性建议添加)
type 连接类型
local_ip 本地被转发ip地址
local_port 本地被转发ip地址对应端口
remote_port 远程开放访问监听端口

修改参数后的frpc.ini

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = example.com
server_port = 7000
token = example_token

[stardewValley]
type = udp
local_ip = 127.0.0.1
local_port = 24642
remote_port = 24642

在这里你会发现type对应的是之前netstat查看星露谷端口的udp协议

local_port是netstat查看的星露谷端口号24642

由于星露谷加入多人游戏时不像Terraria一样会可以让用户选择输入端口,星露谷的端口是固定的(你在加入局域网游戏时输入ip地址后会自动附加24642这个端口),所以remote_port应填24642

启动

服务端启动

通过screen -S frp建立一个新的窗口

启用frps

1
$ ./frps -c frps.ini

看到终端显示如下表示运行成功

1
2
3
4
$ ./frps -c frps.ini
2021/01/05 16:05:27 [I] [service.go:190] frps tcp listen on 0.0.0.0:7000
2021/01/05 16:05:27 [I] [service.go:289] Dashboard listen on 0.0.0.0:7500
2021/01/05 16:05:27 [I] [root.go:215] start frps success

客户端启动

通过screen -S frp建立一个新的窗口

启用frpc

1
$ ./frpc -c frpc.ini

看到终端显示如下表示运行成功

1
2
3
4
5
$ ./frpc -c frpc.ini
2021/01/05 16:06:55 [I] [service.go:288] [b5d1240fd9b4a92b] login to server success, get run id [b5d1240fd9b4a92b], server udp port [0]
2021/01/05 16:06:55 [I] [proxy_manager.go:144] [b5d1240fd9b4a92b] proxy added: [stardewValley]
2021/01/05 16:06:55 [I] [control.go:180] [b5d1240fd9b4a92b] [stardewValley] start proxy success
2021/01/05 16:06:56 [I] [proxy.go:478] [b5d1240fd9b4a92b] [stardewValley] incoming a new work connection for udp proxy, example.com:7000

服务端与客户端连接

在服务器上重新使用screen -R frp进入原有的frp窗口如果查看以下输出表示服务端与客户端连接成功

1
2
3
4
2021/01/05 16:06:55 [I] [service.go:444] [b5d1240fd9b4a92b] client login info: ip [your.ip:37869] version [0.34.3] hostname [] os [linux] arch [amd64]
2021/01/05 16:06:55 [I] [udp.go:84] [b5d1240fd9b4a92b] [stardewValley] udp proxy listen port [24642]
2021/01/05 16:06:55 [I] [control.go:446] [b5d1240fd9b4a92b] new proxy [stardewValley] success
2021/01/05 16:06:56 [I] [proxy.go:103] [b5d1240fd9b4a92b] [stardewValley] get a new work connection: [your.ip:37869]

进行多人局域网游戏

现在就可以小伙伴打开星露谷在局域网联机的ip地址框(不需要输入端口号)输入你的服务器地址和你进行多人联机了~