rc: cosmetic code change
[tomato.git] / release / src / router / rc / firewall.c
blob96c3af11c7babf2fd2b4429edd280b8af111ffe2
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 char wanface[IFNAMSIZ + 1];
33 char manface[IFNAMSIZ + 1];
34 char lanface[IFNAMSIZ + 1];
35 char wanaddr[sizeof("xxx.xxx.xxx.xxx") + 1];
36 char manaddr[sizeof("xxx.xxx.xxx.xxx") + 1];
37 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
38 static int web_lanport;
40 #ifdef DEBUG_IPTFILE
41 static int debug_only = 0;
42 #endif
44 static int gateway_mode;
45 static int remotemanage;
46 static int wanup;
48 const char *chain_in_drop;
49 const char *chain_in_accept;
50 const char *chain_out_drop;
51 const char *chain_out_accept;
52 const char *chain_out_reject;
54 const char ipt_fname[] = "/etc/iptables";
55 FILE *ipt_file;
59 struct {
60 } firewall_data;
63 // -----------------------------------------------------------------------------
66 void enable_ip_forward(void)
69 ip_forward - BOOLEAN
70 0 - disabled (default)
71 not 0 - enabled
73 Forward Packets between interfaces.
75 This variable is special, its change resets all configuration
76 parameters to their default state (RFC1122 for hosts, RFC1812
77 for routers)
79 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
83 // -----------------------------------------------------------------------------
86 static int ip2cclass(char *ipaddr, char *new, int count)
88 int ip[4];
90 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
91 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
96 static int dmz_dst(char *s)
98 struct in_addr ia;
99 char *p;
100 int n;
102 if (nvram_get_int("dmz_enable") <= 0) return 0;
104 p = nvram_safe_get("dmz_ipaddr");
105 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
106 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
107 if (s) sprintf(s, "%s%d", lan_cclass, n);
108 return 1;
111 if (s) strcpy(s, inet_ntoa(ia));
112 return 1;
115 void ipt_addr(char *addr, int maxlen, const char *s, const char *dir)
117 char p[32];
119 if ((*s) && (*dir))
121 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2)
122 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
123 else
124 snprintf(addr, maxlen, "-%c %s", dir[0], s);
126 else
127 *addr = 0;
130 static inline void ipt_source(const char *s, char *src)
132 ipt_addr(src, 64, s, "src");
136 static void get_src(const char *nv, char *src)
138 char *p;
140 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
141 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
143 else {
144 *src = 0;
149 void ipt_write(const char *format, ...)
151 va_list args;
153 va_start(args, format);
154 vfprintf(ipt_file, format, args);
155 va_end(args);
158 // -----------------------------------------------------------------------------
161 int ipt_ipp2p(const char *v, char *opt)
163 int n = atoi(v);
165 if (n == 0) {
166 *opt = 0;
167 return 0;
170 strcpy(opt, "-m ipp2p ");
171 if ((n & 0xFFF) == 0xFFF) {
172 strcat(opt, "--ipp2p");
174 else {
175 // x12
176 if (n & 0x0001) strcat(opt, "--apple ");
177 if (n & 0x0002) strcat(opt, "--ares ");
178 if (n & 0x0004) strcat(opt, "--bit ");
179 if (n & 0x0008) strcat(opt, "--dc ");
180 if (n & 0x0010) strcat(opt, "--edk ");
181 if (n & 0x0020) strcat(opt, "--gnu ");
182 if (n & 0x0040) strcat(opt, "--kazaa ");
183 if (n & 0x0080) strcat(opt, "--mute ");
184 if (n & 0x0100) strcat(opt, "--soul ");
185 if (n & 0x0200) strcat(opt, "--waste ");
186 if (n & 0x0400) strcat(opt, "--winmx ");
187 if (n & 0x0800) strcat(opt, "--xdcc ");
190 modprobe("ipt_ipp2p");
191 return 1;
195 // -----------------------------------------------------------------------------
198 char **layer7_in;
200 // This L7 matches inbound traffic, caches the results, then the L7 outbound
201 // should read the cached result and set the appropriate marks -- zzz
202 void ipt_layer7_inbound(void)
204 int en;
205 char **p;
207 if (!layer7_in) return;
209 en = nvram_match("nf_l7in", "1");
210 if (en) {
211 ipt_write(
212 ":L7in - [0:0]\n"
213 "-A FORWARD -i %s -j L7in\n",
214 wanface);
215 if (*manface)
216 ipt_write(
217 "-A FORWARD -i %s -j L7in\n",
218 manface);
221 p = layer7_in;
222 while (*p) {
223 if (en) ipt_write("-A L7in %s -j RETURN\n", *p);
224 free(*p);
225 ++p;
227 free(layer7_in);
228 layer7_in = NULL;
231 int ipt_layer7(const char *v, char *opt)
233 char s[128];
234 char *path;
236 *opt = 0;
237 if (*v == 0) return 0;
238 if (strlen(v) > 32) return -1;
240 path = "/etc/l7-extra";
241 sprintf(s, "%s/%s.pat", path, v);
242 if (!f_exists(s)) {
243 path = "/etc/l7-protocols";
244 sprintf(s, "%s/%s.pat", path, v);
245 if (!f_exists(s)) {
246 syslog(LOG_ERR, "L7 %s was not found", v);
247 return -1;
251 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
253 if (nvram_match("nf_l7in", "1")) {
254 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
255 if (layer7_in) {
256 char **p;
258 p = layer7_in;
259 while (*p) {
260 if (strcmp(*p, opt) == 0) return 1;
261 ++p;
263 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
267 #ifdef LINUX26
268 modprobe("xt_layer7");
269 #else
270 modprobe("ipt_layer7");
271 #endif
272 return 1;
276 // -----------------------------------------------------------------------------
278 static void save_webmon(void)
280 system("cp /proc/webmon_recent_domains /var/webmon/domain");
281 system("cp /proc/webmon_recent_searches /var/webmon/search");
284 static void ipt_webmon(void)
286 int wmtype, clear;
288 if (!nvram_get_int("log_wm")) return;
289 wmtype = nvram_get_int("log_wmtype");
290 clear = nvram_get_int("log_wmclear");
292 ipt_write(
293 ":monitor - [0:0]\n"
294 "-A FORWARD -o %s -j monitor\n",
295 wanface);
296 if (*manface)
297 ipt_write(
298 "-A FORWARD -o %s -j monitor\n",
299 manface);
301 ipt_write(
302 "-A monitor -m webmon "
303 "--max_domains %d --max_searches %d %s%s %s %s\n",
304 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
305 wmtype == 1 ? "--include_ips " : wmtype == 2 ? "--exclude_ips " : "",
306 wmtype == 0 ? "" : nvram_safe_get("log_wmip"),
307 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
308 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
310 modprobe("ipt_webmon");
314 // -----------------------------------------------------------------------------
315 // MANGLE
316 // -----------------------------------------------------------------------------
318 static void mangle_table(void)
320 int ttl;
321 char *p;
323 ipt_write(
324 "*mangle\n"
325 ":PREROUTING ACCEPT [0:0]\n"
326 ":OUTPUT ACCEPT [0:0]\n");
328 if (wanup) {
329 ipt_qos();
331 ttl = nvram_get_int("nf_ttl");
332 if (ttl != 0) {
333 #ifdef LINUX26
334 modprobe("xt_HL");
335 #else
336 modprobe("ipt_TTL");
337 #endif
338 if (ttl > 0) {
339 p = "in";
341 else {
342 ttl = -ttl;
343 p = "de";
345 ipt_write(
346 "-I PREROUTING -i %s -j TTL --ttl-%sc %d\n"
347 "-I POSTROUTING -o %s -j TTL --ttl-%sc %d\n",
348 wanface, p, ttl,
349 wanface, p, ttl);
353 ipt_write("COMMIT\n");
358 // -----------------------------------------------------------------------------
359 // NAT
360 // -----------------------------------------------------------------------------
362 static void nat_table(void)
364 char lanaddr[32];
365 char lanmask[32];
366 char dst[64];
367 char src[64];
368 char t[512];
369 char *p, *c;
371 ipt_write("*nat\n"
372 ":PREROUTING ACCEPT [0:0]\n"
373 ":POSTROUTING ACCEPT [0:0]\n"
374 ":OUTPUT ACCEPT [0:0]\n"
375 ":WANPREROUTING - [0:0]\n");
377 if (gateway_mode) {
378 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
379 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
381 // WANPREROUTING chain
382 if (wanup)
383 ipt_write("-A PREROUTING -d %s -j WANPREROUTING\n", wanaddr);
384 if (*manaddr)
385 ipt_write("-A PREROUTING -d %s -j WANPREROUTING\n", manaddr);
387 // Drop incoming packets which destination IP address is to our LAN side directly
388 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
389 wanface,
390 lanaddr, lanmask); // note: ipt will correct lanaddr
391 if (*manface)
392 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
393 manface,
394 lanaddr, lanmask); // note: ipt will correct lanaddr
396 if (wanup) {
397 if (nvram_match("dns_intcpt", "1")) {
398 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
399 lanaddr, lanmask,
400 lanaddr, lanmask,
401 lanaddr);
404 // ICMP packets are always redirected to INPUT chains
405 ipt_write("-A WANPREROUTING -p icmp -j DNAT --to-destination %s\n", lanaddr);
407 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
408 p = t;
409 do {
410 if ((c = strchr(p, ',')) != NULL) *c = 0;
411 ipt_source(p, src);
413 if (remotemanage) {
414 ipt_write("-A WANPREROUTING -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
415 src,
416 nvram_safe_get("http_wanport"),
417 lanaddr, web_lanport);
419 if (nvram_get_int("sshd_remote")) {
420 ipt_write("-A WANPREROUTING %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
421 src,
422 nvram_safe_get("sshd_rport"),
423 lanaddr, nvram_safe_get("sshd_port"));
426 if (!c) break;
427 p = c + 1;
428 } while (*p);
430 ipt_forward(IPT_TABLE_NAT);
431 ipt_triggered(IPT_TABLE_NAT);
434 if (nvram_get_int("upnp_enable") & 3) {
435 ipt_write(":upnp - [0:0]\n");
436 if (wanup) {
437 // ! for loopback (all) to work
438 ipt_write("-A WANPREROUTING -j upnp\n");
440 else {
441 ipt_write("-A PREROUTING -i %s -j upnp\n", wanface);
442 if (*manface)
443 ipt_write("-A PREROUTING -i %s -j upnp\n", manface);
447 if (wanup) {
448 if (dmz_dst(dst)) {
449 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
450 p = t;
451 do {
452 if ((c = strchr(p, ',')) != NULL) *c = 0;
453 ipt_source(p, src);
454 ipt_write("-A WANPREROUTING %s -j DNAT --to-destination %s\n", src, dst);
455 if (!c) break;
456 p = c + 1;
457 } while (*p);
461 if ((!wanup) || (nvram_get_int("net_snat") != 1)) {
462 ipt_write("-A POSTROUTING -o %s -j MASQUERADE\n", wanface);
463 if (*manface)
464 ipt_write("-A POSTROUTING -o %s -j MASQUERADE\n", manface);
466 else {
467 ipt_write("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wanface, wanaddr);
468 if (*manface && *manaddr)
469 ipt_write("-A POSTROUTING -o %s -j SNAT --to-source %s\n", manface, manaddr);
472 switch (nvram_get_int("nf_loopback")) {
473 case 1: // 1 = forwarded-only
474 case 2: // 2 = disable
475 break;
476 default: // 0 = all (same as block_loopback=0)
477 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
478 lanface,
479 lanaddr, lanmask,
480 lanaddr, lanmask,
481 lanaddr);
482 break;
485 ipt_write("COMMIT\n");
488 // -----------------------------------------------------------------------------
489 // FILTER
490 // -----------------------------------------------------------------------------
492 static void filter_input(void)
494 char s[64];
495 char t[512];
496 char *en;
497 char *sec;
498 char *hit;
499 int n;
500 char *p, *c;
502 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
503 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanaddr);
504 if (*manaddr)
505 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, manaddr);
508 ipt_write(
509 "-A INPUT -m state --state INVALID -j %s\n"
510 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
511 chain_in_drop);
514 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
515 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
517 ? what if the user uses the start button in GUI ?
518 if (nvram_get_int("telnetd_eas"))
519 if (nvram_get_int("sshd_eas"))
521 #ifdef LINUX26
522 modprobe("xt_recent");
523 #else
524 modprobe("ipt_recent");
525 #endif
527 ipt_write(
528 "-N shlimit\n"
529 "-A shlimit -m recent --set --name shlimit\n"
530 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j DROP\n",
531 atoi(hit) + 1, sec);
533 if (n & 1) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
534 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
537 #ifdef TCONFIG_FTP
538 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
539 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
540 #ifdef LINUX26
541 modprobe("xt_recent");
542 #else
543 modprobe("ipt_recent");
544 #endif
546 ipt_write(
547 "-N ftplimit\n"
548 "-A ftplimit -m recent --set --name ftp\n"
549 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j DROP\n",
550 atoi(hit) + 1, sec);
551 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
553 #endif
555 ipt_write(
556 "-A INPUT -i %s -j ACCEPT\n"
557 "-A INPUT -i lo -j ACCEPT\n",
558 lanface);
560 // ICMP request from WAN interface
561 if (nvram_match("block_wan", "0")) {
562 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
563 // allow udp traceroute packets
564 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -j %s\n", chain_in_accept);
567 /* Accept incoming packets from broken dhcp servers, which are sending replies
568 * from addresses other than used for query. This could lead to a lower level
569 * of security, so allow to disable it via nvram variable.
571 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
572 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
575 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
576 p = t;
577 do {
578 if ((c = strchr(p, ',')) != NULL) *c = 0;
580 ipt_source(p, s);
582 if (remotemanage) {
583 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %d -j %s\n",
584 s, nvram_safe_get("lan_ipaddr"), web_lanport, chain_in_accept);
587 if (nvram_get_int("sshd_remote")) {
588 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %s -j %s\n",
589 s, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"), chain_in_accept);
592 if (!c) break;
593 p = c + 1;
594 } while (*p);
597 #ifdef TCONFIG_FTP // !!TB - FTP Server
598 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
599 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
600 p = t;
601 do {
602 if ((c = strchr(p, ',')) != NULL) *c = 0;
603 ipt_source(p, s);
605 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
606 s, nvram_safe_get("ftp_port"), chain_in_accept);
608 if (!c) break;
609 p = c + 1;
610 } while (*p);
612 #endif
614 // IGMP query from WAN interface
615 if (nvram_match("multicast_pass", "1")) {
616 ipt_write("-A INPUT -p igmp -j ACCEPT\n");
619 // Routing protocol, RIP, accept
620 if (nvram_invmatch("dr_wan_rx", "0")) {
621 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
624 // if logging
625 if (*chain_in_drop == 'l') {
626 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
629 // default policy: DROP
632 // clamp TCP MSS to PMTU of WAN interface
633 static void clampmss(void)
635 #if 1
636 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
637 #else
638 int rmtu = nvram_get_int("wan_run_mtu");
639 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
640 if (rmtu < 576) {
641 ipt_write("--clamp-mss-to-pmtu\n");
643 else {
644 ipt_write("--set-mss %d\n", rmtu - 40);
646 #endif
649 static void filter_forward(void)
651 char dst[64];
652 char src[64];
653 char t[512];
654 char *p, *c;
656 ipt_write(
657 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
658 "-A FORWARD -m state --state INVALID -j DROP\n", // drop if INVALID state
659 lanface, lanface);
661 // clamp tcp mss to pmtu
662 clampmss();
664 if (wanup) {
665 ipt_restrictions();
666 ipt_layer7_inbound();
669 ipt_webmon();
671 ipt_write(
672 ":wanin - [0:0]\n"
673 ":wanout - [0:0]\n"
674 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" // already established or related (via helper)
675 "-A FORWARD -i %s -j wanin\n" // generic from wan
676 "-A FORWARD -o %s -j wanout\n" // generic to wan
677 "-A FORWARD -i %s -j %s\n", // from lan
678 wanface, wanface, lanface, chain_out_accept);
680 if (*manface)
681 ipt_write(
682 "-A FORWARD -i %s -j wanin\n" // generic from wan
683 "-A FORWARD -o %s -j wanout\n", // generic to wan
684 manface, manface);
686 if (nvram_get_int("upnp_enable") & 3) {
687 ipt_write(
688 ":upnp - [0:0]\n"
689 "-A FORWARD -i %s -j upnp\n",
690 wanface);
691 if (*manface)
692 ipt_write(
693 "-A FORWARD -i %s -j upnp\n",
694 manface);
697 if (wanup) {
698 if (nvram_match("multicast_pass", "1")) {
699 ipt_write("-A wanin -p udp -m udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
701 ipt_triggered(IPT_TABLE_FILTER);
702 ipt_forward(IPT_TABLE_FILTER);
704 if (dmz_dst(dst)) {
705 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
706 p = t;
707 do {
708 if ((c = strchr(p, ',')) != NULL) *c = 0;
709 ipt_source(p, src);
710 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
711 if (!c) break;
712 p = c + 1;
713 } while (*p);
718 // default policy: DROP
721 static void filter_table(void)
723 int n;
724 char limit[128];
726 ipt_write(
727 "*filter\n"
728 ":INPUT DROP [0:0]\n"
729 ":OUTPUT ACCEPT [0:0]\n"
732 n = nvram_get_int("log_limit");
733 if ((n >= 1) && (n <= 9999)) {
734 sprintf(limit, "-m limit --limit %d/m", n);
736 else {
737 limit[0] = 0;
740 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
741 ipt_write(
742 ":logdrop - [0:0]\n"
743 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \" --log-tcp-options --log-ip-options\n"
744 "-A logdrop -j DROP\n"
745 ":logreject - [0:0]\n"
746 "-A logreject %s -j LOG --log-prefix \"REJECT \" --log-tcp-options --log-ip-options\n"
747 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
748 limit, limit);
750 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
751 ipt_write(
752 ":logaccept - [0:0]\n"
753 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \" --log-tcp-options --log-ip-options\n"
754 "-A logaccept -j ACCEPT\n",
755 limit);
758 filter_input();
760 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
761 ipt_write(":FORWARD DROP [0:0]\n");
762 filter_forward();
764 else {
765 ipt_write(":FORWARD ACCEPT [0:0]\n");
766 clampmss();
768 ipt_write("COMMIT\n");
772 // -----------------------------------------------------------------------------
774 int start_firewall(void)
776 DIR *dir;
777 struct dirent *dirent;
778 char s[256];
779 char *c;
780 int n;
781 int wanproto;
782 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
784 simple_lock("firewall");
785 simple_lock("restrictions");
787 wanproto = get_wan_proto();
788 wanup = check_wanup();
792 block obviously spoofed IP addresses
794 rp_filter - BOOLEAN
795 1 - do source validation by reversed path, as specified in RFC1812
796 Recommended option for single homed hosts and stub network
797 routers. Could cause troubles for complicated (not loop free)
798 networks running a slow unreliable protocol (sort of RIP),
799 or using static routes.
800 0 - No source validation.
802 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
803 while ((dirent = readdir(dir)) != NULL) {
804 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
805 f_write_string(s, "1", 0, 0);
807 closedir(dir);
810 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
812 /* NAT performance tweaks
813 * These values can be overriden later if needed via firewall script
815 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
816 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
817 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
818 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
819 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
820 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
821 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
822 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
823 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
824 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
825 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
826 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
828 /* DoS-related tweaks */
829 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
830 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
831 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
833 n = nvram_get_int("log_in");
834 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
835 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
837 n = nvram_get_int("log_out");
838 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
839 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
840 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
842 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
844 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
846 manaddr[0] = '\0';
847 manface[0] = '\0';
849 if ((wanproto == WP_PPTP) || (wanproto == WP_L2TP) || (wanproto == WP_PPPOE)) {
850 strcpy(wanface, "ppp+");
852 else {
853 strlcpy(wanface, nvram_safe_get("wan_ifname"), sizeof(wanface));
856 strlcpy(wanaddr, get_wanip(), sizeof(wanaddr));
857 c = nvram_safe_get("wan_ipaddr");
858 if (*c && strcmp(c, wanaddr) != 0 && strcmp(c, "0.0.0.0") != 0) {
859 strlcpy(manaddr, c, sizeof(manaddr));
860 if ((wanproto == WP_PPTP) || (wanproto == WP_L2TP) || (wanproto == WP_PPPOE))
861 strlcpy(manface, nvram_safe_get("wan_ifname"), sizeof(manface));
864 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
865 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
866 strlcpy(lan_cclass, s, sizeof(lan_cclass));
868 gateway_mode = !nvram_match("wk_mode", "router");
869 if (gateway_mode) {
870 /* Remote management */
871 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
872 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
873 else remotemanage = 0;
875 if (nvram_match("remote_mgt_https", "1")) {
876 web_lanport = nvram_get_int("https_lanport");
877 if (web_lanport <= 0) web_lanport = 443;
879 else {
880 web_lanport = nvram_get_int("http_lanport");
881 if (web_lanport <= 0) web_lanport = 80;
886 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
887 notice_set("iptables", "Unable to create iptables restore file");
888 simple_unlock("firewall");
889 return 0;
892 mangle_table();
893 nat_table();
894 filter_table();
896 fclose(ipt_file);
897 ipt_file = NULL;
899 #ifdef DEBUG_IPTFILE
900 if (debug_only) {
901 simple_unlock("firewall");
902 simple_unlock("restrictions");
903 return 0;
905 #endif
907 save_webmon();
909 if (nvram_get_int("upnp_enable") & 3) {
910 f_write("/etc/upnp/save", NULL, 0, 0, 0);
911 if (killall("miniupnpd", SIGUSR2) == 0) {
912 f_wait_notexists("/etc/upnp/save", 5);
916 notice_set("iptables", "");
917 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
918 led(LED_DIAG, 0);
919 notice_set("iptables", "");
921 else {
922 sprintf(s, "%s.error", ipt_fname);
923 rename(ipt_fname, s);
924 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
925 led(LED_DIAG, 1);
929 -P INPUT DROP
930 -F INPUT
931 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
932 -A INPUT -i br0 -j ACCEPT
934 -P FORWARD DROP
935 -F FORWARD
936 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
937 -A FORWARD -i br0 -j ACCEPT
942 if (nvram_get_int("upnp_enable") & 3) {
943 f_write("/etc/upnp/load", NULL, 0, 0, 0);
944 killall("miniupnpd", SIGUSR2);
947 simple_unlock("restrictions");
948 sched_restrictions();
949 enable_ip_forward();
951 led(LED_DMZ, dmz_dst(NULL));
953 #ifdef LINUX26
954 modprobe_r("xt_layer7");
955 modprobe_r("xt_recent");
956 modprobe_r("xt_HL");
957 #else
958 modprobe_r("ipt_layer7");
959 modprobe_r("ipt_recent");
960 modprobe_r("ipt_TTL");
961 #endif
962 modprobe_r("ipt_ipp2p");
963 modprobe_r("ipt_web");
964 modprobe_r("ipt_webmon");
966 unlink("/var/webmon/domain");
967 unlink("/var/webmon/search");
969 #ifdef TCONFIG_OPENVPN
970 run_vpn_firewall_scripts();
971 #endif
972 run_nvscript("script_fire", NULL, 1);
974 simple_unlock("firewall");
975 return 0;
978 int stop_firewall(void)
980 led(LED_DMZ, 0);
981 return 0;
984 #ifdef DEBUG_IPTFILE
985 void create_test_iptfile(void)
987 debug_only = 1;
988 start_firewall();
989 debug_only = 0;
991 #endif