文章目录
一、需求:
需要在外网访问内网的机器及服务.
二、解决方案:
1. 公网ip:
作为大天朝的互联网用户, 向运营商申请公网的ip地址是不容易的,因为资源有限啊.而且就算是拿到公网ip,也是只有一个ip, 不能满足内网中多个设备同时暴露. 所以这就需要端口映射来暴露端口,达到访问内网服务的目的.
2.端口映射:
端口转发是基于公网IP实现的, 端口转发功能是在路由器级实现的, 现在一般的家用路由器都会自带端口映射功能, 当用户访问外网IP的这个端口时,服务器自动将请求映射到对应局域网内部的机器上.
反正我没有能从运营商的客服口中要到公网ip, 要是哪位大佬看到这篇博客,正好有要到公网ip的门路,可以留言沟通一下.
3. frp:
frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透。需要一个具有公网ip的跳板机, 访问跳板机的端口, 对应就是访问反向代理主机上的服务了,但是有一点就是受限于跳板机的带宽.
*4.ipv6(首推):
ipv6的可用资源就要比ipv4多得多,更是万物互联的有力支撑. 通过少量调研了解到, 三大运营商对大部分地区都会分配的ipv6地址,但是,坑爹的北京电信在我们小区并没有分配ipv6,否则,这一篇将会变成"如何使用阿里云的DNS服务实现ipv6的DDNS".
首先ipv6的长度为128位,正常运营商会给分配64为的前缀,这就意味着家里只要有支持ipv6的路由器,就可以分配与路由器前缀相同的ipv6地址,并且这个ipv6就可以直接当做公网的可变ip使用, 既然可变ip,就可以使用ddns的方式. 每台终端机器上运行自己的ddns服务用来监控ipv6地址的变化,.而在公网中的用户就可以使用域名:端口的方式直接访问了.
这里ipv6的ddns本人做过尝试,阿里云对自己的域名解析提供了完整API,稍有开发能力的同学都可一通过阅读文档,开发出自己的小的ddns服务.
阿里云域名解析API:https://help.aliyun.com/document_detail/29776.html
三、什么是FRP:
1. 什么是FRP:
FRP 全名:Fast Reverse Proxy。FRP 是一个使用 Go 语言开发的高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务。FRP 支持 TCP、UDP、HTTP、HTTPS等协议类型,并且支持 Web 服务根据域名进行路由转发。
- FRP 项目地址:https://github.com/fatedier/frp
- FRP中文文档地址: https://github.com/fatedier/frp/blob/master/README_zh.md
2. FRP的作用:
- 利用处于内网或防火墙后的机器,对外网环境提供 HTTP 或 HTTPS 服务。
- 对于 HTTP, HTTPS 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个 80 端口。
- 利用处于内网或防火墙后的机器,对外网环境提供 TCP 和 UDP 服务,例如在家里通过 SSH 访问处于公司内网环境内的主机。
四、FRP的安装与配置:
1. 准备:
- 家里需要内网穿透的终端;
- 一台具有公网ip的主机: 这里选择阿里云ECS的最基础的版本(CPU:1核; 内存:2 GB; 操作系统: Debian 9.8 64位; 带宽: 1Mbps);
- 域名: 如果只是ssh,可以不需要域名;
2. 下载:
FRP 采用 Go 语言开发, 支持 Windows、Linux、MacOS、ARM等多平台部署. FRP 安装非常容易, 只需下载对应系统平台的软件包, 并解压就可用.为了方便管理, 解压后重命名为frp.
以Debian为例:
wget https://github.com/fatedier/frp/releases/download/v0.30.0/frp_0.30.0_linux_amd64.tar.gz
tar -xzvf frp_0.30.0_linux_amd64.tar.gz
mv frp_0.30.0_linux_amd64 frp
3. 编写配置文件并测试:
将 frps 及 frps.ini 放到具有公网 IP 的机器上。
将 frpc 及 frpc.ini 放到处于内网环境的机器上。
通过 ssh 访问公司内网机器
修改 frps.ini 文件,这里使用了最简化的配置:
frps.ini
[common]
bind_port = 7000
启动 frps:
./frps -c ./frps.ini
修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.x;
frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
启动 frpc:
./frpc -c ./frpc.ini
通过 ssh 访问内网机器,假设用户名为 test:
ssh -oPort=6000 test@x.x.x.x
详细请见大佬文章: https://www.jianshu.com/p/00c79df1aaf0
以及查看官方文档:https://github.com/fatedier/frp/blob/master/README_zh.md
4.设置进程守护并开机自启:
4.1 Supervisor守护进程:
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程
Supervisor官方文档: http://supervisord.org/
a. 安装:
sudo apt-get install supervisor
b.配置:
root@iZuf: cat /etc/supervisor/supervisord.conf
通过conf文件而已看出, supervisor的监控的任务是依据是**/etc/supervisor/conf.d/*下的.conf文件, 这就简单了, 来了创建一个 setfrps.conf文件,作为frp服务的启动脚本.
/etc/supervisor/conf.d/setfrps.conf
[program:frps]
user=root
command=/root/Document/frp/frps -c /root/Document/frp/frps.ini
# 要确认该目录已经存在
directory=/etc/supervisor
# 程序停止之后是否需要重新将其启动
autorestart=true
# 重新启动时等待的时间
startsecs=10
# 重启程序的次数
startretries=100
具体的其他没有没有涉及,只做初级配置
> supervisorctl
#读取配置文件
reread
#启动程序
start frps
命令说明
> status # 查看程序状态
> stop usercenter # 关闭 usercenter 程序
> start usercenter # 启动 usercenter 程序
> restart usercenter # 重启 usercenter 程序
> reread # 读取有更新(增加)的配置文件,不会启动新添加的程序
> update # 重启配置文件修改过的程序
也可以不进入交互环境:
$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update
4.2 设置开机自启动:
由于某些软件并没有增加开启启动的服务,很多时候需要手工添加,一般我们都是推荐添加命令到 /etc/rc.local 文件,但是 Debian 9 默认不带 /etc/rc.local 文件,而 rc.local 服务却还是自带的.
root@iZuf6:/etc/supervisor: cat /lib/systemd/system/rc.local.service
并且默认情况下这个服务还是关闭的状态:
root@iZuf6:# systemctl status rc-local
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled)
Drop-In: /lib/systemd/system/rc-local.service.d
└─debian.conf
Active: inactive (dead)
为了解决这个问题,需要手工添加一个 /etc/rc.local 文件:
/etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# 以下为需要开机运行的脚本命令
/usr/bin/supervisord
exit 0
EOF
需要开机启动的命令添加到 /etc/rc.local 文件,丢在 exit 0 前面即可.
chmod +x /etc/rc.local
接着启动 rc-local 服务
systemctl start rc-local
再次查看状态:
尝试重启以后试试是否生效.
五、参考文档
https://www.jianshu.com/p/00c79df1aaf0
https://www.cnblogs.com/sundahua/p/9149692.html
https://www.cnblogs.com/flymeng/p/7901062.html