Build & firewall configuration: ipt_TTL->xt_HL
[tomato.git] / release / src / router / rc / firewall.c
blob7966ac545dd7a9660e0034039e55bb6500436e64
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")) {
572 switch (get_wan_proto()) {
573 case WP_PPTP:
574 if (nvram_get_int("pptp_dhcp") == 0)
575 break;
576 /* Fall through */
577 case WP_DHCP:
578 case WP_L2TP:
579 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
580 break;
581 default:
582 break;
586 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
587 p = t;
588 do {
589 if ((c = strchr(p, ',')) != NULL) *c = 0;
591 ipt_source(p, s);
593 if (remotemanage) {
594 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %d -j %s\n",
595 s, nvram_safe_get("lan_ipaddr"), web_lanport, chain_in_accept);
598 if (nvram_get_int("sshd_remote")) {
599 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %s -j %s\n",
600 s, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"), chain_in_accept);
603 if (!c) break;
604 p = c + 1;
605 } while (*p);
608 #ifdef TCONFIG_FTP // !!TB - FTP Server
609 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
610 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
611 p = t;
612 do {
613 if ((c = strchr(p, ',')) != NULL) *c = 0;
614 ipt_source(p, s);
616 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
617 s, nvram_safe_get("ftp_port"), chain_in_accept);
619 if (!c) break;
620 p = c + 1;
621 } while (*p);
623 #endif
625 // IGMP query from WAN interface
626 if (nvram_match("multicast_pass", "1")) {
627 ipt_write("-A INPUT -p igmp -j ACCEPT\n");
630 // Routing protocol, RIP, accept
631 if (nvram_invmatch("dr_wan_rx", "0")) {
632 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
635 // if logging
636 if (*chain_in_drop == 'l') {
637 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
640 // default policy: DROP
643 // clamp TCP MSS to PMTU of WAN interface
644 static void clampmss(void)
646 #if 1
647 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
648 #else
649 int rmtu = nvram_get_int("wan_run_mtu");
650 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
651 if (rmtu < 576) {
652 ipt_write("--clamp-mss-to-pmtu\n");
654 else {
655 ipt_write("--set-mss %d\n", rmtu - 40);
657 #endif
660 static void filter_forward(void)
662 char dst[64];
663 char src[64];
664 char t[512];
665 char *p, *c;
667 ipt_write(
668 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
669 "-A FORWARD -m state --state INVALID -j DROP\n", // drop if INVALID state
670 lanface, lanface);
672 // clamp tcp mss to pmtu
673 clampmss();
675 if (wanup) {
676 ipt_restrictions();
677 ipt_layer7_inbound();
680 ipt_webmon();
682 ipt_write(
683 ":wanin - [0:0]\n"
684 ":wanout - [0:0]\n"
685 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" // already established or related (via helper)
686 "-A FORWARD -i %s -j wanin\n" // generic from wan
687 "-A FORWARD -o %s -j wanout\n" // generic to wan
688 "-A FORWARD -i %s -j %s\n", // from lan
689 wanface, wanface, lanface, chain_out_accept);
691 if (*manface)
692 ipt_write(
693 "-A FORWARD -i %s -j wanin\n" // generic from wan
694 "-A FORWARD -o %s -j wanout\n", // generic to wan
695 manface, manface);
697 if (nvram_get_int("upnp_enable") & 3) {
698 ipt_write(
699 ":upnp - [0:0]\n"
700 "-A FORWARD -i %s -j upnp\n",
701 wanface);
702 if (*manface)
703 ipt_write(
704 "-A FORWARD -i %s -j upnp\n",
705 manface);
708 if (wanup) {
709 if (nvram_match("multicast_pass", "1")) {
710 ipt_write("-A wanin -p udp -m udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
712 ipt_triggered(IPT_TABLE_FILTER);
713 ipt_forward(IPT_TABLE_FILTER);
715 if (dmz_dst(dst)) {
716 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
717 p = t;
718 do {
719 if ((c = strchr(p, ',')) != NULL) *c = 0;
720 ipt_source(p, src);
721 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
722 if (!c) break;
723 p = c + 1;
724 } while (*p);
729 // default policy: DROP
732 static void filter_table(void)
734 int n;
735 char limit[128];
737 ipt_write(
738 "*filter\n"
739 ":INPUT DROP [0:0]\n"
740 ":OUTPUT ACCEPT [0:0]\n"
743 n = nvram_get_int("log_limit");
744 if ((n >= 1) && (n <= 9999)) {
745 sprintf(limit, "-m limit --limit %d/m", n);
747 else {
748 limit[0] = 0;
751 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
752 ipt_write(
753 ":logdrop - [0:0]\n"
754 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \" --log-tcp-options --log-ip-options\n"
755 "-A logdrop -j DROP\n"
756 ":logreject - [0:0]\n"
757 "-A logreject %s -j LOG --log-prefix \"REJECT \" --log-tcp-options --log-ip-options\n"
758 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
759 limit, limit);
761 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
762 ipt_write(
763 ":logaccept - [0:0]\n"
764 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \" --log-tcp-options --log-ip-options\n"
765 "-A logaccept -j ACCEPT\n",
766 limit);
769 filter_input();
771 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
772 ipt_write(":FORWARD DROP [0:0]\n");
773 filter_forward();
775 else {
776 ipt_write(":FORWARD ACCEPT [0:0]\n");
777 clampmss();
779 ipt_write("COMMIT\n");
783 // -----------------------------------------------------------------------------
785 int start_firewall(void)
787 DIR *dir;
788 struct dirent *dirent;
789 char s[256];
790 char *c;
791 int n;
792 int wanproto;
793 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
795 simple_lock("firewall");
796 simple_lock("restrictions");
798 wanproto = get_wan_proto();
799 wanup = check_wanup();
803 block obviously spoofed IP addresses
805 rp_filter - BOOLEAN
806 1 - do source validation by reversed path, as specified in RFC1812
807 Recommended option for single homed hosts and stub network
808 routers. Could cause troubles for complicated (not loop free)
809 networks running a slow unreliable protocol (sort of RIP),
810 or using static routes.
811 0 - No source validation.
813 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
814 while ((dirent = readdir(dir)) != NULL) {
815 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
816 f_write_string(s, "1", 0, 0);
818 closedir(dir);
821 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
823 /* NAT performance tweaks
824 * These values can be overriden later if needed via firewall script
826 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
827 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
828 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
829 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
830 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
831 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
832 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
833 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
834 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
835 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
836 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
837 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
839 /* DoS-related tweaks */
840 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
841 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
842 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
844 n = nvram_get_int("log_in");
845 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
846 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
848 n = nvram_get_int("log_out");
849 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
850 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
851 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
853 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
855 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
857 manaddr[0] = '\0';
858 manface[0] = '\0';
860 if ((wanproto == WP_PPTP) || (wanproto == WP_L2TP) || (wanproto == WP_PPPOE)) {
861 strcpy(wanface, "ppp+");
863 else {
864 strlcpy(wanface, nvram_safe_get("wan_ifname"), sizeof(wanface));
867 strlcpy(wanaddr, get_wanip(), sizeof(wanaddr));
868 c = nvram_safe_get("wan_ipaddr");
869 if (*c && strcmp(c, wanaddr) != 0 && strcmp(c, "0.0.0.0") != 0) {
870 strlcpy(manaddr, c, sizeof(manaddr));
871 if ((wanproto == WP_PPTP) || (wanproto == WP_L2TP) || (wanproto == WP_PPPOE))
872 strlcpy(manface, nvram_safe_get("wan_ifname"), sizeof(manface));
875 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
876 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
877 strlcpy(lan_cclass, s, sizeof(lan_cclass));
879 gateway_mode = !nvram_match("wk_mode", "router");
880 if (gateway_mode) {
881 /* Remote management */
882 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
883 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
884 else remotemanage = 0;
886 if (nvram_match("remote_mgt_https", "1")) {
887 web_lanport = nvram_get_int("https_lanport");
888 if (web_lanport <= 0) web_lanport = 443;
890 else {
891 web_lanport = nvram_get_int("http_lanport");
892 if (web_lanport <= 0) web_lanport = 80;
897 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
898 notice_set("iptables", "Unable to create iptables restore file");
899 simple_unlock("firewall");
900 return 0;
903 mangle_table();
904 nat_table();
905 filter_table();
907 fclose(ipt_file);
908 ipt_file = NULL;
910 #ifdef DEBUG_IPTFILE
911 if (debug_only) {
912 simple_unlock("firewall");
913 simple_unlock("restrictions");
914 return 0;
916 #endif
918 save_webmon();
920 if (nvram_get_int("upnp_enable") & 3) {
921 f_write("/etc/upnp/save", NULL, 0, 0, 0);
922 if (killall("miniupnpd", SIGUSR2) == 0) {
923 f_wait_notexists("/etc/upnp/save", 5);
927 notice_set("iptables", "");
928 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
929 led(LED_DIAG, 0);
930 notice_set("iptables", "");
932 else {
933 sprintf(s, "%s.error", ipt_fname);
934 rename(ipt_fname, s);
935 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
936 led(LED_DIAG, 1);
940 -P INPUT DROP
941 -F INPUT
942 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
943 -A INPUT -i br0 -j ACCEPT
945 -P FORWARD DROP
946 -F FORWARD
947 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
948 -A FORWARD -i br0 -j ACCEPT
953 if (nvram_get_int("upnp_enable") & 3) {
954 f_write("/etc/upnp/load", NULL, 0, 0, 0);
955 killall("miniupnpd", SIGUSR2);
958 simple_unlock("restrictions");
959 sched_restrictions();
960 enable_ip_forward();
962 led(LED_DMZ, dmz_dst(NULL));
964 #ifdef LINUX26
965 modprobe_r("xt_layer7");
966 modprobe_r("xt_recent");
967 modprobe_r("xt_HL");
968 #else
969 modprobe_r("ipt_layer7");
970 modprobe_r("ipt_recent");
971 modprobe_r("ipt_TTL");
972 #endif
973 modprobe_r("ipt_ipp2p");
974 modprobe_r("ipt_web");
975 modprobe_r("ipt_webmon");
977 unlink("/var/webmon/domain");
978 unlink("/var/webmon/search");
980 #ifdef TCONFIG_OPENVPN
981 run_vpn_firewall_scripts();
982 #endif
983 run_nvscript("script_fire", NULL, 1);
985 simple_unlock("firewall");
986 return 0;
989 int stop_firewall(void)
991 led(LED_DMZ, 0);
992 return 0;
995 #ifdef DEBUG_IPTFILE
996 void create_test_iptfile(void)
998 debug_only = 1;
999 start_firewall();
1000 debug_only = 0;
1002 #endif