Frp是一款高性能的反向代理软件,可以帮助用户轻松地将内网服务映射到公网上,从而实现内网穿透。它支持TCP、UDP、HTTP、HTTPS等多种协议,可以在不同的操作系统上运行,包括Windows、Linux、MacOS等。frp的主要特点是易于配置、高效稳定、安全可靠,因此被广泛应用于各种场景,如远程办公、服务器管理、游戏加速等
1.Frp内网穿透实现SSH访问内网主机
Frp角色 | 网络类型 | IP地址 |
Frps--frp服务端 | 外网(公网) | 某个不知名的公网IP |
Frpc--frp客户端 | 内网(局域网) | 192.168.65.3 |
需要注意的是💻frpc(frp客户端一定需要能够访问外网)
根据不同的系统架构选择不同的安装包,从 frp下载链接 上下载合适的安装包.由于生产环境大多都是Linux系统架构,所以使用的安装包为:frp_0.21.0_linux_amd64.tar.gz
配置步骤如下:
参考链接
官网:http://gofrp.org
下载:https://github.com/fatedier/frp/releases
教程:frp中文文档
https://github.com/fatedier/frp/blob/master/README_zh.md
示例:frps.ini服务端,全配置参数
https://github.com/fatedier/frp/blob/master/conf/frps_full.ini
示例:frpc.ini客户端,全配置参数
https://github.com/fatedier/frp/blob/master/conf/frpc_full.ini
1.1 下载frp安装包
需要在frps和frpc中下载安装包并解压
[root@localhost ~]# wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_linux_amd64.tar.gz
[root@localhost ~]# tar -xzvf frp_0.21.0_linux_amd64.tar.gz
[root@localhost ~]# mv frp_0.21.0_linux_amd64 frp
[root@localhost ~]# cd frp
1.2 配置frps
修改配置文件frps.ini,默认配置如下:
[common]
bind_port = 7000 #frp服务端端口(必须)
启动frps
[root@localhost ~]# nohup /root/frp/frps -c /root/frp/frps.ini &
`此命令会自动生成nohup.out的日志文件
[root@localhost ~]# tf nohub.out
2023/06/25 10:20:57 [I] [service.go:130] frps tcp listen on 0.0.0.0:7000
2023/06/25 10:20:57 [I] [root.go:207] Start frps success
2023/06/25 10:21:19 [I] [service.go:319] client login info: ip [171.83.124.30:44592] version [0.21.0] hostname [] os [linux] arch [amd64]
2023/06/25 10:21:19 [I] [proxy.go:217] [d299621f0f84ee5b] [ssh] tcp proxy listen port [6666]
2023/06/25 10:21:19 [I] [control.go:335] [d299621f0f84ee5b] new proxy [ssh] success
2023/06/25 10:22:03 [I] [proxy.go:87] [d299621f0f84ee5b] [ssh] get a new work connection: [171.83.124.30:44592]
......
使用System管理frps
[root@localhost ~]# yum install systemd
[root@localhost ~]# vi /usr/lib/systemd/system/frps.service
[Unit]
Description=Frp Server Service
After=network.target
[Service]
Type=simple
# 如果只有单个 root 用户,必须指定为 root,否则使用默认的 nobody 即可
# User=nobody 报错:code=exited, status=203/EXEC frp
User=root
Restart=on-failure
RestartSec=5s
# 路径修改
ExecStart=/root/frp/frps -c /root/frp/frps.ini
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart frps.service
[root@localhost ~]# systemctl status frps.service
1.3 配置frpc
在客户端机器上配置文件frpc.ini,配置如下:
[common]
server_addr = 某个不知名的公网IP #frp服务端地址,可以填ip或者域名,这里假设为我的公网IP
server_port = 7000 #frp服务端端口,即填写服务端配置中的 bind_port
[ssh] #这个名称具有唯一性,如果需要映射多台局域网主机.需要设置出差异性
type = tcp #连接类型,填tcp或udp
local_ip = 127.0.0.1 #填127.0.0.1或内网ip都可以
local_port = 22 #需要转发到的端口,ssh端口是22
remote_port = 6666 #frp服务端的远程监听端口,即你访问服务端的remote_port就相当于访问客户端的 local_port,如果填0则会随机分配一个端口
启动frpc
[root@localhost ~]# nohup /root/frp/frpc -c /root/frp/frpc.ini &
`此命令会自动生成nohup.out的日志文件
[root@localhost ~]# tf nohub.out
2023/06/25 10:21:19 [I] [proxy_manager.go:310] proxy added: [ssh]
2023/06/25 10:21:19 [I] [proxy_manager.go:333] visitor removed: []
2023/06/25 10:21:19 [I] [proxy_manager.go:342] visitor added: []
2023/06/25 10:21:19 [I] [control.go:246] [d299621f0f84ee5b] login to server success, get run id [d299621f0f84ee5b], server udp port [0]
2023/06/25 10:21:19 [I] [control.go:169] [d299621f0f84ee5b] [ssh] start proxy success
使用System管理frpc
[root@localhost ~]# yum install systemd
[root@localhost ~]# vi /usr/lib/systemd/system/frpc.service
[Unit]
Description=Frp Server Service
After=network.target
[Service]
Type=simple
# 如果只有单个 root 用户,必须指定为 root,否则使用默认的 nobody 即可
# User=nobody 报错:code=exited, status=203/EXEC frp
User=root
Restart=on-failure
RestartSec=5s
# 路径修改
ExecStart=/root/frp/frpc -c /root/frp/frpc.ini
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart frpc.service
[root@localhost ~]# systemctl status frpc.service
1.4 连接远程主机
ssh -p 6000 username@server_addr 登录的主机密码是局域网机器的密码而不是公网的密码 配置frp一定要允许对应端口的流量通过,不然frp的流量是无法通过防火墙
2.Frp内网穿透实现Web页面的穿透
Frp角色 | 网络类型 | IP地址 |
Frps--frp服务端 | 外网(公网) | 某个不知名的公网IP |
Frpc--frp客户端 | 内网(局域网) | 192.168.65.3 |
需要注意的是💻frpc(frp客户端一定需要能够访问外网)
2.1 配置frps
[root@localhost ~]# cd frp/
[root@localhost frp]# cat frps.ini
[common]
# 用于客户端和服务端连接的端口,自己指定
bind_port = 7342
# 用于客户端和服务端连接的口令,自己指定
token = frpstest
# 服务端仪表板的端口,自己指定
dashboard_port = 7343
# 打开仪表板页面登录的用户名和密码
dashboard_user = username
dashboard_pwd = password
# 这个端口就是服务器开放到外网的,业务端口
vhost_http_port = 8081
[root@localhost frp]# systemctl restart frps && systemctl status frps
可以使用
http://公网ip:7343
访问仪表盘,登录时会需要你输入用户名和密码
2.2 配置frpc
[root@localhost frp]# cat frpc.ini
[common]
# FRP服务器IP,改为自己的服务器IP
server_addr = 某个不知名的公网IP
# FRP服务器bind_port端口
server_port = 7342
authentication_method = token
token = frpstest
[web]
type = http
local_ip = 127.0.0.1
local_port = 80
remote_port = 8081
# FRP服务器IP,可以不需要域名
custom_domains = 某个不知名的公网IP
[root@localhost frp]# systemctl restart frpc.service
[root@localhost ~]# cd /usr/local/nginx/
[root@localhost nginx]# ls
conf html sbin
[root@localhost nginx]# cd html/
[root@localhost html]# echo "hello frpservice,i am frpclient,my ip is 192.168.65.3" > index.html
2.3 使用浏览器访问目标网站
`目标网站 http://某个不知名公网IP:8081
2.4 观察仪表盘上流量
3.Frp内网穿透实现Https传输
Frp角色 | 网络类型 | IP地址 |
Frps--frp服务端 | 外网(公网) | 某个不知名的公网IP |
Frpc--frp客户端 | 内网(局域网) | 192.168.65.3 |
需要注意的是💻frpc(frp客户端一定需要能够访问外网)
3.1 前提准备
3.1.1 Frps安装Nginx
Nginx二进制安装脚本
#!/bin/bash
nginx -V >> /dev/null 2>&1
if [ $? -ne 0 ];then
# 下载Nginx二进制软件包
result=$(find / -name "nginx-1.22.0.tar.gz" 2>/dev/null)
# 判断是否找到文件
if [ -z "$result" ]; then
wget http://nginx.org/download/nginx-1.22.0.tar.gz
fi
# 编译安装Nginx
# 下载相关依赖包
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
cd /usr/local/
find / -name nginx-1.22.0.tar.gz -type f -print0 | xargs -0 -I {} tar -xzf {}
# 这个命令的作用是在整个文件系统中查找nginx-1.22.0.tar.gz的文件,并将其解压缩到/usr/local/目录下
# 其中 -type f选项用于限制查找的结果只包含文件,而不包括目录
# -print0选项用于在查找结果之间使用null字符分割符,以避免文件名中包含空格等特殊字符导致的问题
# xargs命令的-0选项用于告诉他们使用null字符作为分隔符
cd
groupadd nginx
useradd -g nginx -s /bin/nologin nginx
mkdir -p /var/run/nginx/
mkdir -p /data/log/nginx/
mkdir -p /usr/local/run/
mkdir -p /var/temp/nginx/
mkdir -p /var/temp/nginx/
mkdir -p /path/to/
mkdir -p /var/run/nginx/sbin/
cd /usr/local/nginx-1.22.0/
./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/data/log/nginx/error.log --http-log-path=/data/log/nginx/access.log --with-http_gzip_static_module --http-client-body-temp-path=/var/temp/nginx/client --http-proxy-temp-path=/var/temp/nginx/proxy --http-fastcgi-temp-path=/var/temp/nginx/fastcgi --http-uwsgi-temp-path=/var/temp/nginx/uwsgi --http-scgi-temp-path=/var/temp/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
# 创建环境变量
echo "export PATH=\"/usr/local/nginx/sbin:\$PATH\"" >> /etc/profile
# 加载环境变量
source /etc/profile
cd /usr/local/nginx/sbin/
# 启动nginx
./nginx -c /usr/local/nginx/conf/nginx.conf
./nginx -s reload
# 制作软链接
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
# 检查是否安装成功
if [ ! -f /usr/sbin/lsof ];then
yum -y install lsof
fi
lsof -i:80 | grep "nginx" >> /dev/null 2>&1
if [ $? -ne 0 ];then
echo "----------Nginx未成功安装,请查看详细报错信息--------------"
else
echo "-------------------Nginx成功安装-------------------"
rm -rf /usr/local/nginx-1.22.0/
fi
fi
3.1.2 备案域名和SSL证书申请
由于学习用途,就暂时不申请域名和SSL证书 使用脚本生成SSL证书(此证书不被认可,不可做真实生产环境),如果有域名就需要将公网IP地址替换成域名
#!/bin/bash
if [ ! -f "/bin/openssl" ];then
yum -y install openssl
fi
. /etc/init.d/functions
CERT_INFO=([00]="/O=heaven/CN=ca.god.com" \
[01]="cakey.pem" \
[02]="cacert.pem" \
[03]=2048 \
[04]=3650 \
[05]=0 \
[10]="/C=CN/ST=hubei/L=wuhan/O=Gizaworks/CN=某个不知名的公网IP(备案域名)" \
[11]="master.key" \
[12]="master.crt" \
[13]=2048 \
[14]=365
[15]=1 \
[16]="master.csr" \
[20]="/C=CN/ST=hubei/L=wuhan/O=Gizaworks/CN=某个不知名的公网IP(备案域名)" \
[21]="slave.key" \
[22]="slave.crt" \
[23]=2048 \
[24]=365 \
[25]=2 \
[26]="slave.csr" )
COLOR="echo -e \\E[1;32m"
END="\\E[0m"
DIR=/usr/local/nginx/ssl
mkdir -p $DIR
cd $DIR
for i in {0..2};do
if [ $i -eq 0 ] ;then
openssl req -x509 -newkey rsa:${CERT_INFO[${i}3]} -subj ${CERT_INFO[${i}0]} \
-set_serial ${CERT_INFO[${i}5]} -keyout ${CERT_INFO[${i}1]} -nodes -days ${CERT_INFO[${i}4]} \
-out ${CERT_INFO[${i}2]} &>/dev/null
else
openssl req -newkey rsa:${CERT_INFO[${i}3]} -nodes -subj ${CERT_INFO[${i}0]} \
-keyout ${CERT_INFO[${i}1]} -out ${CERT_INFO[${i}6]} &>/dev/null
openssl x509 -req -in ${CERT_INFO[${i}6]} -CA ${CERT_INFO[02]} -CAkey ${CERT_INFO[01]} \
-set_serial ${CERT_INFO[${i}5]} -days ${CERT_INFO[${i}4]} -out ${CERT_INFO[${i}2]} &>/dev/null
fi
$COLOR"**************************************生成证书信息**************************************"$END
openssl x509 -in ${CERT_INFO[${i}2]} -noout -subject -dates -serial
echo
done
chmod 600 *.key
action "证书生成完成"
3.1.3 Nginx监听443端口
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri; # 用户使用http访问会自动跳转到https
}
server {
listen 443 ssl; # 监听端口
server_name localhost; # 监听主机
ssl_certificate /usr/local/nginx/ssl/cacert.pem; # SSL证书路径
ssl_certificate_key /usr/local/nginx/ssl/cakey.pem; # SSL证书私钥路径
ssl_session_cache shared:SSL:1m; # SSL会话缓存时间
ssl_session_timeout 5m; # SSL超时时间
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5; # 用于指定加密算法,HIGH:!aNULL:!MD5表示高强度加密算法
ssl_prefer_server_ciphers on; # 表示优先使用服务器端指定的加密算法
location / {
proxy_pass http://127.0.0.1:8081;
# proxy_set_header:是Nginx中的一个指令,用于设置HTTP请求头中的变量值.它的作用就是在Nginx作为反向代理服务器时,将客户端请求中的某些HTTP头信息传递给后端服务器
# 这样可以让后端服务器获取到客户端真实IP地址,协议类型,请求方法等信息,从而更好的处理请求
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for; # 将客户端的真实IP地址添加到请求头中的X-Forwarded-For字段中,以便后端服务器获取客户端的真实IP地址
proxy_set_header Host $host; # 将请求头中的Host字段设置为反向代理服务器的主机名,以便后端服务器正确处理请求
proxy_set_header X-Nginx-Proxy true; # 设置请求头中X-Nginx-Proxy字段为true,以便后端服务器判断请求是否来在Nginx反向代理服务器
proxy_set_header Upgrade $http_upgrade; # 将请求头中的Upgrade字段设置为$http_upgrade变量的值,以便支持WebSocket等协议的升级
proxy_set_header Conection "upgrade"; # 将请求头中的Connection字段设置为"upgrad",以便支持WebSocket等协议的升级
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
proxy_http_version 1.1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
3.2 配置Frpc
[root@localhost frp]# vim frpc.ini
[common]
# FRP服务器IP,改为自己的服务器IP
server_addr = 47.113.225.222
# FRP服务器bind_port端口
server_port = 7342
authentication_method = token
token = frpstest
[web]
type = http
local_ip = 127.0.0.1
local_port = 80
remote_port = 8081
# FRP服务器IP,可以不需要域名
custom_domains = 47.113.225.222
[webs]
type = https
local_ip = 127.0.0.1
local_port = 443
remote_port = 8081
# FRP服务器IP,可以不需要域名
custom_domains = 47.113.225.222
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6666
[root@localhost frp]# systemctl restart frpc.service
3.3 查看配置是否生效