故事的继续

在之前的文章,华硕路由器实现远程唤醒局域网设备的笔记中提到,在下有着远程控制设备的刚需,而得益于寝室电信宽带分配的公网 IP,在下可以通过 DDNS 和 VPN 功能优雅而又轻松地满足这一需求。然而鉴于魔都电信的性价比对于寝室成员来说并不高,在使用了一年多以后,寝室成员终为魔都移动所折服。魔都移动虽在寝室日常使用时体验并无明显短板之处,但是由于移动手中的 IP 资源稀缺,导致寝室的宽带失去了公网 IP。于是,内网穿透就成了在下所必须折腾的一道坎。

很多路由器的软件中心都有着各种各样的内网穿透软件,在下寝室中的 AC86U koolshare 软件中心就提供了 ddnsto、花生壳和 frp 工具。其中 ddnsto 和花生壳属于平台类型的服务,虽然配置简单,但是存在一些限制。比如 ddnsto 就无法创建 TCP 隧道,还需要微信扫码才能登录管理界面,而花生壳则有隧道数量限制,服务还不是很稳定。因而,最优雅实现内网穿透的方案,还得是 frp,这是一个高性能的反向代理应用,支持 tcp、udp、http、https 等众多协议。另外,很多有名的路由器面板都内置了 frp 工具,这使客户端配置的流程简化了不少。

确定了使用工具之后,接下来就需要一台具有公网 IP 的服务器来运行服务端的服务,这里在下使用了甲骨文的免费云服务器,辅以 aaPanel(宝塔面板国际版)配置。当然,只要是具备了外网访问的服务器皆符合搭建条件。

折腾的继续

配置防火墙

关于甲骨文免费云服务器的申请,相关的教程在搜索引擎已经漫天飞扬了,故这里在下不做赘述,唯一需要注意的是甲骨文实例端口的问题。

以 Ubuntu 为例,除了更改实例的子网策略外,所有后文涉及的端口,都需先在 iptables 这里进行放行操作。

有三种解决方法可供选择:

  • 直接删除 iptables 规则

    sudo rm -rf /etc/iptables && reboot
  • 开放所有端口

    sudo iptables -P INPUT ACCEPT
    sudo iptables -P FORWARD ACCEPT
    sudo iptables -P OUTPUT ACCEPT
    sudo iptables -F
    sudo apt-get purge netfilter-persistent
    reboot
  • 只开放特定端口

    sudo iptables -I INPUT -s 0.0.0.0/0 -p tcp --dport 要放行的端口号 -j ACCEPT
    sudo iptables-save
    sudo apt-get update
    sudo apt-get install iptables-persistent -y
    sudo netfilter-persistent save
    sudo netfilter-persistent reload

CentOS 系统下,除了更改实例的子网策略外,还需要做如下设置:

# 删除多余附件
systemctl stop oracle-cloud-agent
systemctl disable oracle-cloud-agent
systemctl stop oracle-cloud-agent-updater
systemctl disable oracle-cloud-agent-updater

# 停止firewall
systemctl stop firewalld.service
# 禁止firewall开机启动
systemctl disable firewalld.service

安装 aaPanel 面板(可选)

aaPanel 面板是宝塔面板国际版,其精简了一些组件,比宝塔面板的运行要求更低。安装 aaPanel 面板可以提供可视化文件管理页面,编辑配置文件会变得更方便,但这并非必要,若懂得使用 vim 文本编辑器则完全可以跳过此步骤。

注意,若使用甲骨文云服务器,需事先放行面板默认端口。

CentOS

yum install -y wget && wget -O install.sh http://www.aapanel.com/script/install_6.0_en.sh && bash install.sh

Ubuntu

wget -O install.sh http://www.aapanel.com/script/install-ubuntu_6.0_en.sh && sudo bash install.sh

安装 aaPanel 面板后,后文中涉及到的所有端口别忘记在面板 Security 设置里放行。

服务端配置

首先需要准备 frp 程序文件,前往其 Github Releases 页查看自己服务器对应处理器架构的压缩包。

若不清楚服务器架构,可以在服务器输入 arch 命令获取。若输出 x86_64 则对应 linux_amd64 标签,同理 i386 则对应 386,以此类推。

使用 sudo -i 在服务器 SSH 切换到 ROOT 用户,随后下载最新的对应处理器架构的压缩包到服务器。

# 下载压缩包,请将 0.39.1 字段替换成当前最新版本号;若服务器架构不为 x86_64,则替换 linux_amd64 字段为对应版本
wget --no-check-certificate https://github.com/fatedier/frp/releases/download/v0.39.1/frp_0.39.1_linux_amd64.tar.gz

# 解压压缩包
tar -xzvf frp_0.39.1_linux_amd64.tar.gz

