Reinstate dropbear 0.54 update
[tomato.git] / release / src / router / rc / firewall.c
blob52e5971a461dd264ce03dedb78a9661be25592e2
1 /*
3 Copyright 2003-2005, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Modified for Tomato Firmware
22 Portions, Copyright (C) 2006-2009 Jonathan Zarate
26 #include "rc.h"
28 #include <stdarg.h>
29 #include <arpa/inet.h>
30 #include <dirent.h>
32 wanface_list_t wanfaces;
33 char lanface[IFNAMSIZ + 1];
34 #ifdef TCONFIG_VLAN
35 char lan1face[IFNAMSIZ + 1];
36 char lan2face[IFNAMSIZ + 1];
37 char lan3face[IFNAMSIZ + 1];
38 #endif
40 #ifdef TCONFIG_IPV6
41 char wan6face[IFNAMSIZ + 1];
42 #endif
43 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
44 #ifdef LINUX26
45 static int can_enable_fastnat;
46 #endif
48 #ifdef DEBUG_IPTFILE
49 static int debug_only = 0;
50 #endif
52 static int gateway_mode;
53 static int remotemanage;
54 static int wanup;
56 const char *chain_in_drop;
57 const char *chain_in_accept;
58 const char *chain_out_drop;
59 const char *chain_out_accept;
60 const char *chain_out_reject;
62 const char chain_wan_prerouting[] = "WANPREROUTING";
63 const char ipt_fname[] = "/etc/iptables";
64 FILE *ipt_file;
66 #ifdef TCONFIG_IPV6
67 const char ip6t_fname[] = "/etc/ip6tables";
68 FILE *ip6t_file;
70 // RFC-4890, sec. 4.3.1
71 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
72 #endif
76 struct {
77 } firewall_data;
80 // -----------------------------------------------------------------------------
82 #ifdef LINUX26
83 static const char *fastnat_run_dir = "/var/run/fastnat";
85 void allow_fastnat(const char *service, int allow)
87 char p[128];
89 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
90 if (allow) {
91 unlink(p);
93 else {
94 mkdir_if_none(fastnat_run_dir);
95 f_write_string(p, "", 0, 0);
99 static inline int fastnat_allowed(void)
101 DIR *dir;
102 struct dirent *dp;
103 int enabled;
105 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
107 if (enabled && (dir = opendir(fastnat_run_dir))) {
108 while ((dp = readdir(dir))) {
109 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
110 continue;
111 enabled = 0;
112 break;
114 closedir(dir);
117 return (enabled);
120 void try_enabling_fastnat(void)
122 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
123 fastnat_allowed() ? "1" : "0", 0, 0);
125 #endif
127 void enable_ip_forward(void)
130 ip_forward - BOOLEAN
131 0 - disabled (default)
132 not 0 - enabled
134 Forward Packets between interfaces.
136 This variable is special, its change resets all configuration
137 parameters to their default state (RFC1122 for hosts, RFC1812
138 for routers)
140 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
142 #ifdef TCONFIG_IPV6
143 if (ipv6_enabled()) {
144 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
145 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
147 #endif
151 // -----------------------------------------------------------------------------
154 static int ip2cclass(char *ipaddr, char *new, int count)
156 int ip[4];
158 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
159 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
164 static int dmz_dst(char *s)
166 struct in_addr ia;
167 char *p;
168 int n;
170 if (nvram_get_int("dmz_enable") <= 0) return 0;
172 p = nvram_safe_get("dmz_ipaddr");
173 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
174 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
175 if (s) sprintf(s, "%s%d", lan_cclass, n);
176 return 1;
179 if (s) strcpy(s, inet_ntoa(ia));
180 return 1;
183 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
185 char *pre, *post;
187 pre = (name && *name) ? " for \"" : "";
188 post = (name && *name) ? "\"" : "";
190 syslog(LOG_WARNING, "firewall: "
191 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
192 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
195 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
196 int strict, const char *categ, const char *name)
198 char p[INET6_ADDRSTRLEN * 2];
199 int r = 0;
201 if ((s) && (*s) && (*dir))
203 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
204 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
205 r = IPT_V4;
207 #ifdef TCONFIG_IPV6
208 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
209 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
210 r = IPT_V6;
212 #endif
213 else {
214 snprintf(addr, maxlen, "-%c %s", dir[0], s);
215 if (sscanf(s, "%[^/]/", p)) {
216 #ifdef TCONFIG_IPV6
217 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
218 #else
219 r = host_addrtypes(p, IPT_V4);
220 #endif
224 else
226 *addr = 0;
227 r = (IPT_V4 | IPT_V6);
230 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
231 ipt_log_unresolved(s, categ, name,
232 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
235 return (r & af);
238 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
239 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
240 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
243 static void get_src(const char *nv, char *src)
245 char *p;
247 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
248 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
250 else {
251 *src = 0;
256 void ipt_write(const char *format, ...)
258 va_list args;
260 va_start(args, format);
261 vfprintf(ipt_file, format, args);
262 va_end(args);
265 void ip6t_write(const char *format, ...)
267 #ifdef TCONFIG_IPV6
268 va_list args;
270 va_start(args, format);
271 vfprintf(ip6t_file, format, args);
272 va_end(args);
273 #endif
276 // -----------------------------------------------------------------------------
278 int ipt_dscp(const char *v, char *opt)
280 unsigned int n;
282 if (*v == 0) {
283 *opt = 0;
284 return 0;
287 n = strtoul(v, NULL, 0);
288 if (n > 63) n = 63;
289 sprintf(opt, " -m dscp --dscp 0x%02X", n);
291 #ifdef LINUX26
292 modprobe("xt_dscp");
293 #else
294 modprobe("ipt_dscp");
295 #endif
296 return 1;
299 // -----------------------------------------------------------------------------
302 int ipt_ipp2p(const char *v, char *opt)
304 int n = atoi(v);
306 if (n == 0) {
307 *opt = 0;
308 return 0;
311 strcpy(opt, "-m ipp2p ");
312 if ((n & 0xFFF) == 0xFFF) {
313 strcat(opt, "--ipp2p");
315 else {
316 // x12
317 if (n & 0x0001) strcat(opt, "--apple ");
318 if (n & 0x0002) strcat(opt, "--ares ");
319 if (n & 0x0004) strcat(opt, "--bit ");
320 if (n & 0x0008) strcat(opt, "--dc ");
321 if (n & 0x0010) strcat(opt, "--edk ");
322 if (n & 0x0020) strcat(opt, "--gnu ");
323 if (n & 0x0040) strcat(opt, "--kazaa ");
324 if (n & 0x0080) strcat(opt, "--mute ");
325 if (n & 0x0100) strcat(opt, "--soul ");
326 if (n & 0x0200) strcat(opt, "--waste ");
327 if (n & 0x0400) strcat(opt, "--winmx ");
328 if (n & 0x0800) strcat(opt, "--xdcc ");
331 modprobe("ipt_ipp2p");
332 return 1;
336 // -----------------------------------------------------------------------------
339 char **layer7_in;
341 // This L7 matches inbound traffic, caches the results, then the L7 outbound
342 // should read the cached result and set the appropriate marks -- zzz
343 void ipt_layer7_inbound(void)
345 int en, i;
346 char **p;
348 if (!layer7_in) return;
350 en = nvram_match("nf_l7in", "1");
351 if (en) {
352 ipt_write(":L7in - [0:0]\n");
353 for (i = 0; i < wanfaces.count; ++i) {
354 if (*(wanfaces.iface[i].name)) {
355 ipt_write("-A FORWARD -i %s -j L7in\n",
356 wanfaces.iface[i].name);
361 p = layer7_in;
362 while (*p) {
363 if (en) {
364 ipt_write("-A L7in %s -j RETURN\n", *p);
365 #ifdef LINUX26
366 can_enable_fastnat = 0;
367 #endif
369 free(*p);
370 ++p;
372 free(layer7_in);
373 layer7_in = NULL;
376 int ipt_layer7(const char *v, char *opt)
378 char s[128];
379 char *path;
381 *opt = 0;
382 if (*v == 0) return 0;
383 if (strlen(v) > 32) return -1;
385 path = "/etc/l7-extra";
386 sprintf(s, "%s/%s.pat", path, v);
387 if (!f_exists(s)) {
388 path = "/etc/l7-protocols";
389 sprintf(s, "%s/%s.pat", path, v);
390 if (!f_exists(s)) {
391 syslog(LOG_ERR, "L7 %s was not found", v);
392 return -1;
396 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
398 if (nvram_match("nf_l7in", "1")) {
399 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
400 if (layer7_in) {
401 char **p;
403 p = layer7_in;
404 while (*p) {
405 if (strcmp(*p, opt) == 0) return 1;
406 ++p;
408 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
412 #ifdef LINUX26
413 modprobe("xt_layer7");
414 #else
415 modprobe("ipt_layer7");
416 #endif
417 return 1;
421 // -----------------------------------------------------------------------------
423 static void save_webmon(void)
425 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
426 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
429 static void ipt_webmon()
431 int wmtype, clear, i;
432 char t[512];
433 char src[128];
434 char *p, *c;
435 int ok;
437 if (!nvram_get_int("log_wm")) return;
439 #ifdef LINUX26
440 can_enable_fastnat = 0;
441 #endif
442 wmtype = nvram_get_int("log_wmtype");
443 clear = nvram_get_int("log_wmclear");
445 ip46t_write(":monitor - [0:0]\n");
447 // include IPs
448 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
449 p = t;
450 do {
451 if ((c = strchr(p, ',')) != NULL) *c = 0;
453 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
454 #ifdef TCONFIG_IPV6
455 if (*wan6face && (ok & IPT_V6))
456 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
457 #endif
458 if (ok & IPT_V4) {
459 for (i = 0; i < wanfaces.count; ++i) {
460 if (*(wanfaces.iface[i].name)) {
461 ipt_write("-A FORWARD -o %s %s -j monitor\n",
462 wanfaces.iface[i].name, src);
468 if (!c) break;
469 p = c + 1;
470 } while (*p);
472 // exclude IPs
473 if (wmtype == 2) {
474 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
475 p = t;
476 do {
477 if ((c = strchr(p, ',')) != NULL) *c = 0;
478 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
479 if (*src)
480 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
482 if (!c) break;
483 p = c + 1;
484 } while (*p);
487 ip46t_write(
488 "-A monitor -p tcp -m webmon "
489 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
490 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
491 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
492 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
494 #ifdef LINUX26
495 modprobe("xt_webmon");
496 #else
497 modprobe("ipt_webmon");
498 #endif
502 // -----------------------------------------------------------------------------
503 // MANGLE
504 // -----------------------------------------------------------------------------
506 static void mangle_table(void)
508 int ttl;
509 char *p, *wanface;
511 ip46t_write(
512 "*mangle\n"
513 ":PREROUTING ACCEPT [0:0]\n"
514 ":OUTPUT ACCEPT [0:0]\n");
516 if (wanup) {
518 ipt_qos();
519 //1 for mangle
520 ipt_qoslimit(1);
522 p = nvram_safe_get("nf_ttl");
523 if (strncmp(p, "c:", 2) == 0) {
524 p += 2;
525 ttl = atoi(p);
526 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
528 else if ((ttl = atoi(p)) != 0) {
529 if (ttl > 0) {
530 p = "inc";
532 else {
533 ttl = -ttl;
534 p = "dec";
536 if (ttl > 255) p = NULL;
538 else p = NULL;
540 if (p) {
541 #ifdef LINUX26
542 modprobe("xt_HL");
543 #else
544 modprobe("ipt_TTL");
545 #endif
546 // set TTL on primary WAN iface only
547 wanface = wanfaces.iface[0].name;
548 ipt_write(
549 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
550 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
551 wanface, p, ttl,
552 wanface, p, ttl);
553 #ifdef TCONFIG_IPV6
554 // FIXME: IPv6 HL should be configurable separately from TTL.
555 // disable it until GUI setting is implemented.
556 #if 0
557 ip6t_write(
558 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
559 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
560 wan6face, p, ttl,
561 wan6face, p, ttl);
562 #endif
563 #endif
567 ip46t_write("COMMIT\n");
570 // -----------------------------------------------------------------------------
571 // NAT
572 // -----------------------------------------------------------------------------
574 static void nat_table(void)
576 char lanaddr[32];
577 char lanmask[32];
578 #ifdef TCONFIG_VLAN
579 char lan1addr[32];
580 char lan1mask[32];
581 char lan2addr[32];
582 char lan2mask[32];
583 char lan3addr[32];
584 char lan3mask[32];
585 #endif
586 char dst[64];
587 char src[64];
588 char t[512];
589 char *p, *c;
590 int i;
592 ipt_write("*nat\n"
593 ":PREROUTING ACCEPT [0:0]\n"
594 ":POSTROUTING ACCEPT [0:0]\n"
595 ":OUTPUT ACCEPT [0:0]\n"
596 ":%s - [0:0]\n",
597 chain_wan_prerouting);
599 //2 for nat
600 ipt_qoslimit(2);
602 if (gateway_mode) {
603 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
604 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
605 #ifdef TCONFIG_VLAN
606 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
607 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
608 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
609 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
610 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
611 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
612 #endif
614 for (i = 0; i < wanfaces.count; ++i) {
615 if (*(wanfaces.iface[i].name)) {
616 // chain_wan_prerouting
617 if (wanup) {
618 ipt_write("-A PREROUTING -d %s -j %s\n",
619 wanfaces.iface[i].ip, chain_wan_prerouting);
624 // Drop incoming packets which destination IP address is to our LAN side directly
625 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
626 wanfaces.iface[i].name,
627 lanaddr, lanmask); // note: ipt will correct lanaddr
628 #ifdef TCONFIG_VLAN
629 if(strcmp(lan1addr,"")!=0)
630 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
631 wanfaces.iface[i].name,
632 lan1addr, lan1mask);
633 if(strcmp(lan2addr,"")!=0)
634 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
635 wanfaces.iface[i].name,
636 lan2addr, lan2mask);
637 if(strcmp(lan3addr,"")!=0)
638 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
639 wanfaces.iface[i].name,
640 lan3addr, lan3mask);
641 #endif
645 if (wanup) {
646 if (nvram_match("dns_intcpt", "1")) {
647 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
648 lanaddr, lanmask,
649 lanaddr, lanmask,
650 lanaddr);
651 #ifdef TCONFIG_VLAN
652 if(strcmp(lan1addr,"")!=0)
653 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
654 lan1addr, lan1mask,
655 lan1addr, lan1mask,
656 lan1addr);
657 if(strcmp(lan2addr,"")!=0)
658 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
659 lan2addr, lan2mask,
660 lan2addr, lan2mask,
661 lan2addr);
662 if(strcmp(lan3addr,"")!=0)
663 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
664 lan3addr, lan3mask,
665 lan3addr, lan3mask,
666 lan3addr);
667 #endif
670 // ICMP packets are always redirected to INPUT chains
671 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
673 ipt_forward(IPT_TABLE_NAT);
674 ipt_triggered(IPT_TABLE_NAT);
677 if (nvram_get_int("upnp_enable") & 3) {
678 ipt_write(":upnp - [0:0]\n");
680 for (i = 0; i < wanfaces.count; ++i) {
681 if (*(wanfaces.iface[i].name)) {
682 if (wanup) {
683 // ! for loopback (all) to work
684 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
686 else {
687 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
693 if (wanup) {
694 if (dmz_dst(dst)) {
695 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
696 p = t;
697 do {
698 if ((c = strchr(p, ',')) != NULL) *c = 0;
699 if (ipt_source_strict(p, src, "dmz", NULL))
700 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
701 if (!c) break;
702 p = c + 1;
703 } while (*p);
707 p = "";
708 #ifdef TCONFIG_IPV6
709 switch (get_ipv6_service()) {
710 case IPV6_6IN4:
711 // avoid NATing proto-41 packets when using 6in4 tunnel
712 p = "-p ! 41";
713 break;
715 #endif
717 for (i = 0; i < wanfaces.count; ++i) {
718 if (*(wanfaces.iface[i].name)) {
719 if ((!wanup) || (nvram_get_int("net_snat") != 1))
720 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
721 else
722 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
726 char *modem_ipaddr;
727 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") )
728 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0") )
729 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
731 switch (nvram_get_int("nf_loopback")) {
732 case 1: // 1 = forwarded-only
733 case 2: // 2 = disable
734 break;
735 default: // 0 = all (same as block_loopback=0)
736 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
737 lanface,
738 lanaddr, lanmask,
739 lanaddr, lanmask,
740 lanaddr);
741 #ifdef TCONFIG_VLAN
742 if (strcmp(lan1face,"")!=0)
743 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
744 lan1face,
745 lan1addr, lan1mask,
746 lan1addr, lan1mask,
747 lan1addr);
748 if (strcmp(lan2face,"")!=0)
749 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
750 lan2face,
751 lan2addr, lan2mask,
752 lan2addr, lan2mask,
753 lan2addr);
754 if (strcmp(lan3face,"")!=0)
755 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
756 lan3face,
757 lan3addr, lan3mask,
758 lan3addr, lan3mask,
759 lan3addr);
760 #endif
761 break;
764 ipt_write("COMMIT\n");
767 // -----------------------------------------------------------------------------
768 // FILTER
769 // -----------------------------------------------------------------------------
771 static void filter_input(void)
773 char s[64];
774 char t[512];
775 char *en;
776 char *sec;
777 char *hit;
778 int n;
779 char *p, *c;
781 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
782 for (n = 0; n < wanfaces.count; ++n) {
783 if (*(wanfaces.iface[n].name)) {
784 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
785 #ifdef TCONFIG_VLAN
786 if (strcmp(lan1face,"")!=0)
787 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
788 if (strcmp(lan2face,"")!=0)
789 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
790 if (strcmp(lan3face,"")!=0)
791 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
792 #endif
797 ipt_write(
798 "-A INPUT -m state --state INVALID -j DROP\n"
799 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
801 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
802 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
804 ? what if the user uses the start button in GUI ?
805 if (nvram_get_int("telnetd_eas"))
806 if (nvram_get_int("sshd_eas"))
808 #ifdef LINUX26
809 modprobe("xt_recent");
810 #else
811 modprobe("ipt_recent");
812 #endif
814 ipt_write(
815 "-N shlimit\n"
816 "-A shlimit -m recent --set --name shlimit\n"
817 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
818 atoi(hit) + 1, sec, chain_in_drop);
820 if (n & 1) {
821 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
822 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
823 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
826 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
829 #ifdef TCONFIG_FTP
830 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
831 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
832 #ifdef LINUX26
833 modprobe("xt_recent");
834 #else
835 modprobe("ipt_recent");
836 #endif
838 ipt_write(
839 "-N ftplimit\n"
840 "-A ftplimit -m recent --set --name ftp\n"
841 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
842 atoi(hit) + 1, sec, chain_in_drop);
843 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
845 #endif
847 ipt_write(
848 "-A INPUT -i lo -j ACCEPT\n"
849 "-A INPUT -i %s -j ACCEPT\n",
850 lanface);
851 #ifdef TCONFIG_VLAN
852 if (strcmp(lan1face,"")!=0)
853 ipt_write(
854 "-A INPUT -i %s -j ACCEPT\n",
855 lan1face);
856 if (strcmp(lan2face,"")!=0)
857 ipt_write(
858 "-A INPUT -i %s -j ACCEPT\n",
859 lan2face);
860 if (strcmp(lan3face,"")!=0)
861 ipt_write(
862 "-A INPUT -i %s -j ACCEPT\n",
863 lan3face);
864 #endif
866 #ifdef TCONFIG_IPV6
867 n = get_ipv6_service();
868 switch (n) {
869 case IPV6_ANYCAST_6TO4:
870 case IPV6_6IN4:
871 // Accept ICMP requests from the remote tunnel endpoint
872 if (n == IPV6_ANYCAST_6TO4)
873 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
874 else
875 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
876 if (*s && strcmp(s, "0.0.0.0") != 0)
877 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
878 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
879 break;
881 #endif
883 // ICMP request from WAN interface
884 if (nvram_match("block_wan", "0")) {
885 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
886 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept);
887 // allow udp traceroute packets
888 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept);
891 /* Accept incoming packets from broken dhcp servers, which are sending replies
892 * from addresses other than used for query. This could lead to a lower level
893 * of security, so allow to disable it via nvram variable.
895 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
896 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
899 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
900 p = t;
901 do {
902 if ((c = strchr(p, ',')) != NULL) *c = 0;
904 if (ipt_source(p, s, "remote management", NULL)) {
906 if (remotemanage) {
907 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
908 s, nvram_safe_get("http_wanport"), chain_in_accept);
911 if (nvram_get_int("sshd_remote")) {
912 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
913 s, nvram_safe_get("sshd_rport"), chain_in_accept);
917 if (!c) break;
918 p = c + 1;
919 } while (*p);
921 #ifdef TCONFIG_FTP // !!TB - FTP Server
922 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
923 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
924 p = t;
925 do {
926 if ((c = strchr(p, ',')) != NULL) *c = 0;
927 if (ipt_source(p, s, "ftp", "remote access")) {
928 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
929 s, nvram_safe_get("ftp_port"), chain_in_accept);
931 if (!c) break;
932 p = c + 1;
933 } while (*p);
935 #endif
937 // IGMP query from WAN interface
938 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
939 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
940 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
943 // Routing protocol, RIP, accept
944 if (nvram_invmatch("dr_wan_rx", "0")) {
945 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
948 // if logging
949 if (*chain_in_drop == 'l') {
950 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
953 // default policy: DROP
956 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
957 static void clampmss(void)
959 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
960 #ifdef TCONFIG_IPV6
961 switch (get_ipv6_service()) {
962 case IPV6_ANYCAST_6TO4:
963 case IPV6_6IN4:
964 ip6t_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
965 break;
967 #endif
970 static void filter_forward(void)
972 char dst[64];
973 char src[64];
974 char t[512];
975 char *p, *c;
976 int i;
978 #ifdef TCONFIG_IPV6
979 ip6t_write(
980 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
981 #endif
983 ip46t_write(
984 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
985 lanface, lanface);
986 #ifdef TCONFIG_VLAN
987 if (strcmp(lan1face,"")!=0)
988 ip46t_write(
989 "-A FORWARD -i %s -o %s -j ACCEPT\n",
990 lan1face, lan1face);
991 if (strcmp(lan2face,"")!=0)
992 ip46t_write(
993 "-A FORWARD -i %s -o %s -j ACCEPT\n",
994 lan2face, lan2face);
995 if (strcmp(lan3face,"")!=0)
996 ip46t_write(
997 "-A FORWARD -i %s -o %s -j ACCEPT\n",
998 lan3face, lan3face);
1000 char lanAccess[17] = "0000000000000000";
1001 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1002 char *nv, *nvp, *b;
1003 int n;
1004 nvp = nv = strdup(nvram_safe_get("lan_access"));
1005 if (nv) {
1006 while ((b = strsep(&nvp, ">")) != NULL) {
1008 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1010 1 = enabled
1011 0 = src bridge
1012 1.2.3.4 = src addr
1013 1 = dst bridge
1014 5.6.7.8 = dst addr
1015 desc = desc
1017 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1018 if (*d != '1')
1019 continue;
1020 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1021 continue;
1022 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1023 continue;
1025 ip46t_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1026 "br",
1027 sbr,
1028 "br",
1029 dbr,
1030 src,
1031 dst);
1033 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1034 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1038 free(nv);
1039 #endif
1041 ip46t_write(
1042 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1044 // clamp tcp mss to pmtu
1045 clampmss();
1047 if (wanup) {
1048 ipt_restrictions();
1050 ipt_layer7_inbound();
1053 ipt_webmon();
1055 ip46t_write(
1056 ":wanin - [0:0]\n"
1057 ":wanout - [0:0]\n"
1058 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1060 #ifdef TCONFIG_VLAN
1061 char lanN_ifname[] = "lanXX_ifname";
1062 char br;
1063 for(br=0 ; br<=3 ; br++) {
1064 char bridge[2] = "0";
1065 if (br!=0)
1066 bridge[0]+=br;
1067 else
1068 strcpy(bridge, "");
1070 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1071 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1072 char lanN_ifname2[] = "lanXX_ifname";
1073 char br2;
1074 for(br2=0 ; br2<=3 ; br2++) {
1075 if (br==br2) continue;
1077 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1079 char bridge2[2] = "0";
1080 if (br2!=0)
1081 bridge2[0]+=br2;
1082 else
1083 strcpy(bridge2, "");
1085 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1086 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1087 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1088 nvram_safe_get(lanN_ifname),
1089 nvram_safe_get(lanN_ifname2));
1092 // ipt_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1095 #endif
1097 #ifdef TCONFIG_IPV6
1098 // Filter out invalid WAN->WAN connections
1099 if (*wan6face)
1100 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop);
1102 #ifdef LINUX26
1103 modprobe("xt_length");
1104 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1105 #endif
1107 // ICMPv6 rules
1108 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1109 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1112 if (*wan6face) {
1113 ip6t_write(
1114 "-A FORWARD -i %s -j wanin\n" // generic from wan
1115 "-A FORWARD -o %s -j wanout\n", // generic to wan
1116 wan6face, wan6face);
1118 #endif
1120 for (i = 0; i < wanfaces.count; ++i) {
1121 if (*(wanfaces.iface[i].name)) {
1122 ipt_write(
1123 "-A FORWARD -i %s -j wanin\n" // generic from wan
1124 "-A FORWARD -o %s -j wanout\n", // generic to wan
1125 wanfaces.iface[i].name, wanfaces.iface[i].name);
1129 #ifdef TCONFIG_VLAN
1130 for(br=0 ; br<=3 ; br++) {
1131 char bridge[2] = "0";
1132 if (br!=0)
1133 bridge[0]+=br;
1134 else
1135 strcpy(bridge, "");
1137 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1138 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1139 ipt_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1142 #else
1143 ipt_write("-A FORWARD -i %s -j %s\n", lanface, chain_out_accept);
1144 #endif
1146 // #ifdef TCONFIG_VLAN
1147 /* for (i = 0; i < wanfaces.count; ++i) {
1148 if (*(wanfaces.iface[i].name)) {
1149 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wanfaces.iface[i].name, chain_out_accept);
1150 if (strcmp(lan1face,"")!=0)
1151 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wanfaces.iface[i].name, chain_out_accept);
1152 if (strcmp(lan2face,"")!=0)
1153 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wanfaces.iface[i].name, chain_out_accept);
1154 if (strcmp(lan3face,"")!=0)
1155 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wanfaces.iface[i].name, chain_out_accept);
1159 // #else
1160 // ipt_write("-A FORWARD -i %s -j %s\n", lanface, chain_out_accept);
1161 // #endif
1163 #ifdef TCONFIG_IPV6
1164 //IPv6 forward LAN->WAN accept
1165 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1166 #ifdef TCONFIG_VLAN
1167 if (strcmp(lan1face,"")!=0)
1168 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1169 if (strcmp(lan2face,"")!=0)
1170 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1171 if (strcmp(lan3face,"")!=0)
1172 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1173 #endif
1174 #endif
1176 if (nvram_get_int("upnp_enable") & 3) {
1177 ipt_write(":upnp - [0:0]\n");
1178 for (i = 0; i < wanfaces.count; ++i) {
1179 if (*(wanfaces.iface[i].name)) {
1180 ipt_write("-A FORWARD -i %s -j upnp\n",
1181 wanfaces.iface[i].name);
1186 if (wanup) {
1187 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1188 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1190 ipt_triggered(IPT_TABLE_FILTER);
1191 ipt_forward(IPT_TABLE_FILTER);
1192 #ifdef TCONFIG_IPV6
1193 ip6t_forward();
1194 #endif
1196 if (dmz_dst(dst)) {
1197 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1198 p = t;
1199 do {
1200 if ((c = strchr(p, ',')) != NULL) *c = 0;
1201 if (ipt_source_strict(p, src, "dmz", NULL))
1202 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1203 if (!c) break;
1204 p = c + 1;
1205 } while (*p);
1209 // default policy: DROP
1212 static void filter_log(void)
1214 int n;
1215 char limit[128];
1217 n = nvram_get_int("log_limit");
1218 if ((n >= 1) && (n <= 9999)) {
1219 sprintf(limit, "-m limit --limit %d/m", n);
1221 else {
1222 limit[0] = 0;
1225 #ifdef TCONFIG_IPV6
1226 modprobe("ip6t_LOG");
1227 #endif
1228 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1229 ip46t_write(
1230 ":logdrop - [0:0]\n"
1231 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1232 #ifdef LINUX26
1233 " --log-macdecode"
1234 #endif
1235 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1236 "-A logdrop -j DROP\n"
1237 ":logreject - [0:0]\n"
1238 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1239 #ifdef LINUX26
1240 " --log-macdecode"
1241 #endif
1242 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1243 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1244 limit, limit);
1246 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1247 ip46t_write(
1248 ":logaccept - [0:0]\n"
1249 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1250 #ifdef LINUX26
1251 " --log-macdecode"
1252 #endif
1253 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1254 "-A logaccept -j ACCEPT\n",
1255 limit);
1259 #ifdef TCONFIG_IPV6
1260 static void filter6_input(void)
1262 char s[128];
1263 char t[512];
1264 char *en;
1265 char *sec;
1266 char *hit;
1267 int n;
1268 char *p, *c;
1270 // RFC-4890, sec. 4.4.1
1271 const int allowed_local_icmpv6[] =
1272 { 130, 131, 132, 133, 134, 135, 136,
1273 141, 142, 143,
1274 148, 149, 151, 152, 153 };
1276 ip6t_write(
1277 "-A INPUT -m rt --rt-type 0 -j %s\n"
1278 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1279 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1280 chain_in_drop);
1282 #ifdef LINUX26
1283 modprobe("xt_length");
1284 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1285 #endif
1287 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1288 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1289 #ifdef LINUX26
1290 modprobe("xt_recent");
1291 #else
1292 modprobe("ipt_recent");
1293 #endif
1295 ip6t_write(
1296 "-N shlimit\n"
1297 "-A shlimit -m recent --set --name shlimit\n"
1298 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1299 atoi(hit) + 1, sec, chain_in_drop);
1301 if (n & 1) {
1302 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1303 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1304 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1307 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"));
1310 #ifdef TCONFIG_FTP
1311 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1312 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1313 #ifdef LINUX26
1314 modprobe("xt_recent");
1315 #else
1316 modprobe("ipt_recent");
1317 #endif
1319 ip6t_write(
1320 "-N ftplimit\n"
1321 "-A ftplimit -m recent --set --name ftp\n"
1322 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1323 atoi(hit) + 1, sec, chain_in_drop);
1324 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1326 #endif // TCONFIG_FTP
1328 ip6t_write(
1329 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1330 "-A INPUT -i lo -j ACCEPT\n",
1331 lanface );
1333 switch (get_ipv6_service()) {
1334 case IPV6_ANYCAST_6TO4:
1335 case IPV6_NATIVE_DHCP:
1336 // allow responses from the dhcpv6 server
1337 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1338 break;
1341 // ICMPv6 rules
1342 const int allowed_icmpv6[6] = { 1, 2, 3, 4, 128, 129 };
1343 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1344 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1346 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1347 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1350 // Remote Managment
1351 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1352 p = t;
1353 do {
1354 if ((c = strchr(p, ',')) != NULL) *c = 0;
1356 if (ip6t_source(p, s, "remote management", NULL)) {
1358 if (remotemanage) {
1359 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1360 s, nvram_safe_get("http_wanport"), chain_in_accept);
1363 if (nvram_get_int("sshd_remote")) {
1364 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1365 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1369 if (!c) break;
1370 p = c + 1;
1371 } while (*p);
1373 #ifdef TCONFIG_FTP
1374 // FTP server
1375 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1376 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1377 p = t;
1378 do {
1379 if ((c = strchr(p, ',')) != NULL) *c = 0;
1380 if (ip6t_source(p, s, "ftp", "remote access")) {
1381 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1382 s, nvram_safe_get("ftp_port"), chain_in_accept);
1384 if (!c) break;
1385 p = c + 1;
1386 } while (*p);
1388 #endif
1390 // if logging
1391 if (*chain_in_drop == 'l') {
1392 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1395 // default policy: DROP
1398 #endif
1400 static void filter_table(void)
1402 ip46t_write(
1403 "*filter\n"
1404 ":INPUT DROP [0:0]\n"
1405 ":OUTPUT ACCEPT [0:0]\n"
1408 filter_log();
1410 filter_input();
1411 #ifdef TCONFIG_IPV6
1412 filter6_input();
1413 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1414 #endif
1416 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1417 ip46t_write(":FORWARD DROP [0:0]\n");
1418 filter_forward();
1420 else {
1421 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1422 clampmss();
1424 ip46t_write("COMMIT\n");
1427 // -----------------------------------------------------------------------------
1429 int start_firewall(void)
1431 DIR *dir;
1432 struct dirent *dirent;
1433 char s[256];
1434 char *c, *wanface;
1435 int n;
1436 int wanproto;
1437 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1438 #ifdef TCONFIG_IPV6
1439 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1440 #endif
1442 simple_lock("firewall");
1443 simple_lock("restrictions");
1445 wanproto = get_wan_proto();
1446 wanup = check_wanup();
1448 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1450 /* NAT performance tweaks
1451 * These values can be overriden later if needed via firewall script
1453 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1454 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1455 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1456 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1457 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1458 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1459 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1460 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1461 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1462 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1463 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1464 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1466 /* DoS-related tweaks */
1467 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1468 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1469 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1471 wanproto = get_wan_proto();
1472 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1474 #ifdef TCONFIG_EMF
1475 /* Force IGMPv2 due EMF limitations */
1476 if (nvram_get_int("emf_enable")) {
1477 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1478 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1480 #endif
1482 n = nvram_get_int("log_in");
1483 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1484 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1486 n = nvram_get_int("log_out");
1487 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1488 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1489 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1491 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1493 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1494 #ifdef TCONFIG_VLAN
1495 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1496 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1497 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1498 #endif
1500 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1501 wanface = wanfaces.iface[0].name;
1502 #ifdef TCONFIG_IPV6
1503 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1504 #endif
1506 #ifdef LINUX26
1507 can_enable_fastnat = 1;
1508 #endif
1510 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1511 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1512 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1513 #ifdef TCONFIG_VLAN
1515 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1516 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1517 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1519 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1520 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1521 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1523 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1524 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1525 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1527 #endif
1530 block obviously spoofed IP addresses
1532 rp_filter - BOOLEAN
1533 1 - do source validation by reversed path, as specified in RFC1812
1534 Recommended option for single homed hosts and stub network
1535 routers. Could cause troubles for complicated (not loop free)
1536 networks running a slow unreliable protocol (sort of RIP),
1537 or using static routes.
1538 0 - No source validation.
1540 c = nvram_get("wan_ifname");
1541 /* mcast needs rp filter to be turned off only for non default iface */
1542 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1544 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1545 while ((dirent = readdir(dir)) != NULL) {
1546 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1547 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1549 closedir(dir);
1552 remotemanage = 0;
1553 gateway_mode = !nvram_match("wk_mode", "router");
1554 if (gateway_mode) {
1555 /* Remote management */
1556 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1557 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1560 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1561 notice_set("iptables", "Unable to create iptables restore file");
1562 simple_unlock("firewall");
1563 return 0;
1566 #ifdef TCONFIG_IPV6
1567 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1568 notice_set("ip6tables", "Unable to create ip6tables restore file");
1569 simple_unlock("firewall");
1570 return 0;
1572 modprobe("nf_conntrack_ipv6");
1573 modprobe("ip6t_REJECT");
1574 #endif
1575 /*Deon Thomas attempt to start xt_IMQ and imq */
1576 /*shibby - fix modprobing IMQ for kernel 2.4 */
1577 modprobe("imq");
1578 #ifdef LINUX26
1579 modprobe("xt_IMQ");
1580 #else
1581 modprobe("ipt_IMQ");
1582 #endif
1584 mangle_table();
1585 nat_table();
1586 filter_table();
1588 fclose(ipt_file);
1589 ipt_file = NULL;
1591 #ifdef TCONFIG_IPV6
1592 fclose(ip6t_file);
1593 ip6t_file = NULL;
1594 #endif
1596 #ifdef DEBUG_IPTFILE
1597 if (debug_only) {
1598 simple_unlock("firewall");
1599 simple_unlock("restrictions");
1600 return 0;
1602 #endif
1604 save_webmon();
1606 if (nvram_get_int("upnp_enable") & 3) {
1607 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1608 if (killall("miniupnpd", SIGUSR2) == 0) {
1609 f_wait_notexists("/etc/upnp/save", 5);
1613 notice_set("iptables", "");
1614 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1615 led(LED_DIAG, 0);
1616 notice_set("iptables", "");
1618 else {
1619 sprintf(s, "%s.error", ipt_fname);
1620 rename(ipt_fname, s);
1621 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1622 led(LED_DIAG, 1);
1626 -P INPUT DROP
1627 -F INPUT
1628 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1629 -A INPUT -i br0 -j ACCEPT
1631 -P FORWARD DROP
1632 -F FORWARD
1633 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1634 -A FORWARD -i br0 -j ACCEPT
1639 #ifdef TCONFIG_IPV6
1640 if (ipv6_enabled()) {
1641 notice_set("ip6tables", "");
1642 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1643 notice_set("ip6tables", "");
1645 else {
1646 sprintf(s, "%s.error", ip6t_fname);
1647 rename(ip6t_fname, s);
1648 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1649 led(LED_DIAG, 1);
1652 else {
1653 eval("ip6tables", "-F");
1654 eval("ip6tables", "-t", "mangle", "-F");
1656 #endif
1658 if (nvram_get_int("upnp_enable") & 3) {
1659 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1660 killall("miniupnpd", SIGUSR2);
1663 simple_unlock("restrictions");
1664 sched_restrictions();
1665 enable_ip_forward();
1667 led(LED_DMZ, dmz_dst(NULL));
1669 #ifdef TCONFIG_IPV6
1670 modprobe_r("nf_conntrack_ipv6");
1671 modprobe_r("ip6t_LOG");
1672 modprobe_r("ip6t_REJECT");
1673 #endif
1674 #ifdef LINUX26
1675 modprobe_r("xt_layer7");
1676 modprobe_r("xt_recent");
1677 modprobe_r("xt_HL");
1678 modprobe_r("xt_length");
1679 modprobe_r("xt_web");
1680 modprobe_r("xt_webmon");
1681 modprobe_r("xt_dscp");
1682 #else
1683 modprobe_r("ipt_layer7");
1684 modprobe_r("ipt_recent");
1685 modprobe_r("ipt_TTL");
1686 modprobe_r("ipt_web");
1687 modprobe_r("ipt_webmon");
1688 modprobe_r("ipt_dscp");
1689 #endif
1690 modprobe_r("ipt_ipp2p");
1692 unlink("/var/webmon/domain");
1693 unlink("/var/webmon/search");
1695 #ifdef TCONFIG_OPENVPN
1696 run_vpn_firewall_scripts();
1697 #endif
1698 run_nvscript("script_fire", NULL, 1);
1700 start_account();
1701 start_arpbind();
1703 #ifdef LINUX26
1704 allow_fastnat("firewall", can_enable_fastnat);
1705 try_enabling_fastnat();
1706 #endif
1708 simple_unlock("firewall");
1709 return 0;
1712 int stop_firewall(void)
1714 led(LED_DMZ, 0);
1715 return 0;
1718 #ifdef DEBUG_IPTFILE
1719 void create_test_iptfile(void)
1721 debug_only = 1;
1722 start_firewall();
1723 debug_only = 0;
1725 #endif