fix typo
[tomato.git] / release / src / router / rc / firewall.c
blob917a806a36811a2517e153e65a994c79ce7d3aa5
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 static int web_lanport;
33 wanface_list_t wanfaces;
34 char lanface[IFNAMSIZ + 1];
35 char lan1face[IFNAMSIZ + 1];
36 char lan2face[IFNAMSIZ + 1];
37 char lan3face[IFNAMSIZ + 1];
38 #ifdef TCONFIG_IPV6
39 char wan6face[IFNAMSIZ + 1];
40 #endif
41 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
42 #ifdef LINUX26
43 static int can_enable_fastnat;
44 #endif
46 #ifdef DEBUG_IPTFILE
47 static int debug_only = 0;
48 #endif
50 static int gateway_mode;
51 static int remotemanage;
52 static int wanup;
54 const char *chain_in_drop;
55 const char *chain_in_accept;
56 const char *chain_out_drop;
57 const char *chain_out_accept;
58 const char *chain_out_reject;
60 const char chain_wan_prerouting[] = "WANPREROUTING";
61 const char ipt_fname[] = "/etc/iptables";
62 FILE *ipt_file;
64 #ifdef TCONFIG_IPV6
65 const char ip6t_fname[] = "/etc/ip6tables";
66 FILE *ip6t_file;
68 // RFC-4890, sec. 4.3.1
69 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
70 #endif
72 static int is_sta(int idx, int unit, int subunit, void *param)
74 return (nvram_match(wl_nvname("mode", unit, subunit), "sta") && (nvram_match(wl_nvname("bss_enabled", unit, subunit), "1")));
78 struct {
79 } firewall_data;
82 // -----------------------------------------------------------------------------
84 #ifdef LINUX26
85 static const char *fastnat_run_dir = "/var/run/fastnat";
87 void allow_fastnat(const char *service, int allow)
89 char p[128];
91 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
92 if (allow) {
93 unlink(p);
95 else {
96 mkdir_if_none(fastnat_run_dir);
97 f_write_string(p, "", 0, 0);
101 static inline int fastnat_allowed(void)
103 DIR *dir;
104 struct dirent *dp;
105 int enabled;
107 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
109 if (enabled && (dir = opendir(fastnat_run_dir))) {
110 while ((dp = readdir(dir))) {
111 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
112 continue;
113 enabled = 0;
114 break;
116 closedir(dir);
119 return (enabled);
122 void try_enabling_fastnat(void)
124 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
125 fastnat_allowed() ? "1" : "0", 0, 0);
127 #endif
129 void enable_ip_forward(void)
132 ip_forward - BOOLEAN
133 0 - disabled (default)
134 not 0 - enabled
136 Forward Packets between interfaces.
138 This variable is special, its change resets all configuration
139 parameters to their default state (RFC1122 for hosts, RFC1812
140 for routers)
142 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
146 #ifdef TCONFIG_IPV6
147 void enable_ip6_forward(void)
149 if (ipv6_enabled()) {
150 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
151 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
153 else {
154 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "0", 0, 0);
155 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "0", 0, 0);
158 #endif
161 // -----------------------------------------------------------------------------
164 static int ip2cclass(char *ipaddr, char *new, int count)
166 int ip[4];
168 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
169 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
174 static int dmz_dst(char *s)
176 struct in_addr ia;
177 char *p;
178 int n;
180 if (nvram_get_int("dmz_enable") <= 0) return 0;
182 p = nvram_safe_get("dmz_ipaddr");
183 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
184 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
185 if (s) sprintf(s, "%s%d", lan_cclass, n);
186 return 1;
189 if (s) strcpy(s, inet_ntoa(ia));
190 return 1;
193 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
195 char *pre, *post;
197 pre = (name && *name) ? " for \"" : "";
198 post = (name && *name) ? "\"" : "";
200 syslog(LOG_WARNING, "firewall: "
201 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
202 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
205 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
206 int strict, const char *categ, const char *name)
208 char p[INET6_ADDRSTRLEN * 2];
209 int r = 0;
211 if ((s) && (*s) && (*dir))
213 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
214 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
215 r = IPT_V4;
217 #ifdef TCONFIG_IPV6
218 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
219 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
220 r = IPT_V6;
222 #endif
223 else {
224 snprintf(addr, maxlen, "-%c %s", dir[0], s);
225 if (sscanf(s, "%[^/]/", p)) {
226 #ifdef TCONFIG_IPV6
227 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
228 #else
229 r = host_addrtypes(p, IPT_V4);
230 #endif
234 else
236 *addr = 0;
237 r = (IPT_V4 | IPT_V6);
240 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
241 ipt_log_unresolved(s, categ, name,
242 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
245 return (r & af);
248 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
249 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
250 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
253 static void get_src(const char *nv, char *src)
255 char *p;
257 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
258 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
260 else {
261 *src = 0;
266 void ipt_write(const char *format, ...)
268 va_list args;
270 va_start(args, format);
271 vfprintf(ipt_file, format, args);
272 va_end(args);
275 void ip6t_write(const char *format, ...)
277 #ifdef TCONFIG_IPV6
278 va_list args;
280 va_start(args, format);
281 vfprintf(ip6t_file, format, args);
282 va_end(args);
283 #endif
286 // -----------------------------------------------------------------------------
288 int ipt_dscp(const char *v, char *opt)
290 unsigned int n;
292 if (*v == 0) {
293 *opt = 0;
294 return 0;
297 n = strtoul(v, NULL, 0);
298 if (n > 63) n = 63;
299 sprintf(opt, " -m dscp --dscp 0x%02X", n);
301 #ifdef LINUX26
302 modprobe("xt_dscp");
303 #else
304 modprobe("ipt_dscp");
305 #endif
306 return 1;
309 // -----------------------------------------------------------------------------
312 int ipt_ipp2p(const char *v, char *opt)
314 int n = atoi(v);
316 if (n == 0) {
317 *opt = 0;
318 return 0;
321 strcpy(opt, "-m ipp2p ");
322 if ((n & 0xFFF) == 0xFFF) {
323 strcat(opt, "--ipp2p");
325 else {
326 // x12
327 if (n & 0x0001) strcat(opt, "--apple ");
328 if (n & 0x0002) strcat(opt, "--ares ");
329 if (n & 0x0004) strcat(opt, "--bit ");
330 if (n & 0x0008) strcat(opt, "--dc ");
331 if (n & 0x0010) strcat(opt, "--edk ");
332 if (n & 0x0020) strcat(opt, "--gnu ");
333 if (n & 0x0040) strcat(opt, "--kazaa ");
334 if (n & 0x0080) strcat(opt, "--mute ");
335 if (n & 0x0100) strcat(opt, "--soul ");
336 if (n & 0x0200) strcat(opt, "--waste ");
337 if (n & 0x0400) strcat(opt, "--winmx ");
338 if (n & 0x0800) strcat(opt, "--xdcc ");
339 #ifdef LINUX26
340 if (n & 0x1000) strcat(opt, "--pp ");
341 if (n & 0x2000) strcat(opt, "--xunlei ");
342 #endif
345 modprobe("ipt_ipp2p");
346 return 1;
350 // -----------------------------------------------------------------------------
353 char **layer7_in;
355 // This L7 matches inbound traffic, caches the results, then the L7 outbound
356 // should read the cached result and set the appropriate marks -- zzz
357 void ipt_layer7_inbound(void)
359 int en, i;
360 char **p;
362 if (!layer7_in) return;
364 en = nvram_match("nf_l7in", "1");
365 if (en) {
366 ipt_write(":L7in - [0:0]\n");
367 for (i = 0; i < wanfaces.count; ++i) {
368 if (*(wanfaces.iface[i].name)) {
369 ipt_write("-A FORWARD -i %s -j L7in\n",
370 wanfaces.iface[i].name);
375 p = layer7_in;
376 while (*p) {
377 if (en) {
378 ipt_write("-A L7in %s -j RETURN\n", *p);
379 #ifdef LINUX26
380 can_enable_fastnat = 0;
381 #endif
383 free(*p);
384 ++p;
386 free(layer7_in);
387 layer7_in = NULL;
390 int ipt_layer7(const char *v, char *opt)
392 char s[128];
393 char *path;
395 *opt = 0;
396 if (*v == 0) return 0;
397 if (strlen(v) > 32) return -1;
399 path = "/etc/l7-extra";
400 sprintf(s, "%s/%s.pat", path, v);
401 if (!f_exists(s)) {
402 path = "/etc/l7-protocols";
403 sprintf(s, "%s/%s.pat", path, v);
404 if (!f_exists(s)) {
405 syslog(LOG_ERR, "L7 %s was not found", v);
406 return -1;
410 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
412 if (nvram_match("nf_l7in", "1")) {
413 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
414 if (layer7_in) {
415 char **p;
417 p = layer7_in;
418 while (*p) {
419 if (strcmp(*p, opt) == 0) return 1;
420 ++p;
422 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
426 #ifdef LINUX26
427 modprobe("xt_layer7");
428 #else
429 modprobe("ipt_layer7");
430 #endif
431 return 1;
434 // -----------------------------------------------------------------------------
436 static void ipt_account(void) {
437 struct in_addr ipaddr, netmask, network;
438 char lanN_ifname[] = "lanXX_ifname";
439 char lanN_ipaddr[] = "lanXX_ipaddr";
440 char lanN_netmask[] = "lanXX_netmask";
441 char lanN[] = "lanXX";
442 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
443 char br;
444 // If the IP Address changes, the below rule will cause things to choke, and blocking rules don't get applied
445 // As a workaround, flush the entire FORWARD chain
446 system("iptables -F FORWARD");
448 for(br=0 ; br<=3 ; br++) {
449 char bridge[2] = "0";
450 if (br!=0)
451 bridge[0]+=br;
452 else
453 strcpy(bridge, "");
455 sprintf(lanN_ifname, "lan%s_ifname", bridge);
457 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
459 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
460 sprintf(lanN_netmask, "lan%s_netmask", bridge);
461 sprintf(lanN, "lan%s", bridge);
463 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
464 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
466 // bitwise AND of ip and netmask gives the network
467 network.s_addr = ipaddr.s_addr & netmask.s_addr;
469 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
471 //ipv4 only
472 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
477 // -----------------------------------------------------------------------------
479 static void save_webmon(void)
481 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
482 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
485 static void ipt_webmon()
487 int wmtype, clear, i;
488 char t[512];
489 char src[128];
490 char *p, *c;
491 int ok;
493 if (!nvram_get_int("log_wm")) return;
495 #ifdef LINUX26
496 can_enable_fastnat = 0;
497 #endif
498 wmtype = nvram_get_int("log_wmtype");
499 clear = nvram_get_int("log_wmclear");
501 ip46t_write(":monitor - [0:0]\n");
503 // include IPs
504 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
505 p = t;
506 do {
507 if ((c = strchr(p, ',')) != NULL) *c = 0;
509 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
510 #ifdef TCONFIG_IPV6
511 if (*wan6face && (ok & IPT_V6))
512 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
513 #endif
514 if (ok & IPT_V4) {
515 for (i = 0; i < wanfaces.count; ++i) {
516 if (*(wanfaces.iface[i].name)) {
517 ipt_write("-A FORWARD -o %s %s -j monitor\n",
518 wanfaces.iface[i].name, src);
524 if (!c) break;
525 p = c + 1;
526 } while (*p);
528 // exclude IPs
529 if (wmtype == 2) {
530 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
531 p = t;
532 do {
533 if ((c = strchr(p, ',')) != NULL) *c = 0;
534 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
535 if (*src)
536 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
538 if (!c) break;
539 p = c + 1;
540 } while (*p);
543 char webdomain[100];
544 char websearch[100];
546 if( nvram_match( "webmon_bkp", "1" ) ) {
547 xstart( "/usr/sbin/webmon_bkp", "add" ); // add jobs to cru
549 sprintf(webdomain, "--domain_load_file %s/webmon_recent_domains", nvram_safe_get("webmon_dir"));
550 sprintf(websearch, "--search_load_file %s/webmon_recent_searches", nvram_safe_get("webmon_dir"));
551 } else {
552 sprintf(webdomain, "--domain_load_file /var/webmon/domain");
553 sprintf(websearch, "--search_load_file /var/webmon/search");
556 ip46t_write(
557 "-A monitor -p tcp -m webmon "
558 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
559 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
560 (clear & 1) == 0 ? webdomain : "--clear_domain",
561 (clear & 2) == 0 ? websearch : "--clear_search");
563 if( nvram_match( "webmon_bkp", "1" ) )
564 xstart( "/usr/sbin/webmon_bkp", "hourly" ); // make a copy immediately
567 #ifdef LINUX26
568 modprobe("xt_webmon");
569 #else
570 modprobe("ipt_webmon");
571 #endif
576 // -----------------------------------------------------------------------------
577 // MANGLE
578 // -----------------------------------------------------------------------------
580 static void mangle_table(void)
582 int ttl;
583 char *p, *wanface;
585 ip46t_write(
586 "*mangle\n"
587 ":PREROUTING ACCEPT [0:0]\n"
588 ":OUTPUT ACCEPT [0:0]\n");
590 if (wanup) {
592 ipt_qos();
593 //1 for mangle
594 ipt_qoslimit(1);
596 p = nvram_safe_get("nf_ttl");
597 if (strncmp(p, "c:", 2) == 0) {
598 p += 2;
599 ttl = atoi(p);
600 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
602 else if ((ttl = atoi(p)) != 0) {
603 if (ttl > 0) {
604 p = "inc";
606 else {
607 ttl = -ttl;
608 p = "dec";
610 if (ttl > 255) p = NULL;
612 else p = NULL;
614 if (p) {
615 #ifdef LINUX26
616 modprobe("xt_HL");
617 #else
618 modprobe("ipt_TTL");
619 #endif
620 // set TTL on primary WAN iface only
621 wanface = wanfaces.iface[0].name;
622 ipt_write(
623 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
624 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
625 wanface, p, ttl,
626 wanface, p, ttl);
627 #ifdef TCONFIG_IPV6
628 // FIXME: IPv6 HL should be configurable separately from TTL.
629 // disable it until GUI setting is implemented.
630 #if 0
631 ip6t_write(
632 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
633 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
634 wan6face, p, ttl,
635 wan6face, p, ttl);
636 #endif
637 #endif
639 // Reset Incoming DSCP to 0x00
640 if (nvram_match("DSCP_fix_enable", "1")) {
641 #ifdef LINUX26
642 modprobe("xt_DSCP");
643 #else
644 modprobe("ipt_DSCP");
645 #endif
646 ipt_write("-I PREROUTING -i %s -j DSCP --set-dscp 0\n", wanface);
651 // Clamp TCP MSS to PMTU of WAN interface (IPv4 & IPv6)
652 ip46t_write("-I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
654 ip46t_write("COMMIT\n");
657 // -----------------------------------------------------------------------------
658 // NAT
659 // -----------------------------------------------------------------------------
661 static void nat_table(void)
663 char lanaddr[32];
664 char lanmask[32];
665 char lan1addr[32];
666 char lan1mask[32];
667 char lan2addr[32];
668 char lan2mask[32];
669 char lan3addr[32];
670 char lan3mask[32];
671 char dst[64];
672 char src[64];
673 char t[512];
674 char *p, *c;
675 int i;
677 ipt_write("*nat\n"
678 ":PREROUTING ACCEPT [0:0]\n"
679 ":POSTROUTING ACCEPT [0:0]\n"
680 ":OUTPUT ACCEPT [0:0]\n"
681 ":%s - [0:0]\n",
682 chain_wan_prerouting);
684 //2 for nat
685 ipt_qoslimit(2);
687 if (gateway_mode) {
688 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
689 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
690 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
691 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
692 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
693 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
694 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
695 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
698 for (i = 0; i < wanfaces.count; ++i) {
699 if (*(wanfaces.iface[i].name)) {
700 // chain_wan_prerouting
701 if (wanup) {
702 ipt_write("-A PREROUTING -d %s -j %s\n",
703 wanfaces.iface[i].ip, chain_wan_prerouting);
706 // Drop incoming packets which destination IP address is to our LAN side directly
707 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
708 wanfaces.iface[i].name,
709 lanaddr, lanmask); // note: ipt will correct lanaddr
710 if(strcmp(lan1addr,"")!=0)
711 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
712 wanfaces.iface[i].name,
713 lan1addr, lan1mask);
714 if(strcmp(lan2addr,"")!=0)
715 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
716 wanfaces.iface[i].name,
717 lan2addr, lan2mask);
718 if(strcmp(lan3addr,"")!=0)
719 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
720 wanfaces.iface[i].name,
721 lan3addr, lan3mask);
725 if (wanup) {
726 if (nvram_match("dns_intcpt", "1")) {
727 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
728 lanaddr, lanmask,
729 lanaddr, lanmask,
730 lanaddr);
731 if(strcmp(lan1addr,"")!=0)
732 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
733 lan1addr, lan1mask,
734 lan1addr, lan1mask,
735 lan1addr);
736 if(strcmp(lan2addr,"")!=0)
737 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
738 lan2addr, lan2mask,
739 lan2addr, lan2mask,
740 lan2addr);
741 if(strcmp(lan3addr,"")!=0)
742 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
743 lan3addr, lan3mask,
744 lan3addr, lan3mask,
745 lan3addr);
748 // ICMP packets are always redirected to INPUT chains
749 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
752 //force remote access to router if DMZ is enabled - shibby
753 if( (nvram_match("dmz_enable", "1")) && (nvram_match("dmz_ra", "1")) ) {
754 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
755 p = t;
756 do {
757 if ((c = strchr(p, ',')) != NULL) *c = 0;
758 ipt_source(p, src, "ra", NULL);
760 if (remotemanage) {
761 ipt_write("-A %s -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
762 chain_wan_prerouting, src, nvram_safe_get("http_wanport"), lanaddr, web_lanport);
765 if (nvram_get_int("sshd_remote")) {
766 ipt_write("-A %s %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
767 chain_wan_prerouting, src, nvram_safe_get("sshd_rport"), lanaddr, nvram_safe_get("sshd_port"));
770 if (!c) break;
771 p = c + 1;
772 } while (*p);
776 ipt_forward(IPT_TABLE_NAT);
777 ipt_triggered(IPT_TABLE_NAT);
780 if (nvram_get_int("upnp_enable") & 3) {
781 ipt_write(":upnp - [0:0]\n");
783 for (i = 0; i < wanfaces.count; ++i) {
784 if (*(wanfaces.iface[i].name)) {
785 if (wanup) {
786 // ! for loopback (all) to work
787 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
789 else {
790 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
796 #ifdef TCONFIG_TOR
797 //TOR
798 if (nvram_match("tor_enable", "1")) {
799 if (nvram_match("tor_iface", "br0")) {
800 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
801 nvram_safe_get("tor_iface"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
802 } else if (nvram_match("tor_iface", "br1")) {
803 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
804 nvram_safe_get("tor_iface"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("tor_transport") );
805 } else if (nvram_match("tor_iface", "br2")) {
806 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
807 nvram_safe_get("tor_iface"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("tor_transport") );
808 } else if (nvram_match("tor_iface", "br3")) {
809 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
810 nvram_safe_get("tor_iface"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("tor_transport") );
811 } else {
812 strlcpy(t, nvram_safe_get("tor_users"), sizeof(t));
813 p = t;
814 do {
815 if ((c = strchr(p, ',')) != NULL) *c = 0;
817 if (ipt_source_strict(p, src, "tor", NULL))
818 ipt_write("-A PREROUTING %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
819 src, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
821 if (!c) break;
822 p = c + 1;
823 } while (*p);
826 #endif
828 if (wanup) {
829 if (dmz_dst(dst)) {
830 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
831 p = t;
832 do {
833 if ((c = strchr(p, ',')) != NULL) *c = 0;
834 if (ipt_source_strict(p, src, "dmz", NULL))
835 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
836 if (!c) break;
837 p = c + 1;
838 } while (*p);
842 p = "";
843 #ifdef TCONFIG_IPV6
844 switch (get_ipv6_service()) {
845 case IPV6_6IN4:
846 // avoid NATing proto-41 packets when using 6in4 tunnel
847 p = "! -p 41";
848 break;
850 #endif
852 for (i = 0; i < wanfaces.count; ++i) {
853 if (*(wanfaces.iface[i].name)) {
854 if ((!wanup) || (nvram_get_int("ne_snat") != 1))
855 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
856 else
857 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
861 char *modem_ipaddr;
862 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
863 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0")
864 && (!foreach_wif(1, NULL, is_sta)) )
865 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
867 switch (nvram_get_int("nf_loopback")) {
868 case 1: // 1 = forwarded-only
869 case 2: // 2 = disable
870 break;
871 default: // 0 = all (same as block_loopback=0)
872 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
873 lanface,
874 lanaddr, lanmask,
875 lanaddr, lanmask,
876 lanaddr);
877 if (strcmp(lan1face,"")!=0)
878 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
879 lan1face,
880 lan1addr, lan1mask,
881 lan1addr, lan1mask,
882 lan1addr);
883 if (strcmp(lan2face,"")!=0)
884 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
885 lan2face,
886 lan2addr, lan2mask,
887 lan2addr, lan2mask,
888 lan2addr);
889 if (strcmp(lan3face,"")!=0)
890 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
891 lan3face,
892 lan3addr, lan3mask,
893 lan3addr, lan3mask,
894 lan3addr);
895 break;
898 ipt_write("COMMIT\n");
901 // -----------------------------------------------------------------------------
902 // FILTER
903 // -----------------------------------------------------------------------------
905 static void filter_input(void)
907 char s[64];
908 char t[512];
909 char *en;
910 char *sec;
911 char *hit;
912 int n;
913 char *p, *c;
915 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
916 for (n = 0; n < wanfaces.count; ++n) {
917 if (*(wanfaces.iface[n].name)) {
918 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
919 if (strcmp(lan1face,"")!=0)
920 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
921 if (strcmp(lan2face,"")!=0)
922 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
923 if (strcmp(lan3face,"")!=0)
924 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
929 ipt_write(
930 "-A INPUT -m state --state INVALID -j DROP\n"
931 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
933 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
934 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
936 ? what if the user uses the start button in GUI ?
937 if (nvram_get_int("telnetd_eas"))
938 if (nvram_get_int("sshd_eas"))
940 #ifdef LINUX26
941 modprobe("xt_recent");
942 #else
943 modprobe("ipt_recent");
944 #endif
946 ipt_write(
947 "-N shlimit\n"
948 "-A shlimit -m recent --set --name shlimit\n"
949 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
950 atoi(hit) + 1, sec, chain_in_drop);
952 if (n & 1) {
953 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
954 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
955 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
958 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
961 #ifdef TCONFIG_FTP
962 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
963 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
964 #ifdef LINUX26
965 modprobe("xt_recent");
966 #else
967 modprobe("ipt_recent");
968 #endif
970 ipt_write(
971 "-N ftplimit\n"
972 "-A ftplimit -m recent --set --name ftp\n"
973 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
974 atoi(hit) + 1, sec, chain_in_drop);
975 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
977 #endif
979 ipt_write(
980 "-A INPUT -i lo -j ACCEPT\n"
981 "-A INPUT -i %s -j ACCEPT\n",
982 lanface);
983 if (strcmp(lan1face,"")!=0)
984 ipt_write(
985 "-A INPUT -i %s -j ACCEPT\n",
986 lan1face);
987 if (strcmp(lan2face,"")!=0)
988 ipt_write(
989 "-A INPUT -i %s -j ACCEPT\n",
990 lan2face);
991 if (strcmp(lan3face,"")!=0)
992 ipt_write(
993 "-A INPUT -i %s -j ACCEPT\n",
994 lan3face);
996 #ifdef TCONFIG_IPV6
997 n = get_ipv6_service();
998 switch (n) {
999 case IPV6_ANYCAST_6TO4:
1000 case IPV6_6IN4:
1001 // Accept ICMP requests from the remote tunnel endpoint
1002 if (n == IPV6_ANYCAST_6TO4)
1003 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
1004 else
1005 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
1006 if (*s && strcmp(s, "0.0.0.0") != 0)
1007 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
1008 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
1009 break;
1011 #endif
1013 // ICMP request from WAN interface
1014 if (nvram_match("block_wan", "0")) {
1015 if (nvram_match("block_wan_limit", "0")) {
1016 // allow ICMP packets to be received
1017 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
1018 // allow udp traceroute packets
1019 ipt_write("-A INPUT -p udp --dport 33434:33534 -j %s\n", chain_in_accept);
1020 } else {
1021 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
1022 ipt_write("-A INPUT -p icmp -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_icmp"), chain_in_accept);
1023 // allow udp traceroute packets, but restrict the flow to avoid ping flood attacks
1024 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_tr"), chain_in_accept);
1028 /* Accept incoming packets from broken dhcp servers, which are sending replies
1029 * from addresses other than used for query. This could lead to a lower level
1030 * of security, so allow to disable it via nvram variable.
1032 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
1033 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
1036 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1037 p = t;
1038 do {
1039 if ((c = strchr(p, ',')) != NULL) *c = 0;
1041 if (ipt_source(p, s, "remote management", NULL)) {
1043 if (remotemanage) {
1044 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1045 s, nvram_safe_get("http_wanport"), chain_in_accept);
1048 if (nvram_get_int("sshd_remote")) {
1049 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1050 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1054 if (!c) break;
1055 p = c + 1;
1056 } while (*p);
1058 #ifdef TCONFIG_NGINX //Tomato RAF - Web Server
1059 if (nvram_match("nginx_enable", "1") && nvram_match("nginx_remote", "1"))
1060 ipt_write("-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "nginx_port" ));
1061 #endif
1063 #ifdef TCONFIG_FTP // !!TB - FTP Server
1064 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1065 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1066 p = t;
1067 do {
1068 if ((c = strchr(p, ',')) != NULL) *c = 0;
1069 if (ipt_source(p, s, "ftp", "remote access")) {
1070 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1071 s, nvram_safe_get("ftp_port"), chain_in_accept);
1073 if (!c) break;
1074 p = c + 1;
1075 } while (*p);
1077 #endif
1079 #ifdef TCONFIG_SNMP
1080 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
1082 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
1083 p = t;
1084 do {
1085 if ((c = strchr(p, ',')) != NULL) *c = 0;
1087 if (ipt_source(p, s, "snmp", "remote")) {
1088 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
1089 s, nvram_safe_get("snmp_port"), chain_in_accept);
1092 if (!c) break;
1093 p = c + 1;
1094 } while (*p);
1096 #endif
1098 // IGMP query from WAN interface
1099 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1100 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
1101 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
1104 // Routing protocol, RIP, accept
1105 if (nvram_invmatch("dr_wan_rx", "0")) {
1106 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
1109 //BT Client ports from WAN interface
1110 if (nvram_match("bt_enable", "1")) {
1111 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port" ) );
1112 if (nvram_match( "bt_rpc_wan", "1") )
1114 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port_gui" ) );
1118 // if logging
1119 if (*chain_in_drop == 'l') {
1120 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1123 // default policy: DROP
1126 static void filter_forward(void)
1128 char dst[64];
1129 char src[64];
1130 char t[512];
1131 char *p, *c;
1132 int i;
1134 #ifdef TCONFIG_IPV6
1135 ip6t_write(
1136 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1137 #endif
1139 if (nvram_match("cstats_enable", "1")) {
1140 ipt_account();
1143 ip46t_write(
1144 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1145 lanface, lanface);
1146 if (strcmp(lan1face,"")!=0)
1147 ip46t_write(
1148 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1149 lan1face, lan1face);
1150 if (strcmp(lan2face,"")!=0)
1151 ip46t_write(
1152 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1153 lan2face, lan2face);
1154 if (strcmp(lan3face,"")!=0)
1155 ip46t_write(
1156 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1157 lan3face, lan3face);
1159 char lanAccess[17] = "0000000000000000";
1161 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1162 char *nv, *nvp, *b;
1163 int n;
1164 nvp = nv = strdup(nvram_safe_get("lan_access"));
1165 if (nv) {
1166 while ((b = strsep(&nvp, ">")) != NULL) {
1168 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1170 1 = enabled
1171 0 = src bridge
1172 1.2.3.4 = src addr
1173 1 = dst bridge
1174 5.6.7.8 = dst addr
1175 desc = desc
1177 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1178 if (*d != '1')
1179 continue;
1180 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1181 continue;
1182 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1183 continue;
1185 //ipv4 only
1186 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1187 "br",
1188 sbr,
1189 "br",
1190 dbr,
1191 src,
1192 dst);
1194 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1195 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1199 free(nv);
1201 ip46t_write(
1202 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1204 if (wanup) {
1205 ipt_restrictions();
1207 ipt_layer7_inbound();
1210 ipt_webmon();
1212 ip46t_write(
1213 ":wanin - [0:0]\n"
1214 ":wanout - [0:0]\n"
1215 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1217 char lanN_ifname[] = "lanXX_ifname";
1218 char br;
1219 for(br=0 ; br<=3 ; br++) {
1220 char bridge[2] = "0";
1221 if (br!=0)
1222 bridge[0]+=br;
1223 else
1224 strcpy(bridge, "");
1226 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1227 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1228 char lanN_ifname2[] = "lanXX_ifname";
1229 char br2;
1230 for(br2=0 ; br2<=3 ; br2++) {
1231 if (br==br2) continue;
1233 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1235 char bridge2[2] = "0";
1236 if (br2!=0)
1237 bridge2[0]+=br2;
1238 else
1239 strcpy(bridge2, "");
1241 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1242 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1243 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1244 nvram_safe_get(lanN_ifname),
1245 nvram_safe_get(lanN_ifname2));
1248 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1252 #ifdef TCONFIG_PPTPD
1253 //Add for pptp server
1254 if (nvram_match("pptpd_enable", "1")) {
1255 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1256 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1258 #endif
1260 #ifdef TCONFIG_IPV6
1261 // Filter out invalid WAN->WAN connections
1262 if (*wan6face)
1263 // 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
1264 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1266 #ifdef LINUX26
1267 modprobe("xt_length");
1268 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1269 #endif
1271 // ICMPv6 rules
1272 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1273 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1276 //IPv6
1277 if (*wan6face) {
1278 ip6t_write(
1279 "-A FORWARD -i %s -j wanin\n" // generic from wan
1280 "-A FORWARD -o %s -j wanout\n", // generic to wan
1281 wan6face, wan6face);
1283 #endif
1285 //IPv4
1286 for (i = 0; i < wanfaces.count; ++i) {
1287 if (*(wanfaces.iface[i].name)) {
1288 ipt_write(
1289 "-A FORWARD -i %s -j wanin\n" // generic from wan
1290 "-A FORWARD -o %s -j wanout\n", // generic to wan
1291 wanfaces.iface[i].name, wanfaces.iface[i].name);
1295 for(br=0 ; br<=3 ; br++) {
1296 char bridge[2] = "0";
1297 if (br!=0)
1298 bridge[0]+=br;
1299 else
1300 strcpy(bridge, "");
1302 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1303 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1304 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1308 #ifdef TCONFIG_IPV6
1309 //IPv6 forward LAN->WAN accept
1310 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1312 if (strcmp(lan1face,"")!=0)
1313 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1314 if (strcmp(lan2face,"")!=0)
1315 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1316 if (strcmp(lan3face,"")!=0)
1317 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1318 #endif
1320 // IPv4 only
1321 if (nvram_get_int("upnp_enable") & 3) {
1322 ipt_write(":upnp - [0:0]\n");
1323 for (i = 0; i < wanfaces.count; ++i) {
1324 if (*(wanfaces.iface[i].name)) {
1325 ipt_write("-A FORWARD -i %s -j upnp\n",
1326 wanfaces.iface[i].name);
1331 if (wanup) {
1332 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1333 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1335 ipt_triggered(IPT_TABLE_FILTER);
1336 ipt_forward(IPT_TABLE_FILTER);
1337 #ifdef TCONFIG_IPV6
1338 ip6t_forward();
1339 #endif
1341 if (dmz_dst(dst)) {
1342 char dmz_ifname[IFNAMSIZ+1];
1343 strlcpy(dmz_ifname, nvram_safe_get("dmz_ifname"), sizeof(dmz_ifname));
1344 if(strcmp(dmz_ifname, "") == 0)
1345 strlcpy(dmz_ifname, lanface, sizeof(lanface));
1346 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1347 p = t;
1348 do {
1349 if ((c = strchr(p, ',')) != NULL) *c = 0;
1350 if (ipt_source(p, src, "dmz", NULL))
1351 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", dmz_ifname, src, dst, chain_in_accept);
1352 if (!c) break;
1353 p = c + 1;
1354 } while (*p);
1358 // default policy: DROP
1361 static void filter_log(void)
1363 int n;
1364 char limit[128];
1366 n = nvram_get_int("log_limit");
1367 if ((n >= 1) && (n <= 9999)) {
1368 sprintf(limit, "-m limit --limit %d/m", n);
1370 else {
1371 limit[0] = 0;
1374 #ifdef TCONFIG_IPV6
1375 modprobe("ip6t_LOG");
1376 #endif
1377 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1378 ip46t_write(
1379 ":logdrop - [0:0]\n"
1380 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1381 #ifdef LINUX26
1382 " --log-macdecode"
1383 #endif
1384 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1385 "-A logdrop -j DROP\n"
1386 ":logreject - [0:0]\n"
1387 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1388 #ifdef LINUX26
1389 " --log-macdecode"
1390 #endif
1391 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1392 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1393 limit, limit);
1395 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1396 ip46t_write(
1397 ":logaccept - [0:0]\n"
1398 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1399 #ifdef LINUX26
1400 " --log-macdecode"
1401 #endif
1402 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1403 "-A logaccept -j ACCEPT\n",
1404 limit);
1408 #ifdef TCONFIG_IPV6
1409 static void filter6_input(void)
1411 char s[128];
1412 char t[512];
1413 char *en;
1414 char *sec;
1415 char *hit;
1416 int n;
1417 char *p, *c;
1419 // RFC-4890, sec. 4.4.1
1420 const int allowed_local_icmpv6[] =
1421 { 130, 131, 132, 133, 134, 135, 136,
1422 141, 142, 143,
1423 148, 149, 151, 152, 153 };
1425 ip6t_write(
1426 "-A INPUT -m rt --rt-type 0 -j %s\n"
1427 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1428 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1429 chain_in_drop);
1431 #ifdef LINUX26
1432 modprobe("xt_length");
1433 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1434 #endif
1436 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1437 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1438 #ifdef LINUX26
1439 modprobe("xt_recent");
1440 #else
1441 modprobe("ipt_recent");
1442 #endif
1444 ip6t_write(
1445 "-N shlimit\n"
1446 "-A shlimit -m recent --set --name shlimit\n"
1447 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1448 atoi(hit) + 1, sec, chain_in_drop);
1450 if (n & 1) {
1451 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1452 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1453 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1456 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"));
1459 #ifdef TCONFIG_FTP
1460 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1461 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1462 #ifdef LINUX26
1463 modprobe("xt_recent");
1464 #else
1465 modprobe("ipt_recent");
1466 #endif
1468 ip6t_write(
1469 "-N ftplimit\n"
1470 "-A ftplimit -m recent --set --name ftp\n"
1471 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1472 atoi(hit) + 1, sec, chain_in_drop);
1473 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1475 #endif // TCONFIG_FTP
1477 ip6t_write(
1478 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1479 "-A INPUT -i lo -j ACCEPT\n",
1480 lanface );
1482 switch (get_ipv6_service()) {
1483 case IPV6_ANYCAST_6TO4:
1484 case IPV6_NATIVE_DHCP:
1485 // allow responses from the dhcpv6 server
1486 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1487 break;
1490 // ICMPv6 rules
1491 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1492 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1494 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1495 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1498 // Remote Managment
1499 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1500 p = t;
1501 do {
1502 if ((c = strchr(p, ',')) != NULL) *c = 0;
1504 if (ip6t_source(p, s, "remote management", NULL)) {
1506 if (remotemanage) {
1507 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1508 s, nvram_safe_get("http_wanport"), chain_in_accept);
1511 if (nvram_get_int("sshd_remote")) {
1512 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1513 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1517 if (!c) break;
1518 p = c + 1;
1519 } while (*p);
1521 #ifdef TCONFIG_FTP
1522 // FTP server
1523 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1524 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1525 p = t;
1526 do {
1527 if ((c = strchr(p, ',')) != NULL) *c = 0;
1528 if (ip6t_source(p, s, "ftp", "remote access")) {
1529 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1530 s, nvram_safe_get("ftp_port"), chain_in_accept);
1532 if (!c) break;
1533 p = c + 1;
1534 } while (*p);
1536 #endif
1538 // if logging
1539 if (*chain_in_drop == 'l') {
1540 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1543 // default policy: DROP
1546 #endif
1548 static void filter_table(void)
1550 ip46t_write(
1551 "*filter\n"
1552 ":INPUT DROP [0:0]\n"
1553 ":OUTPUT ACCEPT [0:0]\n"
1556 filter_log();
1558 filter_input();
1559 #ifdef TCONFIG_IPV6
1560 filter6_input();
1561 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1562 #endif
1564 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1565 ip46t_write(":FORWARD DROP [0:0]\n");
1566 filter_forward();
1568 else {
1569 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1571 ip46t_write("COMMIT\n");
1574 // -----------------------------------------------------------------------------
1576 int start_firewall(void)
1578 DIR *dir;
1579 struct dirent *dirent;
1580 char s[256];
1581 char *c, *wanface;
1582 int n;
1583 int wanproto;
1584 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1585 #ifdef TCONFIG_IPV6
1586 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1587 #endif
1589 simple_lock("firewall");
1590 simple_lock("restrictions");
1592 wanup = check_wanup();
1594 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1596 /* NAT performance tweaks
1597 * These values can be overriden later if needed via firewall script
1599 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1600 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1601 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1602 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1603 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1604 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1605 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1606 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1607 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1608 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1609 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1610 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1612 /* DoS-related tweaks */
1613 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1614 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1615 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1617 wanproto = get_wan_proto();
1618 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1620 #ifdef TCONFIG_EMF
1621 /* Force IGMPv2 due EMF limitations */
1622 if (nvram_get_int("emf_enable")) {
1623 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1624 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1626 #endif
1628 n = nvram_get_int("log_in");
1629 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1630 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1632 n = nvram_get_int("log_out");
1633 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1634 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1635 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1637 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1639 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1640 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1641 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1642 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1644 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1645 wanface = wanfaces.iface[0].name;
1646 #ifdef TCONFIG_IPV6
1647 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1648 #endif
1650 #ifdef LINUX26
1651 can_enable_fastnat = 1;
1652 #endif
1654 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1655 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1656 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1658 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1659 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1660 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1662 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1663 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1664 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1666 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1667 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1668 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1672 block obviously spoofed IP addresses
1674 rp_filter - BOOLEAN
1675 1 - do source validation by reversed path, as specified in RFC1812
1676 Recommended option for single homed hosts and stub network
1677 routers. Could cause troubles for complicated (not loop free)
1678 networks running a slow unreliable protocol (sort of RIP),
1679 or using static routes.
1680 0 - No source validation.
1682 c = nvram_get("wan_ifname");
1683 /* mcast needs rp filter to be turned off only for non default iface */
1684 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1686 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1687 while ((dirent = readdir(dir)) != NULL) {
1688 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1689 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1691 closedir(dir);
1694 remotemanage = 0;
1695 gateway_mode = !nvram_match("wk_mode", "router");
1696 if (gateway_mode) {
1697 /* Remote management */
1698 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1699 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1701 if (nvram_match("remote_mgt_https", "1")) {
1702 web_lanport = nvram_get_int("https_lanport");
1703 if (web_lanport <= 0) web_lanport = 443;
1704 } else {
1705 web_lanport = nvram_get_int("http_lanport");
1706 if (web_lanport <= 0) web_lanport = 80;
1710 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1711 notice_set("iptables", "Unable to create iptables restore file");
1712 simple_unlock("firewall");
1713 return 0;
1716 #ifdef TCONFIG_IPV6
1717 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1718 notice_set("ip6tables", "Unable to create ip6tables restore file");
1719 simple_unlock("firewall");
1720 return 0;
1722 modprobe("nf_conntrack_ipv6");
1723 modprobe("ip6t_REJECT");
1724 #endif
1726 //shibby
1727 //if (nvram_match("imq_enable", "1")) {
1728 // char numdevs[10];
1729 // sprintf(numdevs, "numdevs=%d", nvram_get_int("imq_numdevs"));
1730 // modprobe("imq", numdevs );
1732 modprobe("imq");
1733 #ifdef LINUX26
1734 modprobe("xt_IMQ");
1735 #else
1736 modprobe("ipt_IMQ");
1737 #endif
1738 // }
1741 mangle_table();
1742 nat_table();
1743 filter_table();
1745 fclose(ipt_file);
1746 ipt_file = NULL;
1748 #ifdef TCONFIG_IPV6
1749 fclose(ip6t_file);
1750 ip6t_file = NULL;
1751 #endif
1753 #ifdef DEBUG_IPTFILE
1754 if (debug_only) {
1755 simple_unlock("firewall");
1756 simple_unlock("restrictions");
1757 return 0;
1759 #endif
1761 save_webmon();
1763 if (nvram_get_int("upnp_enable") & 3) {
1764 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1765 if (killall("miniupnpd", SIGUSR2) == 0) {
1766 f_wait_notexists("/etc/upnp/save", 5);
1770 notice_set("iptables", "");
1771 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1772 led(LED_DIAG, 0);
1773 notice_set("iptables", "");
1775 else {
1776 sprintf(s, "%s.error", ipt_fname);
1777 rename(ipt_fname, s);
1778 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1779 led(LED_DIAG, 1);
1783 -P INPUT DROP
1784 -F INPUT
1785 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1786 -A INPUT -i br0 -j ACCEPT
1788 -P FORWARD DROP
1789 -F FORWARD
1790 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1791 -A FORWARD -i br0 -j ACCEPT
1796 #ifdef TCONFIG_IPV6
1797 if (ipv6_enabled()) {
1798 notice_set("ip6tables", "");
1799 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1800 notice_set("ip6tables", "");
1802 else {
1803 sprintf(s, "%s.error", ip6t_fname);
1804 rename(ip6t_fname, s);
1805 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1806 led(LED_DIAG, 1);
1809 else {
1810 eval("ip6tables", "-F");
1811 eval("ip6tables", "-t", "mangle", "-F");
1813 #endif
1815 if (nvram_get_int("upnp_enable") & 3) {
1816 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1817 killall("miniupnpd", SIGUSR2);
1820 simple_unlock("restrictions");
1821 sched_restrictions();
1822 enable_ip_forward();
1823 #ifdef TCONFIG_IPV6
1824 if (ipv6_enabled()) enable_ip6_forward();
1825 #endif
1827 led(LED_DMZ, dmz_dst(NULL));
1829 #ifdef TCONFIG_IPV6
1830 modprobe_r("nf_conntrack_ipv6");
1831 modprobe_r("ip6t_LOG");
1832 modprobe_r("ip6t_REJECT");
1833 #endif
1834 #ifdef LINUX26
1835 modprobe_r("xt_layer7");
1836 modprobe_r("xt_recent");
1837 modprobe_r("xt_HL");
1838 modprobe_r("xt_length");
1839 modprobe_r("xt_web");
1840 modprobe_r("xt_webmon");
1841 modprobe_r("xt_dscp");
1842 #else
1843 modprobe_r("ipt_layer7");
1844 modprobe_r("ipt_recent");
1845 modprobe_r("ipt_TTL");
1846 modprobe_r("ipt_web");
1847 modprobe_r("ipt_webmon");
1848 modprobe_r("ipt_dscp");
1849 #endif
1850 modprobe_r("ipt_ipp2p");
1852 unlink("/var/webmon/domain");
1853 unlink("/var/webmon/search");
1855 #ifdef TCONFIG_OPENVPN
1856 run_vpn_firewall_scripts();
1857 #endif
1859 #ifdef TCONFIG_TINC
1860 run_tinc_firewall_script();
1861 #endif
1863 run_nvscript("script_fire", NULL, 1);
1865 #ifdef LINUX26
1866 allow_fastnat("firewall", can_enable_fastnat);
1867 try_enabling_fastnat();
1868 #endif
1869 simple_unlock("firewall");
1870 return 0;
1873 int stop_firewall(void)
1875 led(LED_DMZ, 0);
1876 return 0;
1879 #ifdef DEBUG_IPTFILE
1880 void create_test_iptfile(void)
1882 debug_only = 1;
1883 start_firewall();
1884 debug_only = 0;
1886 #endif