# 将解压后的文件夹改名为 frp
mv frp_0.39.1_linux_amd64 frp
cd frp

接着,使用 aaPanel 中的文件浏览功能,定位到 /root/frp,编辑 frps.ini 文件,可参考以下代码来完善 frp 的服务端配置:

[common]

# frp 服务端端口,默认为 7000
bind_port = 7000

# frp 服务端密码,可使用任意字符组合
token = password

# 服务端仪表盘端口,默认为 7500
dashboard_port = 7500

# 服务端仪表盘的用户名和密码
dashboard_user = username
dashboard_pwd = password

# 如果想要用 frp 穿透访问路由器设置页面等 web 页面,则必须要设置以下两个监听端口
vhost_http_port = 7100
vhost_https_port = 7200

以上是服务端一些常用的配置,若想实现更加复杂的功能,敬请参阅 frp 中文说明文档

配置编写完成并保存之后,输入 ./frps -c frps.ini 测试 frp 能否正常运行,若无报错,则说明一切正常。

尝试在浏览器输入 服务器 IP 或域名:服务端仪表盘端口 例如 127.0.0.1:7500,若能正常显示出仪表盘界面,且登录后 BindPortHttp Port 等端口显示的和配置时相同,则服务端的配置已经可以宣告成功。

最后输入以下代码使 frp 服务端能在后台持续运行:

nohup /root/frp/frps -c /root/frp/frps.ini &

这之后如果需要修改配置文件,需要保存后重启服务才可得到应用,方法是输入 pkill frps 终止服务再输入持续运行代码启动服务即可。

客户端配置

很多有名的服务器面板的软件中心中都提供了 frp 客户端,如若没有,则同样可 SSH 至路由器,前往 Github Releases 页安装对应的客户端。

在客户端,需要配置的文件就变成了 frpc.ini,当然,如果路由器软件中心的 frp 客户端支持可视化配置的话,就可省去配置 frpc.ini 的麻烦。

例如在下使用的 AC86U 路由器 koolshare 软件中心的 frp 客户端。在简单设置中就可以直接填入对应的服务器、端口、Token、HTTP/HTTPS 端口,随后在穿透服务配置中便可直接创建各种协议的内网穿透隧道。

当然,学会配置 frpc.ini 永远是不会错的,即便支持可视化配置,有些玩法还是只能通过写配置文件来解决的。

以下是一些常见配置写法,可依照需求整合到 frpc.ini 中,若想实现更加复杂的功能,敬请参阅 frp 中文说明文档。:

[common]

# frp 服务端地址,可以填ip或者域名
server_addr = 0.0.0.0

# frp 服务端端口,即填写服务端配置中的 bind_port
server_port = 7000

# 填写 frp 服务端密码
token = password
# TCP/UDP 隧道
[ssh]

# 连接类型,填 tcp 或 udp
type = tcp

# 需要转发的内网 ip
local_ip = 127.0.0.1

# 需要转发的端口,比如 ssh 端口是 22,Windows 远程桌面端口是 3389
local_port = 22

# 是否加密客户端与服务端之间的通信,默认是 false
use_encryption = false
# 是否压缩客户端与服务端之间的通信,默认是 false
use_compression = false

# frp 服务端的远程监听端口,需要在面板和服务器防火墙处同时放行
remote_port = 7001
# HTTP 隧道
[router-web]

# 连接类型,填 http 或 https
type = http

# 需要转发的内网 ip
local_ip = 127.0.0.1

# 需要转发的内网端口
local_port = 80

# 出于安全因素加密和压缩 http 隧道
use_encryption = true
use_compression = true

# 访问网站的用户名和密码,如不设置,则代表任何人都可以访问
http_user = username
http_pwd = password

# 自定义域名(必要),需要一个可用域名并解析到服务端的服务器 IP
custom_domains = yourdomain.com

完成配置后,登录服务端仪表盘,查看隧道是否连接成功。

真·大功告成

最后,就是测试各项转发是否可用的时间。

  • 如果建立了路由器管理页面的 HTTP 隧道,则直接在浏览器输入 yourdomain.com:7100 即可,注意,这里的 7100 是之前在 frps.ini 中设置的 vhost_http_port 字段。

  • 如果建立的是 SSH 远程隧道,则在主机名处输入 frp 服务端地址:7001 尝试连接,注意,这里的 7001 是之前在 frpc.ini 中设置的 remote_port 字段。

  • 以此类推,确保所有的隧道都正常工作。

至此,所有的配置已经全部完成,尽情享受如此优雅的内网穿透吧!


封面来源:r | LM7 #pixiv https://www.pixiv.net/artworks/63888719


Stay hungry, Stay foolish.