Web monitor: add GUI and iptables support
[tomato.git] / release / src / router / rc / firewall.c
blob7c8c9d6176beeb5dbc3104dbed6dfd16bf3a4e40
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];
33 char lanface[IFNAMSIZ];
34 char lan_cclass[sizeof("xxx.xxx.xxx.")];
35 char wanaddr[sizeof("xxx.xxx.xxx.xxx")];
36 static int web_lanport;
38 #ifdef DEBUG_IPTFILE
39 static int debug_only = 0;
40 #endif
42 static int gateway_mode;
43 static int remotemanage;
44 static int wanup;
46 const char *chain_in_drop;
47 const char *chain_in_accept;
48 const char *chain_out_drop;
49 const char *chain_out_accept;
50 const char *chain_out_reject;
52 const char ipt_fname[] = "/etc/iptables";
53 FILE *ipt_file;
57 struct {
58 } firewall_data;
61 // -----------------------------------------------------------------------------
64 void enable_ip_forward(void)
67 ip_forward - BOOLEAN
68 0 - disabled (default)
69 not 0 - enabled
71 Forward Packets between interfaces.
73 This variable is special, its change resets all configuration
74 parameters to their default state (RFC1122 for hosts, RFC1812
75 for routers)
77 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
81 // -----------------------------------------------------------------------------
84 static int ip2cclass(char *ipaddr, char *new, int count)
86 int ip[4];
88 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
89 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
94 static int dmz_dst(char *s)
96 struct in_addr ia;
97 char *p;
98 int n;
100 if (nvram_get_int("dmz_enable") <= 0) return 0;
102 p = nvram_safe_get("dmz_ipaddr");
103 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
104 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
105 if (s) sprintf(s, "%s%d", lan_cclass, n);
106 return 1;
109 if (s) strcpy(s, inet_ntoa(ia));
110 return 1;
113 static void ipt_source(const char *s, char *src)
115 char p[32];
117 if ((*s) && (strlen(s) < 32))
119 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2)
120 sprintf(src, "-m iprange --src-range %s", s);
121 else
122 sprintf(src, "-s %s", s);
124 else
125 *src = 0;
129 static void get_src(const char *nv, char *src)
131 char *p;
133 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
134 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
136 else {
137 *src = 0;
142 void ipt_write(const char *format, ...)
144 va_list args;
146 va_start(args, format);
147 vfprintf(ipt_file, format, args);
148 va_end(args);
151 // -----------------------------------------------------------------------------
154 int ipt_ipp2p(const char *v, char *opt)
156 int n = atoi(v);
158 if (n == 0) {
159 *opt = 0;
160 return 0;
163 strcpy(opt, "-m ipp2p ");
164 if ((n & 0xFFF) == 0xFFF) {
165 strcat(opt, "--ipp2p");
167 else {
168 // x12
169 if (n & 0x0001) strcat(opt, "--apple ");
170 if (n & 0x0002) strcat(opt, "--ares ");
171 if (n & 0x0004) strcat(opt, "--bit ");
172 if (n & 0x0008) strcat(opt, "--dc ");
173 if (n & 0x0010) strcat(opt, "--edk ");
174 if (n & 0x0020) strcat(opt, "--gnu ");
175 if (n & 0x0040) strcat(opt, "--kazaa ");
176 if (n & 0x0080) strcat(opt, "--mute ");
177 if (n & 0x0100) strcat(opt, "--soul ");
178 if (n & 0x0200) strcat(opt, "--waste ");
179 if (n & 0x0400) strcat(opt, "--winmx ");
180 if (n & 0x0800) strcat(opt, "--xdcc ");
183 modprobe("ipt_ipp2p");
184 return 1;
188 // -----------------------------------------------------------------------------
191 char **layer7_in;
193 // This L7 matches inbound traffic, caches the results, then the L7 outbound
194 // should read the cached result and set the appropriate marks -- zzz
195 void ipt_layer7_inbound(void)
197 int en;
198 char **p;
200 if (!layer7_in) return;
202 en = nvram_match("nf_l7in", "1");
203 if (en) {
204 ipt_write(
205 ":L7in - [0:0]\n"
206 "-A FORWARD -i %s -j L7in\n",
207 wanface);
210 p = layer7_in;
211 while (*p) {
212 if (en) ipt_write("-A L7in %s -j RETURN\n", *p);
213 free(*p);
214 ++p;
216 free(layer7_in);
217 layer7_in = NULL;
220 int ipt_layer7(const char *v, char *opt)
222 char s[128];
223 char *path;
225 *opt = 0;
226 if (*v == 0) return 0;
227 if (strlen(v) > 32) return -1;
229 path = "/etc/l7-extra";
230 sprintf(s, "%s/%s.pat", path, v);
231 if (!f_exists(s)) {
232 path = "/etc/l7-protocols";
233 sprintf(s, "%s/%s.pat", path, v);
234 if (!f_exists(s)) {
235 syslog(LOG_ERR, "L7 %s was not found", v);
236 return -1;
240 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
242 if (nvram_match("nf_l7in", "1")) {
243 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
244 if (layer7_in) {
245 char **p;
247 p = layer7_in;
248 while (*p) {
249 if (strcmp(*p, opt) == 0) return 1;
250 ++p;
252 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
256 #ifdef LINUX26
257 modprobe("xt_layer7");
258 #else
259 modprobe("ipt_layer7");
260 #endif
261 return 1;
265 // -----------------------------------------------------------------------------
267 static void save_webmon(void)
269 system("cp /proc/webmon_recent_domains /var/webmon/domain");
270 system("cp /proc/webmon_recent_searches /var/webmon/search");
273 static void ipt_webmon(void)
275 int wmtype;
277 if (!nvram_get_int("log_wm")) return;
278 wmtype = nvram_get_int("log_wmtype");
280 ipt_write(
281 ":monitor - [0:0]\n"
282 "-A FORWARD -o %s -j monitor\n",
283 wanface);
285 ipt_write(
286 "-A monitor -m webmon "
287 "--max_domains %d --max_searches %d %s%s "
288 "--search_load_file /var/webmon/search "
289 "--domain_load_file /var/webmon/domain\n",
290 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
291 wmtype == 1 ? "--include_ips " : wmtype == 2 ? "--exclude_ips " : "",
292 wmtype == 0 ? "" : nvram_safe_get("log_wmip"));
294 modprobe("ipt_webmon");
298 // -----------------------------------------------------------------------------
299 // MANGLE
300 // -----------------------------------------------------------------------------
302 static void mangle_table(void)
304 int ttl;
305 char *p;
307 ipt_write(
308 "*mangle\n"
309 ":PREROUTING ACCEPT [0:0]\n"
310 ":OUTPUT ACCEPT [0:0]\n");
312 if (wanup) {
313 ipt_qos();
315 ttl = nvram_get_int("nf_ttl");
316 if (ttl != 0) {
317 modprobe("ipt_TTL");
318 if (ttl > 0) {
319 p = "in";
321 else {
322 ttl = -ttl;
323 p = "de";
325 ipt_write(
326 "-I PREROUTING -i %s -j TTL --ttl-%sc %d\n"
327 "-I POSTROUTING -o %s -j TTL --ttl-%sc %d\n",
328 wanface, p, ttl,
329 wanface, p, ttl);
333 ipt_write("COMMIT\n");
338 // -----------------------------------------------------------------------------
339 // NAT
340 // -----------------------------------------------------------------------------
342 static void nat_table(void)
344 char lanaddr[32];
345 char lanmask[32];
346 char dst[64];
347 char src[64];
348 char t[512];
349 char *p, *c;
351 ipt_write("*nat\n"
352 ":PREROUTING ACCEPT [0:0]\n"
353 ":POSTROUTING ACCEPT [0:0]\n"
354 ":OUTPUT ACCEPT [0:0]\n");
355 if (gateway_mode) {
356 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
357 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
359 // Drop incoming packets which destination IP address is to our LAN side directly
360 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
361 wanface,
362 lanaddr, lanmask); // note: ipt will correct lanaddr
364 if (wanup) {
365 if (nvram_match("dns_intcpt", "1")) {
366 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
367 lanaddr, lanmask,
368 lanaddr, lanmask,
369 lanaddr);
372 // ICMP packets are always redirected to INPUT chains
373 ipt_write("-A PREROUTING -p icmp -d %s -j DNAT --to-destination %s\n", wanaddr, lanaddr);
376 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
377 p = t;
378 do {
379 if ((c = strchr(p, ',')) != NULL) *c = 0;
380 ipt_source(p, src);
382 if (remotemanage) {
383 ipt_write("-A PREROUTING -p tcp -m tcp %s -d %s --dport %s -j DNAT --to-destination %s:%d\n",
384 src,
385 wanaddr, nvram_safe_get("http_wanport"),
386 lanaddr, web_lanport);
388 if (nvram_get_int("sshd_remote")) {
389 ipt_write("-A PREROUTING %s -p tcp -m tcp -d %s --dport %s -j DNAT --to-destination %s:%s\n",
390 src,
391 wanaddr, nvram_safe_get("sshd_rport"),
392 lanaddr, nvram_safe_get("sshd_port"));
395 if (!c) break;
396 p = c + 1;
397 } while (*p);
399 ipt_forward(IPT_TABLE_NAT);
400 ipt_triggered(IPT_TABLE_NAT);
403 if (nvram_get_int("upnp_enable") & 3) {
404 ipt_write(":upnp - [0:0]\n");
405 if (wanup) {
406 // ! for loopback (all) to work
407 ipt_write("-A PREROUTING -d %s -j upnp\n", wanaddr);
409 else {
410 ipt_write("-A PREROUTING -i %s -j upnp\n", wanface);
414 if (wanup) {
415 if (dmz_dst(dst)) {
416 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
417 p = t;
418 do {
419 if ((c = strchr(p, ',')) != NULL) *c = 0;
420 ipt_source(p, src);
421 ipt_write("-A PREROUTING %s -d %s -j DNAT --to-destination %s\n", src, wanaddr, dst);
422 if (!c) break;
423 p = c + 1;
424 } while (*p);
428 if ((!wanup) || (nvram_get_int("net_snat") != 1)) {
429 ipt_write("-A POSTROUTING -o %s -j MASQUERADE\n", wanface);
431 else {
432 ipt_write("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wanface, wanaddr);
435 switch (nvram_get_int("nf_loopback")) {
436 case 1: // 1 = forwarded-only
437 case 2: // 2 = disable
438 break;
439 default: // 0 = all (same as block_loopback=0)
440 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
441 lanface,
442 lanaddr, lanmask,
443 lanaddr, lanmask,
444 lanaddr);
445 break;
448 ipt_write("COMMIT\n");
451 // -----------------------------------------------------------------------------
452 // FILTER
453 // -----------------------------------------------------------------------------
455 static void filter_input(void)
457 char s[64];
458 char t[512];
459 char *en;
460 char *sec;
461 char *hit;
462 int n;
463 char *p, *c;
465 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
466 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanaddr);
469 ipt_write(
470 "-A INPUT -m state --state INVALID -j %s\n"
471 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
472 chain_in_drop);
475 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
476 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
478 ? what if the user uses the start button in GUI ?
479 if (nvram_get_int("telnetd_eas"))
480 if (nvram_get_int("sshd_eas"))
482 #ifdef LINUX26
483 modprobe("xt_recent");
484 #else
485 modprobe("ipt_recent");
486 #endif
488 ipt_write(
489 "-N shlimit\n"
490 "-A shlimit -m recent --set --name shlimit\n"
491 "-A shlimit -m recent --update --hitcount %s --seconds %s --name shlimit -j DROP\n",
492 hit, sec);
494 if (n & 1) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
495 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
498 #ifdef TCONFIG_FTP
499 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
500 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
501 #ifdef LINUX26
502 modprobe("xt_recent");
503 #else
504 modprobe("ipt_recent");
505 #endif
507 ipt_write(
508 "-N ftplimit\n"
509 "-A ftplimit -m recent --set --name ftp\n"
510 "-A ftplimit -m recent --update --hitcount %s --seconds %s --name ftp -j DROP\n",
511 hit, sec);
512 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
514 #endif
516 ipt_write(
517 "-A INPUT -i %s -j ACCEPT\n"
518 "-A INPUT -i lo -j ACCEPT\n",
519 lanface);
521 // ICMP request from WAN interface
522 if (nvram_match("block_wan", "0")) {
523 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
524 // allow udp traceroute packets
525 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -j %s\n", chain_in_accept);
528 /* Accept incoming packets from broken dhcp servers, which are sending replies
529 * from addresses other than used for query. This could lead to a lower level
530 * of security, so allow to disable it via nvram variable.
532 if (nvram_invmatch("dhcp_pass", "0")) {
533 switch (get_wan_proto()) {
534 case WP_PPTP:
535 if (nvram_get_int("pptp_dhcp") == 0)
536 break;
537 /* Fall through */
538 case WP_DHCP:
539 case WP_L2TP:
540 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
541 break;
542 default:
543 break;
547 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
548 p = t;
549 do {
550 if ((c = strchr(p, ',')) != NULL) *c = 0;
552 ipt_source(p, s);
554 if (remotemanage) {
555 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %d -j %s\n",
556 s, nvram_safe_get("lan_ipaddr"), web_lanport, chain_in_accept);
559 if (nvram_get_int("sshd_remote")) {
560 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %s -j %s\n",
561 s, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"), chain_in_accept);
564 if (!c) break;
565 p = c + 1;
566 } while (*p);
569 #ifdef TCONFIG_FTP // !!TB - FTP Server
570 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
571 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
572 p = t;
573 do {
574 if ((c = strchr(p, ',')) != NULL) *c = 0;
575 ipt_source(p, s);
577 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
578 s, nvram_safe_get("ftp_port"), chain_in_accept);
580 if (!c) break;
581 p = c + 1;
582 } while (*p);
584 #endif
586 // IGMP query from WAN interface
587 if (nvram_match("multicast_pass", "1")) {
588 ipt_write("-A INPUT -p igmp -j ACCEPT\n");
591 // Routing protocol, RIP, accept
592 if (nvram_invmatch("dr_wan_rx", "0")) {
593 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
596 // if logging
597 if (*chain_in_drop == 'l') {
598 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
601 // default policy: DROP
604 // clamp TCP MSS to PMTU of WAN interface
605 static void clampmss(void)
607 #if 1
608 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
609 #else
610 int rmtu = nvram_get_int("wan_run_mtu");
611 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
612 if (rmtu < 576) {
613 ipt_write("--clamp-mss-to-pmtu\n");
615 else {
616 ipt_write("--set-mss %d\n", rmtu - 40);
618 #endif
621 static void filter_forward(void)
623 char dst[64];
624 char src[64];
625 char t[512];
626 char *p, *c;
628 ipt_write(
629 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
630 "-A FORWARD -m state --state INVALID -j DROP\n", // drop if INVALID state
631 lanface, lanface);
633 // clamp tcp mss to pmtu
634 clampmss();
636 if (wanup) {
637 ipt_restrictions();
638 ipt_layer7_inbound();
641 ipt_webmon();
643 ipt_write(
644 ":wanin - [0:0]\n"
645 ":wanout - [0:0]\n"
646 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" // already established or related (via helper)
647 "-A FORWARD -i %s -j wanin\n" // generic from wan
648 "-A FORWARD -o %s -j wanout\n" // generic to wan
649 "-A FORWARD -i %s -j %s\n", // from lan
650 wanface, wanface, lanface, chain_out_accept);
652 if (nvram_get_int("upnp_enable") & 3) {
653 ipt_write(
654 ":upnp - [0:0]\n"
655 "-A FORWARD -i %s -j upnp\n",
656 wanface);
659 if (wanup) {
660 if (nvram_match("multicast_pass", "1")) {
661 ipt_write("-A wanin -p udp -m udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
663 ipt_triggered(IPT_TABLE_FILTER);
664 ipt_forward(IPT_TABLE_FILTER);
666 if (dmz_dst(dst)) {
667 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
668 p = t;
669 do {
670 if ((c = strchr(p, ',')) != NULL) *c = 0;
671 ipt_source(p, src);
672 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
673 if (!c) break;
674 p = c + 1;
675 } while (*p);
680 // default policy: DROP
683 static void filter_table(void)
685 int n;
686 char limit[128];
688 ipt_write(
689 "*filter\n"
690 ":INPUT DROP [0:0]\n"
691 ":OUTPUT ACCEPT [0:0]\n"
694 n = nvram_get_int("log_limit");
695 if ((n >= 1) && (n <= 9999)) {
696 sprintf(limit, "-m limit --limit %d/m", n);
698 else {
699 limit[0] = 0;
702 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
703 ipt_write(
704 ":logdrop - [0:0]\n"
705 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \" --log-tcp-options --log-ip-options\n"
706 "-A logdrop -j DROP\n"
707 ":logreject - [0:0]\n"
708 "-A logreject %s -j LOG --log-prefix \"REJECT \" --log-tcp-options --log-ip-options\n"
709 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
710 limit, limit);
712 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
713 ipt_write(
714 ":logaccept - [0:0]\n"
715 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \" --log-tcp-options --log-ip-options\n"
716 "-A logaccept -j ACCEPT\n",
717 limit);
720 filter_input();
722 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
723 ipt_write(":FORWARD DROP [0:0]\n");
724 filter_forward();
726 else {
727 ipt_write(":FORWARD ACCEPT [0:0]\n");
728 clampmss();
729 ipt_webmon();
731 ipt_write("COMMIT\n");
735 // -----------------------------------------------------------------------------
737 int start_firewall(void)
739 DIR *dir;
740 struct dirent *dirent;
741 char s[256];
742 char *c;
743 int n;
744 int wanproto;
746 simple_lock("firewall");
747 simple_lock("restrictions");
749 wanproto = get_wan_proto();
750 wanup = check_wanup();
754 block obviously spoofed IP addresses
756 rp_filter - BOOLEAN
757 1 - do source validation by reversed path, as specified in RFC1812
758 Recommended option for single homed hosts and stub network
759 routers. Could cause troubles for complicated (not loop free)
760 networks running a slow unreliable protocol (sort of RIP),
761 or using static routes.
762 0 - No source validation.
764 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
765 while ((dirent = readdir(dir)) != NULL) {
766 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
767 f_write_string(s, "1", 0, 0);
769 closedir(dir);
772 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
774 /* NAT performance tweaks
775 * These values can be overriden later if needed via firewall script
777 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
778 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
779 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
780 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
781 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
782 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
783 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
784 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
785 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
786 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
787 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
788 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
790 /* DoS-related tweaks */
791 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
792 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
793 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
795 n = nvram_get_int("log_in");
796 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
797 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
799 n = nvram_get_int("log_out");
800 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
801 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
802 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
804 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
806 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
808 if ((wanproto == WP_PPTP) || (wanproto == WP_L2TP) || (wanproto == WP_PPPOE)) {
809 strcpy(wanface, "ppp+");
811 else {
812 strlcpy(wanface, nvram_safe_get("wan_ifname"), sizeof(wanface));
815 strlcpy(wanaddr, get_wanip(), sizeof(wanaddr));
817 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
818 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
819 strlcpy(lan_cclass, s, sizeof(lan_cclass));
821 gateway_mode = !nvram_match("wk_mode", "router");
822 if (gateway_mode) {
823 /* Remote management */
824 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
825 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
826 else remotemanage = 0;
828 if (nvram_match("remote_mgt_https", "1")) {
829 web_lanport = nvram_get_int("https_lanport");
830 if (web_lanport <= 0) web_lanport = 443;
832 else {
833 web_lanport = nvram_get_int("http_lanport");
834 if (web_lanport <= 0) web_lanport = 80;
839 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
840 syslog(LOG_CRIT, "Unable to create iptables restore file");
841 simple_unlock("firewall");
842 return 0;
845 mangle_table();
846 nat_table();
847 filter_table();
849 fclose(ipt_file);
850 ipt_file = NULL;
852 #ifdef DEBUG_IPTFILE
853 if (debug_only) {
854 simple_unlock("firewall");
855 simple_unlock("restrictions");
856 return 0;
858 #endif
860 save_webmon();
862 if (nvram_get_int("upnp_enable") & 3) {
863 f_write("/etc/upnp/save", NULL, 0, 0, 0);
864 if (killall("miniupnpd", SIGUSR2) == 0) {
865 f_wait_notexists("/etc/upnp/save", 5);
869 if (eval("iptables-restore", (char *)ipt_fname) == 0) {
870 led(LED_DIAG, 0);
872 else {
873 sprintf(s, "%s.error", ipt_fname);
874 rename(ipt_fname, s);
875 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
876 led(LED_DIAG, 1);
880 -P INPUT DROP
881 -F INPUT
882 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
883 -A INPUT -i br0 -j ACCEPT
885 -P FORWARD DROP
886 -F FORWARD
887 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
888 -A FORWARD -i br0 -j ACCEPT
893 if (nvram_get_int("upnp_enable") & 3) {
894 f_write("/etc/upnp/load", NULL, 0, 0, 0);
895 killall("miniupnpd", SIGUSR2);
898 simple_unlock("restrictions");
899 sched_restrictions();
900 enable_ip_forward();
902 led(LED_DMZ, dmz_dst(NULL));
904 #ifdef LINUX26
905 modprobe_r("xt_layer7");
906 #else
907 modprobe_r("ipt_layer7");
908 #endif
909 modprobe_r("ipt_ipp2p");
910 modprobe_r("ipt_web");
911 modprobe_r("ipt_TTL");
912 modprobe_r("ipt_webmon");
914 unlink("/var/webmon/domain");
915 unlink("/var/webmon/search");
917 #ifdef TCONFIG_OPENVPN
918 run_vpn_firewall_scripts();
919 #endif
920 run_nvscript("script_fire", NULL, 1);
922 simple_unlock("firewall");
923 return 0;
926 int stop_firewall(void)
928 led(LED_DMZ, 0);
929 return 0;
932 #ifdef DEBUG_IPTFILE
933 void create_test_iptfile(void)
935 debug_only = 1;
936 start_firewall();
937 debug_only = 0;
939 #endif