BW Limiter: Restore BW limiter broken.
[tomato.git] / release / src / router / rc / firewall.c
blob63ca01e5a67dbe6e809af1243ffae3e17821b186
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 #ifdef TCONFIG_VLAN
36 char lan1face[IFNAMSIZ + 1];
37 char lan2face[IFNAMSIZ + 1];
38 char lan3face[IFNAMSIZ + 1];
39 #endif
41 #ifdef TCONFIG_IPV6
42 char wan6face[IFNAMSIZ + 1];
43 #endif
44 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
45 #ifdef LINUX26
46 static int can_enable_fastnat;
47 #endif
49 #ifdef DEBUG_IPTFILE
50 static int debug_only = 0;
51 #endif
53 static int gateway_mode;
54 static int remotemanage;
55 static int wanup;
57 const char *chain_in_drop;
58 const char *chain_in_accept;
59 const char *chain_out_drop;
60 const char *chain_out_accept;
61 const char *chain_out_reject;
63 const char chain_wan_prerouting[] = "WANPREROUTING";
64 const char ipt_fname[] = "/etc/iptables";
65 FILE *ipt_file;
67 #ifdef TCONFIG_IPV6
68 const char ip6t_fname[] = "/etc/ip6tables";
69 FILE *ip6t_file;
71 // RFC-4890, sec. 4.3.1
72 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
73 #endif
75 static int is_sta(int idx, int unit, int subunit, void *param)
77 return (nvram_match(wl_nvname("mode", unit, subunit), "sta") && (nvram_match(wl_nvname("bss_enabled", unit, subunit), "1")));
81 struct {
82 } firewall_data;
85 // -----------------------------------------------------------------------------
87 #ifdef LINUX26
88 static const char *fastnat_run_dir = "/var/run/fastnat";
90 void allow_fastnat(const char *service, int allow)
92 char p[128];
94 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
95 if (allow) {
96 unlink(p);
98 else {
99 mkdir_if_none(fastnat_run_dir);
100 f_write_string(p, "", 0, 0);
104 static inline int fastnat_allowed(void)
106 DIR *dir;
107 struct dirent *dp;
108 int enabled;
110 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
112 if (enabled && (dir = opendir(fastnat_run_dir))) {
113 while ((dp = readdir(dir))) {
114 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
115 continue;
116 enabled = 0;
117 break;
119 closedir(dir);
122 return (enabled);
125 void try_enabling_fastnat(void)
127 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
128 fastnat_allowed() ? "1" : "0", 0, 0);
130 #endif
132 void enable_ip_forward(void)
135 ip_forward - BOOLEAN
136 0 - disabled (default)
137 not 0 - enabled
139 Forward Packets between interfaces.
141 This variable is special, its change resets all configuration
142 parameters to their default state (RFC1122 for hosts, RFC1812
143 for routers)
145 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
149 #ifdef TCONFIG_IPV6
150 void enable_ip6_forward(void)
152 if (ipv6_enabled()) {
153 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
154 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
156 else {
157 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "0", 0, 0);
158 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "0", 0, 0);
161 #endif
164 // -----------------------------------------------------------------------------
167 static int ip2cclass(char *ipaddr, char *new, int count)
169 int ip[4];
171 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
172 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
177 static int dmz_dst(char *s)
179 struct in_addr ia;
180 char *p;
181 int n;
183 if (nvram_get_int("dmz_enable") <= 0) return 0;
185 p = nvram_safe_get("dmz_ipaddr");
186 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
187 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
188 if (s) sprintf(s, "%s%d", lan_cclass, n);
189 return 1;
192 if (s) strcpy(s, inet_ntoa(ia));
193 return 1;
196 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
198 char *pre, *post;
200 pre = (name && *name) ? " for \"" : "";
201 post = (name && *name) ? "\"" : "";
203 syslog(LOG_WARNING, "firewall: "
204 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
205 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
208 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
209 int strict, const char *categ, const char *name)
211 char p[INET6_ADDRSTRLEN * 2];
212 int r = 0;
214 if ((s) && (*s) && (*dir))
216 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
217 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
218 r = IPT_V4;
220 #ifdef TCONFIG_IPV6
221 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
222 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
223 r = IPT_V6;
225 #endif
226 else {
227 snprintf(addr, maxlen, "-%c %s", dir[0], s);
228 if (sscanf(s, "%[^/]/", p)) {
229 #ifdef TCONFIG_IPV6
230 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
231 #else
232 r = host_addrtypes(p, IPT_V4);
233 #endif
237 else
239 *addr = 0;
240 r = (IPT_V4 | IPT_V6);
243 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
244 ipt_log_unresolved(s, categ, name,
245 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
248 return (r & af);
251 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
252 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
253 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
256 static void get_src(const char *nv, char *src)
258 char *p;
260 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
261 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
263 else {
264 *src = 0;
269 void ipt_write(const char *format, ...)
271 va_list args;
273 va_start(args, format);
274 vfprintf(ipt_file, format, args);
275 va_end(args);
278 void ip6t_write(const char *format, ...)
280 #ifdef TCONFIG_IPV6
281 va_list args;
283 va_start(args, format);
284 vfprintf(ip6t_file, format, args);
285 va_end(args);
286 #endif
289 // -----------------------------------------------------------------------------
291 int ipt_dscp(const char *v, char *opt)
293 unsigned int n;
295 if (*v == 0) {
296 *opt = 0;
297 return 0;
300 n = strtoul(v, NULL, 0);
301 if (n > 63) n = 63;
302 sprintf(opt, " -m dscp --dscp 0x%02X", n);
304 #ifdef LINUX26
305 modprobe("xt_dscp");
306 #else
307 modprobe("ipt_dscp");
308 #endif
309 return 1;
312 // -----------------------------------------------------------------------------
315 int ipt_ipp2p(const char *v, char *opt)
317 int n = atoi(v);
319 if (n == 0) {
320 *opt = 0;
321 return 0;
324 strcpy(opt, "-m ipp2p ");
325 if ((n & 0xFFF) == 0xFFF) {
326 strcat(opt, "--ipp2p");
328 else {
329 // x12
330 if (n & 0x0001) strcat(opt, "--apple ");
331 if (n & 0x0002) strcat(opt, "--ares ");
332 if (n & 0x0004) strcat(opt, "--bit ");
333 if (n & 0x0008) strcat(opt, "--dc ");
334 if (n & 0x0010) strcat(opt, "--edk ");
335 if (n & 0x0020) strcat(opt, "--gnu ");
336 if (n & 0x0040) strcat(opt, "--kazaa ");
337 if (n & 0x0080) strcat(opt, "--mute ");
338 if (n & 0x0100) strcat(opt, "--soul ");
339 if (n & 0x0200) strcat(opt, "--waste ");
340 if (n & 0x0400) strcat(opt, "--winmx ");
341 if (n & 0x0800) strcat(opt, "--xdcc ");
342 #ifdef LINUX26
343 if (n & 0x1000) strcat(opt, "--pp ");
344 if (n & 0x2000) strcat(opt, "--xunlei ");
345 #endif
348 modprobe("ipt_ipp2p");
349 return 1;
353 // -----------------------------------------------------------------------------
356 char **layer7_in;
358 // This L7 matches inbound traffic, caches the results, then the L7 outbound
359 // should read the cached result and set the appropriate marks -- zzz
360 void ipt_layer7_inbound(void)
362 int en, i;
363 char **p;
365 if (!layer7_in) return;
367 en = nvram_match("nf_l7in", "1");
368 if (en) {
369 ipt_write(":L7in - [0:0]\n");
370 for (i = 0; i < wanfaces.count; ++i) {
371 if (*(wanfaces.iface[i].name)) {
372 ipt_write("-A FORWARD -i %s -j L7in\n",
373 wanfaces.iface[i].name);
378 p = layer7_in;
379 while (*p) {
380 if (en) {
381 ipt_write("-A L7in %s -j RETURN\n", *p);
382 #ifdef LINUX26
383 can_enable_fastnat = 0;
384 #endif
386 free(*p);
387 ++p;
389 free(layer7_in);
390 layer7_in = NULL;
393 int ipt_layer7(const char *v, char *opt)
395 char s[128];
396 char *path;
398 *opt = 0;
399 if (*v == 0) return 0;
400 if (strlen(v) > 32) return -1;
402 path = "/etc/l7-extra";
403 sprintf(s, "%s/%s.pat", path, v);
404 if (!f_exists(s)) {
405 path = "/etc/l7-protocols";
406 sprintf(s, "%s/%s.pat", path, v);
407 if (!f_exists(s)) {
408 syslog(LOG_ERR, "L7 %s was not found", v);
409 return -1;
413 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
415 if (nvram_match("nf_l7in", "1")) {
416 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
417 if (layer7_in) {
418 char **p;
420 p = layer7_in;
421 while (*p) {
422 if (strcmp(*p, opt) == 0) return 1;
423 ++p;
425 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
429 #ifdef LINUX26
430 modprobe("xt_layer7");
431 #else
432 modprobe("ipt_layer7");
433 #endif
434 return 1;
437 // -----------------------------------------------------------------------------
439 static void ipt_account(void) {
440 struct in_addr ipaddr, netmask, network;
441 char lanN_ifname[] = "lanXX_ifname";
442 char lanN_ipaddr[] = "lanXX_ipaddr";
443 char lanN_netmask[] = "lanXX_netmask";
444 char lanN[] = "lanXX";
445 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
446 char br;
447 // If the IP Address changes, the below rule will cause things to choke, and blocking rules don't get applied
448 // As a workaround, flush the entire FORWARD chain
449 system("iptables -F FORWARD");
450 #ifdef TCONFIG_IPV6
451 system("ip6tables -F FORWARD");
452 #endif
453 for(br=0 ; br<=3 ; br++) {
454 char bridge[2] = "0";
455 if (br!=0)
456 bridge[0]+=br;
457 else
458 strcpy(bridge, "");
460 sprintf(lanN_ifname, "lan%s_ifname", bridge);
462 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
464 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
465 sprintf(lanN_netmask, "lan%s_netmask", bridge);
466 sprintf(lanN, "lan%s", bridge);
468 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
469 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
471 // bitwise AND of ip and netmask gives the network
472 network.s_addr = ipaddr.s_addr & netmask.s_addr;
474 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
476 //ipv4 only
477 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
482 // -----------------------------------------------------------------------------
484 static void save_webmon(void)
486 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
487 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
490 static void ipt_webmon()
492 int wmtype, clear, i;
493 char t[512];
494 char src[128];
495 char *p, *c;
496 int ok;
498 if (!nvram_get_int("log_wm")) return;
500 #ifdef LINUX26
501 can_enable_fastnat = 0;
502 #endif
503 wmtype = nvram_get_int("log_wmtype");
504 clear = nvram_get_int("log_wmclear");
506 ip46t_write(":monitor - [0:0]\n");
508 // include IPs
509 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
510 p = t;
511 do {
512 if ((c = strchr(p, ',')) != NULL) *c = 0;
514 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
515 #ifdef TCONFIG_IPV6
516 if (*wan6face && (ok & IPT_V6))
517 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
518 #endif
519 if (ok & IPT_V4) {
520 for (i = 0; i < wanfaces.count; ++i) {
521 if (*(wanfaces.iface[i].name)) {
522 ipt_write("-A FORWARD -o %s %s -j monitor\n",
523 wanfaces.iface[i].name, src);
529 if (!c) break;
530 p = c + 1;
531 } while (*p);
533 // exclude IPs
534 if (wmtype == 2) {
535 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
536 p = t;
537 do {
538 if ((c = strchr(p, ',')) != NULL) *c = 0;
539 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
540 if (*src)
541 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
543 if (!c) break;
544 p = c + 1;
545 } while (*p);
548 ip46t_write(
549 "-A monitor -p tcp -m webmon "
550 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
551 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
552 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
553 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
555 #ifdef LINUX26
556 modprobe("xt_webmon");
557 #else
558 modprobe("ipt_webmon");
559 #endif
564 // -----------------------------------------------------------------------------
565 // MANGLE
566 // -----------------------------------------------------------------------------
568 static void mangle_table(void)
570 int ttl;
571 char *p, *wanface;
573 ip46t_write(
574 "*mangle\n"
575 ":PREROUTING ACCEPT [0:0]\n"
576 ":OUTPUT ACCEPT [0:0]\n");
578 if (wanup) {
580 ipt_qos();
581 //1 for mangle
582 ipt_qoslimit(1);
584 p = nvram_safe_get("nf_ttl");
585 if (strncmp(p, "c:", 2) == 0) {
586 p += 2;
587 ttl = atoi(p);
588 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
590 else if ((ttl = atoi(p)) != 0) {
591 if (ttl > 0) {
592 p = "inc";
594 else {
595 ttl = -ttl;
596 p = "dec";
598 if (ttl > 255) p = NULL;
600 else p = NULL;
602 if (p) {
603 #ifdef LINUX26
604 modprobe("xt_HL");
605 #else
606 modprobe("ipt_TTL");
607 #endif
608 // set TTL on primary WAN iface only
609 wanface = wanfaces.iface[0].name;
610 ipt_write(
611 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
612 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
613 wanface, p, ttl,
614 wanface, p, ttl);
615 #ifdef TCONFIG_IPV6
616 // FIXME: IPv6 HL should be configurable separately from TTL.
617 // disable it until GUI setting is implemented.
618 #if 0
619 ip6t_write(
620 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
621 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
622 wan6face, p, ttl,
623 wan6face, p, ttl);
624 #endif
625 #endif
629 ip46t_write("COMMIT\n");
632 // -----------------------------------------------------------------------------
633 // NAT
634 // -----------------------------------------------------------------------------
636 static void nat_table(void)
638 char lanaddr[32];
639 char lanmask[32];
640 #ifdef TCONFIG_VLAN
641 char lan1addr[32];
642 char lan1mask[32];
643 char lan2addr[32];
644 char lan2mask[32];
645 char lan3addr[32];
646 char lan3mask[32];
647 #endif
648 char dst[64];
649 char src[64];
650 char t[512];
651 char *p, *c;
652 int i;
654 ipt_write("*nat\n"
655 ":PREROUTING ACCEPT [0:0]\n"
656 ":POSTROUTING ACCEPT [0:0]\n"
657 ":OUTPUT ACCEPT [0:0]\n"
658 ":%s - [0:0]\n",
659 chain_wan_prerouting);
661 //2 for nat
662 ipt_qoslimit(2);
664 if (gateway_mode) {
665 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
666 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
667 #ifdef TCONFIG_VLAN
668 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
669 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
670 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
671 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
672 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
673 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
674 #endif
676 for (i = 0; i < wanfaces.count; ++i) {
677 if (*(wanfaces.iface[i].name)) {
678 // chain_wan_prerouting
679 if (wanup) {
680 ipt_write("-A PREROUTING -d %s -j %s\n",
681 wanfaces.iface[i].ip, chain_wan_prerouting);
684 // Drop incoming packets which destination IP address is to our LAN side directly
685 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
686 wanfaces.iface[i].name,
687 lanaddr, lanmask); // note: ipt will correct lanaddr
688 #ifdef TCONFIG_VLAN
689 if(strcmp(lan1addr,"")!=0)
690 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
691 wanfaces.iface[i].name,
692 lan1addr, lan1mask);
693 if(strcmp(lan2addr,"")!=0)
694 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
695 wanfaces.iface[i].name,
696 lan2addr, lan2mask);
697 if(strcmp(lan3addr,"")!=0)
698 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
699 wanfaces.iface[i].name,
700 lan3addr, lan3mask);
701 #endif
705 if (wanup) {
706 if (nvram_match("dns_intcpt", "1")) {
707 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
708 lanaddr, lanmask,
709 lanaddr, lanmask,
710 lanaddr);
711 #ifdef TCONFIG_VLAN
712 if(strcmp(lan1addr,"")!=0)
713 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
714 lan1addr, lan1mask,
715 lan1addr, lan1mask,
716 lan1addr);
717 if(strcmp(lan2addr,"")!=0)
718 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
719 lan2addr, lan2mask,
720 lan2addr, lan2mask,
721 lan2addr);
722 if(strcmp(lan3addr,"")!=0)
723 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
724 lan3addr, lan3mask,
725 lan3addr, lan3mask,
726 lan3addr);
727 #endif
730 // ICMP packets are always redirected to INPUT chains
731 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
734 //force remote access to router if DMZ is enabled - shibby
735 if( (nvram_match("dmz_enable", "1")) && (nvram_match("dmz_ra", "1")) ) {
736 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
737 p = t;
738 do {
739 if ((c = strchr(p, ',')) != NULL) *c = 0;
740 ipt_source(p, src, "ra", NULL);
742 if (remotemanage) {
743 ipt_write("-A %s -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
744 chain_wan_prerouting, src, nvram_safe_get("http_wanport"), lanaddr, web_lanport);
747 if (nvram_get_int("sshd_remote")) {
748 ipt_write("-A %s %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
749 chain_wan_prerouting, src, nvram_safe_get("sshd_rport"), lanaddr, nvram_safe_get("sshd_port"));
752 if (!c) break;
753 p = c + 1;
754 } while (*p);
758 ipt_forward(IPT_TABLE_NAT);
759 ipt_triggered(IPT_TABLE_NAT);
762 if (nvram_get_int("upnp_enable") & 3) {
763 ipt_write(":upnp - [0:0]\n");
765 for (i = 0; i < wanfaces.count; ++i) {
766 if (*(wanfaces.iface[i].name)) {
767 if (wanup) {
768 // ! for loopback (all) to work
769 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
771 else {
772 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
778 if (wanup) {
779 if (dmz_dst(dst)) {
780 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
781 p = t;
782 do {
783 if ((c = strchr(p, ',')) != NULL) *c = 0;
784 if (ipt_source_strict(p, src, "dmz", NULL))
785 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
786 if (!c) break;
787 p = c + 1;
788 } while (*p);
792 p = "";
793 #ifdef TCONFIG_IPV6
794 switch (get_ipv6_service()) {
795 case IPV6_6IN4:
796 // avoid NATing proto-41 packets when using 6in4 tunnel
797 p = "-p ! 41";
798 break;
800 #endif
802 for (i = 0; i < wanfaces.count; ++i) {
803 if (*(wanfaces.iface[i].name)) {
804 if ((!wanup) || (nvram_get_int("ne_snat") != 1))
805 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
806 else
807 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
811 char *modem_ipaddr;
812 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
813 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0")
814 && (!foreach_wif(1, NULL, is_sta)) )
815 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
817 switch (nvram_get_int("nf_loopback")) {
818 case 1: // 1 = forwarded-only
819 case 2: // 2 = disable
820 break;
821 default: // 0 = all (same as block_loopback=0)
822 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
823 lanface,
824 lanaddr, lanmask,
825 lanaddr, lanmask,
826 lanaddr);
827 #ifdef TCONFIG_VLAN
828 if (strcmp(lan1face,"")!=0)
829 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
830 lan1face,
831 lan1addr, lan1mask,
832 lan1addr, lan1mask,
833 lan1addr);
834 if (strcmp(lan2face,"")!=0)
835 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
836 lan2face,
837 lan2addr, lan2mask,
838 lan2addr, lan2mask,
839 lan2addr);
840 if (strcmp(lan3face,"")!=0)
841 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
842 lan3face,
843 lan3addr, lan3mask,
844 lan3addr, lan3mask,
845 lan3addr);
846 #endif
847 break;
850 ipt_write("COMMIT\n");
853 // -----------------------------------------------------------------------------
854 // FILTER
855 // -----------------------------------------------------------------------------
857 static void filter_input(void)
859 char s[64];
860 char t[512];
861 char *en;
862 char *sec;
863 char *hit;
864 int n;
865 char *p, *c;
867 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
868 for (n = 0; n < wanfaces.count; ++n) {
869 if (*(wanfaces.iface[n].name)) {
870 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
871 #ifdef TCONFIG_VLAN
872 if (strcmp(lan1face,"")!=0)
873 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
874 if (strcmp(lan2face,"")!=0)
875 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
876 if (strcmp(lan3face,"")!=0)
877 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
878 #endif
883 ipt_write(
884 "-A INPUT -m state --state INVALID -j DROP\n"
885 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
887 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
888 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
890 ? what if the user uses the start button in GUI ?
891 if (nvram_get_int("telnetd_eas"))
892 if (nvram_get_int("sshd_eas"))
894 #ifdef LINUX26
895 modprobe("xt_recent");
896 #else
897 modprobe("ipt_recent");
898 #endif
900 ipt_write(
901 "-N shlimit\n"
902 "-A shlimit -m recent --set --name shlimit\n"
903 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
904 atoi(hit) + 1, sec, chain_in_drop);
906 if (n & 1) {
907 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
908 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
909 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
912 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
915 #ifdef TCONFIG_FTP
916 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
917 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
918 #ifdef LINUX26
919 modprobe("xt_recent");
920 #else
921 modprobe("ipt_recent");
922 #endif
924 ipt_write(
925 "-N ftplimit\n"
926 "-A ftplimit -m recent --set --name ftp\n"
927 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
928 atoi(hit) + 1, sec, chain_in_drop);
929 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
931 #endif
933 ipt_write(
934 "-A INPUT -i lo -j ACCEPT\n"
935 "-A INPUT -i %s -j ACCEPT\n",
936 lanface);
938 #ifdef TCONFIG_VLAN
939 if (strcmp(lan1face,"")!=0)
940 ipt_write(
941 "-A INPUT -i %s -j ACCEPT\n",
942 lan1face);
943 if (strcmp(lan2face,"")!=0)
944 ipt_write(
945 "-A INPUT -i %s -j ACCEPT\n",
946 lan2face);
947 if (strcmp(lan3face,"")!=0)
948 ipt_write(
949 "-A INPUT -i %s -j ACCEPT\n",
950 lan3face);
951 #endif
953 #ifdef TCONFIG_IPV6
954 n = get_ipv6_service();
955 switch (n) {
956 case IPV6_ANYCAST_6TO4:
957 case IPV6_6IN4:
958 // Accept ICMP requests from the remote tunnel endpoint
959 if (n == IPV6_ANYCAST_6TO4)
960 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
961 else
962 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
963 if (*s && strcmp(s, "0.0.0.0") != 0)
964 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
965 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
966 break;
968 #endif
970 // ICMP request from WAN interface
971 if (nvram_match("block_wan", "0")) {
972 if (nvram_match("block_wan_limit", "0")) {
973 // allow ICMP packets to be received
974 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
975 // allow udp traceroute packets
976 ipt_write("-A INPUT -p udp --dport 33434:33534 -j %s\n", chain_in_accept);
977 } else {
978 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
979 ipt_write("-A INPUT -p icmp -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_icmp"), chain_in_accept);
980 // allow udp traceroute packets, but restrict the flow to avoid ping flood attacks
981 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);
985 /* Accept incoming packets from broken dhcp servers, which are sending replies
986 * from addresses other than used for query. This could lead to a lower level
987 * of security, so allow to disable it via nvram variable.
989 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
990 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
993 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
994 p = t;
995 do {
996 if ((c = strchr(p, ',')) != NULL) *c = 0;
998 if (ipt_source(p, s, "remote management", NULL)) {
1000 if (remotemanage) {
1001 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1002 s, nvram_safe_get("http_wanport"), chain_in_accept);
1005 if (nvram_get_int("sshd_remote")) {
1006 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1007 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1011 #ifdef TCONFIG_NGINX //!!Victek - Web Server
1012 if (nvram_match("nginx_enable", "1")) {
1013 ipt_write("-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "nginx_port" ));
1015 #endif
1017 if (!c) break;
1018 p = c + 1;
1019 } while (*p);
1021 #ifdef TCONFIG_FTP // !!TB - FTP Server
1022 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1023 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1024 p = t;
1025 do {
1026 if ((c = strchr(p, ',')) != NULL) *c = 0;
1027 if (ipt_source(p, s, "ftp", "remote access")) {
1028 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1029 s, nvram_safe_get("ftp_port"), chain_in_accept);
1031 if (!c) break;
1032 p = c + 1;
1033 } while (*p);
1035 #endif
1037 #ifdef TCONFIG_SNMP
1038 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
1040 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
1041 p = t;
1042 do {
1043 if ((c = strchr(p, ',')) != NULL) *c = 0;
1045 if (ipt_source(p, s, "snmp", "remote")) {
1046 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
1047 s, nvram_safe_get("snmp_port"), chain_in_accept);
1050 if (!c) break;
1051 p = c + 1;
1052 } while (*p);
1054 #endif
1056 // IGMP query from WAN interface
1057 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1058 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
1059 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
1062 // Routing protocol, RIP, accept
1063 if (nvram_invmatch("dr_wan_rx", "0")) {
1064 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
1067 // if logging
1068 if (*chain_in_drop == 'l') {
1069 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1072 // default policy: DROP
1075 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
1076 static void clampmss(void)
1078 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1079 #ifdef TCONFIG_IPV6
1080 switch (get_ipv6_service()) {
1081 case IPV6_ANYCAST_6TO4:
1082 case IPV6_6IN4:
1083 ip6t_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1084 break;
1086 #endif
1089 static void filter_forward(void)
1091 char dst[64];
1092 char src[64];
1093 char t[512];
1094 char *p, *c;
1095 int i;
1097 if (nvram_match("cstats_enable", "1")) {
1098 ipt_account();
1101 #ifdef TCONFIG_IPV6
1102 ip6t_write(
1103 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1104 #endif
1106 ip46t_write(
1107 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1108 lanface, lanface);
1109 #ifdef TCONFIG_VLAN
1110 if (strcmp(lan1face,"")!=0)
1111 ip46t_write(
1112 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1113 lan1face, lan1face);
1114 if (strcmp(lan2face,"")!=0)
1115 ip46t_write(
1116 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1117 lan2face, lan2face);
1118 if (strcmp(lan3face,"")!=0)
1119 ip46t_write(
1120 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1121 lan3face, lan3face);
1123 char lanAccess[17] = "0000000000000000";
1124 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1125 char *nv, *nvp, *b;
1126 int n;
1127 nvp = nv = strdup(nvram_safe_get("lan_access"));
1128 if (nv) {
1129 while ((b = strsep(&nvp, ">")) != NULL) {
1131 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1133 1 = enabled
1134 0 = src bridge
1135 1.2.3.4 = src addr
1136 1 = dst bridge
1137 5.6.7.8 = dst addr
1138 desc = desc
1140 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1141 if (*d != '1')
1142 continue;
1143 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1144 continue;
1145 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1146 continue;
1148 //ipv4 only
1149 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1150 "br",
1151 sbr,
1152 "br",
1153 dbr,
1154 src,
1155 dst);
1157 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1158 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1162 free(nv);
1163 #endif
1165 ip46t_write(
1166 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1168 // clamp tcp mss to pmtu
1169 clampmss();
1171 if (wanup) {
1172 ipt_restrictions();
1174 ipt_layer7_inbound();
1177 ipt_webmon();
1179 ip46t_write(
1180 ":wanin - [0:0]\n"
1181 ":wanout - [0:0]\n"
1182 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1184 #ifdef TCONFIG_VLAN
1185 char lanN_ifname[] = "lanXX_ifname";
1186 char br;
1187 for(br=0 ; br<=3 ; br++) {
1188 char bridge[2] = "0";
1189 if (br!=0)
1190 bridge[0]+=br;
1191 else
1192 strcpy(bridge, "");
1194 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1195 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1196 char lanN_ifname2[] = "lanXX_ifname";
1197 char br2;
1198 for(br2=0 ; br2<=3 ; br2++) {
1199 if (br==br2) continue;
1201 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1203 char bridge2[2] = "0";
1204 if (br2!=0)
1205 bridge2[0]+=br2;
1206 else
1207 strcpy(bridge2, "");
1209 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1210 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1211 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1212 nvram_safe_get(lanN_ifname),
1213 nvram_safe_get(lanN_ifname2));
1216 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1219 #endif
1221 #ifdef TCONFIG_PPTPD
1222 //Add for pptp server
1223 if (nvram_match("pptpd_enable", "1")) {
1224 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1225 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1227 #endif
1229 #ifdef TCONFIG_IPV6
1230 // Filter out invalid WAN->WAN connections
1231 if (*wan6face)
1232 // 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
1233 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1235 #ifdef LINUX26
1236 modprobe("xt_length");
1237 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1238 #endif
1240 // ICMPv6 rules
1241 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1242 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1245 //IPv6
1246 if (*wan6face) {
1247 ip6t_write(
1248 "-A FORWARD -i %s -j wanin\n" // generic from wan
1249 "-A FORWARD -o %s -j wanout\n", // generic to wan
1250 wan6face, wan6face);
1252 #endif
1254 //IPv4
1255 for (i = 0; i < wanfaces.count; ++i) {
1256 if (*(wanfaces.iface[i].name)) {
1257 ipt_write(
1258 "-A FORWARD -i %s -j wanin\n" // generic from wan
1259 "-A FORWARD -o %s -j wanout\n", // generic to wan
1260 wanfaces.iface[i].name, wanfaces.iface[i].name);
1264 #ifdef TCONFIG_VLAN
1265 for(br=0 ; br<=3 ; br++) {
1266 char bridge[2] = "0";
1267 if (br!=0)
1268 bridge[0]+=br;
1269 else
1270 strcpy(bridge, "");
1272 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1273 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1274 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1277 #else
1278 ipt_write("-A FORWARD -i %s -j %s\n", lanface, chain_out_accept);
1279 #endif
1282 #ifdef TCONFIG_IPV6
1283 //IPv6 forward LAN->WAN accept
1284 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1285 #ifdef TCONFIG_VLAN
1286 if (strcmp(lan1face,"")!=0)
1287 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1288 if (strcmp(lan2face,"")!=0)
1289 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1290 if (strcmp(lan3face,"")!=0)
1291 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1292 #endif
1293 #endif
1295 // IPv4 only
1296 if (nvram_get_int("upnp_enable") & 3) {
1297 ipt_write(":upnp - [0:0]\n");
1298 for (i = 0; i < wanfaces.count; ++i) {
1299 if (*(wanfaces.iface[i].name)) {
1300 ipt_write("-A FORWARD -i %s -j upnp\n",
1301 wanfaces.iface[i].name);
1306 if (wanup) {
1307 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1308 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1310 ipt_triggered(IPT_TABLE_FILTER);
1311 ipt_forward(IPT_TABLE_FILTER);
1312 #ifdef TCONFIG_IPV6
1313 ip6t_forward();
1314 #endif
1316 if (dmz_dst(dst)) {
1317 #ifdef TCONFIG_VLAN
1318 char dmz_ifname[IFNAMSIZ+1];
1319 strlcpy(dmz_ifname, nvram_safe_get("dmz_ifname"), sizeof(dmz_ifname));
1320 if(strcmp(dmz_ifname, "") == 0)
1321 strlcpy(dmz_ifname, lanface, sizeof(lanface));
1322 #endif
1323 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1324 p = t;
1325 do {
1326 if ((c = strchr(p, ',')) != NULL) *c = 0;
1327 if (ipt_source_strict(p, src, "dmz", NULL))
1328 #ifdef TCONFIG_VLAN
1329 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", dmz_ifname, src, dst, chain_in_accept);
1330 #else
1331 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1332 #endif
1333 if (!c) break;
1334 p = c + 1;
1335 } while (*p);
1339 // default policy: DROP
1342 static void filter_log(void)
1344 int n;
1345 char limit[128];
1347 n = nvram_get_int("log_limit");
1348 if ((n >= 1) && (n <= 9999)) {
1349 sprintf(limit, "-m limit --limit %d/m", n);
1351 else {
1352 limit[0] = 0;
1355 #ifdef TCONFIG_IPV6
1356 modprobe("ip6t_LOG");
1357 #endif
1358 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1359 ip46t_write(
1360 ":logdrop - [0:0]\n"
1361 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1362 #ifdef LINUX26
1363 " --log-macdecode"
1364 #endif
1365 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1366 "-A logdrop -j DROP\n"
1367 ":logreject - [0:0]\n"
1368 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1369 #ifdef LINUX26
1370 " --log-macdecode"
1371 #endif
1372 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1373 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1374 limit, limit);
1376 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1377 ip46t_write(
1378 ":logaccept - [0:0]\n"
1379 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1380 #ifdef LINUX26
1381 " --log-macdecode"
1382 #endif
1383 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1384 "-A logaccept -j ACCEPT\n",
1385 limit);
1389 #ifdef TCONFIG_IPV6
1390 static void filter6_input(void)
1392 char s[128];
1393 char t[512];
1394 char *en;
1395 char *sec;
1396 char *hit;
1397 int n;
1398 char *p, *c;
1400 // RFC-4890, sec. 4.4.1
1401 const int allowed_local_icmpv6[] =
1402 { 130, 131, 132, 133, 134, 135, 136,
1403 141, 142, 143,
1404 148, 149, 151, 152, 153 };
1406 ip6t_write(
1407 "-A INPUT -m rt --rt-type 0 -j %s\n"
1408 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1409 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1410 chain_in_drop);
1412 #ifdef LINUX26
1413 modprobe("xt_length");
1414 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1415 #endif
1417 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1418 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1419 #ifdef LINUX26
1420 modprobe("xt_recent");
1421 #else
1422 modprobe("ipt_recent");
1423 #endif
1425 ip6t_write(
1426 "-N shlimit\n"
1427 "-A shlimit -m recent --set --name shlimit\n"
1428 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1429 atoi(hit) + 1, sec, chain_in_drop);
1431 if (n & 1) {
1432 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1433 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1434 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1437 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"));
1440 #ifdef TCONFIG_FTP
1441 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1442 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1443 #ifdef LINUX26
1444 modprobe("xt_recent");
1445 #else
1446 modprobe("ipt_recent");
1447 #endif
1449 ip6t_write(
1450 "-N ftplimit\n"
1451 "-A ftplimit -m recent --set --name ftp\n"
1452 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1453 atoi(hit) + 1, sec, chain_in_drop);
1454 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1456 #endif // TCONFIG_FTP
1458 ip6t_write(
1459 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1460 "-A INPUT -i lo -j ACCEPT\n",
1461 lanface );
1463 switch (get_ipv6_service()) {
1464 case IPV6_ANYCAST_6TO4:
1465 case IPV6_NATIVE_DHCP:
1466 // allow responses from the dhcpv6 server
1467 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1468 break;
1471 // ICMPv6 rules
1472 const int allowed_icmpv6[6] = { 1, 2, 3, 4, 128, 129 };
1473 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1474 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1476 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1477 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1480 // Remote Managment
1481 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1482 p = t;
1483 do {
1484 if ((c = strchr(p, ',')) != NULL) *c = 0;
1486 if (ip6t_source(p, s, "remote management", NULL)) {
1488 if (remotemanage) {
1489 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1490 s, nvram_safe_get("http_wanport"), chain_in_accept);
1493 if (nvram_get_int("sshd_remote")) {
1494 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1495 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1499 if (!c) break;
1500 p = c + 1;
1501 } while (*p);
1503 #ifdef TCONFIG_FTP
1504 // FTP server
1505 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1506 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1507 p = t;
1508 do {
1509 if ((c = strchr(p, ',')) != NULL) *c = 0;
1510 if (ip6t_source(p, s, "ftp", "remote access")) {
1511 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1512 s, nvram_safe_get("ftp_port"), chain_in_accept);
1514 if (!c) break;
1515 p = c + 1;
1516 } while (*p);
1518 #endif
1520 // if logging
1521 if (*chain_in_drop == 'l') {
1522 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1525 // default policy: DROP
1528 #endif
1530 static void filter_table(void)
1532 ip46t_write(
1533 "*filter\n"
1534 ":INPUT DROP [0:0]\n"
1535 ":OUTPUT ACCEPT [0:0]\n"
1538 filter_log();
1540 filter_input();
1541 #ifdef TCONFIG_IPV6
1542 filter6_input();
1543 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1544 #endif
1546 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1547 ip46t_write(":FORWARD DROP [0:0]\n");
1548 filter_forward();
1550 else {
1551 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1552 clampmss();
1554 ip46t_write("COMMIT\n");
1557 // -----------------------------------------------------------------------------
1559 int start_firewall(void)
1561 DIR *dir;
1562 struct dirent *dirent;
1563 char s[256];
1564 char *c, *wanface;
1565 int n;
1566 int wanproto;
1567 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1568 #ifdef TCONFIG_IPV6
1569 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1570 #endif
1572 simple_lock("firewall");
1573 simple_lock("restrictions");
1575 wanproto = get_wan_proto();
1576 wanup = check_wanup();
1578 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1580 /* NAT performance tweaks
1581 * These values can be overriden later if needed via firewall script
1583 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1584 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1585 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1586 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1587 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1588 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1589 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1590 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1591 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1592 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1593 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1594 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1596 /* DoS-related tweaks */
1597 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1598 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1599 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1601 wanproto = get_wan_proto();
1602 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1604 #ifdef TCONFIG_EMF
1605 /* Force IGMPv2 due EMF limitations */
1606 if (nvram_get_int("emf_enable")) {
1607 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1608 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1610 #endif
1612 n = nvram_get_int("log_in");
1613 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1614 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1616 n = nvram_get_int("log_out");
1617 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1618 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1619 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1621 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1623 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1624 #ifdef TCONFIG_VLAN
1625 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1626 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1627 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1628 #endif
1630 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1631 wanface = wanfaces.iface[0].name;
1632 #ifdef TCONFIG_IPV6
1633 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1634 #endif
1636 #ifdef LINUX26
1637 can_enable_fastnat = 1;
1638 #endif
1640 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1641 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1642 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1643 #ifdef TCONFIG_VLAN
1645 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1646 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1647 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1649 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1650 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1651 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1653 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1654 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1655 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1657 #endif
1660 block obviously spoofed IP addresses
1662 rp_filter - BOOLEAN
1663 1 - do source validation by reversed path, as specified in RFC1812
1664 Recommended option for single homed hosts and stub network
1665 routers. Could cause troubles for complicated (not loop free)
1666 networks running a slow unreliable protocol (sort of RIP),
1667 or using static routes.
1668 0 - No source validation.
1670 c = nvram_get("wan_ifname");
1671 /* mcast needs rp filter to be turned off only for non default iface */
1672 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1674 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1675 while ((dirent = readdir(dir)) != NULL) {
1676 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1677 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1679 closedir(dir);
1682 remotemanage = 0;
1683 gateway_mode = !nvram_match("wk_mode", "router");
1684 if (gateway_mode) {
1685 /* Remote management */
1686 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1687 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1689 if (nvram_match("remote_mgt_https", "1")) {
1690 web_lanport = nvram_get_int("https_lanport");
1691 if (web_lanport <= 0) web_lanport = 443;
1692 } else {
1693 web_lanport = nvram_get_int("http_lanport");
1694 if (web_lanport <= 0) web_lanport = 80;
1698 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1699 notice_set("iptables", "Unable to create iptables restore file");
1700 simple_unlock("firewall");
1701 return 0;
1704 #ifdef TCONFIG_IPV6
1705 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1706 notice_set("ip6tables", "Unable to create ip6tables restore file");
1707 simple_unlock("firewall");
1708 return 0;
1710 modprobe("nf_conntrack_ipv6");
1711 modprobe("ip6t_REJECT");
1712 #endif
1713 /*Start xt_IMQ and imq */
1714 modprobe("imq");
1715 #ifdef LINUX26
1716 modprobe("xt_IMQ");
1717 #else
1718 modprobe("ipt_IMQ");
1719 #endif
1721 mangle_table();
1722 nat_table();
1723 filter_table();
1725 fclose(ipt_file);
1726 ipt_file = NULL;
1728 #ifdef TCONFIG_IPV6
1729 fclose(ip6t_file);
1730 ip6t_file = NULL;
1731 #endif
1733 #ifdef DEBUG_IPTFILE
1734 if (debug_only) {
1735 simple_unlock("firewall");
1736 simple_unlock("restrictions");
1737 return 0;
1739 #endif
1741 save_webmon();
1743 if (nvram_get_int("upnp_enable") & 3) {
1744 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1745 if (killall("miniupnpd", SIGUSR2) == 0) {
1746 f_wait_notexists("/etc/upnp/save", 5);
1750 notice_set("iptables", "");
1751 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1752 led(LED_DIAG, 0);
1753 notice_set("iptables", "");
1755 else {
1756 sprintf(s, "%s.error", ipt_fname);
1757 rename(ipt_fname, s);
1758 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1759 led(LED_DIAG, 1);
1763 -P INPUT DROP
1764 -F INPUT
1765 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1766 -A INPUT -i br0 -j ACCEPT
1768 -P FORWARD DROP
1769 -F FORWARD
1770 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1771 -A FORWARD -i br0 -j ACCEPT
1776 #ifdef TCONFIG_IPV6
1777 if (ipv6_enabled()) {
1778 notice_set("ip6tables", "");
1779 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1780 notice_set("ip6tables", "");
1782 else {
1783 sprintf(s, "%s.error", ip6t_fname);
1784 rename(ip6t_fname, s);
1785 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1786 led(LED_DIAG, 1);
1789 else {
1790 eval("ip6tables", "-F");
1791 eval("ip6tables", "-t", "mangle", "-F");
1793 #endif
1795 if (nvram_get_int("upnp_enable") & 3) {
1796 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1797 killall("miniupnpd", SIGUSR2);
1800 simple_unlock("restrictions");
1801 sched_restrictions();
1802 enable_ip_forward();
1803 #ifdef TCONFIG_IPV6
1804 if (ipv6_enabled()) enable_ip6_forward();
1805 #endif
1807 led(LED_DMZ, dmz_dst(NULL));
1809 #ifdef TCONFIG_IPV6
1810 modprobe_r("nf_conntrack_ipv6");
1811 modprobe_r("ip6t_LOG");
1812 modprobe_r("ip6t_REJECT");
1813 #endif
1814 #ifdef LINUX26
1815 modprobe_r("xt_layer7");
1816 modprobe_r("xt_recent");
1817 modprobe_r("xt_HL");
1818 modprobe_r("xt_length");
1819 modprobe_r("xt_web");
1820 modprobe_r("xt_webmon");
1821 modprobe_r("xt_dscp");
1822 #else
1823 modprobe_r("ipt_layer7");
1824 modprobe_r("ipt_recent");
1825 modprobe_r("ipt_TTL");
1826 modprobe_r("ipt_web");
1827 modprobe_r("ipt_webmon");
1828 modprobe_r("ipt_dscp");
1829 #endif
1830 modprobe_r("ipt_ipp2p");
1832 unlink("/var/webmon/domain");
1833 unlink("/var/webmon/search");
1835 #ifdef TCONFIG_OPENVPN
1836 run_vpn_firewall_scripts();
1837 #endif
1838 run_nvscript("script_fire", NULL, 1);
1840 start_arpbind();
1842 #ifdef LINUX26
1843 allow_fastnat("firewall", can_enable_fastnat);
1844 try_enabling_fastnat();
1845 #endif
1847 simple_unlock("firewall");
1848 return 0;
1851 int stop_firewall(void)
1853 led(LED_DMZ, 0);
1854 return 0;
1857 #ifdef DEBUG_IPTFILE
1858 void create_test_iptfile(void)
1860 debug_only = 1;
1861 start_firewall();
1862 debug_only = 0;
1864 #endif