Frp内网穿透_IP

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


Frp内网穿透_服务端_02

 

2.4 观察仪表盘上流量

Frp内网穿透_nginx_03

 

3.Frp内网穿透实现Https传输

Frp角色

网络类型

IP地址

Frps--frp服务端

外网(公网)

某个不知名的公网IP

Frpc--frp客户端

内网(局域网)

192.168.65.3

需要注意的是💻frpc(frp客户端一定需要能够访问外网)

3.1 前提准备

3.1.1 Frps安装Nginx

Frp内网穿透_IP_04

 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 查看配置是否生效

Frp内网穿透_IP_05