Skip to content

Comments

feature: webhook outbound#5722

Open
kastov wants to merge 2 commits intoXTLS:mainfrom
kastov:feat/webhook
Open

feature: webhook outbound#5722
kastov wants to merge 2 commits intoXTLS:mainfrom
kastov:feat/webhook

Conversation

@kastov
Copy link
Contributor

@kastov kastov commented Feb 23, 2026

Many administrators use Xray's built-in routing capabilities to block certain traffic, such as BitTorrent. Tools like Xray Torrent Blocker exist for this purpose — they work by monitoring log files, parsing tags, and applying the necessary actions. While this approach works well, reading log files is far from an ideal solution and comes with a number of inherent limitations.

This PR introduces a new outbound type — webhook. Its behavior is very similar to blackhole, but with the additional capability of sending an HTTP POST request to a specified address with a JSON body. The request can be sent either over regular HTTP(S) or via a Unix Domain Socket.

Request Structure

{
  "email": "2",                        // string | null
  "level": null,                       // number | null
  "protocol": "tls",                   // string | null
  "network": "tcp",                    // string
  "source": "tcp:127.0.0.1:54203",     // string | null
  "destination": "tcp:dns.google:443", // string
  "routeTarget": null,                 // string | null
  "originalTarget": "tcp:8.8.8.8:443",// string | null
  "inboundTag": "VLESS_TCP",           // string | null
  "inboundName": "vless",              // string | null
  "inboundLocal": "tcp:192.168.108.1:443", // string | null
  "outboundTag": "NTFY_BLOCK",  // string | null
  "ts": 1771886901                     // number
}

Note: The PR intentionally uses pointer types so that all fields are always present in the request body. If any data is unavailable, the corresponding field is sent as null. This significantly simplifies parsing on the receiving end.

Usage Example

The following example demonstrates how to use this feature with Xray's built-in routing:

Routing rule:

{
  "protocol": ["bittorrent"],
  "outboundTag": "NTFY_BLOCK"
}

Webhook outbound configuration:

{
  "tag": "NTFY_BLOCK",
  "protocol": "webhook",
  "settings": {
    "url": "https://api.example.com/ntfy/core",
    "deduplication": 10
  }
}

Documentation

A companion PR has also been submitted to add documentation for the feature described above. The documentation has been translated into all supported languages. Please note that the Chinese translation was produced with the assistance of AI and should be reviewed by a native speaker.

Linked PR: XTLS/Xray-docs-next#823


There was also an alternative implementation approach — via the dispatcher, however I have serious doubts that such a PR would have been accepted.

@Fangliding
Copy link
Member

Fangliding commented Feb 24, 2026

xray的torrent嗅探极其原始很容易被绕过
添加这个出站的用途很明显在用户发送服务提供者不想要的请求的时候触发回调记录用户数据用以记录请求信息/警告/封禁账号等用途 总感觉这看起来更像是一个审查系统而不是一个反审查系统(

@kastov
Copy link
Contributor Author

kastov commented Feb 24, 2026

xray的torrent嗅探极其原始很容易被绕过

That is entirely true, and I see no reason to deny it. However, even such a primitive protection — combined with Xray-Torrent-Blocker (linked above) — can work together quite effectively. Xray reports the information (currently only through the log file), and Xray-Torrent-Blocker applies a temporary IP ban for a specified duration. This way, even with a basic detection mechanism, the risks can be meaningfully minimised.

添加这个出站的用途很明显在用户发送服务提供者不想要的请求的时候触发回调记录用户数据用以记录请求信息/警告/封禁账号等用途 总感觉这看起来更像是一个审查系统而不是一个反审查系统(

All the data included in the webhook request is already available to the administrator through the standard access.log. Following this logic, access.log can also be used as "spy tool" — since it allows performing exactly the same actions as the webhookSource IP, Destination IP/domain, routing tag, timestamp: Xray-Log-Analyzer, xray-logger.
Let me give a concrete example. Suppose I want to disable logging entirely and set "access": "none". This immediately creates a problem: tools like Xray-Torrent-Blocker stop working, since they rely on reading the log file – monitoring it in real time for the -> TORRENT string, parsing the IP address, and blocking it via nftables/iptables/ufw for a specified duration.
At the same time, there is no way to configure logging selectively — so that only entries with the TORRENT tag are written to the file. It's all or nothing.
This is exactly where the webhook solves the problem elegantly: instead of enabling full logging just for a single use case, we simply receive a notification at the right moment. Yes, the webhook carries the same data as access.log – but only for a specific event, without recording all traffic indiscriminately. As things stand, if we need even a minimal reaction to certain types of connections, we are forced to enable full logging — even if we don't want to store anything at all.


we already have a real surveillance tool – IP Map...

@gfw-killer
Copy link

At the same time, there is no way to configure logging selectively — so that only entries with the TORRENT tag are written to the file. It's all or nothing.

It seem to be very useful to categorize logs and disable/enable them and write each category logs to a different file

Another way to mitigate the torrent and also other abuse reports, is to whitelist protocols (http/tls/quic/dns/ntp/etc.) and games by asn/cidr and disallow others or route them to a bulletproof server, it allows your users to torrent too
but currently Xray-core can only detect http/tls/quic/bittorrent (and detects them all even if you don't need it)

@RPRX
Copy link
Member

RPRX commented Feb 24, 2026

用户跑 BT 的话会导致 VPS 被服务商封掉,且涉及版权问题,所以我觉得出发点没啥问题

但是比起来加个出站不如完善日志系统,使它支持选择性日志和多重日志(同一条日志写两个地方),主动请求倒是没必要

@Fangliding
Copy link
Member

Fangliding commented Feb 24, 2026

担心用户跑bt直接导到黑洞就行了(假如相信那个sniffer)

以及

reading log files is far from an ideal solution and comes with a number of inherent limitations

恐怕这个pr本身就是为了解决处理log作为一个纯文本系统和面板自动化集成的不便

改log一边一个需求没完没了了 除了log level没有看到什么很理想的分类 像chrome的日志稍微启动一下就导出来高大全一堆然后自己往里翻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants