472 {
473 if (
backend_ !=
"nftables")
return false;
474
476 if (!nft_bin) {
478 "nft non trovato: impossibile installare la regola NFQUEUE, "
479 "fallback su polling /proc");
480 return false;
481 }
482
483
484
485
486 std::ostringstream script;
487 script << "add table inet bsc_intercept\n";
488
489 script << "delete chain inet bsc_intercept output\n";
490 script << "add chain inet bsc_intercept output "
491 "{ type filter hook output priority mangle - 10; policy accept; }\n";
492
493
494
495
496 script << "add rule inet bsc_intercept output oif lo accept\n";
497 script << "add rule inet bsc_intercept output meta mark 0x42 accept\n";
498
499 script << "add rule inet bsc_intercept output udp dport 53 accept\n";
500 script << "add rule inet bsc_intercept output tcp dport 53 accept\n";
501
502 script << "add rule inet bsc_intercept output udp sport { 67, 68 } accept\n";
503 script << "add rule inet bsc_intercept output udp dport { 67, 68 } accept\n";
504
505 script << "add rule inet bsc_intercept output udp dport 5353 accept\n";
506
507 script << "add rule inet bsc_intercept output udp dport 123 accept\n";
508
509 script << "add rule inet bsc_intercept output meta l4proto icmp accept\n";
510 script << "add rule inet bsc_intercept output meta l4proto icmpv6 accept\n";
511
512 script << "add rule inet bsc_intercept output meta l4proto igmp accept\n";
513
514
515
516 script << "add rule inet bsc_intercept output ct state new queue num "
517 << queue_num;
518 if (queue_bypass) script << " bypass";
519 script << "\n";
520
521
522
523 fs::path tmp_script = fs::temp_directory_path() / "bsc-nfqueue-install.nft";
524 {
525 std::ofstream out(tmp_script);
526 if (!out) {
528 "Impossibile creare lo script temporaneo nft in " + tmp_script.string());
529 return false;
530 }
531 out << script.str();
532 }
533
534 const auto cmd = *nft_bin +
" -f " +
shell_quote(tmp_script.string()) +
535 " 2>/dev/null";
536
537
538
539 int rc = std::system(cmd.c_str());
540 if (rc != 0) {
541 std::ostringstream s2;
542 s2 << "add table inet bsc_intercept\n";
543 s2 << "add chain inet bsc_intercept output "
544 "{ type filter hook output priority mangle - 10; policy accept; }\n";
545 s2 << "flush chain inet bsc_intercept output\n";
546 s2 << "add rule inet bsc_intercept output oif lo accept\n";
547 s2 << "add rule inet bsc_intercept output meta mark 0x42 accept\n";
548 s2 << "add rule inet bsc_intercept output udp dport 53 accept\n";
549 s2 << "add rule inet bsc_intercept output tcp dport 53 accept\n";
550 s2 << "add rule inet bsc_intercept output udp sport { 67, 68 } accept\n";
551 s2 << "add rule inet bsc_intercept output udp dport { 67, 68 } accept\n";
552 s2 << "add rule inet bsc_intercept output udp dport 5353 accept\n";
553 s2 << "add rule inet bsc_intercept output udp dport 123 accept\n";
554 s2 << "add rule inet bsc_intercept output meta l4proto icmp accept\n";
555 s2 << "add rule inet bsc_intercept output meta l4proto icmpv6 accept\n";
556 s2 << "add rule inet bsc_intercept output meta l4proto igmp accept\n";
557 s2 << "add rule inet bsc_intercept output ct state new queue num "
558 << queue_num;
559 if (queue_bypass) s2 << " bypass";
560 s2 << "\n";
561 std::ofstream out(tmp_script);
562 out << s2.str();
563 out.close();
564 rc = std::system(cmd.c_str());
565 }
566
567 std::error_code ec;
568 fs::remove(tmp_script, ec);
569
570 if (rc != 0) {
572 "installazione regola NFQUEUE fallita "
573 "(permessi insufficienti? manca CAP_NET_ADMIN?): fallback su /proc");
574 return false;
575 }
576
578 "regola NFQUEUE installata sulla coda " + std::to_string(queue_num) +
579 (queue_bypass ? " (bypass abilitato)" : ""));
580 return true;
581}
void warning(const std::string &msg)
void info(const std::string &msg)
static Logger & instance()
std::string shell_quote(const std::string &argument)
std::optional< std::string > resolve_nft_binary()