V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shendaowu
V2EX  ›  信息安全

有没有简单高效可靠的方法防止 web 服务半夜定时执行的耗时任务被恶意执行?

  •  
  •   shendaowu · 12 小时 51 分钟前 · 2133 次点击

    我要求是不是太多了?如果属于不可能三角的话可以去掉高效。反正本来就是很耗时的任务,除非会大幅影响其他页面的延迟之类的。

    耗时任务是一些数据库查询,还有数据库备份,可能还会有别的。每天每种只执行一次。

    我目前计划用 cron 定时访问 web 服务的一个地址。后端语言是 Go 。Go 有个很多人用的第三方的 cron 库,但是五年没更了,看 issue 好像也不是没问题,不敢用。

    我问 deepseek 它说验证源 IP 是不是 127.0.0.1 、::1 、localhost 就行了。另外需要注意一些特殊情况。比如代理、负载均衡器和容器。这个有漏洞吗?还要不要在耗时任务执行之前加个时段判断和今天是否已经执行过了?还有当前是否正在执行耗时任务。cron 好像在特殊情况下会重复执行?比如修改系统时间。

    主要需求就是防止这个东西成为被攻击的点。

    34 条回复    2025-09-12 15:57:43 +08:00
    totoro625
        1
    totoro625  
       12 小时 47 分钟前   ❤️ 1
    定时访问 web 服务的一个地址
    nginx 里面把 URL 改成随机字符串

    验证源 IP
    主要看你自己的设置

    cron 重复执行
    用 systemd timer 替代
    oh
        2
    oh  
       12 小时 43 分钟前   ❤️ 1
    nginx 里把那个 location 屏蔽掉
    本地 cron 直接访问本地端口
    Zakl21
        3
    Zakl21  
       12 小时 34 分钟前   ❤️ 1
    加个对称加密就行了把
    shendaowu
        4
    shendaowu  
    OP
       12 小时 34 分钟前
    实在不行简单也去掉吧,最重要的是可靠。
    sduoduo233
        5
    sduoduo233  
       12 小时 19 分钟前 via Android   ❤️ 1
    把定时任务拆分成一个单独的二进制文件
    用 cron 定时执行这个二进制
    mengdodo
        6
    mengdodo  
       12 小时 12 分钟前   ❤️ 1
    历史的经验告诉我们:对应旧项目的老代码,如果自己是接手方,最好就是别动,出问题拿 commit 节点去找人背锅即可。如果别人已离职更好,把锅架他们头上还不会反驳你。
    faceRollingKB
        7
    faceRollingKB  
       12 小时 11 分钟前   ❤️ 1
    定义恶意,代码识别恶意,处理恶意
    opengps
        8
    opengps  
       12 小时 9 分钟前   ❤️ 1
    我没看明白怎么来的恶意,如果说你使用对外特定接口来做,那么 ds 说的没错,过滤掉白名单之外,自己就可控了。
    dfkjgklfdjg
        9
    dfkjgklfdjg  
       12 小时 7 分钟前   ❤️ 1
    对应的 web 服务不对外开放出去不就好了吗?而且数据库备份这种阿里云这种服务商不都是有提供自动备份的功能么,直接用就好了哇。
    如果怕重复执行了,在业务里面增加一个是否执行的标识就好了。

    至于修改系统时间之类的不用放在应该考虑的范围内,如果不是自己修改时间或者时间同步服务器出现问题就不会出现回到历史时间的情况。如果是服务器失守了,在某一个业务里面干啥防御都没有用。
    dode
        10
    dode  
       12 小时 4 分钟前   ❤️ 1
    内存设置一个状态,每次执行前检查状态+当前时间,然后在系统内配置一个定时任务脚本,每天自动启动就行,还可以为这个接口加配一个随机密钥参数,简单验证权限
    wogogoing
        11
    wogogoing  
    PRO
       11 小时 57 分钟前 via iPhone   ❤️ 1
    robfig/cron 这个库没什么问题,用了好几年了。

    op 可以瞅瞅我实现的计划任务:

    https://go-sail.dev/zh-CN/docs/examples/schedule
    xuanbg
        12
    xuanbg  
       11 小时 48 分钟前   ❤️ 1
    不能远程执行的就都很安全,除非服务器被入侵
    FrankAdler
        13
    FrankAdler  
       11 小时 41 分钟前 via Android   ❤️ 1
    什么叫被恶意执行
    shendaowu
        14
    shendaowu  
    OP
       11 小时 37 分钟前
    @sduoduo233 #5 感谢大佬。我感觉你这个方法的可靠性是碾压性的,就是有点麻烦,如果没有更好的方法我就用这个了。之前我总想就靠一个单独的二进制文件,现在想象好像好处也不是碾压性的。
    shendaowu
        15
    shendaowu  
    OP
       11 小时 36 分钟前
    @FrankAdler #13 像 DDoS 那样疯狂调用,然后降低或者破坏系统的可用性。
    FrankAdler
        16
    FrankAdler  
       11 小时 33 分钟前 via Android   ❤️ 1
    不对外开放不就行了吗,开放了加个鉴权也行,你在纠结什么
    shendaowu
        17
    shendaowu  
    OP
       11 小时 29 分钟前
    @FrankAdler #16 我在纠结我垃圾的智商无法考虑到所有危险的情况。另外我被某小日子写的安全书籍洗脑了,里面提到不是安全专家就别期待自己拍脑袋想出来的方案有多安全。
    oh
        18
    oh  
       11 小时 19 分钟前   ❤️ 1
    @shendaowu #14 那也没解决你正文中说的 “修改系统时间 引起 cron 重复执行” 的问题……
    ericguo
        19
    ericguo  
       11 小时 14 分钟前   ❤️ 1
    https://github.com/go-dev-frame/sponge/tree/main/pkg/gocron

    你为啥需要通过 web 访问来触发,直接写成 gocron.Run 不就好了。。。 🤷
    cheng6563
        20
    cheng6563  
       11 小时 11 分钟前   ❤️ 1
    算了吧,这问题也想那么多,不如给我服务器账号,我来帮你搞定。
    ggzhyipeng
        21
    ggzhyipeng  
       11 小时 3 分钟前   ❤️ 1
    robfig/cron 我们生产用挺久了,没啥问题吧。
    实在要用外部 cron 的话,接口限制只能从内网/127 调用,或者改成命令行调用
    edward1987
        22
    edward1987  
       11 小时 1 分钟前   ❤️ 1
    执行前加个锁呗,就算被多次调用也不怕
    zjyl1994
        23
    zjyl1994  
       10 小时 45 分钟前   ❤️ 1
    robfig/cron 没什么问题,程序里直接调用肯定是最安全的。
    如果非要通过 http 进行触发,可以加个 token 验证。

    至于被人进到服务器里面改时间反复触发 cron ,很难解决的。还是要做好防护把安全问题拦在外面。
    juzisang
        24
    juzisang  
       10 小时 41 分钟前   ❤️ 1
    加个 token 校验或者随机字符的 url 不就行了,就是个普普通通的 webhook 需求...
    sthwrong
        25
    sthwrong  
       10 小时 39 分钟前   ❤️ 1
    触发多次的问题可以上锁,同一个任务只有一个实例在执行。接口鉴权和高频请求都好处理。至于系统时间修改,都能改时间了估计也能删你库了,那没啥了。
    way2create
        26
    way2create  
       10 小时 33 分钟前   ❤️ 1
    不知道在讲什么,你定义的恶意执行是什么呢?不如举几个实际场景吧,不要虚空索敌。
    sagnitude
        27
    sagnitude  
       9 小时 6 分钟前   ❤️ 1
    1. 管理接口也对互联网开放并且不加任何认证措施?
    2. 为什么不另起一个服务或者 docker 去做耗时的任务?放在生产服务器上跑这种任务是严重影响使用的,万一跑到早上呢,万一出错把线程池占满了,早上起来所有客户都 boom 了呢
    3. 就好比用 spring 的定时执行就可以做到的事情,不应当暴露一个接口出来,其他语言也肯定有类似的功能
    4. 内网找另一台机器用 crontab 启动/停止一个单独的程序,执行完就关掉是最好的
    momocraft
        28
    momocraft  
       9 小时 2 分钟前   ❤️ 1
    单独二进制(或者进程入口)挺好的
    不要用 http 触发
    oneisall8955
        29
    oneisall8955  
    PRO
       8 小时 37 分钟前   ❤️ 1
    加参数校验
    realpg
        30
    realpg  
    PRO
       7 小时 47 分钟前   ❤️ 1
    你连个鉴权都不会写吗?
    ruanimal
        31
    ruanimal  
       7 小时 0 分钟前   ❤️ 1
    @sduoduo233 复用二进制文件,加个参数就行了啊
    yinmin
        32
    yinmin  
       6 小时 51 分钟前 via iPhone   ❤️ 1
    类似 openai 的 api 认证 key ,每次 web api 调用时都验证 http request header

    Authorization: Bearer YOUR_API_KEY

    然后客户端请求的时候加上 YOUR_API_KEY 访问你的 web api
    litchinn
        33
    litchinn  
       6 小时 19 分钟前   ❤️ 1
    首先考虑这个定时任务是不是非得以 http 接口的形式调用 否:用应用内部调度器实现
    这个 http 接口是否必须暴露到外网 是:添加白名单或者认证机制 否:禁止外网的直接访问
    重复执行的问题,如果已经有能修改你的系统时间的权限了,那应该没法避免,重复执行些任务已经是轻的了
    你应该要重点考虑的是这个“耗时任务”会不会影响系统正常功能,能不能限制它使用的资源
    momocraft
        34
    momocraft  
       5 小时 8 分钟前
    如果需要理论依据:这类负载类似于 12 factor app 里的这个: https://www.12factor.net/admin-processes
    建议做法是从同一套代码构建,但是和 web server 分开执行
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2742 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 13:06 · PVG 21:06 · LAX 06:06 · JFK 09:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.