ip6tables fixed - account error
[tomato.git] / release / src / router / rc / firewall.c
blob62c646dd4d987efa57578feba05456e09a524129
1 /*
3 Copyright 2003-2005, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Modified for Tomato Firmware
22 Portions, Copyright (C) 2006-2009 Jonathan Zarate
26 #include "rc.h"
28 #include <stdarg.h>
29 #include <arpa/inet.h>
30 #include <dirent.h>
32 wanface_list_t wanfaces;
33 char lanface[IFNAMSIZ + 1];
34 char lan1face[IFNAMSIZ + 1];
35 char lan2face[IFNAMSIZ + 1];
36 char lan3face[IFNAMSIZ + 1];
37 #ifdef TCONFIG_IPV6
38 char wan6face[IFNAMSIZ + 1];
39 #endif
40 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
41 #ifdef LINUX26
42 static int can_enable_fastnat;
43 #endif
45 #ifdef DEBUG_IPTFILE
46 static int debug_only = 0;
47 #endif
49 static int gateway_mode;
50 static int remotemanage;
51 static int wanup;
53 const char *chain_in_drop;
54 const char *chain_in_accept;
55 const char *chain_out_drop;
56 const char *chain_out_accept;
57 const char *chain_out_reject;
59 const char chain_wan_prerouting[] = "WANPREROUTING";
60 const char ipt_fname[] = "/etc/iptables";
61 FILE *ipt_file;
63 #ifdef TCONFIG_IPV6
64 const char ip6t_fname[] = "/etc/ip6tables";
65 FILE *ip6t_file;
67 // RFC-4890, sec. 4.3.1
68 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
69 #endif
73 struct {
74 } firewall_data;
77 // -----------------------------------------------------------------------------
79 #ifdef LINUX26
80 static const char *fastnat_run_dir = "/var/run/fastnat";
82 void allow_fastnat(const char *service, int allow)
84 char p[128];
86 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
87 if (allow) {
88 unlink(p);
90 else {
91 mkdir_if_none(fastnat_run_dir);
92 f_write_string(p, "", 0, 0);
96 static inline int fastnat_allowed(void)
98 DIR *dir;
99 struct dirent *dp;
100 int enabled;
102 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
104 if (enabled && (dir = opendir(fastnat_run_dir))) {
105 while ((dp = readdir(dir))) {
106 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
107 continue;
108 enabled = 0;
109 break;
111 closedir(dir);
114 return (enabled);
117 void try_enabling_fastnat(void)
119 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
120 fastnat_allowed() ? "1" : "0", 0, 0);
122 #endif
124 void enable_ip_forward(void)
127 ip_forward - BOOLEAN
128 0 - disabled (default)
129 not 0 - enabled
131 Forward Packets between interfaces.
133 This variable is special, its change resets all configuration
134 parameters to their default state (RFC1122 for hosts, RFC1812
135 for routers)
137 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
139 #ifdef TCONFIG_IPV6
140 if (ipv6_enabled()) {
141 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
142 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
144 #endif
148 // -----------------------------------------------------------------------------
151 static int ip2cclass(char *ipaddr, char *new, int count)
153 int ip[4];
155 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
156 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
161 static int dmz_dst(char *s)
163 struct in_addr ia;
164 char *p;
165 int n;
167 if (nvram_get_int("dmz_enable") <= 0) return 0;
169 p = nvram_safe_get("dmz_ipaddr");
170 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
171 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
172 if (s) sprintf(s, "%s%d", lan_cclass, n);
173 return 1;
176 if (s) strcpy(s, inet_ntoa(ia));
177 return 1;
180 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
182 char *pre, *post;
184 pre = (name && *name) ? " for \"" : "";
185 post = (name && *name) ? "\"" : "";
187 syslog(LOG_WARNING, "firewall: "
188 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
189 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
192 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
193 int strict, const char *categ, const char *name)
195 char p[INET6_ADDRSTRLEN * 2];
196 int r = 0;
198 if ((s) && (*s) && (*dir))
200 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
201 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
202 r = IPT_V4;
204 #ifdef TCONFIG_IPV6
205 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
206 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
207 r = IPT_V6;
209 #endif
210 else {
211 snprintf(addr, maxlen, "-%c %s", dir[0], s);
212 if (sscanf(s, "%[^/]/", p)) {
213 #ifdef TCONFIG_IPV6
214 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
215 #else
216 r = host_addrtypes(p, IPT_V4);
217 #endif
221 else
223 *addr = 0;
224 r = (IPT_V4 | IPT_V6);
227 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
228 ipt_log_unresolved(s, categ, name,
229 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
232 return (r & af);
235 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
236 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
237 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
240 static void get_src(const char *nv, char *src)
242 char *p;
244 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
245 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
247 else {
248 *src = 0;
253 void ipt_write(const char *format, ...)
255 va_list args;
257 va_start(args, format);
258 vfprintf(ipt_file, format, args);
259 va_end(args);
262 void ip6t_write(const char *format, ...)
264 #ifdef TCONFIG_IPV6
265 va_list args;
267 va_start(args, format);
268 vfprintf(ip6t_file, format, args);
269 va_end(args);
270 #endif
273 // -----------------------------------------------------------------------------
275 int ipt_dscp(const char *v, char *opt)
277 unsigned int n;
279 if (*v == 0) {
280 *opt = 0;
281 return 0;
284 n = strtoul(v, NULL, 0);
285 if (n > 63) n = 63;
286 sprintf(opt, " -m dscp --dscp 0x%02X", n);
288 #ifdef LINUX26
289 modprobe("xt_dscp");
290 #else
291 modprobe("ipt_dscp");
292 #endif
293 return 1;
296 // -----------------------------------------------------------------------------
299 int ipt_ipp2p(const char *v, char *opt)
301 int n = atoi(v);
303 if (n == 0) {
304 *opt = 0;
305 return 0;
308 strcpy(opt, "-m ipp2p ");
309 if ((n & 0xFFF) == 0xFFF) {
310 strcat(opt, "--ipp2p");
312 else {
313 // x12
314 if (n & 0x0001) strcat(opt, "--apple ");
315 if (n & 0x0002) strcat(opt, "--ares ");
316 if (n & 0x0004) strcat(opt, "--bit ");
317 if (n & 0x0008) strcat(opt, "--dc ");
318 if (n & 0x0010) strcat(opt, "--edk ");
319 if (n & 0x0020) strcat(opt, "--gnu ");
320 if (n & 0x0040) strcat(opt, "--kazaa ");
321 if (n & 0x0080) strcat(opt, "--mute ");
322 if (n & 0x0100) strcat(opt, "--soul ");
323 if (n & 0x0200) strcat(opt, "--waste ");
324 if (n & 0x0400) strcat(opt, "--winmx ");
325 if (n & 0x0800) strcat(opt, "--xdcc ");
328 modprobe("ipt_ipp2p");
329 return 1;
333 // -----------------------------------------------------------------------------
336 char **layer7_in;
338 // This L7 matches inbound traffic, caches the results, then the L7 outbound
339 // should read the cached result and set the appropriate marks -- zzz
340 void ipt_layer7_inbound(void)
342 int en, i;
343 char **p;
345 if (!layer7_in) return;
347 en = nvram_match("nf_l7in", "1");
348 if (en) {
349 ipt_write(":L7in - [0:0]\n");
350 for (i = 0; i < wanfaces.count; ++i) {
351 if (*(wanfaces.iface[i].name)) {
352 ipt_write("-A FORWARD -i %s -j L7in\n",
353 wanfaces.iface[i].name);
358 p = layer7_in;
359 while (*p) {
360 if (en) {
361 ipt_write("-A L7in %s -j RETURN\n", *p);
362 #ifdef LINUX26
363 can_enable_fastnat = 0;
364 #endif
366 free(*p);
367 ++p;
369 free(layer7_in);
370 layer7_in = NULL;
373 int ipt_layer7(const char *v, char *opt)
375 char s[128];
376 char *path;
378 *opt = 0;
379 if (*v == 0) return 0;
380 if (strlen(v) > 32) return -1;
382 path = "/etc/l7-extra";
383 sprintf(s, "%s/%s.pat", path, v);
384 if (!f_exists(s)) {
385 path = "/etc/l7-protocols";
386 sprintf(s, "%s/%s.pat", path, v);
387 if (!f_exists(s)) {
388 syslog(LOG_ERR, "L7 %s was not found", v);
389 return -1;
393 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
395 if (nvram_match("nf_l7in", "1")) {
396 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
397 if (layer7_in) {
398 char **p;
400 p = layer7_in;
401 while (*p) {
402 if (strcmp(*p, opt) == 0) return 1;
403 ++p;
405 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
409 #ifdef LINUX26
410 modprobe("xt_layer7");
411 #else
412 modprobe("ipt_layer7");
413 #endif
414 return 1;
417 // -----------------------------------------------------------------------------
419 static void ipt_account(void) {
420 struct in_addr ipaddr, netmask, network;
421 char lanN_ifname[] = "lanXX_ifname";
422 char lanN_ipaddr[] = "lanXX_ipaddr";
423 char lanN_netmask[] = "lanXX_netmask";
424 char lanN[] = "lanXX";
425 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
426 char br;
428 for(br=0 ; br<=3 ; br++) {
429 char bridge[2] = "0";
430 if (br!=0)
431 bridge[0]+=br;
432 else
433 strcpy(bridge, "");
435 sprintf(lanN_ifname, "lan%s_ifname", bridge);
437 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
439 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
440 sprintf(lanN_netmask, "lan%s_netmask", bridge);
441 sprintf(lanN, "lan%s", bridge);
443 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
444 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
446 // bitwise AND of ip and netmask gives the network
447 network.s_addr = ipaddr.s_addr & netmask.s_addr;
449 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
451 //ipv4 only
452 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
457 // -----------------------------------------------------------------------------
459 static void save_webmon(void)
461 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
462 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
465 static void ipt_webmon()
467 int wmtype, clear, i;
468 char t[512];
469 char src[128];
470 char *p, *c;
471 int ok;
473 if (!nvram_get_int("log_wm")) return;
475 #ifdef LINUX26
476 can_enable_fastnat = 0;
477 #endif
478 wmtype = nvram_get_int("log_wmtype");
479 clear = nvram_get_int("log_wmclear");
481 ip46t_write(":monitor - [0:0]\n");
483 // include IPs
484 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
485 p = t;
486 do {
487 if ((c = strchr(p, ',')) != NULL) *c = 0;
489 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
490 #ifdef TCONFIG_IPV6
491 if (*wan6face && (ok & IPT_V6))
492 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
493 #endif
494 if (ok & IPT_V4) {
495 for (i = 0; i < wanfaces.count; ++i) {
496 if (*(wanfaces.iface[i].name)) {
497 ipt_write("-A FORWARD -o %s %s -j monitor\n",
498 wanfaces.iface[i].name, src);
504 if (!c) break;
505 p = c + 1;
506 } while (*p);
508 // exclude IPs
509 if (wmtype == 2) {
510 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
511 p = t;
512 do {
513 if ((c = strchr(p, ',')) != NULL) *c = 0;
514 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
515 if (*src)
516 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
518 if (!c) break;
519 p = c + 1;
520 } while (*p);
523 ip46t_write(
524 "-A monitor -p tcp -m webmon "
525 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
526 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
527 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
528 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
530 #ifdef LINUX26
531 modprobe("xt_webmon");
532 #else
533 modprobe("ipt_webmon");
534 #endif
538 // -----------------------------------------------------------------------------
539 // MANGLE
540 // -----------------------------------------------------------------------------
542 static void mangle_table(void)
544 int ttl;
545 char *p, *wanface;
547 ip46t_write(
548 "*mangle\n"
549 ":PREROUTING ACCEPT [0:0]\n"
550 ":OUTPUT ACCEPT [0:0]\n");
552 if (wanup) {
554 ipt_qos();
555 //1 for mangle
556 ipt_qoslimit(1);
558 p = nvram_safe_get("nf_ttl");
559 if (strncmp(p, "c:", 2) == 0) {
560 p += 2;
561 ttl = atoi(p);
562 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
564 else if ((ttl = atoi(p)) != 0) {
565 if (ttl > 0) {
566 p = "inc";
568 else {
569 ttl = -ttl;
570 p = "dec";
572 if (ttl > 255) p = NULL;
574 else p = NULL;
576 if (p) {
577 #ifdef LINUX26
578 modprobe("xt_HL");
579 #else
580 modprobe("ipt_TTL");
581 #endif
582 // set TTL on primary WAN iface only
583 wanface = wanfaces.iface[0].name;
584 ipt_write(
585 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
586 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
587 wanface, p, ttl,
588 wanface, p, ttl);
589 #ifdef TCONFIG_IPV6
590 // FIXME: IPv6 HL should be configurable separately from TTL.
591 // disable it until GUI setting is implemented.
592 #if 0
593 ip6t_write(
594 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
595 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
596 wan6face, p, ttl,
597 wan6face, p, ttl);
598 #endif
599 #endif
603 ip46t_write("COMMIT\n");
606 // -----------------------------------------------------------------------------
607 // NAT
608 // -----------------------------------------------------------------------------
610 static void nat_table(void)
612 char lanaddr[32];
613 char lanmask[32];
614 char lan1addr[32];
615 char lan1mask[32];
616 char lan2addr[32];
617 char lan2mask[32];
618 char lan3addr[32];
619 char lan3mask[32];
620 char dst[64];
621 char src[64];
622 char t[512];
623 char *p, *c;
624 int i;
626 ipt_write("*nat\n"
627 ":PREROUTING ACCEPT [0:0]\n"
628 ":POSTROUTING ACCEPT [0:0]\n"
629 ":OUTPUT ACCEPT [0:0]\n"
630 ":%s - [0:0]\n",
631 chain_wan_prerouting);
633 //2 for nat
634 ipt_qoslimit(2);
636 if (gateway_mode) {
637 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
638 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
639 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
640 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
641 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
642 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
643 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
644 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
647 for (i = 0; i < wanfaces.count; ++i) {
648 if (*(wanfaces.iface[i].name)) {
649 // chain_wan_prerouting
650 if (wanup) {
651 ipt_write("-A PREROUTING -d %s -j %s\n",
652 wanfaces.iface[i].ip, chain_wan_prerouting);
655 // Drop incoming packets which destination IP address is to our LAN side directly
656 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
657 wanfaces.iface[i].name,
658 lanaddr, lanmask); // note: ipt will correct lanaddr
659 if(strcmp(lan1addr,"")!=0)
660 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
661 wanfaces.iface[i].name,
662 lan1addr, lan1mask);
663 if(strcmp(lan2addr,"")!=0)
664 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
665 wanfaces.iface[i].name,
666 lan2addr, lan2mask);
667 if(strcmp(lan3addr,"")!=0)
668 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
669 wanfaces.iface[i].name,
670 lan3addr, lan3mask);
674 if (wanup) {
675 if (nvram_match("dns_intcpt", "1")) {
676 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
677 lanaddr, lanmask,
678 lanaddr, lanmask,
679 lanaddr);
680 if(strcmp(lan1addr,"")!=0)
681 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
682 lan1addr, lan1mask,
683 lan1addr, lan1mask,
684 lan1addr);
685 if(strcmp(lan2addr,"")!=0)
686 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
687 lan2addr, lan2mask,
688 lan2addr, lan2mask,
689 lan2addr);
690 if(strcmp(lan3addr,"")!=0)
691 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
692 lan3addr, lan3mask,
693 lan3addr, lan3mask,
694 lan3addr);
697 // ICMP packets are always redirected to INPUT chains
698 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
700 ipt_forward(IPT_TABLE_NAT);
701 ipt_triggered(IPT_TABLE_NAT);
704 if (nvram_get_int("upnp_enable") & 3) {
705 ipt_write(":upnp - [0:0]\n");
707 for (i = 0; i < wanfaces.count; ++i) {
708 if (*(wanfaces.iface[i].name)) {
709 if (wanup) {
710 // ! for loopback (all) to work
711 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
713 else {
714 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
720 if (wanup) {
721 if (dmz_dst(dst)) {
722 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
723 p = t;
724 do {
725 if ((c = strchr(p, ',')) != NULL) *c = 0;
726 if (ipt_source_strict(p, src, "dmz", NULL))
727 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
728 if (!c) break;
729 p = c + 1;
730 } while (*p);
734 p = "";
735 #ifdef TCONFIG_IPV6
736 switch (get_ipv6_service()) {
737 case IPV6_6IN4:
738 // avoid NATing proto-41 packets when using 6in4 tunnel
739 p = "-p ! 41";
740 break;
742 #endif
744 for (i = 0; i < wanfaces.count; ++i) {
745 if (*(wanfaces.iface[i].name)) {
746 if ((!wanup) || (nvram_get_int("net_snat") != 1))
747 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
748 else
749 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
753 char *modem_ipaddr;
754 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
755 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0") )
756 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
758 switch (nvram_get_int("nf_loopback")) {
759 case 1: // 1 = forwarded-only
760 case 2: // 2 = disable
761 break;
762 default: // 0 = all (same as block_loopback=0)
763 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
764 lanface,
765 lanaddr, lanmask,
766 lanaddr, lanmask,
767 lanaddr);
768 if (strcmp(lan1face,"")!=0)
769 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
770 lan1face,
771 lan1addr, lan1mask,
772 lan1addr, lan1mask,
773 lan1addr);
774 if (strcmp(lan2face,"")!=0)
775 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
776 lan2face,
777 lan2addr, lan2mask,
778 lan2addr, lan2mask,
779 lan2addr);
780 if (strcmp(lan3face,"")!=0)
781 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
782 lan3face,
783 lan3addr, lan3mask,
784 lan3addr, lan3mask,
785 lan3addr);
786 break;
789 ipt_write("COMMIT\n");
792 // -----------------------------------------------------------------------------
793 // FILTER
794 // -----------------------------------------------------------------------------
796 static void filter_input(void)
798 char s[64];
799 char t[512];
800 char *en;
801 char *sec;
802 char *hit;
803 int n;
804 char *p, *c;
806 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
807 for (n = 0; n < wanfaces.count; ++n) {
808 if (*(wanfaces.iface[n].name)) {
809 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
810 if (strcmp(lan1face,"")!=0)
811 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
812 if (strcmp(lan2face,"")!=0)
813 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
814 if (strcmp(lan3face,"")!=0)
815 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
820 ipt_write(
821 "-A INPUT -m state --state INVALID -j DROP\n"
822 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
824 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
825 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
827 ? what if the user uses the start button in GUI ?
828 if (nvram_get_int("telnetd_eas"))
829 if (nvram_get_int("sshd_eas"))
831 #ifdef LINUX26
832 modprobe("xt_recent");
833 #else
834 modprobe("ipt_recent");
835 #endif
837 ipt_write(
838 "-N shlimit\n"
839 "-A shlimit -m recent --set --name shlimit\n"
840 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
841 atoi(hit) + 1, sec, chain_in_drop);
843 if (n & 1) {
844 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
845 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
846 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
849 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
852 #ifdef TCONFIG_FTP
853 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
854 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
855 #ifdef LINUX26
856 modprobe("xt_recent");
857 #else
858 modprobe("ipt_recent");
859 #endif
861 ipt_write(
862 "-N ftplimit\n"
863 "-A ftplimit -m recent --set --name ftp\n"
864 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
865 atoi(hit) + 1, sec, chain_in_drop);
866 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
868 #endif
870 ipt_write(
871 "-A INPUT -i lo -j ACCEPT\n"
872 "-A INPUT -i %s -j ACCEPT\n",
873 lanface);
874 if (strcmp(lan1face,"")!=0)
875 ipt_write(
876 "-A INPUT -i %s -j ACCEPT\n",
877 lan1face);
878 if (strcmp(lan2face,"")!=0)
879 ipt_write(
880 "-A INPUT -i %s -j ACCEPT\n",
881 lan2face);
882 if (strcmp(lan3face,"")!=0)
883 ipt_write(
884 "-A INPUT -i %s -j ACCEPT\n",
885 lan3face);
887 #ifdef TCONFIG_IPV6
888 n = get_ipv6_service();
889 switch (n) {
890 case IPV6_ANYCAST_6TO4:
891 case IPV6_6IN4:
892 // Accept ICMP requests from the remote tunnel endpoint
893 if (n == IPV6_ANYCAST_6TO4)
894 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
895 else
896 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
897 if (*s && strcmp(s, "0.0.0.0") != 0)
898 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
899 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
900 break;
902 #endif
904 // ICMP request from WAN interface
905 if (nvram_match("block_wan", "0")) {
906 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
907 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept);
908 // allow udp traceroute packets
909 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept);
912 /* Accept incoming packets from broken dhcp servers, which are sending replies
913 * from addresses other than used for query. This could lead to a lower level
914 * of security, so allow to disable it via nvram variable.
916 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
917 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
920 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
921 p = t;
922 do {
923 if ((c = strchr(p, ',')) != NULL) *c = 0;
925 if (ipt_source(p, s, "remote management", NULL)) {
927 if (remotemanage) {
928 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
929 s, nvram_safe_get("http_wanport"), chain_in_accept);
932 if (nvram_get_int("sshd_remote")) {
933 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
934 s, nvram_safe_get("sshd_rport"), chain_in_accept);
938 if (!c) break;
939 p = c + 1;
940 } while (*p);
942 #ifdef TCONFIG_FTP // !!TB - FTP Server
943 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
944 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
945 p = t;
946 do {
947 if ((c = strchr(p, ',')) != NULL) *c = 0;
948 if (ipt_source(p, s, "ftp", "remote access")) {
949 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
950 s, nvram_safe_get("ftp_port"), chain_in_accept);
952 if (!c) break;
953 p = c + 1;
954 } while (*p);
956 #endif
958 // IGMP query from WAN interface
959 if (nvram_match("multicast_pass", "1")) {
960 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
961 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
964 // Routing protocol, RIP, accept
965 if (nvram_invmatch("dr_wan_rx", "0")) {
966 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
969 //BT Client ports from WAN interface
970 if (nvram_match("bt_enable", "1")) {
971 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port" ) );
972 if (nvram_match( "bt_rpc_wan", "1") )
974 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port_gui" ) );
978 // if logging
979 if (*chain_in_drop == 'l') {
980 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
983 // default policy: DROP
986 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
987 static void clampmss(void)
989 #if 1
990 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
991 #else
992 int rmtu = nvram_get_int("wan_run_mtu");
993 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
994 if (rmtu < 576) {
995 ipt_write("--clamp-mss-to-pmtu\n");
997 else {
998 ipt_write("--set-mss %d\n", rmtu - 40);
1000 #endif
1003 static void filter_forward(void)
1005 char dst[64];
1006 char src[64];
1007 char t[512];
1008 char *p, *c;
1009 int i;
1011 #ifdef TCONFIG_IPV6
1012 ip6t_write(
1013 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1014 #endif
1016 ipt_account();
1018 ip46t_write(
1019 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1020 lanface, lanface);
1021 if (strcmp(lan1face,"")!=0)
1022 ip46t_write(
1023 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1024 lan1face, lan1face);
1025 if (strcmp(lan2face,"")!=0)
1026 ip46t_write(
1027 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1028 lan2face, lan2face);
1029 if (strcmp(lan3face,"")!=0)
1030 ip46t_write(
1031 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1032 lan3face, lan3face);
1034 char lanAccess[17] = "0000000000000000";
1036 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1037 char *nv, *nvp, *b;
1038 int n;
1039 nvp = nv = strdup(nvram_safe_get("lan_access"));
1040 if (nv) {
1041 while ((b = strsep(&nvp, ">")) != NULL) {
1043 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1045 1 = enabled
1046 0 = src bridge
1047 1.2.3.4 = src addr
1048 1 = dst bridge
1049 5.6.7.8 = dst addr
1050 desc = desc
1052 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1053 if (*d != '1')
1054 continue;
1055 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 1, "LAN access IPv4", desc))
1056 continue;
1057 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 1, "LAN access IPv4", desc))
1058 continue;
1060 ip46t_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1061 "br",
1062 sbr,
1063 "br",
1064 dbr,
1065 src,
1066 dst);
1068 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1069 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1073 free(nv);
1075 ip46t_write(
1076 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1078 // clamp tcp mss to pmtu
1079 clampmss();
1081 if (wanup) {
1082 ipt_restrictions();
1084 ipt_layer7_inbound();
1087 ipt_webmon();
1089 ip46t_write(
1090 ":wanin - [0:0]\n"
1091 ":wanout - [0:0]\n"
1092 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1094 char lanN_ifname[] = "lanXX_ifname";
1095 char br;
1096 for(br=0 ; br<=3 ; br++) {
1097 char bridge[2] = "0";
1098 if (br!=0)
1099 bridge[0]+=br;
1100 else
1101 strcpy(bridge, "");
1103 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1104 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1105 char lanN_ifname2[] = "lanXX_ifname";
1106 char br2;
1107 for(br2=0 ; br2<=3 ; br2++) {
1108 if (br==br2) continue;
1110 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1112 char bridge2[2] = "0";
1113 if (br2!=0)
1114 bridge2[0]+=br2;
1115 else
1116 strcpy(bridge2, "");
1118 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1119 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1120 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1121 nvram_safe_get(lanN_ifname),
1122 nvram_safe_get(lanN_ifname2));
1125 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1129 #ifdef TCONFIG_IPV6
1130 // Filter out invalid WAN->WAN connections
1131 if (*wan6face)
1132 // ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop); //shibby - we cant drop connections from WAN to LAN1-3
1133 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1135 #ifdef LINUX26
1136 modprobe("xt_length");
1137 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1138 #endif
1140 // ICMPv6 rules
1141 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1142 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1145 //IPv6
1146 if (*wan6face) {
1147 ip6t_write(
1148 "-A FORWARD -i %s -j wanin\n" // generic from wan
1149 "-A FORWARD -o %s -j wanout\n", // generic to wan
1150 wan6face, wan6face);
1152 #endif
1154 //IPv4
1155 for (i = 0; i < wanfaces.count; ++i) {
1156 if (*(wanfaces.iface[i].name)) {
1157 ipt_write(
1158 "-A FORWARD -i %s -j wanin\n" // generic from wan
1159 "-A FORWARD -o %s -j wanout\n", // generic to wan
1160 wanfaces.iface[i].name, wanfaces.iface[i].name);
1164 for(br=0 ; br<=3 ; br++) {
1165 char bridge[2] = "0";
1166 if (br!=0)
1167 bridge[0]+=br;
1168 else
1169 strcpy(bridge, "");
1171 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1172 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1173 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1177 // IPv4 only
1178 if (nvram_get_int("upnp_enable") & 3) {
1179 ipt_write(":upnp - [0:0]\n");
1180 for (i = 0; i < wanfaces.count; ++i) {
1181 if (*(wanfaces.iface[i].name)) {
1182 ipt_write("-A FORWARD -i %s -j upnp\n",
1183 wanfaces.iface[i].name);
1188 if (wanup) {
1189 if (nvram_match("multicast_pass", "1")) {
1190 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1192 ipt_triggered(IPT_TABLE_FILTER);
1193 ipt_forward(IPT_TABLE_FILTER);
1194 #ifdef TCONFIG_IPV6
1195 ip6t_forward();
1196 #endif
1198 if (dmz_dst(dst)) {
1199 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1200 p = t;
1201 do {
1202 if ((c = strchr(p, ',')) != NULL) *c = 0;
1203 if (ipt_source_strict(p, src, "dmz", NULL))
1204 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1205 if (!c) break;
1206 p = c + 1;
1207 } while (*p);
1211 // default policy: DROP
1214 static void filter_log(void)
1216 int n;
1217 char limit[128];
1219 n = nvram_get_int("log_limit");
1220 if ((n >= 1) && (n <= 9999)) {
1221 sprintf(limit, "-m limit --limit %d/m", n);
1223 else {
1224 limit[0] = 0;
1227 #ifdef TCONFIG_IPV6
1228 modprobe("ip6t_LOG");
1229 #endif
1230 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1231 ip46t_write(
1232 ":logdrop - [0:0]\n"
1233 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1234 #ifdef LINUX26
1235 " --log-macdecode"
1236 #endif
1237 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1238 "-A logdrop -j DROP\n"
1239 ":logreject - [0:0]\n"
1240 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1241 #ifdef LINUX26
1242 " --log-macdecode"
1243 #endif
1244 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1245 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1246 limit, limit);
1248 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1249 ip46t_write(
1250 ":logaccept - [0:0]\n"
1251 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1252 #ifdef LINUX26
1253 " --log-macdecode"
1254 #endif
1255 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1256 "-A logaccept -j ACCEPT\n",
1257 limit);
1261 #ifdef TCONFIG_IPV6
1262 static void filter6_input(void)
1264 char s[128];
1265 char t[512];
1266 char *en;
1267 char *sec;
1268 char *hit;
1269 int n;
1270 char *p, *c;
1272 // RFC-4890, sec. 4.4.1
1273 const int allowed_local_icmpv6[] =
1274 { 130, 131, 132, 133, 134, 135, 136,
1275 141, 142, 143,
1276 148, 149, 151, 152, 153 };
1278 ip6t_write(
1279 "-A INPUT -m rt --rt-type 0 -j %s\n"
1280 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1281 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1282 chain_in_drop);
1284 #ifdef LINUX26
1285 modprobe("xt_length");
1286 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1287 #endif
1289 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1290 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1291 #ifdef LINUX26
1292 modprobe("xt_recent");
1293 #else
1294 modprobe("ipt_recent");
1295 #endif
1297 ip6t_write(
1298 "-N shlimit\n"
1299 "-A shlimit -m recent --set --name shlimit\n"
1300 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1301 atoi(hit) + 1, sec, chain_in_drop);
1303 if (n & 1) {
1304 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1305 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1306 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1309 if (n & 2) ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("telnetd_port"));
1312 #ifdef TCONFIG_FTP
1313 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1314 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1315 #ifdef LINUX26
1316 modprobe("xt_recent");
1317 #else
1318 modprobe("ipt_recent");
1319 #endif
1321 ip6t_write(
1322 "-N ftplimit\n"
1323 "-A ftplimit -m recent --set --name ftp\n"
1324 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1325 atoi(hit) + 1, sec, chain_in_drop);
1326 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1328 #endif // TCONFIG_FTP
1330 ip6t_write(
1331 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1332 "-A INPUT -i lo -j ACCEPT\n",
1333 lanface );
1335 switch (get_ipv6_service()) {
1336 case IPV6_ANYCAST_6TO4:
1337 case IPV6_NATIVE_DHCP:
1338 // allow responses from the dhcpv6 server
1339 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1340 break;
1343 // ICMPv6 rules
1344 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1345 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1347 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1348 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1351 // Remote Managment
1352 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1353 p = t;
1354 do {
1355 if ((c = strchr(p, ',')) != NULL) *c = 0;
1357 if (ip6t_source(p, s, "remote management", NULL)) {
1359 if (remotemanage) {
1360 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1361 s, nvram_safe_get("http_wanport"), chain_in_accept);
1364 if (nvram_get_int("sshd_remote")) {
1365 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1366 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1370 if (!c) break;
1371 p = c + 1;
1372 } while (*p);
1374 #ifdef TCONFIG_FTP
1375 // FTP server
1376 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1377 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1378 p = t;
1379 do {
1380 if ((c = strchr(p, ',')) != NULL) *c = 0;
1381 if (ip6t_source(p, s, "ftp", "remote access")) {
1382 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1383 s, nvram_safe_get("ftp_port"), chain_in_accept);
1385 if (!c) break;
1386 p = c + 1;
1387 } while (*p);
1389 #endif
1391 // if logging
1392 if (*chain_in_drop == 'l') {
1393 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1396 // default policy: DROP
1399 #endif
1401 static void filter_table(void)
1403 ip46t_write(
1404 "*filter\n"
1405 ":INPUT DROP [0:0]\n"
1406 ":OUTPUT ACCEPT [0:0]\n"
1409 filter_log();
1411 filter_input();
1412 #ifdef TCONFIG_IPV6
1413 filter6_input();
1414 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1415 #endif
1417 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1418 ip46t_write(":FORWARD DROP [0:0]\n");
1419 filter_forward();
1421 else {
1422 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1423 clampmss();
1425 ip46t_write("COMMIT\n");
1428 // -----------------------------------------------------------------------------
1430 int start_firewall(void)
1432 DIR *dir;
1433 struct dirent *dirent;
1434 char s[256];
1435 char *c, *wanface;
1436 int n;
1437 int wanproto;
1438 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1439 #ifdef TCONFIG_IPV6
1440 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1441 #endif
1443 simple_lock("firewall");
1444 simple_lock("restrictions");
1446 wanup = check_wanup();
1448 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1450 /* NAT performance tweaks
1451 * These values can be overriden later if needed via firewall script
1453 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1454 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1455 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1456 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1457 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1458 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1459 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1460 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1461 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1462 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1463 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1464 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1466 /* DoS-related tweaks */
1467 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1468 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1469 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1471 wanproto = get_wan_proto();
1472 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1474 #ifdef TCONFIG_EMF
1475 /* Force IGMPv2 due EMF limitations */
1476 if (nvram_get_int("emf_enable")) {
1477 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1478 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1480 #endif
1482 n = nvram_get_int("log_in");
1483 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1484 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1486 n = nvram_get_int("log_out");
1487 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1488 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1489 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1491 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1493 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1494 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1495 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1496 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1498 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1499 wanface = wanfaces.iface[0].name;
1500 #ifdef TCONFIG_IPV6
1501 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1502 #endif
1504 #ifdef LINUX26
1505 can_enable_fastnat = 1;
1506 #endif
1508 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1509 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1510 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1512 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1513 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1514 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1516 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1517 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1518 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1520 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1521 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1522 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1526 block obviously spoofed IP addresses
1528 rp_filter - BOOLEAN
1529 1 - do source validation by reversed path, as specified in RFC1812
1530 Recommended option for single homed hosts and stub network
1531 routers. Could cause troubles for complicated (not loop free)
1532 networks running a slow unreliable protocol (sort of RIP),
1533 or using static routes.
1534 0 - No source validation.
1536 c = nvram_get("wan_ifname");
1537 /* mcast needs rp filter to be turned off only for non default iface */
1538 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface, c) == 0) c = NULL;
1540 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1541 while ((dirent = readdir(dir)) != NULL) {
1542 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1543 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1545 closedir(dir);
1548 remotemanage = 0;
1549 gateway_mode = !nvram_match("wk_mode", "router");
1550 if (gateway_mode) {
1551 /* Remote management */
1552 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1553 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1556 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1557 notice_set("iptables", "Unable to create iptables restore file");
1558 simple_unlock("firewall");
1559 return 0;
1562 #ifdef TCONFIG_IPV6
1563 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1564 notice_set("ip6tables", "Unable to create ip6tables restore file");
1565 simple_unlock("firewall");
1566 return 0;
1568 modprobe("nf_conntrack_ipv6");
1569 modprobe("ip6t_REJECT");
1570 #endif
1572 /* shibby */
1573 if (nvram_match("imq_enable", "1")) {
1574 char numdevs[10];
1575 sprintf(numdevs, "numdevs=%d", nvram_get_int("imq_numdevs"));
1576 modprobe("imq", numdevs );
1577 #ifdef LINUX26
1578 modprobe("xt_IMQ");
1579 #else
1580 modprobe("ipt_IMQ");
1581 #endif
1584 mangle_table();
1585 nat_table();
1586 filter_table();
1588 fclose(ipt_file);
1589 ipt_file = NULL;
1591 #ifdef TCONFIG_IPV6
1592 fclose(ip6t_file);
1593 ip6t_file = NULL;
1594 #endif
1596 #ifdef DEBUG_IPTFILE
1597 if (debug_only) {
1598 simple_unlock("firewall");
1599 simple_unlock("restrictions");
1600 return 0;
1602 #endif
1604 save_webmon();
1606 if (nvram_get_int("upnp_enable") & 3) {
1607 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1608 if (killall("miniupnpd", SIGUSR2) == 0) {
1609 f_wait_notexists("/etc/upnp/save", 5);
1613 notice_set("iptables", "");
1614 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1615 led(LED_DIAG, 0);
1616 notice_set("iptables", "");
1618 else {
1619 sprintf(s, "%s.error", ipt_fname);
1620 rename(ipt_fname, s);
1621 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1622 led(LED_DIAG, 1);
1626 -P INPUT DROP
1627 -F INPUT
1628 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1629 -A INPUT -i br0 -j ACCEPT
1631 -P FORWARD DROP
1632 -F FORWARD
1633 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1634 -A FORWARD -i br0 -j ACCEPT
1639 #ifdef TCONFIG_IPV6
1640 if (ipv6_enabled()) {
1641 notice_set("ip6tables", "");
1642 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1643 notice_set("ip6tables", "");
1645 else {
1646 sprintf(s, "%s.error", ip6t_fname);
1647 rename(ip6t_fname, s);
1648 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1649 led(LED_DIAG, 1);
1652 else {
1653 eval("ip6tables", "-F");
1654 eval("ip6tables", "-t", "mangle", "-F");
1656 #endif
1658 if (nvram_get_int("upnp_enable") & 3) {
1659 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1660 killall("miniupnpd", SIGUSR2);
1663 simple_unlock("restrictions");
1664 sched_restrictions();
1665 enable_ip_forward();
1667 led(LED_DMZ, dmz_dst(NULL));
1669 #ifdef TCONFIG_IPV6
1670 modprobe_r("nf_conntrack_ipv6");
1671 modprobe_r("ip6t_LOG");
1672 modprobe_r("ip6t_REJECT");
1673 #endif
1674 #ifdef LINUX26
1675 modprobe_r("xt_layer7");
1676 modprobe_r("xt_recent");
1677 modprobe_r("xt_HL");
1678 modprobe_r("xt_length");
1679 modprobe_r("xt_web");
1680 modprobe_r("xt_webmon");
1681 modprobe_r("xt_dscp");
1682 #else
1683 modprobe_r("ipt_layer7");
1684 modprobe_r("ipt_recent");
1685 modprobe_r("ipt_TTL");
1686 modprobe_r("ipt_web");
1687 modprobe_r("ipt_webmon");
1688 modprobe_r("ipt_dscp");
1689 #endif
1690 modprobe_r("ipt_ipp2p");
1692 unlink("/var/webmon/domain");
1693 unlink("/var/webmon/search");
1695 #ifdef TCONFIG_OPENVPN
1696 run_vpn_firewall_scripts();
1697 #endif
1698 run_nvscript("script_fire", NULL, 1);
1700 #ifdef LINUX26
1701 allow_fastnat("firewall", can_enable_fastnat);
1702 try_enabling_fastnat();
1703 #endif
1704 simple_unlock("firewall");
1705 return 0;
1708 int stop_firewall(void)
1710 led(LED_DMZ, 0);
1711 return 0;
1714 #ifdef DEBUG_IPTFILE
1715 void create_test_iptfile(void)
1717 debug_only = 1;
1718 start_firewall();
1719 debug_only = 0;
1721 #endif