V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX  ›  程序员

有什么把 ASP.NET Core MVC 写的企业官网所有页面渲染成静态的吗?最近经常有 CC 攻击把 CPU 占满。或者 Nginx 配什么参数能把所有页面都缓存下来?(内容非常少变动,没有用户可以提交的内容)

  •  
  •   edis0n0 · 2023-01-15 21:18:32 +08:00 · 2000 次点击
    这是一个创建于 437 天前的主题,其中的信息可能已经有所发展或是发生改变。
    24 条回复    2023-01-17 17:17:41 +08:00
    edis0n0
        1
    edis0n0  
    OP
       2023-01-15 21:19:26 +08:00
    没有 CDN 和 WAF ,传统企业这些服务预算肯定批不下来,不用提了
    foolishnobody
        2
    foolishnobody  
       2023-01-15 21:21:53 +08:00 via Android
    前面加个 cf 试试
    idragonet
        3
    idragonet  
       2023-01-15 21:38:04 +08:00
    CDN 也有免费的。
    edis0n0
        4
    edis0n0  
    OP
       2023-01-15 21:57:12 +08:00
    @foolishnobody #2
    @idragonet #3 国内的站
    learningman
        5
    learningman  
       2023-01-15 22:05:38 +08:00
    Nginx Proxy Cache ,可以存硬盘上
    learningman
        6
    learningman  
       2023-01-15 22:07:48 +08:00
    或者如果真的确信不会变动,wget -r 把所有页面下载下来,nginx 直接静态提供
    idragonet
        7
    idragonet  
       2023-01-15 22:13:25 +08:00
    @edis0n0 国内也有免费 CDN
    edis0n0
        8
    edis0n0  
    OP
       2023-01-15 22:24:18 +08:00
    @idragonet #7 企业站 免费的领导肯定不让用
    zhchyu999
        9
    zhchyu999  
       2023-01-15 22:31:36 +08:00
    最好 CDN 解决,其次 Nginx ,通过限制 IP 请求次数,缓存似乎不治本,也不一定治标
    ASP.NET Core MVC 应该有一个拦截器,把渲染过后的 HTML 缓存起来
    thinkershare
        11
    thinkershare  
       2023-01-15 23:00:22 +08:00
    @edis0n0 最简单情况是使用输出缓存, 不过这个玩意非常新,需要 ASP.NET Core 7.0 的支持
    ryd994
        12
    ryd994  
       2023-01-16 01:53:52 +08:00 via Android
    用好 proxy_cache 和 proxy_store ,可以实现你的需求。proxy_cache_key 可能需要一些调整优化。
    限制请求频率是后话,因为如果不做好缓存,限制请求频率很容易误伤正常用户。
    kkk9
        13
    kkk9  
       2023-01-16 02:21:25 +08:00
    ngx_lua:先载出一个纯 js 验证页,简单算法带上值验证,正确跳转 ASP.NET ,不正确(没有的)直接拉黑 IP 。拉黑机制自行斟酌,顺便可以过滤不正常的 UA
    edis0n0
        14
    edis0n0  
    OP
       2023-01-16 02:28:42 +08:00
    @kkk9 #13 企业官网是要考虑搜索引擎 SEO 的,还要维护一个搜索引擎 IP 白名单,国内有的搜索引擎好像没给爬虫 IP 段
    dayeye2006199
        15
    dayeye2006199  
       2023-01-16 04:09:09 +08:00
    免费的不让用,收费的没预算。。左转换领导
    netnr
        16
    netnr  
       2023-01-16 08:48:29 +08:00 via Android
    #12 提到的磁盘缓存感觉是最适合的方案

    个人目前用这种方式做 unpkg 白名单镜像
    lslqtz
        17
    lslqtz  
       2023-01-16 09:31:01 +08:00
    @edis0n0 付费 DNS 通常可以解决这个问题, 其次是 UA 爬虫判断和 IP 段.
    lslqtz
        18
    lslqtz  
       2023-01-16 09:31:29 +08:00
    然后国内的付费 CDN, 5 秒盾部分也有, 不出意外也是有爬虫白名单的.
    quan01994
        19
    quan01994  
       2023-01-16 09:44:08 +08:00
    https://learn.microsoft.com/zh-cn/aspnet/core/performance/caching/output?view=aspnetcore-7.0

    你可以看看微软官方文档,这个功能应该可以解决你的问题 。
    ragnaroks
        20
    ragnaroks  
       2023-01-16 14:19:34 +08:00
    前面套 CF ,其次控制器上加 [ResponseCache]
    xioxu
        21
    xioxu  
       2023-01-16 17:02:41 +08:00
    自己写一个 Filter ,自行控制过期、缓存逻辑。
    xioxu
        22
    xioxu  
       2023-01-16 17:09:31 +08:00
    这是 chatGPT 生成的示例代码:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;

    public class CacheFilter : IActionFilter
    {
    private static ConcurrentDictionary<string, byte[]> _cache = new ConcurrentDictionary<string, byte[]>();

    public void OnActionExecuted(ActionExecutedContext context)
    {
    if (context.Result is FileResult)
    {
    // 缓存 FileResult 类型的结果
    var file = context.Result as FileResult;
    using (var stream = new MemoryStream())
    {
    file.CopyTo(stream);
    var key = $"{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}";
    _cache.TryAdd(key, stream.ToArray());
    }
    }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
    var key = $"{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}";
    if (_cache.TryGetValue(key, out var data))
    {
    // 如果缓存中有,则直接返回
    context.Result = new FileContentResult(data, "application/octet-stream");
    }
    }
    }
    sky857412
        23
    sky857412  
       2023-01-17 09:51:03 +08:00
    不是有个名词叫静态化,ASP.NET Core MVC 静态化 搜索下
    zimrigeek
        24
    zimrigeek  
       2023-01-17 17:17:41 +08:00
    面对攻击 最有效的解决方案一般 2 大类,1 是从 Web Server 端限制流量,2 是从 CDN 限制流量
    1. Web Server 端限制流量
    无论是 nginx 还是 openresty 均有相关模块可以直接调用

    nginx.conf

    http{
    ...
    # 防止 CC 攻击配置;
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    ...
    }


    vhost.conf

    server{
    ...
    # 并发限制;
    limit_conn perserver 500;
    limit_conn perip 50;
    limit_rate 5120k;
    # 并发限制-END
    ...
    }


    2. CDN 一般因厂商而异,通过流量、CC 控制相应功能 来限制
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3213 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 11:56 · PVG 19:56 · LAX 04:56 · JFK 07:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.