FRP進行端口轉發訪問web服務


利用Frp進行端口轉發詳細操作

服務器部署Frps

下載運行

  • 下載frp可執行包
wget https://github.com/fatedier/frp/releases/download/v0.32.0/frp_0.32.0_linux_amd64.tar.gz
  • 解壓
tar zxf frp_0.32.0_linux_amd64.tar.gz
  • 進入文件
cd frp_0.32.0_linux_amd64/
  • 修改配置文件frps.ini為如下內容
[common]
# frps與frpc通訊的端口
bind_port = 7000

# http請求監聽的端口
vhost_http_port = 8888

# dashboard的用戶名密碼以及端口
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = 123456

# XXX.com,和*.XXX.com都必須可以解析到本服務器IP
subdomain_host = XXX.com
  • 啟動
./frps -c frps.ini 

開機自啟服務

  • 創建后台啟動模版
vi /etc/systemd/system/frp.service
  • frp.service內容如下:
[Unit]
Description=frps
After=network.target

[Service]
ExecStart=/root/frp_0.32.0_linux_amd64/frps -c /root/frp_0.32.0_linux_amd64/frps.ini 

[Install]
WantedBy=multi-user.target
  • 啟動測試
systemctl start frp.service
  • 查看啟動狀態
systemctl status frp.service
  • 開機自啟
systemctl enable frp.service

客戶端(采集端工控機)部署Frpc

下載運行

從https://github.com/fatedier/frp/releases下載windows版本包frp_0.32.0_windows_amd64.zip

  • 修改Frpc.ini如下
[common]
#服務器IP,域名也可以
server_addr = 123.45.67.89
server_port = 7000

[Test1]
type = http
local_port = 12345
# 二級域名名稱
subdomain = test1
# 使用壓縮
use_compression = true 

[Test2]
type = http
local_port = 12346
subdomain = test2
use_compression = true
  • 在Frpc.exe所在文件夾,cmd進入命令行
frpc -c .\frpc.ini

出現start proxy success就表示已經連接成功,此時任何發往http://test1.XXX.com:8888的請求會轉發至12345端口,http://test2.XXX.com:8888的請求會發往12346端口

采集端區分請求來源

請求分類

  1. 來自端口轉發的請求

    Frp轉發Http請求時,會在headers中加入一個header:X-Forwarded-For,值就是該請求來源的真實IP

  2. 局域網內的請求

    此類請求可直接從HttpContext中獲取IP

  3. 本地請求

    此類請求的IP為127.0.0.1,localhost,::1

過濾器

設計一個過濾器,為涉及到修改的Action打上過濾IP的標簽.具體邏輯如下:

  • 先設計一張IP白名單

  • 判斷headers中有沒有X-Forwarded-For,有的話直接攔截.

  • 判斷IP在不在白名單內,不在白名單內直接攔截.

過濾器代碼如下:

public class HttpRequestIPFilterAttribute : ActionFilterAttribute
    {
        private ILogger logger;
        private readonly SystemService systemService;

        public HttpRequestIPFilterAttribute(ILogger<HttpRequestIPFilterAttribute> logger, SystemService systemService)
        {
            this.logger = logger;
            this.systemService = systemService;
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var headers = context.HttpContext.Request.Headers;
            if (headers.ContainsKey("X-Forwarded-For"))
            {
                //請求來自端口轉發
                logger.LogWarning("檢測到遠程IP的訪問,IP地址:{0}", headers["X-Forwarded-For"]);
                var rspmsg = new RspMsg<string>
                {
                    Code = 401,
                    Msg = "遠程請求無法調用此方法",
                    Data = null,
                };
                context.Result = new OkObjectResult(rspmsg);
                return;
            }
            else
            {
                //請求不是轉發來的
                var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
                var isWhite=systemService.WhiteIPList.Contains(remoteIp.ToString());
                if (!isWhite)
                {
                    logger.LogWarning("檢測到白名單外的IP訪問,IP地址:{0}", remoteIp.ToString());

                    var rspmsg = new RspMsg<string>
                    {
                        Code = 401,
                        Msg = "非白名單內的IP無法調用此方法",
                        Data = null,
                    };
                    context.Result = new OkObjectResult(rspmsg);
                    return;
                } 
            }
        }

注冊過濾器:

services.AddScoped<HttpRequestIPFilterAttribute>();

在action中使用過濾器

    /// <summary>
    /// 獲取所有報警項目
    /// </summary>
    /// <returns></returns>
    [HttpGet("v1")]
    [ServiceFilter(typeof(HttpRequestIPFilterAttribute))]  //使用過濾器
    public RspMsg<IEnumerable<AlarmItem>> GetAll()
    {
        var alarmItems = alarmService.GetAllItems();
        return RspMsg<IEnumerable<AlarmItem>>.Success(alarmItems);
    }

在遠程請求時會返回:

局域網內白名單外:

本地或者白名單內:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM