IPTraffic: fix backup/restore cstats data via web UI
[tomato.git] / release / src / router / rc / firewall.c
bloba180c6e5c9042269b549826133386031d9d012d6
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];
42 #ifdef DEBUG_IPTFILE
43 static int debug_only = 0;
44 #endif
46 static int gateway_mode;
47 static int remotemanage;
48 static int wanup;
50 const char *chain_in_drop;
51 const char *chain_in_accept;
52 const char *chain_out_drop;
53 const char *chain_out_accept;
54 const char *chain_out_reject;
56 const char chain_wan_prerouting[] = "WANPREROUTING";
57 const char ipt_fname[] = "/etc/iptables";
58 FILE *ipt_file;
60 #ifdef TCONFIG_IPV6
61 const char ip6t_fname[] = "/etc/ip6tables";
62 FILE *ip6t_file;
63 #endif
67 struct {
68 } firewall_data;
71 // -----------------------------------------------------------------------------
74 void enable_ip_forward(void)
77 ip_forward - BOOLEAN
78 0 - disabled (default)
79 not 0 - enabled
81 Forward Packets between interfaces.
83 This variable is special, its change resets all configuration
84 parameters to their default state (RFC1122 for hosts, RFC1812
85 for routers)
87 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
89 #ifdef TCONFIG_IPV6
90 if (ipv6_enabled()) {
91 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
92 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
94 #endif
98 // -----------------------------------------------------------------------------
101 static int ip2cclass(char *ipaddr, char *new, int count)
103 int ip[4];
105 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
106 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
111 static int dmz_dst(char *s)
113 struct in_addr ia;
114 char *p;
115 int n;
117 if (nvram_get_int("dmz_enable") <= 0) return 0;
119 p = nvram_safe_get("dmz_ipaddr");
120 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
121 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
122 if (s) sprintf(s, "%s%d", lan_cclass, n);
123 return 1;
126 if (s) strcpy(s, inet_ntoa(ia));
127 return 1;
130 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int family,
131 const char *categ, const char *name)
133 char p[INET6_ADDRSTRLEN * 2];
134 int r = 1;
136 if ((s) && (*s) && (*dir))
138 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
139 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
140 r = (family == AF_INET);
142 #ifdef TCONFIG_IPV6
143 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
144 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
145 r = (family == AF_INET6);
147 #endif
148 else {
149 snprintf(addr, maxlen, "-%c %s", dir[0], s);
150 r = (host_to_addr(s, family) != NULL);
153 else
154 *addr = 0;
156 if (r == 0 && (categ && *categ)) {
157 syslog(LOG_WARNING,
158 "IPv%d firewall: %s: not using %s%s%s (could not resolve as valid IPv%d address)",
159 (family == AF_INET6) ? 6 : 4, categ, s,
160 (name && *name) ? " for " : "", (name && *name) ? name : "",
161 (family == AF_INET6) ? 6 : 4);
164 return r;
167 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", AF_INET, categ, name)
168 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", AF_INET6, categ, name)
171 static void get_src(const char *nv, char *src)
173 char *p;
175 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
176 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
178 else {
179 *src = 0;
184 void ipt_write(const char *format, ...)
186 va_list args;
188 va_start(args, format);
189 vfprintf(ipt_file, format, args);
190 va_end(args);
193 void ip6t_write(const char *format, ...)
195 #ifdef TCONFIG_IPV6
196 va_list args;
198 va_start(args, format);
199 vfprintf(ip6t_file, format, args);
200 va_end(args);
201 #endif
204 // -----------------------------------------------------------------------------
206 int ipt_dscp(const char *v, char *opt)
208 unsigned int n;
210 if (*v == 0) {
211 *opt = 0;
212 return 0;
215 n = strtoul(v, NULL, 0);
216 if (n > 63) n = 63;
217 sprintf(opt, " -m dscp --dscp 0x%02X", n);
219 #ifdef LINUX26
220 modprobe("xt_dscp");
221 #else
222 modprobe("ipt_dscp");
223 #endif
224 return 1;
227 // -----------------------------------------------------------------------------
230 int ipt_ipp2p(const char *v, char *opt)
232 int n = atoi(v);
234 if (n == 0) {
235 *opt = 0;
236 return 0;
239 strcpy(opt, "-m ipp2p ");
240 if ((n & 0xFFF) == 0xFFF) {
241 strcat(opt, "--ipp2p");
243 else {
244 // x12
245 if (n & 0x0001) strcat(opt, "--apple ");
246 if (n & 0x0002) strcat(opt, "--ares ");
247 if (n & 0x0004) strcat(opt, "--bit ");
248 if (n & 0x0008) strcat(opt, "--dc ");
249 if (n & 0x0010) strcat(opt, "--edk ");
250 if (n & 0x0020) strcat(opt, "--gnu ");
251 if (n & 0x0040) strcat(opt, "--kazaa ");
252 if (n & 0x0080) strcat(opt, "--mute ");
253 if (n & 0x0100) strcat(opt, "--soul ");
254 if (n & 0x0200) strcat(opt, "--waste ");
255 if (n & 0x0400) strcat(opt, "--winmx ");
256 if (n & 0x0800) strcat(opt, "--xdcc ");
259 modprobe("ipt_ipp2p");
260 return 1;
264 // -----------------------------------------------------------------------------
267 char **layer7_in;
269 // This L7 matches inbound traffic, caches the results, then the L7 outbound
270 // should read the cached result and set the appropriate marks -- zzz
271 void ipt_layer7_inbound(void)
273 int en, i;
274 char **p;
276 if (!layer7_in) return;
278 en = nvram_match("nf_l7in", "1");
279 if (en) {
280 ipt_write(":L7in - [0:0]\n");
281 for (i = 0; i < wanfaces.count; ++i) {
282 if (*(wanfaces.iface[i].name)) {
283 ipt_write("-A FORWARD -i %s -j L7in\n",
284 wanfaces.iface[i].name);
289 p = layer7_in;
290 while (*p) {
291 if (en) ipt_write("-A L7in %s -j RETURN\n", *p);
292 free(*p);
293 ++p;
295 free(layer7_in);
296 layer7_in = NULL;
299 int ipt_layer7(const char *v, char *opt)
301 char s[128];
302 char *path;
304 *opt = 0;
305 if (*v == 0) return 0;
306 if (strlen(v) > 32) return -1;
308 path = "/etc/l7-extra";
309 sprintf(s, "%s/%s.pat", path, v);
310 if (!f_exists(s)) {
311 path = "/etc/l7-protocols";
312 sprintf(s, "%s/%s.pat", path, v);
313 if (!f_exists(s)) {
314 syslog(LOG_ERR, "L7 %s was not found", v);
315 return -1;
319 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
321 if (nvram_match("nf_l7in", "1")) {
322 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
323 if (layer7_in) {
324 char **p;
326 p = layer7_in;
327 while (*p) {
328 if (strcmp(*p, opt) == 0) return 1;
329 ++p;
331 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
335 #ifdef LINUX26
336 modprobe("xt_layer7");
337 #else
338 modprobe("ipt_layer7");
339 #endif
340 return 1;
343 // -----------------------------------------------------------------------------
345 static void ipt_account(void) {
346 struct in_addr ipaddr, netmask, network;
347 char lanN_ifname[] = "lanXX_ifname";
348 char lanN_ipaddr[] = "lanXX_ipaddr";
349 char lanN_netmask[] = "lanXX_netmask";
350 char lanN[] = "lanXX";
351 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
352 char br;
354 for(br=0 ; br<=3 ; br++) {
355 char bridge[2] = "0";
356 if (br!=0)
357 bridge[0]+=br;
358 else
359 strcpy(bridge, "");
361 sprintf(lanN_ifname, "lan%s_ifname", bridge);
363 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
365 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
366 sprintf(lanN_netmask, "lan%s_netmask", bridge);
367 sprintf(lanN, "lan%s", bridge);
369 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
370 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
372 // bitwise AND of ip and netmask gives the network
373 network.s_addr = ipaddr.s_addr & netmask.s_addr;
375 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
377 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
382 // -----------------------------------------------------------------------------
384 static void save_webmon(void)
386 system("cp /proc/webmon_recent_domains /var/webmon/domain");
387 system("cp /proc/webmon_recent_searches /var/webmon/search");
390 static void ipt_webmon(int do_ip6t)
392 int wmtype, clear, i;
393 char t[512];
394 char src[128];
395 char *p, *c;
397 if (!nvram_get_int("log_wm")) return;
398 wmtype = nvram_get_int("log_wmtype");
399 clear = nvram_get_int("log_wmclear");
401 ip46t_cond_write(do_ip6t, ":monitor - [0:0]\n");
403 // include IPs
404 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
405 p = t;
406 do {
407 if ((c = strchr(p, ',')) != NULL) *c = 0;
409 if (ipt_addr(src, sizeof(src), p, "src", do_ip6t ? AF_INET6 : AF_INET, "webmon", "filtering")) {
410 #ifdef TCONFIG_IPV6
411 if (do_ip6t) {
412 if (*wan6face)
413 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
415 else
416 #endif
417 for (i = 0; i < wanfaces.count; ++i) {
418 if (*(wanfaces.iface[i].name)) {
419 ipt_write("-A FORWARD -o %s %s -j monitor\n",
420 wanfaces.iface[i].name, src);
425 if (!c) break;
426 p = c + 1;
427 } while (*p);
429 // exclude IPs
430 if (wmtype == 2) {
431 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
432 p = t;
433 do {
434 if ((c = strchr(p, ',')) != NULL) *c = 0;
435 if (ipt_addr(src, sizeof(src), p, "src", do_ip6t ? AF_INET6 : AF_INET, "webmon", "filtering")) {
436 if (*src)
437 ip46t_cond_write(do_ip6t, "-A monitor %s -j RETURN\n", src);
439 if (!c) break;
440 p = c + 1;
441 } while (*p);
444 ip46t_cond_write(do_ip6t,
445 "-A monitor -p tcp -m webmon "
446 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
447 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
448 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
449 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
451 #ifdef LINUX26
452 modprobe("xt_webmon");
453 #else
454 modprobe("ipt_webmon");
455 #endif
459 // -----------------------------------------------------------------------------
460 // MANGLE
461 // -----------------------------------------------------------------------------
463 static void mangle_table(void)
465 int ttl;
466 char *p, *wanface;
468 ip46t_write(
469 "*mangle\n"
470 ":PREROUTING ACCEPT [0:0]\n"
471 ":OUTPUT ACCEPT [0:0]\n");
473 if (wanup) {
475 ipt_qos();
477 p = nvram_safe_get("nf_ttl");
478 if (strncmp(p, "c:", 2) == 0) {
479 p += 2;
480 ttl = atoi(p);
481 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
483 else if ((ttl = atoi(p)) != 0) {
484 if (ttl > 0) {
485 p = "inc";
487 else {
488 ttl = -ttl;
489 p = "dec";
491 if (ttl > 255) p = NULL;
493 else p = NULL;
495 if (p) {
496 #ifdef LINUX26
497 modprobe("xt_HL");
498 #else
499 modprobe("ipt_TTL");
500 #endif
501 // set TTL on primary WAN iface only
502 wanface = wanfaces.iface[0].name;
503 ip46t_write(
504 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
505 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
506 wanface, p, ttl,
507 wanface, p, ttl);
511 ip46t_write("COMMIT\n");
516 // -----------------------------------------------------------------------------
517 // NAT
518 // -----------------------------------------------------------------------------
520 static void nat_table(void)
522 char lanaddr[32];
523 char lanmask[32];
524 char lan1addr[32];
525 char lan1mask[32];
526 char lan2addr[32];
527 char lan2mask[32];
528 char lan3addr[32];
529 char lan3mask[32];
530 char dst[64];
531 char src[64];
532 char t[512];
533 char *p, *c;
534 int i;
536 ipt_write("*nat\n"
537 ":PREROUTING ACCEPT [0:0]\n"
538 ":POSTROUTING ACCEPT [0:0]\n"
539 ":OUTPUT ACCEPT [0:0]\n"
540 ":%s - [0:0]\n",
541 chain_wan_prerouting);
543 if (gateway_mode) {
544 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
545 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
546 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
547 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
548 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
549 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
550 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
551 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
554 for (i = 0; i < wanfaces.count; ++i) {
555 if (*(wanfaces.iface[i].name)) {
556 // chain_wan_prerouting
557 if (wanup)
558 ipt_write("-A PREROUTING -d %s -j %s\n",
559 wanfaces.iface[i].ip, chain_wan_prerouting);
561 // Drop incoming packets which destination IP address is to our LAN side directly
562 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
563 wanfaces.iface[i].name,
564 lanaddr, lanmask); // note: ipt will correct lanaddr
565 if(strcmp(lan1addr,"")!=0)
566 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
567 wanfaces.iface[i].name,
568 lan1addr, lan1mask);
569 if(strcmp(lan2addr,"")!=0)
570 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
571 wanfaces.iface[i].name,
572 lan2addr, lan2mask);
573 if(strcmp(lan3addr,"")!=0)
574 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
575 wanfaces.iface[i].name,
576 lan3addr, lan3mask);
580 if (wanup) {
581 if (nvram_match("dns_intcpt", "1")) {
582 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
583 lanaddr, lanmask,
584 lanaddr, lanmask,
585 lanaddr);
586 if(strcmp(lan1addr,"")!=0)
587 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
588 lan1addr, lan1mask,
589 lan1addr, lan1mask,
590 lan1addr);
591 if(strcmp(lan2addr,"")!=0)
592 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
593 lan2addr, lan2mask,
594 lan2addr, lan2mask,
595 lan2addr);
596 if(strcmp(lan3addr,"")!=0)
597 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
598 lan3addr, lan3mask,
599 lan3addr, lan3mask,
600 lan3addr);
603 // ICMP packets are always redirected to INPUT chains
604 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
606 ipt_forward(IPT_TABLE_NAT);
607 ipt_triggered(IPT_TABLE_NAT);
610 if (nvram_get_int("upnp_enable") & 3) {
611 ipt_write(":upnp - [0:0]\n");
612 if (wanup) {
613 // ! for loopback (all) to work
614 ipt_write("-A %s -j upnp\n", chain_wan_prerouting);
616 else {
617 for (i = 0; i < wanfaces.count; ++i) {
618 if (*(wanfaces.iface[i].name)) {
619 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
625 if (wanup) {
626 if (dmz_dst(dst)) {
627 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
628 p = t;
629 do {
630 if ((c = strchr(p, ',')) != NULL) *c = 0;
631 if (ipt_source(p, src, "dmz", NULL))
632 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
633 if (!c) break;
634 p = c + 1;
635 } while (*p);
639 p = "";
640 #ifdef TCONFIG_IPV6
641 switch (get_ipv6_service()) {
642 case IPV6_6IN4:
643 // avoid NATing proto-41 packets when using 6in4 tunnel
644 p = "-p ! 41";
645 break;
647 #endif
649 for (i = 0; i < wanfaces.count; ++i) {
650 if (*(wanfaces.iface[i].name)) {
651 if ((!wanup) || (nvram_get_int("net_snat") != 1))
652 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
653 else
654 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
658 switch (nvram_get_int("nf_loopback")) {
659 case 1: // 1 = forwarded-only
660 case 2: // 2 = disable
661 break;
662 default: // 0 = all (same as block_loopback=0)
663 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
664 lanface,
665 lanaddr, lanmask,
666 lanaddr, lanmask,
667 lanaddr);
668 if (strcmp(lan1face,"")!=0)
669 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
670 lan1face,
671 lan1addr, lan1mask,
672 lan1addr, lan1mask,
673 lan1addr);
674 if (strcmp(lan2face,"")!=0)
675 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
676 lan2face,
677 lan2addr, lan2mask,
678 lan2addr, lan2mask,
679 lan2addr);
680 if (strcmp(lan3face,"")!=0)
681 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
682 lan3face,
683 lan3addr, lan3mask,
684 lan3addr, lan3mask,
685 lan3addr);
686 break;
689 ipt_write("COMMIT\n");
692 // -----------------------------------------------------------------------------
693 // FILTER
694 // -----------------------------------------------------------------------------
696 static void filter_input(void)
698 char s[64];
699 char t[512];
700 char *en;
701 char *sec;
702 char *hit;
703 int n;
704 char *p, *c;
706 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
707 for (n = 0; n < wanfaces.count; ++n) {
708 if (*(wanfaces.iface[n].name)) {
709 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
710 if (strcmp(lan1face,"")!=0)
711 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
712 if (strcmp(lan2face,"")!=0)
713 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
714 if (strcmp(lan3face,"")!=0)
715 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
720 ipt_write(
721 "-A INPUT -m state --state INVALID -j %s\n"
722 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
723 chain_in_drop);
726 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
727 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
729 ? what if the user uses the start button in GUI ?
730 if (nvram_get_int("telnetd_eas"))
731 if (nvram_get_int("sshd_eas"))
733 #ifdef LINUX26
734 modprobe("xt_recent");
735 #else
736 modprobe("ipt_recent");
737 #endif
739 ipt_write(
740 "-N shlimit\n"
741 "-A shlimit -m recent --set --name shlimit\n"
742 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
743 atoi(hit) + 1, sec, chain_in_drop);
745 if (n & 1) {
746 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
747 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
748 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
751 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
754 #ifdef TCONFIG_FTP
755 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
756 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
757 #ifdef LINUX26
758 modprobe("xt_recent");
759 #else
760 modprobe("ipt_recent");
761 #endif
763 ipt_write(
764 "-N ftplimit\n"
765 "-A ftplimit -m recent --set --name ftp\n"
766 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
767 atoi(hit) + 1, sec, chain_in_drop);
768 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
770 #endif
772 ipt_write(
773 "-A INPUT -i lo -j ACCEPT\n"
774 "-A INPUT -i %s -j ACCEPT\n",
775 lanface);
776 if (strcmp(lan1face,"")!=0)
777 ipt_write(
778 "-A INPUT -i %s -j ACCEPT\n",
779 lan1face);
780 if (strcmp(lan2face,"")!=0)
781 ipt_write(
782 "-A INPUT -i %s -j ACCEPT\n",
783 lan2face);
784 if (strcmp(lan3face,"")!=0)
785 ipt_write(
786 "-A INPUT -i %s -j ACCEPT\n",
787 lan3face);
789 #ifdef TCONFIG_IPV6
790 switch (get_ipv6_service()) {
791 case IPV6_6IN4:
792 // Accept ICMP requests from the remote tunnel endpoint
793 if ((p = nvram_get("ipv6_tun_v4end")) && *p && strcmp(p, "0.0.0.0") != 0)
794 ipt_write("-A INPUT -p icmp -s %s -j %s\n", p, chain_in_accept);
795 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
796 break;
798 #endif
800 // ICMP request from WAN interface
801 if (nvram_match("block_wan", "0")) {
802 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
803 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept);
804 // allow udp traceroute packets
805 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept);
808 /* Accept incoming packets from broken dhcp servers, which are sending replies
809 * from addresses other than used for query. This could lead to a lower level
810 * of security, so allow to disable it via nvram variable.
812 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
813 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
816 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
817 p = t;
818 do {
819 if ((c = strchr(p, ',')) != NULL) *c = 0;
821 if (ipt_source(p, s, "remote management", NULL)) {
823 if (remotemanage) {
824 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
825 s, nvram_safe_get("http_wanport"), chain_in_accept);
828 if (nvram_get_int("sshd_remote")) {
829 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
830 s, nvram_safe_get("sshd_rport"), chain_in_accept);
834 if (!c) break;
835 p = c + 1;
836 } while (*p);
838 #ifdef TCONFIG_FTP // !!TB - FTP Server
839 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
840 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
841 p = t;
842 do {
843 if ((c = strchr(p, ',')) != NULL) *c = 0;
844 if (ipt_source(p, s, "ftp", "remote access")) {
845 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
846 s, nvram_safe_get("ftp_port"), chain_in_accept);
848 if (!c) break;
849 p = c + 1;
850 } while (*p);
852 #endif
854 // IGMP query from WAN interface
855 if (nvram_match("multicast_pass", "1")) {
856 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
857 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
860 // Routing protocol, RIP, accept
861 if (nvram_invmatch("dr_wan_rx", "0")) {
862 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
865 // if logging
866 if (*chain_in_drop == 'l') {
867 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
870 // default policy: DROP
873 // clamp TCP MSS to PMTU of WAN interface
874 static void clampmss(void)
876 #if 1
877 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
878 #else
879 int rmtu = nvram_get_int("wan_run_mtu");
880 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
881 if (rmtu < 576) {
882 ipt_write("--clamp-mss-to-pmtu\n");
884 else {
885 ipt_write("--set-mss %d\n", rmtu - 40);
887 #endif
890 static void filter_forward(void)
892 char dst[64];
893 char src[64];
894 char t[512];
895 char *p, *c;
896 int i;
898 if (nvram_match("cstats_enable", "1")) {
899 ipt_account();
902 ipt_write(
903 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
904 lanface, lanface);
905 if (strcmp(lan1face,"")!=0)
906 ipt_write(
907 "-A FORWARD -i %s -o %s -j ACCEPT\n",
908 lan1face, lan1face);
909 if (strcmp(lan2face,"")!=0)
910 ipt_write(
911 "-A FORWARD -i %s -o %s -j ACCEPT\n",
912 lan2face, lan2face);
913 if (strcmp(lan3face,"")!=0)
914 ipt_write(
915 "-A FORWARD -i %s -o %s -j ACCEPT\n",
916 lan3face, lan3face);
917 ipt_write(
918 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
920 // clamp tcp mss to pmtu
921 clampmss();
923 if (wanup) {
924 ipt_restrictions();
925 ipt_layer7_inbound();
928 ipt_webmon(0);
930 ipt_write(
931 ":wanin - [0:0]\n"
932 ":wanout - [0:0]\n"
933 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
935 for (i = 0; i < wanfaces.count; ++i) {
936 if (*(wanfaces.iface[i].name)) {
937 ipt_write(
938 "-A FORWARD -i %s -j wanin\n" // generic from wan
939 "-A FORWARD -o %s -j wanout\n", // generic to wan
940 wanfaces.iface[i].name, wanfaces.iface[i].name);
944 for (i = 0; i < wanfaces.count; ++i) {
945 if (*(wanfaces.iface[i].name)) {
946 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wanfaces.iface[i].name, chain_out_accept);
947 if (strcmp(lan1face,"")!=0)
948 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wanfaces.iface[i].name, chain_out_accept);
949 if (strcmp(lan2face,"")!=0)
950 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wanfaces.iface[i].name, chain_out_accept);
951 if (strcmp(lan3face,"")!=0)
952 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wanfaces.iface[i].name, chain_out_accept);
956 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
957 char *nv, *nvp, *b;
958 int n;
959 nvp = nv = strdup(nvram_safe_get("lan_access"));
960 if (nv) {
961 while ((b = strsep(&nvp, ">")) != NULL) {
963 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
965 1 = enabled
966 0 = src bridge
967 1.2.3.4 = src addr
968 1 = dst bridge
969 5.6.7.8 = dst addr
970 desc = desc
972 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
973 if (*d != '1')
974 continue;
975 if (!ipt_addr(src, sizeof(src), saddr, "src", AF_INET, "LAN access", desc))
976 continue;
977 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", AF_INET, "LAN access", desc))
978 continue;
980 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
981 "br",
982 sbr,
983 "br",
984 dbr,
985 src,
986 dst);
989 free(nv);
991 if (nvram_get_int("upnp_enable") & 3) {
992 ipt_write(":upnp - [0:0]\n");
993 for (i = 0; i < wanfaces.count; ++i) {
994 if (*(wanfaces.iface[i].name)) {
995 ipt_write("-A FORWARD -i %s -j upnp\n",
996 wanfaces.iface[i].name);
1001 if (wanup) {
1002 if (nvram_match("multicast_pass", "1")) {
1003 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1005 ipt_triggered(IPT_TABLE_FILTER);
1006 ipt_forward(IPT_TABLE_FILTER);
1008 if (dmz_dst(dst)) {
1009 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1010 p = t;
1011 do {
1012 if ((c = strchr(p, ',')) != NULL) *c = 0;
1013 if (ipt_source(p, src, "dmz", NULL))
1014 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1015 if (!c) break;
1016 p = c + 1;
1017 } while (*p);
1021 // default policy: DROP
1024 static void filter_log(void)
1026 int n;
1027 char limit[128];
1029 n = nvram_get_int("log_limit");
1030 if ((n >= 1) && (n <= 9999)) {
1031 sprintf(limit, "-m limit --limit %d/m", n);
1033 else {
1034 limit[0] = 0;
1037 #ifdef TCONFIG_IPV6
1038 modprobe("ip6t_LOG");
1039 #endif
1040 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1041 ip46t_write(
1042 ":logdrop - [0:0]\n"
1043 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \" --log-tcp-options --log-ip-options\n"
1044 "-A logdrop -j DROP\n"
1045 ":logreject - [0:0]\n"
1046 "-A logreject %s -j LOG --log-prefix \"REJECT \" --log-tcp-options --log-ip-options\n"
1047 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1048 limit, limit);
1050 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1051 ip46t_write(
1052 ":logaccept - [0:0]\n"
1053 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \" --log-tcp-options --log-ip-options\n"
1054 "-A logaccept -j ACCEPT\n",
1055 limit);
1059 #ifdef TCONFIG_IPV6
1060 static void filter6_input(void)
1062 char s[128];
1063 char t[512];
1064 char *en;
1065 char *sec;
1066 char *hit;
1067 int n;
1068 char *p, *c;
1070 ip6t_write(
1071 "-A INPUT -m rt --rt-type 0 -j %s\n"
1072 /* "-A INPUT -m state --state INVALID -j %s\n" */
1073 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1074 chain_in_drop/*, chain_in_drop*/);
1076 #ifdef LINUX26
1077 modprobe("xt_length");
1078 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1079 #endif
1081 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1082 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1083 #ifdef LINUX26
1084 modprobe("xt_recent");
1085 #else
1086 modprobe("ipt_recent");
1087 #endif
1089 ip6t_write(
1090 "-N shlimit\n"
1091 "-A shlimit -m recent --set --name shlimit\n"
1092 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1093 atoi(hit) + 1, sec, chain_in_drop);
1095 if (n & 1) {
1096 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1097 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1098 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1101 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"));
1104 #ifdef TCONFIG_FTP
1105 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1106 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1107 #ifdef LINUX26
1108 modprobe("xt_recent");
1109 #else
1110 modprobe("ipt_recent");
1111 #endif
1113 ip6t_write(
1114 "-N ftplimit\n"
1115 "-A ftplimit -m recent --set --name ftp\n"
1116 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1117 atoi(hit) + 1, sec, chain_in_drop);
1118 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1120 #endif // TCONFIG_FTP
1122 ip6t_write(
1123 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1124 "-A INPUT -i lo -j ACCEPT\n",
1125 lanface );
1127 switch (get_ipv6_service()) {
1128 case IPV6_NATIVE_DHCP:
1129 // allow responses from the dhcpv6 server
1130 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1131 break;
1134 // ICMPv6 rules
1135 const int allowed_icmpv6[6] = { 1, 2, 3, 4, 128, 129 };
1136 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1137 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1140 // Remote Managment
1141 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1142 p = t;
1143 do {
1144 if ((c = strchr(p, ',')) != NULL) *c = 0;
1146 if (ip6t_source(p, s, "remote management", NULL)) {
1148 if (remotemanage) {
1149 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1150 s, nvram_safe_get("http_wanport"), chain_in_accept);
1153 if (nvram_get_int("sshd_remote")) {
1154 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1155 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1159 if (!c) break;
1160 p = c + 1;
1161 } while (*p);
1163 #ifdef TCONFIG_FTP
1164 // FTP server
1165 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1166 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1167 p = t;
1168 do {
1169 if ((c = strchr(p, ',')) != NULL) *c = 0;
1170 if (ip6t_source(p, s, "ftp", "remote access")) {
1171 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1172 s, nvram_safe_get("ftp_port"), chain_in_accept);
1174 if (!c) break;
1175 p = c + 1;
1176 } while (*p);
1178 #endif
1180 // if logging
1181 if (*chain_in_drop == 'l') {
1182 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1185 // default policy: DROP
1188 static void filter6_forward(void)
1190 int n;
1192 ip6t_write(
1193 "-A FORWARD -m rt --rt-type 0 -j DROP\n"
1194 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
1195 /*"-A FORWARD -m state --state INVALID -j DROP\n"*/, // drop if INVALID state
1196 lanface, lanface);
1198 // Filter out invalid WAN->WAN connections
1199 if (*wan6face)
1200 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop);
1202 #ifdef LINUX26
1203 modprobe("xt_length");
1204 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1205 #endif
1207 // clamp tcp mss to pmtu TODO?
1208 // clampmss();
1210 // TODO: support l7, access restrictions on ipv6?
1212 if (wanup) {
1213 ipt_restrictions();
1214 ipt_layer7_inbound();
1217 #ifdef LINUX26
1218 ipt_webmon(1);
1219 #endif
1221 ip6t_write(
1222 ":wanin - [0:0]\n"
1223 ":wanout - [0:0]\n"
1224 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1226 if (*wan6face) {
1227 ip6t_write(
1228 "-A FORWARD -i %s -j wanin\n" // generic from wan
1229 "-A FORWARD -o %s -j wanout\n", // generic to wan
1230 wan6face, wan6face);
1233 ip6t_write(
1234 "-A FORWARD -i %s -j %s\n", // from lan
1235 lanface, chain_out_accept);
1237 // ICMPv6 rules
1238 const int allowed_icmpv6[6] = { 1, 2, 3, 4, 128, 129 };
1239 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1240 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1243 if (wanup) {
1244 //ipt_triggered(IPT_TABLE_FILTER);
1245 ip6t_forward();
1248 // default policy: DROP
1251 #endif
1253 static void filter_table(void)
1255 ip46t_write(
1256 "*filter\n"
1257 ":INPUT DROP [0:0]\n"
1258 ":OUTPUT ACCEPT [0:0]\n"
1261 filter_log();
1263 filter_input();
1264 #ifdef TCONFIG_IPV6
1265 filter6_input();
1266 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1267 #endif
1269 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1270 ip46t_write(":FORWARD DROP [0:0]\n");
1271 filter_forward();
1272 #ifdef TCONFIG_IPV6
1273 filter6_forward();
1274 #endif
1276 else {
1277 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1278 clampmss();
1280 ip46t_write("COMMIT\n");
1283 // -----------------------------------------------------------------------------
1285 int start_firewall(void)
1287 DIR *dir;
1288 struct dirent *dirent;
1289 char s[256];
1290 char *c, *wanface;
1291 int n;
1292 int wanproto;
1293 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1294 #ifdef TCONFIG_IPV6
1295 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1296 #endif
1298 simple_lock("firewall");
1299 simple_lock("restrictions");
1301 wanproto = get_wan_proto();
1302 wanup = check_wanup();
1304 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1306 /* NAT performance tweaks
1307 * These values can be overriden later if needed via firewall script
1309 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1310 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1311 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1312 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1313 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1314 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1315 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1316 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1317 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1318 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1319 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1320 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1322 /* DoS-related tweaks */
1323 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1324 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1325 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1327 #ifdef TCONFIG_EMF
1328 /* Force IGMPv2 due EMF limitations */
1329 if (nvram_get_int("emf_enable")) {
1330 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1331 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1333 #endif
1335 n = nvram_get_int("log_in");
1336 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1337 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1339 n = nvram_get_int("log_out");
1340 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1341 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1342 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1344 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1346 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1347 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1348 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1349 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1351 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1352 wanface = wanfaces.iface[0].name;
1353 #ifdef TCONFIG_IPV6
1354 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1355 #endif
1357 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1358 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1359 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1361 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1362 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1363 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1365 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1366 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1367 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1369 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1370 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1371 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1375 block obviously spoofed IP addresses
1377 rp_filter - BOOLEAN
1378 1 - do source validation by reversed path, as specified in RFC1812
1379 Recommended option for single homed hosts and stub network
1380 routers. Could cause troubles for complicated (not loop free)
1381 networks running a slow unreliable protocol (sort of RIP),
1382 or using static routes.
1383 0 - No source validation.
1385 c = nvram_get("wan_ifname");
1386 /* mcast needs rp filter to be turned off only for non default iface */
1387 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface, c) == 0) c = NULL;
1389 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1390 while ((dirent = readdir(dir)) != NULL) {
1391 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1392 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1394 closedir(dir);
1397 remotemanage = 0;
1398 gateway_mode = !nvram_match("wk_mode", "router");
1399 if (gateway_mode) {
1400 /* Remote management */
1401 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1402 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1405 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1406 notice_set("iptables", "Unable to create iptables restore file");
1407 simple_unlock("firewall");
1408 return 0;
1411 #ifdef TCONFIG_IPV6
1412 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1413 notice_set("ip6tables", "Unable to create ip6tables restore file");
1414 simple_unlock("firewall");
1415 return 0;
1417 modprobe("nf_conntrack_ipv6");
1418 modprobe("ip6t_REJECT");
1419 #endif
1421 mangle_table();
1422 nat_table();
1423 filter_table();
1425 fclose(ipt_file);
1426 ipt_file = NULL;
1428 #ifdef TCONFIG_IPV6
1429 fclose(ip6t_file);
1430 ip6t_file = NULL;
1431 #endif
1433 #ifdef DEBUG_IPTFILE
1434 if (debug_only) {
1435 simple_unlock("firewall");
1436 simple_unlock("restrictions");
1437 return 0;
1439 #endif
1441 save_webmon();
1443 if (nvram_get_int("upnp_enable") & 3) {
1444 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1445 if (killall("miniupnpd", SIGUSR2) == 0) {
1446 f_wait_notexists("/etc/upnp/save", 5);
1450 notice_set("iptables", "");
1451 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1452 led(LED_DIAG, 0);
1453 notice_set("iptables", "");
1455 else {
1456 sprintf(s, "%s.error", ipt_fname);
1457 rename(ipt_fname, s);
1458 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1459 led(LED_DIAG, 1);
1463 -P INPUT DROP
1464 -F INPUT
1465 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1466 -A INPUT -i br0 -j ACCEPT
1468 -P FORWARD DROP
1469 -F FORWARD
1470 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1471 -A FORWARD -i br0 -j ACCEPT
1476 #ifdef TCONFIG_IPV6
1477 if (ipv6_enabled()) {
1478 notice_set("ip6tables", "");
1479 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1480 notice_set("ip6tables", "");
1482 else {
1483 sprintf(s, "%s.error", ip6t_fname);
1484 rename(ip6t_fname, s);
1485 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1486 led(LED_DIAG, 1);
1489 #endif
1491 if (nvram_get_int("upnp_enable") & 3) {
1492 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1493 killall("miniupnpd", SIGUSR2);
1496 simple_unlock("restrictions");
1497 sched_restrictions();
1498 enable_ip_forward();
1500 led(LED_DMZ, dmz_dst(NULL));
1502 #ifdef TCONFIG_IPV6
1503 modprobe_r("nf_conntrack_ipv6");
1504 modprobe_r("ip6t_LOG");
1505 modprobe_r("ip6t_REJECT");
1506 #endif
1507 #ifdef LINUX26
1508 modprobe_r("xt_layer7");
1509 modprobe_r("xt_recent");
1510 modprobe_r("xt_HL");
1511 modprobe_r("xt_length");
1512 modprobe_r("xt_web");
1513 modprobe_r("xt_webmon");
1514 modprobe_r("xt_dscp");
1515 #else
1516 modprobe_r("ipt_layer7");
1517 modprobe_r("ipt_recent");
1518 modprobe_r("ipt_TTL");
1519 modprobe_r("ipt_web");
1520 modprobe_r("ipt_webmon");
1521 modprobe_r("ipt_dscp");
1522 #endif
1523 modprobe_r("ipt_ipp2p");
1525 unlink("/var/webmon/domain");
1526 unlink("/var/webmon/search");
1528 #ifdef TCONFIG_OPENVPN
1529 run_vpn_firewall_scripts();
1530 #endif
1531 run_nvscript("script_fire", NULL, 1);
1533 simple_unlock("firewall");
1534 return 0;
1537 int stop_firewall(void)
1539 led(LED_DMZ, 0);
1540 return 0;
1543 #ifdef DEBUG_IPTFILE
1544 void create_test_iptfile(void)
1546 debug_only = 1;
1547 start_firewall();
1548 debug_only = 0;
1550 #endif