受欢迎的博客标签

Creating a Reverse Proxy Server with YARP(appsettings.json)

Published

 

 

YARP 构建反向代理服务 

Creating a Reverse Proxy Server with YARP

 

.NET 8 SDK

step 1. create new project

 

step 2.nguet Yarp.ReverseProxy

Install-Package Yarp.ReverseProxy

step 3.

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.MapReverseProxy();
app.Run();

 

step 3.Configuring YARP

path:F:\developer_frpcsharp\src\Frpcsharp\appsettings.json

before
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
 
}

new

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeAll": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      }
    }
  }
}

Test.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <PublishAot>true</PublishAot>


        <StackTraceSupport>false</StackTraceSupport>
        <OptimizationPreference>Size</OptimizationPreference>
        <PublishTrimmed>true</PublishTrimmed>
        <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
        <EventSourceSupport>false</EventSourceSupport>
        <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
        <EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
        <MetadataUpdaterSupport>false</MetadataUpdaterSupport>
        <UseNativeHttpHandler>true</UseNativeHttpHandler>
        <TrimMode>link</TrimMode>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Yarp.ReverseProxy" Version="2.1.0" />
    </ItemGroup>

</Project>

 

aot

dotnet publish -c Release -r linux-x64 --self-contained true /p:PublishAot=true --output ../output 

detail:https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=net8plus%2Cwindows

 

other

 

Yarp主要要配置的东西就是Cluster(集群)和ProxyRoute(路由),

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeAll": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      }
    }
  }
}

 

YARP 根据单个域名实现默认路由代理百度,访问 /movie 是代理 b站转发的appsettings.json配置

 

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeBaidu": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      },
      "routeBiliBili": {
        "ClusterId": "clusterBiliBili",
        "Match": {
          "Path": "/movie/{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      },
      "clusterBiliBili": {
        "Destinations": {
          "bilibili": {
            "Address": "https://www.bilibili.com/"
          }
        }
      }
    }
  }
}

YARP 根据单个域名转发的appsettings.json配置

"ReverseProxy": {
   "Routes": {
     //描述一个路由,该路由根据匹配规则匹配传入的请求,并将匹配请求的代理到其ClusterId标识的群集。
     "route1" : {
       //与此路由匹配的集群标识。这里与下文的cluster1对应,如果路由匹配正确则访问cluster1配置的后端服务器地址。
       "ClusterId": "cluster1",
       //匹配规则 这里个正则表示匹配任何路径
       "Match": {
         "Path": "{**catch-all}"
       }
     }
   },
   //后端服务器集群
   "Clusters": {
     //集群标识
     "cluster1": {
       //服务器配置
       "Destinations": {
         //目标服务器1,可以有多个
         "destination1": {
           //服务器地址
           "Address": "https://cn.bing.com/"
         }
       }
     }
   }
 }

 

YARP 根据多个域名转发的appsettings.json配置

"ReverseProxy": {
  "Routes": {
    "baidu": {
      "ClusterId": "baidu",
      "Match": {
        "Hosts": [ "test1.ysmc.net.cn" ],
        "Path": "{**catch-all}"
      }
    },
    "blazor": {
      "ClusterId": "blazor",
      "Match": {
        "Hosts": [ "test2.ysmc.net.cn" ],
        "Path": "{**catch-all}"
      }
    }
  },
  "Clusters": {
    "baidu": {
      "LoadBalancingPolicy": "RoundRobin",
      "Destinations": {
        "baidu": {
          "Address": "https://www.baidu.com/"
        }
      }
    },
    "blazor": {
      "LoadBalancingPolicy": "RoundRobin",
      "Destinations": {
        "blazor": {
          "Address": "https://www.blazor.zone/"
        }
      }
    }
  }
}

https://www.cnblogs.com/ysmc/p/16714201.html

 

YARP config sample shows all the properties in appsettings.json

The config sample shows all the properties that can be set through config, which is similar in concept to most of what you find in NGINX.

https://github.com/microsoft/reverse-proxy/blob/main/samples/ReverseProxy.Config.Sample/appsettings.json

microsoft yarp Reverse Proxy 与 Nginx 配置对比

路由匹配


Nginx:

location  /WebUI

Yarp:在Routes中增加

"svc-web-route": {
        "ClusterId": "svc-web-cluster",
        "Match": {
          "Path": "/WebUI/{**catch-all}"
        }
      },



路由转发


Nginx:

proxy_pass   http://svc-api;
1
Yarp: 在Clusters中增加

"Destinations": {
          "svc-api-destination": {
            "Address": "http://svc-api"
          }
        },

默认页面:
Nginx:

index  index.html index.htm;

Yarp:暂时没找到,可由程序完成默认路由

超时配置
Nginx:

proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout  300;

Yarp:在Clusters中增加

"HttpRequest": {
          "ActivityTimeout": "00:03:00"
    }

重定向关闭
proxy_redirect off;
替换方案:默认关闭

Forward配置
Nignx:

proxy_set_header  X-Forwarded-Proto  $http_X_Forwarded_Proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Yarp:默认 X-Forwarded-For,X-Forwarded-Proto,X-Forwarded-Host ,可在 Transforms 中修改

地址重写


我们一般会增加一个固定前缀到后端,或者删除一个前缀到后端
nginx: rewrite
Yarp: route中增加

"Transforms": [
          { "PathRemovePrefix": "/OMS" }
        ]

https://blog.csdn.net/gavin_luo/article/details/128316913

 

在YARP中 代理时会创建一个(HttpMessageInvoker) httpClient 转发亲求。每一个 Clusters 项 都会创建独有的一个 HttpMessageInvoker

 

YARP HTTPS 和 TLS

YARP 是 7 级 HTTP 代理,这意味着传入的 HTTPS/TLS 连接由代理完全解密,以便它可以处理和转发 HTTP 请求。人话:网络ISO 7七层模型中他 他的代理支持 7 层 ,如果你要代理TCP /UDP 他是 4曾 。
使用 CONNECT 方法的 TLS 隧道是一种用于在不解密请求的情况下代理请求的功能。YARP不支持此功能,并且没有计划添加它。人话: YARP 不支持HTTPS 请求 不揭密转发。
YARP可以在所有 http://ASP.NET 核心服务器上运行,为传入连接配置HTTPS / TLS是特定于服务器的,人话:YARP 是一个http://asp.net core 的一个插件。所以 asp.net core 可以在哪里托管。他就可以在哪里托管。
Kestrel 支持在 TLS 握手之前拦截传入的连接。YARP 包含一个 TLS帧帮助程序 API,可以分析原始 TLS握手,使你能够收集自定义遥测数据或急切地拒绝连接。
要在与目标通信时启用 TLS 加密,请将目标地址指定为 类似 "https://destinationHost" 目标地址中指定的主机名将用于 TLS 握手,包括 SNI 和服务器证书验证。如果启用了代理原始主机标头,则该值将改为用于 TLS 握手。如果需要使用自定义主机值,请使用RequestHeader转换来设置主机标头。

https://www.cnblogs.com/ysmc/p/16717580.html

useful links

https://github.com/microsoft/reverse-proxy/discussions/1829

https://microsoft.github.io/reverse-proxy/articles/direct-forwarding.html

 

 

Useful links

https://mbarkt3sto.hashnode.dev/creating-a-reverse-proxy-server-with-yarp

https://www.milanjovanovic.tech/blog/implementing-an-api-gateway-for-microservices-with-yarp