1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2013 Patrick McHardy <kaber@trash.net> 4 */ 5 6 #include <linux/module.h> 7 #include <linux/skbuff.h> 8 #include <asm/unaligned.h> 9 #include <net/tcp.h> 10 #include <net/netns/generic.h> 11 #include <linux/proc_fs.h> 12 13 #include <linux/netfilter_ipv6.h> 14 #include <linux/netfilter/nf_synproxy.h> 15 16 #include <net/netfilter/nf_conntrack.h> 17 #include <net/netfilter/nf_conntrack_ecache.h> 18 #include <net/netfilter/nf_conntrack_extend.h> 19 #include <net/netfilter/nf_conntrack_seqadj.h> 20 #include <net/netfilter/nf_conntrack_synproxy.h> 21 #include <net/netfilter/nf_conntrack_zones.h> 22 #include <net/netfilter/nf_synproxy.h> 23 24 unsigned int synproxy_net_id; 25 EXPORT_SYMBOL_GPL(synproxy_net_id); 26 27 bool 28 synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, 29 const struct tcphdr *th, struct synproxy_options *opts) 30 { 31 int length = (th->doff * 4) - sizeof(*th); 32 u8 buf[40], *ptr; 33 34 if (unlikely(length < 0)) 35 return false; 36 37 ptr = skb_header_pointer(skb, doff + sizeof(*th), length, buf); 38 if (ptr == NULL) 39 return false; 40 41 opts->options = 0; 42 while (length > 0) { 43 int opcode = *ptr++; 44 int opsize; 45 46 switch (opcode) { 47 case TCPOPT_EOL: 48 return true; 49 case TCPOPT_NOP: 50 length--; 51 continue; 52 default: 53 if (length < 2) 54 return true; 55 opsize = *ptr++; 56 if (opsize < 2) 57 return true; 58 if (opsize > length) 59 return true; 60 61 switch (opcode) { 62 case TCPOPT_MSS: 63 if (opsize == TCPOLEN_MSS) { 64 opts->mss_option = get_unaligned_be16(ptr); 65 opts->options |= NF_SYNPROXY_OPT_MSS; 66 } 67 break; 68 case TCPOPT_WINDOW: 69 if (opsize == TCPOLEN_WINDOW) { 70 opts->wscale = *ptr; 71 if (opts->wscale > TCP_MAX_WSCALE) 72 opts->wscale = TCP_MAX_WSCALE; 73 opts->options |= NF_SYNPROXY_OPT_WSCALE; 74 } 75 break; 76 case TCPOPT_TIMESTAMP: 77 if (opsize == TCPOLEN_TIMESTAMP) { 78 opts->tsval = get_unaligned_be32(ptr); 79 opts->tsecr = get_unaligned_be32(ptr + 4); 80 opts->options |= NF_SYNPROXY_OPT_TIMESTAMP; 81 } 82 break; 83 case TCPOPT_SACK_PERM: 84 if (opsize == TCPOLEN_SACK_PERM) 85 opts->options |= NF_SYNPROXY_OPT_SACK_PERM; 86 break; 87 } 88 89 ptr += opsize - 2; 90 length -= opsize; 91 } 92 } 93 return true; 94 } 95 EXPORT_SYMBOL_GPL(synproxy_parse_options); 96 97 static unsigned int 98 synproxy_options_size(const struct synproxy_options *opts) 99 { 100 unsigned int size = 0; 101 102 if (opts->options & NF_SYNPROXY_OPT_MSS) 103 size += TCPOLEN_MSS_ALIGNED; 104 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 105 size += TCPOLEN_TSTAMP_ALIGNED; 106 else if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 107 size += TCPOLEN_SACKPERM_ALIGNED; 108 if (opts->options & NF_SYNPROXY_OPT_WSCALE) 109 size += TCPOLEN_WSCALE_ALIGNED; 110 111 return size; 112 } 113 114 static void 115 synproxy_build_options(struct tcphdr *th, const struct synproxy_options *opts) 116 { 117 __be32 *ptr = (__be32 *)(th + 1); 118 u8 options = opts->options; 119 120 if (options & NF_SYNPROXY_OPT_MSS) 121 *ptr++ = htonl((TCPOPT_MSS << 24) | 122 (TCPOLEN_MSS << 16) | 123 opts->mss_option); 124 125 if (options & NF_SYNPROXY_OPT_TIMESTAMP) { 126 if (options & NF_SYNPROXY_OPT_SACK_PERM) 127 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | 128 (TCPOLEN_SACK_PERM << 16) | 129 (TCPOPT_TIMESTAMP << 8) | 130 TCPOLEN_TIMESTAMP); 131 else 132 *ptr++ = htonl((TCPOPT_NOP << 24) | 133 (TCPOPT_NOP << 16) | 134 (TCPOPT_TIMESTAMP << 8) | 135 TCPOLEN_TIMESTAMP); 136 137 *ptr++ = htonl(opts->tsval); 138 *ptr++ = htonl(opts->tsecr); 139 } else if (options & NF_SYNPROXY_OPT_SACK_PERM) 140 *ptr++ = htonl((TCPOPT_NOP << 24) | 141 (TCPOPT_NOP << 16) | 142 (TCPOPT_SACK_PERM << 8) | 143 TCPOLEN_SACK_PERM); 144 145 if (options & NF_SYNPROXY_OPT_WSCALE) 146 *ptr++ = htonl((TCPOPT_NOP << 24) | 147 (TCPOPT_WINDOW << 16) | 148 (TCPOLEN_WINDOW << 8) | 149 opts->wscale); 150 } 151 152 void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info, 153 struct synproxy_options *opts) 154 { 155 opts->tsecr = opts->tsval; 156 opts->tsval = tcp_time_stamp_raw() & ~0x3f; 157 158 if (opts->options & NF_SYNPROXY_OPT_WSCALE) { 159 opts->tsval |= opts->wscale; 160 opts->wscale = info->wscale; 161 } else 162 opts->tsval |= 0xf; 163 164 if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 165 opts->tsval |= 1 << 4; 166 167 if (opts->options & NF_SYNPROXY_OPT_ECN) 168 opts->tsval |= 1 << 5; 169 } 170 EXPORT_SYMBOL_GPL(synproxy_init_timestamp_cookie); 171 172 static void 173 synproxy_check_timestamp_cookie(struct synproxy_options *opts) 174 { 175 opts->wscale = opts->tsecr & 0xf; 176 if (opts->wscale != 0xf) 177 opts->options |= NF_SYNPROXY_OPT_WSCALE; 178 179 opts->options |= opts->tsecr & (1 << 4) ? NF_SYNPROXY_OPT_SACK_PERM : 0; 180 181 opts->options |= opts->tsecr & (1 << 5) ? NF_SYNPROXY_OPT_ECN : 0; 182 } 183 184 static unsigned int 185 synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, 186 struct tcphdr *th, struct nf_conn *ct, 187 enum ip_conntrack_info ctinfo, 188 const struct nf_conn_synproxy *synproxy) 189 { 190 unsigned int optoff, optend; 191 __be32 *ptr, old; 192 193 if (synproxy->tsoff == 0) 194 return 1; 195 196 optoff = protoff + sizeof(struct tcphdr); 197 optend = protoff + th->doff * 4; 198 199 if (skb_ensure_writable(skb, optend)) 200 return 0; 201 202 while (optoff < optend) { 203 unsigned char *op = skb->data + optoff; 204 205 switch (op[0]) { 206 case TCPOPT_EOL: 207 return 1; 208 case TCPOPT_NOP: 209 optoff++; 210 continue; 211 default: 212 if (optoff + 1 == optend || 213 optoff + op[1] > optend || 214 op[1] < 2) 215 return 0; 216 if (op[0] == TCPOPT_TIMESTAMP && 217 op[1] == TCPOLEN_TIMESTAMP) { 218 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { 219 ptr = (__be32 *)&op[2]; 220 old = *ptr; 221 *ptr = htonl(ntohl(*ptr) - 222 synproxy->tsoff); 223 } else { 224 ptr = (__be32 *)&op[6]; 225 old = *ptr; 226 *ptr = htonl(ntohl(*ptr) + 227 synproxy->tsoff); 228 } 229 inet_proto_csum_replace4(&th->check, skb, 230 old, *ptr, false); 231 return 1; 232 } 233 optoff += op[1]; 234 } 235 } 236 return 1; 237 } 238 239 static struct nf_ct_ext_type nf_ct_synproxy_extend __read_mostly = { 240 .len = sizeof(struct nf_conn_synproxy), 241 .align = __alignof__(struct nf_conn_synproxy), 242 .id = NF_CT_EXT_SYNPROXY, 243 }; 244 245 #ifdef CONFIG_PROC_FS 246 static void *synproxy_cpu_seq_start(struct seq_file *seq, loff_t *pos) 247 { 248 struct synproxy_net *snet = synproxy_pernet(seq_file_net(seq)); 249 int cpu; 250 251 if (*pos == 0) 252 return SEQ_START_TOKEN; 253 254 for (cpu = *pos - 1; cpu < nr_cpu_ids; cpu++) { 255 if (!cpu_possible(cpu)) 256 continue; 257 *pos = cpu + 1; 258 return per_cpu_ptr(snet->stats, cpu); 259 } 260 261 return NULL; 262 } 263 264 static void *synproxy_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 265 { 266 struct synproxy_net *snet = synproxy_pernet(seq_file_net(seq)); 267 int cpu; 268 269 for (cpu = *pos; cpu < nr_cpu_ids; cpu++) { 270 if (!cpu_possible(cpu)) 271 continue; 272 *pos = cpu + 1; 273 return per_cpu_ptr(snet->stats, cpu); 274 } 275 (*pos)++; 276 return NULL; 277 } 278 279 static void synproxy_cpu_seq_stop(struct seq_file *seq, void *v) 280 { 281 return; 282 } 283 284 static int synproxy_cpu_seq_show(struct seq_file *seq, void *v) 285 { 286 struct synproxy_stats *stats = v; 287 288 if (v == SEQ_START_TOKEN) { 289 seq_puts(seq, "entries\t\tsyn_received\t" 290 "cookie_invalid\tcookie_valid\t" 291 "cookie_retrans\tconn_reopened\n"); 292 return 0; 293 } 294 295 seq_printf(seq, "%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", 0, 296 stats->syn_received, 297 stats->cookie_invalid, 298 stats->cookie_valid, 299 stats->cookie_retrans, 300 stats->conn_reopened); 301 302 return 0; 303 } 304 305 static const struct seq_operations synproxy_cpu_seq_ops = { 306 .start = synproxy_cpu_seq_start, 307 .next = synproxy_cpu_seq_next, 308 .stop = synproxy_cpu_seq_stop, 309 .show = synproxy_cpu_seq_show, 310 }; 311 312 static int __net_init synproxy_proc_init(struct net *net) 313 { 314 if (!proc_create_net("synproxy", 0444, net->proc_net_stat, 315 &synproxy_cpu_seq_ops, sizeof(struct seq_net_private))) 316 return -ENOMEM; 317 return 0; 318 } 319 320 static void __net_exit synproxy_proc_exit(struct net *net) 321 { 322 remove_proc_entry("synproxy", net->proc_net_stat); 323 } 324 #else 325 static int __net_init synproxy_proc_init(struct net *net) 326 { 327 return 0; 328 } 329 330 static void __net_exit synproxy_proc_exit(struct net *net) 331 { 332 return; 333 } 334 #endif /* CONFIG_PROC_FS */ 335 336 static int __net_init synproxy_net_init(struct net *net) 337 { 338 struct synproxy_net *snet = synproxy_pernet(net); 339 struct nf_conn *ct; 340 int err = -ENOMEM; 341 342 ct = nf_ct_tmpl_alloc(net, &nf_ct_zone_dflt, GFP_KERNEL); 343 if (!ct) 344 goto err1; 345 346 if (!nfct_seqadj_ext_add(ct)) 347 goto err2; 348 if (!nfct_synproxy_ext_add(ct)) 349 goto err2; 350 351 __set_bit(IPS_CONFIRMED_BIT, &ct->status); 352 nf_conntrack_get(&ct->ct_general); 353 snet->tmpl = ct; 354 355 snet->stats = alloc_percpu(struct synproxy_stats); 356 if (snet->stats == NULL) 357 goto err2; 358 359 err = synproxy_proc_init(net); 360 if (err < 0) 361 goto err3; 362 363 return 0; 364 365 err3: 366 free_percpu(snet->stats); 367 err2: 368 nf_ct_tmpl_free(ct); 369 err1: 370 return err; 371 } 372 373 static void __net_exit synproxy_net_exit(struct net *net) 374 { 375 struct synproxy_net *snet = synproxy_pernet(net); 376 377 nf_ct_put(snet->tmpl); 378 synproxy_proc_exit(net); 379 free_percpu(snet->stats); 380 } 381 382 static struct pernet_operations synproxy_net_ops = { 383 .init = synproxy_net_init, 384 .exit = synproxy_net_exit, 385 .id = &synproxy_net_id, 386 .size = sizeof(struct synproxy_net), 387 }; 388 389 static int __init synproxy_core_init(void) 390 { 391 int err; 392 393 err = nf_ct_extend_register(&nf_ct_synproxy_extend); 394 if (err < 0) 395 goto err1; 396 397 err = register_pernet_subsys(&synproxy_net_ops); 398 if (err < 0) 399 goto err2; 400 401 return 0; 402 403 err2: 404 nf_ct_extend_unregister(&nf_ct_synproxy_extend); 405 err1: 406 return err; 407 } 408 409 static void __exit synproxy_core_exit(void) 410 { 411 unregister_pernet_subsys(&synproxy_net_ops); 412 nf_ct_extend_unregister(&nf_ct_synproxy_extend); 413 } 414 415 module_init(synproxy_core_init); 416 module_exit(synproxy_core_exit); 417 418 static struct iphdr * 419 synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, 420 __be32 daddr) 421 { 422 struct iphdr *iph; 423 424 skb_reset_network_header(skb); 425 iph = skb_put(skb, sizeof(*iph)); 426 iph->version = 4; 427 iph->ihl = sizeof(*iph) / 4; 428 iph->tos = 0; 429 iph->id = 0; 430 iph->frag_off = htons(IP_DF); 431 iph->ttl = net->ipv4.sysctl_ip_default_ttl; 432 iph->protocol = IPPROTO_TCP; 433 iph->check = 0; 434 iph->saddr = saddr; 435 iph->daddr = daddr; 436 437 return iph; 438 } 439 440 static void 441 synproxy_send_tcp(struct net *net, 442 const struct sk_buff *skb, struct sk_buff *nskb, 443 struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 444 struct iphdr *niph, struct tcphdr *nth, 445 unsigned int tcp_hdr_size) 446 { 447 nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); 448 nskb->ip_summed = CHECKSUM_PARTIAL; 449 nskb->csum_start = (unsigned char *)nth - nskb->head; 450 nskb->csum_offset = offsetof(struct tcphdr, check); 451 452 skb_dst_set_noref(nskb, skb_dst(skb)); 453 nskb->protocol = htons(ETH_P_IP); 454 if (ip_route_me_harder(net, nskb->sk, nskb, RTN_UNSPEC)) 455 goto free_nskb; 456 457 if (nfct) { 458 nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 459 nf_conntrack_get(nfct); 460 } 461 462 ip_local_out(net, nskb->sk, nskb); 463 return; 464 465 free_nskb: 466 kfree_skb(nskb); 467 } 468 469 void 470 synproxy_send_client_synack(struct net *net, 471 const struct sk_buff *skb, const struct tcphdr *th, 472 const struct synproxy_options *opts) 473 { 474 struct sk_buff *nskb; 475 struct iphdr *iph, *niph; 476 struct tcphdr *nth; 477 unsigned int tcp_hdr_size; 478 u16 mss = opts->mss_encode; 479 480 iph = ip_hdr(skb); 481 482 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 483 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 484 GFP_ATOMIC); 485 if (!nskb) 486 return; 487 skb_reserve(nskb, MAX_TCP_HEADER); 488 489 niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 490 491 skb_reset_transport_header(nskb); 492 nth = skb_put(nskb, tcp_hdr_size); 493 nth->source = th->dest; 494 nth->dest = th->source; 495 nth->seq = htonl(__cookie_v4_init_sequence(iph, th, &mss)); 496 nth->ack_seq = htonl(ntohl(th->seq) + 1); 497 tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 498 if (opts->options & NF_SYNPROXY_OPT_ECN) 499 tcp_flag_word(nth) |= TCP_FLAG_ECE; 500 nth->doff = tcp_hdr_size / 4; 501 nth->window = 0; 502 nth->check = 0; 503 nth->urg_ptr = 0; 504 505 synproxy_build_options(nth, opts); 506 507 synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 508 IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 509 } 510 EXPORT_SYMBOL_GPL(synproxy_send_client_synack); 511 512 static void 513 synproxy_send_server_syn(struct net *net, 514 const struct sk_buff *skb, const struct tcphdr *th, 515 const struct synproxy_options *opts, u32 recv_seq) 516 { 517 struct synproxy_net *snet = synproxy_pernet(net); 518 struct sk_buff *nskb; 519 struct iphdr *iph, *niph; 520 struct tcphdr *nth; 521 unsigned int tcp_hdr_size; 522 523 iph = ip_hdr(skb); 524 525 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 526 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 527 GFP_ATOMIC); 528 if (!nskb) 529 return; 530 skb_reserve(nskb, MAX_TCP_HEADER); 531 532 niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 533 534 skb_reset_transport_header(nskb); 535 nth = skb_put(nskb, tcp_hdr_size); 536 nth->source = th->source; 537 nth->dest = th->dest; 538 nth->seq = htonl(recv_seq - 1); 539 /* ack_seq is used to relay our ISN to the synproxy hook to initialize 540 * sequence number translation once a connection tracking entry exists. 541 */ 542 nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 543 tcp_flag_word(nth) = TCP_FLAG_SYN; 544 if (opts->options & NF_SYNPROXY_OPT_ECN) 545 tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 546 nth->doff = tcp_hdr_size / 4; 547 nth->window = th->window; 548 nth->check = 0; 549 nth->urg_ptr = 0; 550 551 synproxy_build_options(nth, opts); 552 553 synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, 554 niph, nth, tcp_hdr_size); 555 } 556 557 static void 558 synproxy_send_server_ack(struct net *net, 559 const struct ip_ct_tcp *state, 560 const struct sk_buff *skb, const struct tcphdr *th, 561 const struct synproxy_options *opts) 562 { 563 struct sk_buff *nskb; 564 struct iphdr *iph, *niph; 565 struct tcphdr *nth; 566 unsigned int tcp_hdr_size; 567 568 iph = ip_hdr(skb); 569 570 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 571 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 572 GFP_ATOMIC); 573 if (!nskb) 574 return; 575 skb_reserve(nskb, MAX_TCP_HEADER); 576 577 niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 578 579 skb_reset_transport_header(nskb); 580 nth = skb_put(nskb, tcp_hdr_size); 581 nth->source = th->dest; 582 nth->dest = th->source; 583 nth->seq = htonl(ntohl(th->ack_seq)); 584 nth->ack_seq = htonl(ntohl(th->seq) + 1); 585 tcp_flag_word(nth) = TCP_FLAG_ACK; 586 nth->doff = tcp_hdr_size / 4; 587 nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 588 nth->check = 0; 589 nth->urg_ptr = 0; 590 591 synproxy_build_options(nth, opts); 592 593 synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); 594 } 595 596 static void 597 synproxy_send_client_ack(struct net *net, 598 const struct sk_buff *skb, const struct tcphdr *th, 599 const struct synproxy_options *opts) 600 { 601 struct sk_buff *nskb; 602 struct iphdr *iph, *niph; 603 struct tcphdr *nth; 604 unsigned int tcp_hdr_size; 605 606 iph = ip_hdr(skb); 607 608 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 609 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 610 GFP_ATOMIC); 611 if (!nskb) 612 return; 613 skb_reserve(nskb, MAX_TCP_HEADER); 614 615 niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 616 617 skb_reset_transport_header(nskb); 618 nth = skb_put(nskb, tcp_hdr_size); 619 nth->source = th->source; 620 nth->dest = th->dest; 621 nth->seq = htonl(ntohl(th->seq) + 1); 622 nth->ack_seq = th->ack_seq; 623 tcp_flag_word(nth) = TCP_FLAG_ACK; 624 nth->doff = tcp_hdr_size / 4; 625 nth->window = htons(ntohs(th->window) >> opts->wscale); 626 nth->check = 0; 627 nth->urg_ptr = 0; 628 629 synproxy_build_options(nth, opts); 630 631 synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 632 IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 633 } 634 635 bool 636 synproxy_recv_client_ack(struct net *net, 637 const struct sk_buff *skb, const struct tcphdr *th, 638 struct synproxy_options *opts, u32 recv_seq) 639 { 640 struct synproxy_net *snet = synproxy_pernet(net); 641 int mss; 642 643 mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); 644 if (mss == 0) { 645 this_cpu_inc(snet->stats->cookie_invalid); 646 return false; 647 } 648 649 this_cpu_inc(snet->stats->cookie_valid); 650 opts->mss_option = mss; 651 opts->options |= NF_SYNPROXY_OPT_MSS; 652 653 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 654 synproxy_check_timestamp_cookie(opts); 655 656 synproxy_send_server_syn(net, skb, th, opts, recv_seq); 657 return true; 658 } 659 EXPORT_SYMBOL_GPL(synproxy_recv_client_ack); 660 661 unsigned int 662 ipv4_synproxy_hook(void *priv, struct sk_buff *skb, 663 const struct nf_hook_state *nhs) 664 { 665 struct net *net = nhs->net; 666 struct synproxy_net *snet = synproxy_pernet(net); 667 enum ip_conntrack_info ctinfo; 668 struct nf_conn *ct; 669 struct nf_conn_synproxy *synproxy; 670 struct synproxy_options opts = {}; 671 const struct ip_ct_tcp *state; 672 struct tcphdr *th, _th; 673 unsigned int thoff; 674 675 ct = nf_ct_get(skb, &ctinfo); 676 if (!ct) 677 return NF_ACCEPT; 678 679 synproxy = nfct_synproxy(ct); 680 if (!synproxy) 681 return NF_ACCEPT; 682 683 if (nf_is_loopback_packet(skb) || 684 ip_hdr(skb)->protocol != IPPROTO_TCP) 685 return NF_ACCEPT; 686 687 thoff = ip_hdrlen(skb); 688 th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 689 if (!th) 690 return NF_DROP; 691 692 state = &ct->proto.tcp; 693 switch (state->state) { 694 case TCP_CONNTRACK_CLOSE: 695 if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { 696 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 697 ntohl(th->seq) + 1); 698 break; 699 } 700 701 if (!th->syn || th->ack || 702 CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 703 break; 704 705 /* Reopened connection - reset the sequence number and timestamp 706 * adjustments, they will get initialized once the connection is 707 * reestablished. 708 */ 709 nf_ct_seqadj_init(ct, ctinfo, 0); 710 synproxy->tsoff = 0; 711 this_cpu_inc(snet->stats->conn_reopened); 712 fallthrough; 713 case TCP_CONNTRACK_SYN_SENT: 714 if (!synproxy_parse_options(skb, thoff, th, &opts)) 715 return NF_DROP; 716 717 if (!th->syn && th->ack && 718 CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 719 /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 720 * therefore we need to add 1 to make the SYN sequence 721 * number match the one of first SYN. 722 */ 723 if (synproxy_recv_client_ack(net, skb, th, &opts, 724 ntohl(th->seq) + 1)) { 725 this_cpu_inc(snet->stats->cookie_retrans); 726 consume_skb(skb); 727 return NF_STOLEN; 728 } else { 729 return NF_DROP; 730 } 731 } 732 733 synproxy->isn = ntohl(th->ack_seq); 734 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 735 synproxy->its = opts.tsecr; 736 737 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 738 break; 739 case TCP_CONNTRACK_SYN_RECV: 740 if (!th->syn || !th->ack) 741 break; 742 743 if (!synproxy_parse_options(skb, thoff, th, &opts)) 744 return NF_DROP; 745 746 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 747 synproxy->tsoff = opts.tsval - synproxy->its; 748 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 749 } 750 751 opts.options &= ~(NF_SYNPROXY_OPT_MSS | 752 NF_SYNPROXY_OPT_WSCALE | 753 NF_SYNPROXY_OPT_SACK_PERM); 754 755 swap(opts.tsval, opts.tsecr); 756 synproxy_send_server_ack(net, state, skb, th, &opts); 757 758 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 759 nf_conntrack_event_cache(IPCT_SEQADJ, ct); 760 761 swap(opts.tsval, opts.tsecr); 762 synproxy_send_client_ack(net, skb, th, &opts); 763 764 consume_skb(skb); 765 return NF_STOLEN; 766 default: 767 break; 768 } 769 770 synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 771 return NF_ACCEPT; 772 } 773 EXPORT_SYMBOL_GPL(ipv4_synproxy_hook); 774 775 static const struct nf_hook_ops ipv4_synproxy_ops[] = { 776 { 777 .hook = ipv4_synproxy_hook, 778 .pf = NFPROTO_IPV4, 779 .hooknum = NF_INET_LOCAL_IN, 780 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 781 }, 782 { 783 .hook = ipv4_synproxy_hook, 784 .pf = NFPROTO_IPV4, 785 .hooknum = NF_INET_POST_ROUTING, 786 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 787 }, 788 }; 789 790 int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net) 791 { 792 int err; 793 794 if (snet->hook_ref4 == 0) { 795 err = nf_register_net_hooks(net, ipv4_synproxy_ops, 796 ARRAY_SIZE(ipv4_synproxy_ops)); 797 if (err) 798 return err; 799 } 800 801 snet->hook_ref4++; 802 return 0; 803 } 804 EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_init); 805 806 void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net) 807 { 808 snet->hook_ref4--; 809 if (snet->hook_ref4 == 0) 810 nf_unregister_net_hooks(net, ipv4_synproxy_ops, 811 ARRAY_SIZE(ipv4_synproxy_ops)); 812 } 813 EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_fini); 814 815 #if IS_ENABLED(CONFIG_IPV6) 816 static struct ipv6hdr * 817 synproxy_build_ip_ipv6(struct net *net, struct sk_buff *skb, 818 const struct in6_addr *saddr, 819 const struct in6_addr *daddr) 820 { 821 struct ipv6hdr *iph; 822 823 skb_reset_network_header(skb); 824 iph = skb_put(skb, sizeof(*iph)); 825 ip6_flow_hdr(iph, 0, 0); 826 iph->hop_limit = net->ipv6.devconf_all->hop_limit; 827 iph->nexthdr = IPPROTO_TCP; 828 iph->saddr = *saddr; 829 iph->daddr = *daddr; 830 831 return iph; 832 } 833 834 static void 835 synproxy_send_tcp_ipv6(struct net *net, 836 const struct sk_buff *skb, struct sk_buff *nskb, 837 struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 838 struct ipv6hdr *niph, struct tcphdr *nth, 839 unsigned int tcp_hdr_size) 840 { 841 struct dst_entry *dst; 842 struct flowi6 fl6; 843 int err; 844 845 nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); 846 nskb->ip_summed = CHECKSUM_PARTIAL; 847 nskb->csum_start = (unsigned char *)nth - nskb->head; 848 nskb->csum_offset = offsetof(struct tcphdr, check); 849 850 memset(&fl6, 0, sizeof(fl6)); 851 fl6.flowi6_proto = IPPROTO_TCP; 852 fl6.saddr = niph->saddr; 853 fl6.daddr = niph->daddr; 854 fl6.fl6_sport = nth->source; 855 fl6.fl6_dport = nth->dest; 856 security_skb_classify_flow((struct sk_buff *)skb, 857 flowi6_to_flowi_common(&fl6)); 858 err = nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false); 859 if (err) { 860 goto free_nskb; 861 } 862 863 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); 864 if (IS_ERR(dst)) 865 goto free_nskb; 866 867 skb_dst_set(nskb, dst); 868 869 if (nfct) { 870 nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 871 nf_conntrack_get(nfct); 872 } 873 874 ip6_local_out(net, nskb->sk, nskb); 875 return; 876 877 free_nskb: 878 kfree_skb(nskb); 879 } 880 881 void 882 synproxy_send_client_synack_ipv6(struct net *net, 883 const struct sk_buff *skb, 884 const struct tcphdr *th, 885 const struct synproxy_options *opts) 886 { 887 struct sk_buff *nskb; 888 struct ipv6hdr *iph, *niph; 889 struct tcphdr *nth; 890 unsigned int tcp_hdr_size; 891 u16 mss = opts->mss_encode; 892 893 iph = ipv6_hdr(skb); 894 895 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 896 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 897 GFP_ATOMIC); 898 if (!nskb) 899 return; 900 skb_reserve(nskb, MAX_TCP_HEADER); 901 902 niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 903 904 skb_reset_transport_header(nskb); 905 nth = skb_put(nskb, tcp_hdr_size); 906 nth->source = th->dest; 907 nth->dest = th->source; 908 nth->seq = htonl(nf_ipv6_cookie_init_sequence(iph, th, &mss)); 909 nth->ack_seq = htonl(ntohl(th->seq) + 1); 910 tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 911 if (opts->options & NF_SYNPROXY_OPT_ECN) 912 tcp_flag_word(nth) |= TCP_FLAG_ECE; 913 nth->doff = tcp_hdr_size / 4; 914 nth->window = 0; 915 nth->check = 0; 916 nth->urg_ptr = 0; 917 918 synproxy_build_options(nth, opts); 919 920 synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 921 IP_CT_ESTABLISHED_REPLY, niph, nth, 922 tcp_hdr_size); 923 } 924 EXPORT_SYMBOL_GPL(synproxy_send_client_synack_ipv6); 925 926 static void 927 synproxy_send_server_syn_ipv6(struct net *net, const struct sk_buff *skb, 928 const struct tcphdr *th, 929 const struct synproxy_options *opts, u32 recv_seq) 930 { 931 struct synproxy_net *snet = synproxy_pernet(net); 932 struct sk_buff *nskb; 933 struct ipv6hdr *iph, *niph; 934 struct tcphdr *nth; 935 unsigned int tcp_hdr_size; 936 937 iph = ipv6_hdr(skb); 938 939 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 940 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 941 GFP_ATOMIC); 942 if (!nskb) 943 return; 944 skb_reserve(nskb, MAX_TCP_HEADER); 945 946 niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 947 948 skb_reset_transport_header(nskb); 949 nth = skb_put(nskb, tcp_hdr_size); 950 nth->source = th->source; 951 nth->dest = th->dest; 952 nth->seq = htonl(recv_seq - 1); 953 /* ack_seq is used to relay our ISN to the synproxy hook to initialize 954 * sequence number translation once a connection tracking entry exists. 955 */ 956 nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 957 tcp_flag_word(nth) = TCP_FLAG_SYN; 958 if (opts->options & NF_SYNPROXY_OPT_ECN) 959 tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 960 nth->doff = tcp_hdr_size / 4; 961 nth->window = th->window; 962 nth->check = 0; 963 nth->urg_ptr = 0; 964 965 synproxy_build_options(nth, opts); 966 967 synproxy_send_tcp_ipv6(net, skb, nskb, &snet->tmpl->ct_general, 968 IP_CT_NEW, niph, nth, tcp_hdr_size); 969 } 970 971 static void 972 synproxy_send_server_ack_ipv6(struct net *net, const struct ip_ct_tcp *state, 973 const struct sk_buff *skb, 974 const struct tcphdr *th, 975 const struct synproxy_options *opts) 976 { 977 struct sk_buff *nskb; 978 struct ipv6hdr *iph, *niph; 979 struct tcphdr *nth; 980 unsigned int tcp_hdr_size; 981 982 iph = ipv6_hdr(skb); 983 984 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 985 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 986 GFP_ATOMIC); 987 if (!nskb) 988 return; 989 skb_reserve(nskb, MAX_TCP_HEADER); 990 991 niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 992 993 skb_reset_transport_header(nskb); 994 nth = skb_put(nskb, tcp_hdr_size); 995 nth->source = th->dest; 996 nth->dest = th->source; 997 nth->seq = htonl(ntohl(th->ack_seq)); 998 nth->ack_seq = htonl(ntohl(th->seq) + 1); 999 tcp_flag_word(nth) = TCP_FLAG_ACK; 1000 nth->doff = tcp_hdr_size / 4; 1001 nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 1002 nth->check = 0; 1003 nth->urg_ptr = 0; 1004 1005 synproxy_build_options(nth, opts); 1006 1007 synproxy_send_tcp_ipv6(net, skb, nskb, NULL, 0, niph, nth, 1008 tcp_hdr_size); 1009 } 1010 1011 static void 1012 synproxy_send_client_ack_ipv6(struct net *net, const struct sk_buff *skb, 1013 const struct tcphdr *th, 1014 const struct synproxy_options *opts) 1015 { 1016 struct sk_buff *nskb; 1017 struct ipv6hdr *iph, *niph; 1018 struct tcphdr *nth; 1019 unsigned int tcp_hdr_size; 1020 1021 iph = ipv6_hdr(skb); 1022 1023 tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 1024 nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 1025 GFP_ATOMIC); 1026 if (!nskb) 1027 return; 1028 skb_reserve(nskb, MAX_TCP_HEADER); 1029 1030 niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 1031 1032 skb_reset_transport_header(nskb); 1033 nth = skb_put(nskb, tcp_hdr_size); 1034 nth->source = th->source; 1035 nth->dest = th->dest; 1036 nth->seq = htonl(ntohl(th->seq) + 1); 1037 nth->ack_seq = th->ack_seq; 1038 tcp_flag_word(nth) = TCP_FLAG_ACK; 1039 nth->doff = tcp_hdr_size / 4; 1040 nth->window = htons(ntohs(th->window) >> opts->wscale); 1041 nth->check = 0; 1042 nth->urg_ptr = 0; 1043 1044 synproxy_build_options(nth, opts); 1045 1046 synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 1047 IP_CT_ESTABLISHED_REPLY, niph, nth, 1048 tcp_hdr_size); 1049 } 1050 1051 bool 1052 synproxy_recv_client_ack_ipv6(struct net *net, 1053 const struct sk_buff *skb, 1054 const struct tcphdr *th, 1055 struct synproxy_options *opts, u32 recv_seq) 1056 { 1057 struct synproxy_net *snet = synproxy_pernet(net); 1058 int mss; 1059 1060 mss = nf_cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1); 1061 if (mss == 0) { 1062 this_cpu_inc(snet->stats->cookie_invalid); 1063 return false; 1064 } 1065 1066 this_cpu_inc(snet->stats->cookie_valid); 1067 opts->mss_option = mss; 1068 opts->options |= NF_SYNPROXY_OPT_MSS; 1069 1070 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 1071 synproxy_check_timestamp_cookie(opts); 1072 1073 synproxy_send_server_syn_ipv6(net, skb, th, opts, recv_seq); 1074 return true; 1075 } 1076 EXPORT_SYMBOL_GPL(synproxy_recv_client_ack_ipv6); 1077 1078 unsigned int 1079 ipv6_synproxy_hook(void *priv, struct sk_buff *skb, 1080 const struct nf_hook_state *nhs) 1081 { 1082 struct net *net = nhs->net; 1083 struct synproxy_net *snet = synproxy_pernet(net); 1084 enum ip_conntrack_info ctinfo; 1085 struct nf_conn *ct; 1086 struct nf_conn_synproxy *synproxy; 1087 struct synproxy_options opts = {}; 1088 const struct ip_ct_tcp *state; 1089 struct tcphdr *th, _th; 1090 __be16 frag_off; 1091 u8 nexthdr; 1092 int thoff; 1093 1094 ct = nf_ct_get(skb, &ctinfo); 1095 if (!ct) 1096 return NF_ACCEPT; 1097 1098 synproxy = nfct_synproxy(ct); 1099 if (!synproxy) 1100 return NF_ACCEPT; 1101 1102 if (nf_is_loopback_packet(skb)) 1103 return NF_ACCEPT; 1104 1105 nexthdr = ipv6_hdr(skb)->nexthdr; 1106 thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 1107 &frag_off); 1108 if (thoff < 0 || nexthdr != IPPROTO_TCP) 1109 return NF_ACCEPT; 1110 1111 th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 1112 if (!th) 1113 return NF_DROP; 1114 1115 state = &ct->proto.tcp; 1116 switch (state->state) { 1117 case TCP_CONNTRACK_CLOSE: 1118 if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { 1119 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 1120 ntohl(th->seq) + 1); 1121 break; 1122 } 1123 1124 if (!th->syn || th->ack || 1125 CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 1126 break; 1127 1128 /* Reopened connection - reset the sequence number and timestamp 1129 * adjustments, they will get initialized once the connection is 1130 * reestablished. 1131 */ 1132 nf_ct_seqadj_init(ct, ctinfo, 0); 1133 synproxy->tsoff = 0; 1134 this_cpu_inc(snet->stats->conn_reopened); 1135 fallthrough; 1136 case TCP_CONNTRACK_SYN_SENT: 1137 if (!synproxy_parse_options(skb, thoff, th, &opts)) 1138 return NF_DROP; 1139 1140 if (!th->syn && th->ack && 1141 CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 1142 /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 1143 * therefore we need to add 1 to make the SYN sequence 1144 * number match the one of first SYN. 1145 */ 1146 if (synproxy_recv_client_ack_ipv6(net, skb, th, &opts, 1147 ntohl(th->seq) + 1)) { 1148 this_cpu_inc(snet->stats->cookie_retrans); 1149 consume_skb(skb); 1150 return NF_STOLEN; 1151 } else { 1152 return NF_DROP; 1153 } 1154 } 1155 1156 synproxy->isn = ntohl(th->ack_seq); 1157 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 1158 synproxy->its = opts.tsecr; 1159 1160 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1161 break; 1162 case TCP_CONNTRACK_SYN_RECV: 1163 if (!th->syn || !th->ack) 1164 break; 1165 1166 if (!synproxy_parse_options(skb, thoff, th, &opts)) 1167 return NF_DROP; 1168 1169 if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 1170 synproxy->tsoff = opts.tsval - synproxy->its; 1171 nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1172 } 1173 1174 opts.options &= ~(NF_SYNPROXY_OPT_MSS | 1175 NF_SYNPROXY_OPT_WSCALE | 1176 NF_SYNPROXY_OPT_SACK_PERM); 1177 1178 swap(opts.tsval, opts.tsecr); 1179 synproxy_send_server_ack_ipv6(net, state, skb, th, &opts); 1180 1181 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 1182 nf_conntrack_event_cache(IPCT_SEQADJ, ct); 1183 1184 swap(opts.tsval, opts.tsecr); 1185 synproxy_send_client_ack_ipv6(net, skb, th, &opts); 1186 1187 consume_skb(skb); 1188 return NF_STOLEN; 1189 default: 1190 break; 1191 } 1192 1193 synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 1194 return NF_ACCEPT; 1195 } 1196 EXPORT_SYMBOL_GPL(ipv6_synproxy_hook); 1197 1198 static const struct nf_hook_ops ipv6_synproxy_ops[] = { 1199 { 1200 .hook = ipv6_synproxy_hook, 1201 .pf = NFPROTO_IPV6, 1202 .hooknum = NF_INET_LOCAL_IN, 1203 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1204 }, 1205 { 1206 .hook = ipv6_synproxy_hook, 1207 .pf = NFPROTO_IPV6, 1208 .hooknum = NF_INET_POST_ROUTING, 1209 .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1210 }, 1211 }; 1212 1213 int 1214 nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net) 1215 { 1216 int err; 1217 1218 if (snet->hook_ref6 == 0) { 1219 err = nf_register_net_hooks(net, ipv6_synproxy_ops, 1220 ARRAY_SIZE(ipv6_synproxy_ops)); 1221 if (err) 1222 return err; 1223 } 1224 1225 snet->hook_ref6++; 1226 return 0; 1227 } 1228 EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_init); 1229 1230 void 1231 nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net) 1232 { 1233 snet->hook_ref6--; 1234 if (snet->hook_ref6 == 0) 1235 nf_unregister_net_hooks(net, ipv6_synproxy_ops, 1236 ARRAY_SIZE(ipv6_synproxy_ops)); 1237 } 1238 EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_fini); 1239 #endif /* CONFIG_IPV6 */ 1240 1241 MODULE_LICENSE("GPL"); 1242 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 1243 MODULE_DESCRIPTION("nftables SYNPROXY expression support"); 1244