Add --udp-filter-quic=parse

This will enable QUIC decryption and parsing.
This commit is contained in:
Vadim Vetrov
2025-01-03 15:52:53 +03:00
parent 91e6825cb2
commit 0280fe383f
4 changed files with 27 additions and 7 deletions

View File

@@ -9,7 +9,7 @@
- [IPv6](#ipv6) - [IPv6](#ipv6)
- [Check it](#check-it) - [Check it](#check-it)
- [Flags](#flags) - [Flags](#flags)
- [UDP](#udp) - [UDP/QUIC](#udp/quic)
- [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
- [TV](#tv) - [TV](#tv)
- [Troubleshooting EPERMS (Operation not permitted)](#troubleshooting-eperms-operation-not-permitted) - [Troubleshooting EPERMS (Operation not permitted)](#troubleshooting-eperms-operation-not-permitted)
@@ -270,13 +270,21 @@ Flags that do not scoped to a specific section, used over all the youtubeUnblock
- `--udp-faking-strategy={checksum|ttl|none}` Faking strategy for udp. `checksum` will fake UDP checksum, `ttl` won't fake but will make UDP content relatively small, `none` is no faking. Defaults to none. - `--udp-faking-strategy={checksum|ttl|none}` Faking strategy for udp. `checksum` will fake UDP checksum, `ttl` won't fake but will make UDP content relatively small, `none` is no faking. Defaults to none.
- `--udp-filter-quic={disabled|all}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all, all quic initial packets will be handled. Defaults to disabled. - `--udp-filter-quic={disabled|all|parsed}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all, all quic initial packets will be handled. `parsed` will decrypt and parse QUIC initial message and match it with `--sni-domains`. Defaults to disabled.
- `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Just an alias for `--udp-filter-quic=all --udp-mode=drop`. - `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Just an alias for `--udp-filter-quic=all --udp-mode=drop`.
## UDP ## UDP/QUIC
UDP is another communication protocol. Well-known technologies that use it are DNS, QUIC, voice chats. UDP does not provide reliable connection and its header is much simpler than TCP thus fragmentation is limited. The support provided primarily by faking. For QUIC faking may not work well, so use `--quic-drop` if you want to drop all quic traffic. For other technologies I recommend to configure UDP support in the separate section from TCP, like `--fbegin --udp-dport-filter=50000-50099 --tls=disabled`. See more in flags related to udp and [issues tagged with udp label](https://github.com/Waujito/youtubeUnblock/issues?q=label%3Audp+). UDP is another communication protocol. Well-known technologies that use it are DNS, QUIC, voice chats. UDP does not provide reliable connection and its header is much simpler than TCP thus fragmentation is limited. The support provided primarily by faking.
Right now, QUIC faking may not work well, so use `--udp-mode=drop` option.
QUIC is enabled with `--udp-filter-quic` flag. The flag supports two modes: `all` will handle all the QUIC initial messages and `parse` will decrypt and parse the QUIC initial message, and then compare it with `--sni-domains` flag.
**I recommend to use** `--udp-mode=drop --udp-filter-quic=parse`.
For **other UDP protocols** I recommend to configure UDP support in the separate section from TCP, like `--fbegin --udp-dport-filter=50000-50099 --tls=disabled`. See more in flags related to udp and [tickets tagged with udp label](https://github.com/Waujito/youtubeUnblock/issues?q=label%3Audp+).
## Troubleshooting ## Troubleshooting

View File

@@ -368,7 +368,7 @@ void print_usage(const char *argv0) {
printf("\t--udp-fake-len=<size of upd fake>\n"); printf("\t--udp-fake-len=<size of upd fake>\n");
printf("\t--udp-faking-strategy={checksum|ttl|none}\n"); printf("\t--udp-faking-strategy={checksum|ttl|none}\n");
printf("\t--udp-dport-filter=<5,6,200-500>\n"); printf("\t--udp-dport-filter=<5,6,200-500>\n");
printf("\t--udp-filter-quic={disabled|all}\n"); printf("\t--udp-filter-quic={disabled|all|parsed}\n");
printf("\t--threads=<threads number>\n"); printf("\t--threads=<threads number>\n");
printf("\t--packet-mark=<mark>\n"); printf("\t--packet-mark=<mark>\n");
printf("\t--connbytes-limit=<pkts>\n"); printf("\t--connbytes-limit=<pkts>\n");
@@ -764,6 +764,8 @@ int yparse_args(int argc, char *argv[]) {
sect_config->udp_filter_quic = UDP_FILTER_QUIC_DISABLED; sect_config->udp_filter_quic = UDP_FILTER_QUIC_DISABLED;
} else if (strcmp(optarg, "all") == 0) { } else if (strcmp(optarg, "all") == 0) {
sect_config->udp_filter_quic = UDP_FILTER_QUIC_ALL; sect_config->udp_filter_quic = UDP_FILTER_QUIC_ALL;
} else if (strcmp(optarg, "parsed") == 0) {
sect_config->udp_filter_quic = UDP_FILTER_QUIC_PARSED;
} else { } else {
goto invalid_opt; goto invalid_opt;
} }
@@ -930,6 +932,9 @@ static size_t print_config_section(const struct section_config_t *section, char
case UDP_FILTER_QUIC_DISABLED: case UDP_FILTER_QUIC_DISABLED:
print_cnf_buf("--udp-filter-quic=disabled"); print_cnf_buf("--udp-filter-quic=disabled");
break; break;
case UDP_FILTER_QUIC_PARSED:
print_cnf_buf("--udp-filter-quic=parsed");
break;
} }
if (section->udp_dport_range_len != 0) { if (section->udp_dport_range_len != 0) {

View File

@@ -218,6 +218,7 @@ enum {
enum { enum {
UDP_FILTER_QUIC_DISABLED, UDP_FILTER_QUIC_DISABLED,
UDP_FILTER_QUIC_ALL, UDP_FILTER_QUIC_ALL,
UDP_FILTER_QUIC_PARSED,
}; };
#define default_section_config { \ #define default_section_config { \

View File

@@ -404,7 +404,7 @@ int detect_udp_filtered(const struct section_config_t *section,
goto skip; goto skip;
} }
if (section->udp_filter_quic) { if (section->udp_filter_quic != UDP_FILTER_QUIC_DISABLED) {
const struct quic_lhdr *qch; const struct quic_lhdr *qch;
uint32_t qch_len; uint32_t qch_len;
struct quic_cids qci; struct quic_cids qci;
@@ -430,6 +430,12 @@ int detect_udp_filtered(const struct section_config_t *section,
goto match_port; goto match_port;
} }
if (section->udp_filter_quic == UDP_FILTER_QUIC_ALL ||
section->all_domains) {
lgtrace_addp("QUIC early approve");
goto approve;
}
uint8_t *decrypted_payload; uint8_t *decrypted_payload;
uint32_t decrypted_payload_len; uint32_t decrypted_payload_len;
const uint8_t *decrypted_message; const uint8_t *decrypted_message;
@@ -452,7 +458,7 @@ int detect_udp_filtered(const struct section_config_t *section,
); );
if (tlsv.sni_len != 0) { if (tlsv.sni_len != 0) {
lgdebugmsg("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr); lgtrace_addp("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr);
} }
if (tlsv.target_sni) { if (tlsv.target_sni) {