diff --git a/README.md b/README.md index cda92d0..1872f09 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ - [Firewall configuration](#firewall-configuration) - [nftables rules](#nftables-rules) - [Iptables rules](#iptables-rules) + - [IPv6](#ipv6) - [Check it](#check-it) - [Flags](#flags) - [Troubleshooting](#troubleshooting) @@ -104,6 +105,16 @@ iptables -t mangle -A FORWARD -p tcp --dport 443 -m connbytes --connbytes-dir or iptables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT ``` +#### IPv6 + +For IPv6 on iptables you need to duplicate rules above for ip6tables: +```sh +ip6tables -t mangle -A FORWARD -p tcp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass +ip6tables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT +``` + + + Note that above rules use *conntrack* to route only first 20 packets from the connection to **youtubeUnblock**. If you got some troubles with it, for example **youtubeUnblock** doesn't detect YouTube, try to delete *connbytes* from the rules. But it is an unlikely behavior and you should probably check your ruleset. @@ -170,6 +181,8 @@ Available flags: - `--no-gso` Disables support for Google Chrome fat packets which uses GSO. This feature is well tested now, so this flag probably won't fix anything. +- `--no-ipv6` Disables support for ipv6. May be useful if you don't want for ipv6 socket to be opened. + - `--threads=` Specifies the amount of threads you want to be running for your program. This defaults to **1** and shouldn't be edited for normal use. If you have performance issues, consult [performance chaptr](https://github.com/Waujito/youtubeUnblock?tab=readme-ov-file#performance) ## Troubleshooting diff --git a/args.c b/args.c index b69e0ce..cb044ec 100644 --- a/args.c +++ b/args.c @@ -20,6 +20,7 @@ struct config_t config = { .fake_sni_seq_len = 1, .frag_middle_sni = 1, .frag_sni_pos = 2, + .use_ipv6 = 1, .sni_detection = SNI_DETECTION_PARSE, @@ -63,13 +64,14 @@ struct config_t config = { #define OPT_TRACE 15 #define OPT_QUIC_DROP 16 #define OPT_SNI_DETECTION 17 +#define OPT_NO_IPV6 20 #define OPT_SEG2DELAY 5 #define OPT_THREADS 6 #define OPT_SILENT 7 #define OPT_NO_GSO 8 #define OPT_QUEUE_NUM 9 -#define OPT_MAX OPT_FRAG_SNI_POS +#define OPT_MAX OPT_NO_IPV6 static struct option long_opt[] = { {"help", 0, 0, 'h'}, @@ -92,6 +94,7 @@ static struct option long_opt[] = { {"silent", 0, 0, OPT_SILENT}, {"trace", 0, 0, OPT_TRACE}, {"no-gso", 0, 0, OPT_NO_GSO}, + {"no-ipv6", 0, 0, OPT_NO_IPV6}, {"queue-num", 1, 0, OPT_QUEUE_NUM}, {0,0,0,0} }; @@ -144,6 +147,7 @@ void print_usage(const char *argv0) { printf("\t--silent\n"); printf("\t--trace\n"); printf("\t--no-gso\n"); + printf("\t--no-ipv6\n"); printf("\n"); } @@ -169,6 +173,9 @@ int parse_args(int argc, char *argv[]) { case OPT_NO_GSO: config.use_gso = 0; break; + case OPT_NO_IPV6: + config.use_ipv6 = 0; + break; case OPT_QUIC_DROP: config.quic_drop = 1; break; @@ -393,6 +400,12 @@ void print_welcome() { printf("GSO is enabled\n"); } + if (config.use_ipv6) { + printf("IPv6 is enabled\n"); + } else { + printf("IPv6 is disabled\n"); + } + if (config.quic_drop) { printf("All QUIC packets will be dropped\n"); } diff --git a/config.h b/config.h index 5de4260..e084a3a 100644 --- a/config.h +++ b/config.h @@ -18,6 +18,7 @@ struct config_t { unsigned int queue_start_num; int threads; int use_gso; + int use_ipv6; int fragmentation_strategy; int frag_sni_reverse; int frag_sni_faked; diff --git a/mangle.c b/mangle.c index cf04378..694deff 100644 --- a/mangle.c +++ b/mangle.c @@ -35,7 +35,7 @@ int process_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { transport_proto = iph ->protocol; - } else if (ipver == IP6VERSION) { + } else if (ipver == IP6VERSION && config.use_ipv6) { ret = ip6_payload_split((uint8_t *)raw_payload, raw_payload_len, (struct ip6_hdr **)&ip6h, &iph_len, (uint8_t **)&ip_payload, &ip_payload_len); @@ -45,11 +45,11 @@ int process_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { transport_proto = ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt; + } else { + lgtracemsg("Unknown layer 3 protocol version: %d", ipver); + goto accept; } - - if (ret < 0) - goto accept; switch (transport_proto) { case IPPROTO_TCP: diff --git a/youtubeUnblock.c b/youtubeUnblock.c index 5876c5a..0d1ca33 100644 --- a/youtubeUnblock.c +++ b/youtubeUnblock.c @@ -579,10 +579,12 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } - if (open_raw6_socket() < 0) { - perror("Unable to open raw socket for ipv6"); - close_raw_socket(); - exit(EXIT_FAILURE); + if (config.use_ipv6) { + if (open_raw6_socket() < 0) { + perror("Unable to open raw socket for ipv6"); + close_raw_socket(); + exit(EXIT_FAILURE); + } } struct queue_res *qres = &defqres; @@ -618,7 +620,8 @@ int main(int argc, char *argv[]) { } close_raw_socket(); - close_raw6_socket(); + if (config.use_ipv6) + close_raw6_socket(); return -qres->status; }