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
29 #include <arpa/inet.h>
32 char wanface
[IFNAMSIZ
+ 1];
33 char manface
[IFNAMSIZ
+ 1];
34 char lanface
[IFNAMSIZ
+ 1];
36 char wan6face
[IFNAMSIZ
+ 1];
38 char wanaddr
[sizeof("xxx.xxx.xxx.xxx") + 1];
39 char manaddr
[sizeof("xxx.xxx.xxx.xxx") + 1];
40 char lan_cclass
[sizeof("xxx.xxx.xxx.") + 1];
41 static int web_lanport
;
44 static int debug_only
= 0;
47 static int gateway_mode
;
48 static int remotemanage
;
51 const char *chain_in_drop
;
52 const char *chain_in_accept
;
53 const char *chain_out_drop
;
54 const char *chain_out_accept
;
55 const char *chain_out_reject
;
57 const char chain_wan_prerouting
[] = "WANPREROUTING";
58 const char ipt_fname
[] = "/etc/iptables";
62 const char ip6t_fname
[] = "/etc/ip6tables";
72 // -----------------------------------------------------------------------------
75 void enable_ip_forward(void)
79 0 - disabled (default)
82 Forward Packets between interfaces.
84 This variable is special, its change resets all configuration
85 parameters to their default state (RFC1122 for hosts, RFC1812
88 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
92 // -----------------------------------------------------------------------------
95 static int ip2cclass(char *ipaddr, char *new, int count)
99 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
100 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
105 static int dmz_dst(char *s
)
111 if (nvram_get_int("dmz_enable") <= 0) return 0;
113 p
= nvram_safe_get("dmz_ipaddr");
114 if ((ia
.s_addr
= inet_addr(p
)) == (in_addr_t
)-1) {
115 if (((n
= atoi(p
)) <= 0) || (n
>= 255)) return 0;
116 if (s
) sprintf(s
, "%s%d", lan_cclass
, n
);
120 if (s
) strcpy(s
, inet_ntoa(ia
));
124 void ipt_addr(char *addr
, int maxlen
, const char *s
, const char *dir
)
130 if (sscanf(s
, "%[0-9.]-%[0-9.]", p
, p
) == 2)
131 snprintf(addr
, maxlen
, "-m iprange --%s-range %s", dir
, s
);
133 snprintf(addr
, maxlen
, "-%c %s", dir
[0], s
);
139 static inline void ipt_source(const char *s
, char *src
)
141 ipt_addr(src
, 64, s
, "src");
145 static void get_src(const char *nv, char *src)
149 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
150 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
158 void ipt_write(const char *format
, ...)
162 va_start(args
, format
);
163 vfprintf(ipt_file
, format
, args
);
167 void ip6t_write(const char *format
, ...)
172 va_start(args
, format
);
173 vfprintf(ip6t_file
, format
, args
);
178 // -----------------------------------------------------------------------------
181 int ipt_ipp2p(const char *v
, char *opt
)
190 strcpy(opt
, "-m ipp2p ");
191 if ((n
& 0xFFF) == 0xFFF) {
192 strcat(opt
, "--ipp2p");
196 if (n
& 0x0001) strcat(opt
, "--apple ");
197 if (n
& 0x0002) strcat(opt
, "--ares ");
198 if (n
& 0x0004) strcat(opt
, "--bit ");
199 if (n
& 0x0008) strcat(opt
, "--dc ");
200 if (n
& 0x0010) strcat(opt
, "--edk ");
201 if (n
& 0x0020) strcat(opt
, "--gnu ");
202 if (n
& 0x0040) strcat(opt
, "--kazaa ");
203 if (n
& 0x0080) strcat(opt
, "--mute ");
204 if (n
& 0x0100) strcat(opt
, "--soul ");
205 if (n
& 0x0200) strcat(opt
, "--waste ");
206 if (n
& 0x0400) strcat(opt
, "--winmx ");
207 if (n
& 0x0800) strcat(opt
, "--xdcc ");
210 modprobe("ipt_ipp2p");
215 // -----------------------------------------------------------------------------
220 // This L7 matches inbound traffic, caches the results, then the L7 outbound
221 // should read the cached result and set the appropriate marks -- zzz
222 void ipt_layer7_inbound(void)
227 if (!layer7_in
) return;
229 en
= nvram_match("nf_l7in", "1");
233 "-A FORWARD -i %s -j L7in\n",
237 "-A FORWARD -i %s -j L7in\n",
243 if (en
) ipt_write("-A L7in %s -j RETURN\n", *p
);
251 int ipt_layer7(const char *v
, char *opt
)
257 if (*v
== 0) return 0;
258 if (strlen(v
) > 32) return -1;
260 path
= "/etc/l7-extra";
261 sprintf(s
, "%s/%s.pat", path
, v
);
263 path
= "/etc/l7-protocols";
264 sprintf(s
, "%s/%s.pat", path
, v
);
266 syslog(LOG_ERR
, "L7 %s was not found", v
);
271 sprintf(opt
, "-m layer7 --l7dir %s --l7proto %s", path
, v
);
273 if (nvram_match("nf_l7in", "1")) {
274 if (!layer7_in
) layer7_in
= calloc(51, sizeof(char *));
280 if (strcmp(*p
, opt
) == 0) return 1;
283 if (((p
- layer7_in
) / sizeof(char *)) < 50) *p
= strdup(opt
);
288 modprobe("xt_layer7");
290 modprobe("ipt_layer7");
296 // -----------------------------------------------------------------------------
298 static void save_webmon(void)
300 system("cp /proc/webmon_recent_domains /var/webmon/domain");
301 system("cp /proc/webmon_recent_searches /var/webmon/search");
304 static void ipt_webmon(void)
308 if (!nvram_get_int("log_wm")) return;
309 wmtype
= nvram_get_int("log_wmtype");
310 clear
= nvram_get_int("log_wmclear");
314 "-A FORWARD -o %s -j monitor\n",
318 "-A FORWARD -o %s -j monitor\n",
322 "-A monitor -m webmon "
323 "--max_domains %d --max_searches %d %s%s %s %s\n",
324 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
325 wmtype
== 1 ? "--include_ips " : wmtype
== 2 ? "--exclude_ips " : "",
326 wmtype
== 0 ? "" : nvram_safe_get("log_wmip"),
327 (clear
& 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
328 (clear
& 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
330 modprobe("ipt_webmon");
334 // -----------------------------------------------------------------------------
336 // -----------------------------------------------------------------------------
338 static void mangle_table(void)
345 ":PREROUTING ACCEPT [0:0]\n"
346 ":OUTPUT ACCEPT [0:0]\n");
352 p
= nvram_safe_get("nf_ttl");
353 if (strncmp(p
, "c:", 2) == 0) {
356 p
= (ttl
>= 0 && ttl
<= 255) ? "set" : NULL
;
358 else if ((ttl
= atoi(p
)) != 0) {
366 if (ttl
> 255) p
= NULL
;
377 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
378 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
384 ip46t_write("COMMIT\n");
389 // -----------------------------------------------------------------------------
391 // -----------------------------------------------------------------------------
393 static void nat_table(void)
403 ":PREROUTING ACCEPT [0:0]\n"
404 ":POSTROUTING ACCEPT [0:0]\n"
405 ":OUTPUT ACCEPT [0:0]\n"
407 chain_wan_prerouting
);
410 strlcpy(lanaddr
, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr
));
411 strlcpy(lanmask
, nvram_safe_get("lan_netmask"), sizeof(lanmask
));
413 // chain_wan_prerouting
415 ipt_write("-A PREROUTING -d %s -j %s\n", wanaddr
, chain_wan_prerouting
);
417 ipt_write("-A PREROUTING -d %s -j %s\n", manaddr
, chain_wan_prerouting
);
419 // Drop incoming packets which destination IP address is to our LAN side directly
420 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
422 lanaddr
, lanmask
); // note: ipt will correct lanaddr
424 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
426 lanaddr
, lanmask
); // note: ipt will correct lanaddr
429 if (nvram_match("dns_intcpt", "1")) {
430 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
436 // ICMP packets are always redirected to INPUT chains
437 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting
, lanaddr
);
439 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
442 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
446 ipt_write("-A %s -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
447 chain_wan_prerouting
,
449 nvram_safe_get("http_wanport"),
450 lanaddr
, web_lanport
);
452 if (nvram_get_int("sshd_remote")) {
453 ipt_write("-A %s %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
454 chain_wan_prerouting
,
456 nvram_safe_get("sshd_rport"),
457 lanaddr
, nvram_safe_get("sshd_port"));
464 ipt_forward(IPT_TABLE_NAT
);
465 ipt_triggered(IPT_TABLE_NAT
);
468 if (nvram_get_int("upnp_enable") & 3) {
469 ipt_write(":upnp - [0:0]\n");
471 // ! for loopback (all) to work
472 ipt_write("-A %s -j upnp\n", chain_wan_prerouting
);
475 ipt_write("-A PREROUTING -i %s -j upnp\n", wanface
);
477 ipt_write("-A PREROUTING -i %s -j upnp\n", manface
);
483 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
486 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
488 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting
, src
, dst
);
495 if ((!wanup
) || (nvram_get_int("net_snat") != 1)) {
496 ipt_write("-A POSTROUTING -o %s -j MASQUERADE\n", wanface
);
498 ipt_write("-A POSTROUTING -o %s -j MASQUERADE\n", manface
);
501 ipt_write("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wanface
, wanaddr
);
502 if (*manface
&& *manaddr
)
503 ipt_write("-A POSTROUTING -o %s -j SNAT --to-source %s\n", manface
, manaddr
);
506 switch (nvram_get_int("nf_loopback")) {
507 case 1: // 1 = forwarded-only
508 case 2: // 2 = disable
510 default: // 0 = all (same as block_loopback=0)
511 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
519 ipt_write("COMMIT\n");
522 // -----------------------------------------------------------------------------
524 // -----------------------------------------------------------------------------
526 static void filter_input(void)
536 if ((nvram_get_int("nf_loopback") != 0) && (wanup
)) { // 0 = all
537 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface
, wanaddr
);
539 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface
, manaddr
);
543 "-A INPUT -m state --state INVALID -j %s\n"
544 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
548 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
549 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
551 ? what if the user uses the start button in GUI ?
552 if (nvram_get_int("telnetd_eas"))
553 if (nvram_get_int("sshd_eas"))
556 modprobe("xt_recent");
558 modprobe("ipt_recent");
563 "-A shlimit -m recent --set --name shlimit\n"
564 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
565 atoi(hit
) + 1, sec
, chain_in_drop
);
567 if (n
& 1) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
568 if (n
& 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
572 strlcpy(s
, nvram_safe_get("ftp_limit"), sizeof(s
));
573 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && (atoi(en
)) && (nvram_get_int("ftp_enable") == 1)) {
575 modprobe("xt_recent");
577 modprobe("ipt_recent");
582 "-A ftplimit -m recent --set --name ftp\n"
583 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
584 atoi(hit
) + 1, sec
, chain_in_drop
);
585 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
590 "-A INPUT -i %s -j ACCEPT\n"
591 "-A INPUT -i lo -j ACCEPT\n",
594 // ICMP request from WAN interface
595 if (nvram_match("block_wan", "0")) {
596 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
597 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept
);
598 // allow udp traceroute packets
599 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept
);
602 /* Accept incoming packets from broken dhcp servers, which are sending replies
603 * from addresses other than used for query. This could lead to a lower level
604 * of security, so allow to disable it via nvram variable.
606 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
607 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept
);
610 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
613 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
618 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %d -j %s\n",
619 s
, nvram_safe_get("lan_ipaddr"), web_lanport
, chain_in_accept
);
622 if (nvram_get_int("sshd_remote")) {
623 ipt_write("-A INPUT -p tcp %s -m tcp -d %s --dport %s -j %s\n",
624 s
, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"), chain_in_accept
);
632 #ifdef TCONFIG_FTP // !!TB - FTP Server
633 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
634 strlcpy(t
, nvram_safe_get("ftp_sip"), sizeof(t
));
637 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
640 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
641 s
, nvram_safe_get("ftp_port"), chain_in_accept
);
649 // IGMP query from WAN interface
650 if (nvram_match("multicast_pass", "1")) {
651 ipt_write("-A INPUT -p igmp -j ACCEPT\n");
654 // Routing protocol, RIP, accept
655 if (nvram_invmatch("dr_wan_rx", "0")) {
656 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
660 if (*chain_in_drop
== 'l') {
661 ipt_write( "-A INPUT -j %s\n", chain_in_drop
);
664 // default policy: DROP
667 // clamp TCP MSS to PMTU of WAN interface
668 static void clampmss(void)
671 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
673 int rmtu
= nvram_get_int("wan_run_mtu");
674 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu
- 39);
676 ipt_write("--clamp-mss-to-pmtu\n");
679 ipt_write("--set-mss %d\n", rmtu
- 40);
684 static void filter_forward(void)
692 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
693 "-A FORWARD -m state --state INVALID -j DROP\n", // drop if INVALID state
696 // clamp tcp mss to pmtu
701 ipt_layer7_inbound();
709 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" // already established or related (via helper)
710 "-A FORWARD -i %s -j wanin\n" // generic from wan
711 "-A FORWARD -o %s -j wanout\n" // generic to wan
712 "-A FORWARD -i %s -j %s\n", // from lan
713 wanface
, wanface
, lanface
, chain_out_accept
);
717 "-A FORWARD -i %s -j wanin\n" // generic from wan
718 "-A FORWARD -o %s -j wanout\n", // generic to wan
721 if (nvram_get_int("upnp_enable") & 3) {
724 "-A FORWARD -i %s -j upnp\n",
728 "-A FORWARD -i %s -j upnp\n",
733 if (nvram_match("multicast_pass", "1")) {
734 ipt_write("-A wanin -p udp -m udp -d 224.0.0.0/4 -j %s\n", chain_in_accept
);
736 ipt_triggered(IPT_TABLE_FILTER
);
737 ipt_forward(IPT_TABLE_FILTER
);
740 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
743 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
745 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface
, src
, dst
, chain_in_accept
);
753 // default policy: DROP
756 static void filter_log(void)
761 n
= nvram_get_int("log_limit");
762 if ((n
>= 1) && (n
<= 9999)) {
763 sprintf(limit
, "-m limit --limit %d/m", n
);
769 if ((*chain_in_drop
== 'l') || (*chain_out_drop
== 'l')) {
772 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \" --log-tcp-options --log-ip-options\n"
773 "-A logdrop -j DROP\n"
774 ":logreject - [0:0]\n"
775 "-A logreject %s -j LOG --log-prefix \"REJECT \" --log-tcp-options --log-ip-options\n"
776 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
779 if ((*chain_in_accept
== 'l') || (*chain_out_accept
== 'l')) {
781 ":logaccept - [0:0]\n"
782 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \" --log-tcp-options --log-ip-options\n"
783 "-A logaccept -j ACCEPT\n",
789 static void filter6_input(void)
798 "-A INPUT -m rt --rt-type 0 -j %s\n"
799 /* "-A INPUT -m state --state INVALID -j %s\n" */
800 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
801 chain_in_drop
/*, chain_in_drop*/);
804 modprobe("xt_length");
805 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
807 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
808 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
810 ? what if the user uses the start button in GUI ?
811 if (nvram_get_int("telnetd_eas"))
812 if (nvram_get_int("sshd_eas"))
814 modprobe("xt_recent");
818 "-A shlimit -m recent --set --name shlimit\n"
819 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
820 atoi(hit
) + 1, sec
, chain_in_drop
);
823 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface
, nvram_safe_get("sshd_port"));
824 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
825 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
828 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"));
833 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
834 "-A INPUT -i lo -j ACCEPT\n",
838 const int allowed_icmpv6
[6] = { 1, 2, 3, 4, 128, 129 };
839 for (n
= 0; n
< sizeof(allowed_icmpv6
)/sizeof(int); n
++) {
840 ip6t_write("-A INPUT -p icmpv6 --icmpv6-type %i -j %s\n", allowed_icmpv6
[n
], chain_in_accept
);
844 // TODO: create list for allowed remote ipv6 addresses? currently: unrestricted by src addr
846 ip6t_write("-A INPUT -p tcp -m tcp --dport %s -j %s\n",
847 nvram_safe_get("http_wanport"), chain_in_accept
);
850 if (nvram_get_int("sshd_remote")) {
851 ip6t_write("-A INPUT -p tcp -m tcp --dport %s -j %s\n",
852 nvram_safe_get("sshd_rport"), chain_in_accept
);
858 if (*chain_in_drop
== 'l') {
859 ip6t_write( "-A INPUT -j %s\n", chain_in_drop
);
862 // default policy: DROP
865 static void filter6_forward(void)
870 "-A FORWARD -m rt --rt-type 0 -j DROP\n"
871 "-A FORWARD -i %s -o %s -j ACCEPT\n" // accept all lan to lan
872 /*"-A FORWARD -m state --state INVALID -j DROP\n"*/, // drop if INVALID state
876 modprobe("xt_length");
877 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
881 // clamp tcp mss to pmtu TODO?
884 // TODO: support l7, restrictions, webmon on ipv6?
887 ipt_layer7_inbound();
895 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" // already established or related (via helper)
896 "-A FORWARD -i %s -j wanin\n" // generic from wan
897 "-A FORWARD -o %s -j wanout\n" // generic to wan
898 "-A FORWARD -i %s -j %s\n", // from lan
899 wan6face
, wan6face
, lanface
, chain_out_accept
);
902 const int allowed_icmpv6
[6] = { 1, 2, 3, 4, 128, 129 };
903 for (n
= 0; n
< sizeof(allowed_icmpv6
)/sizeof(int); n
++) {
904 ip6t_write("-A FORWARD -p icmpv6 --icmpv6-type %i -j %s\n", allowed_icmpv6
[n
], chain_in_accept
);
908 //ipt_triggered(IPT_TABLE_FILTER);
912 // default policy: DROP
917 static void filter_table(void)
921 ":INPUT DROP [0:0]\n"
922 ":OUTPUT ACCEPT [0:0]\n"
931 if ((gateway_mode
) || (nvram_match("wk_mode_x", "1"))) {
932 ip46t_write(":FORWARD DROP [0:0]\n");
939 ip46t_write(":FORWARD ACCEPT [0:0]\n");
942 ip46t_write("COMMIT\n");
946 // -----------------------------------------------------------------------------
948 int start_firewall(void)
951 struct dirent
*dirent
;
956 char *iptrestore_argv
[] = { "iptables-restore", (char *)ipt_fname
, NULL
};
958 char *ip6trestore_argv
[] = { "ip6tables-restore", (char *)ip6t_fname
, NULL
};
961 simple_lock("firewall");
962 simple_lock("restrictions");
964 wanproto
= get_wan_proto();
965 wanup
= check_wanup();
969 block obviously spoofed IP addresses
972 1 - do source validation by reversed path, as specified in RFC1812
973 Recommended option for single homed hosts and stub network
974 routers. Could cause troubles for complicated (not loop free)
975 networks running a slow unreliable protocol (sort of RIP),
976 or using static routes.
977 0 - No source validation.
979 if ((dir
= opendir("/proc/sys/net/ipv4/conf")) != NULL
) {
980 while ((dirent
= readdir(dir
)) != NULL
) {
981 sprintf(s
, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent
->d_name
);
982 f_write_string(s
, "1", 0, 0);
987 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
989 /* NAT performance tweaks
990 * These values can be overriden later if needed via firewall script
992 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
993 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
994 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
995 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
996 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
997 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
998 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
999 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1000 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1001 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1002 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1003 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1005 /* DoS-related tweaks */
1006 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1007 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1008 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1011 /* Force IGMPv2 due EMF limitations */
1012 if (nvram_get_int("emf_enable")) {
1013 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1014 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1018 n
= nvram_get_int("log_in");
1019 chain_in_drop
= (n
& 1) ? "logdrop" : "DROP";
1020 chain_in_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1022 n
= nvram_get_int("log_out");
1023 chain_out_drop
= (n
& 1) ? "logdrop" : "DROP";
1024 chain_out_reject
= (n
& 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1025 chain_out_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1027 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1029 strlcpy(lanface
, nvram_safe_get("lan_ifname"), IFNAMSIZ
);
1034 if ((wanproto
== WP_PPTP
) || (wanproto
== WP_L2TP
) || (wanproto
== WP_PPPOE
)) {
1035 strcpy(wanface
, "ppp+");
1038 strlcpy(wanface
, nvram_safe_get("wan_ifname"), sizeof(wanface
));
1041 strlcpy(wanaddr
, get_wanip(), sizeof(wanaddr
));
1042 c
= nvram_safe_get("wan_ipaddr");
1043 if (*c
&& strcmp(c
, wanaddr
) != 0 && strcmp(c
, "0.0.0.0") != 0) {
1044 strlcpy(manaddr
, c
, sizeof(manaddr
));
1045 if ((wanproto
== WP_PPTP
) || (wanproto
== WP_L2TP
) || (wanproto
== WP_PPPOE
))
1046 strlcpy(manface
, nvram_safe_get("wan_ifname"), sizeof(manface
));
1050 if (nvram_match("ipv6_service", "native"))
1051 strlcpy(wan6face
, wanface
, sizeof(wan6face
));
1052 else if (nvram_invmatch("ipv6_service", ""))
1053 strlcpy(wan6face
, nvram_safe_get("ipv6_ifname"), sizeof(wan6face
));
1056 strlcpy(s
, nvram_safe_get("lan_ipaddr"), sizeof(s
));
1057 if ((c
= strrchr(s
, '.')) != NULL
) *(c
+ 1) = 0;
1058 strlcpy(lan_cclass
, s
, sizeof(lan_cclass
));
1060 gateway_mode
= !nvram_match("wk_mode", "router");
1062 /* Remote management */
1063 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1064 nvram_invmatch("http_wanport", "0")) remotemanage
= 1;
1065 else remotemanage
= 0;
1067 if (nvram_match("remote_mgt_https", "1")) {
1068 web_lanport
= nvram_get_int("https_lanport");
1069 if (web_lanport
<= 0) web_lanport
= 443;
1072 web_lanport
= nvram_get_int("http_lanport");
1073 if (web_lanport
<= 0) web_lanport
= 80;
1078 if ((ipt_file
= fopen(ipt_fname
, "w")) == NULL
) {
1079 notice_set("iptables", "Unable to create iptables restore file");
1080 simple_unlock("firewall");
1085 if ((ip6t_file
= fopen(ip6t_fname
, "w")) == NULL
) {
1086 notice_set("ip6tables", "Unable to create ip6tables restore file");
1087 simple_unlock("firewall");
1090 modprobe("nf_conntrack_ipv6");
1105 #ifdef DEBUG_IPTFILE
1107 simple_unlock("firewall");
1108 simple_unlock("restrictions");
1115 if (nvram_get_int("upnp_enable") & 3) {
1116 f_write("/etc/upnp/save", NULL
, 0, 0, 0);
1117 if (killall("miniupnpd", SIGUSR2
) == 0) {
1118 f_wait_notexists("/etc/upnp/save", 5);
1122 notice_set("iptables", "");
1123 if (_eval(iptrestore_argv
, ">/var/notice/iptables", 0, NULL
) == 0) {
1125 notice_set("iptables", "");
1128 sprintf(s
, "%s.error", ipt_fname
);
1129 rename(ipt_fname
, s
);
1130 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1137 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1138 -A INPUT -i br0 -j ACCEPT
1142 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1143 -A FORWARD -i br0 -j ACCEPT
1149 if (nvram_invmatch("ipv6_service", "")) {
1150 notice_set("ip6tables", "");
1151 if (_eval(ip6trestore_argv
, ">/var/notice/ip6tables", 0, NULL
) == 0) {
1153 notice_set("ip6tables", "");
1156 sprintf(s
, "%s.error", ip6t_fname
);
1157 rename(ip6t_fname
, s
);
1158 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1164 if (nvram_get_int("upnp_enable") & 3) {
1165 f_write("/etc/upnp/load", NULL
, 0, 0, 0);
1166 killall("miniupnpd", SIGUSR2
);
1169 simple_unlock("restrictions");
1170 sched_restrictions();
1171 enable_ip_forward();
1173 led(LED_DMZ
, dmz_dst(NULL
));
1176 modprobe_r("nf_conntrack_ipv6");
1179 modprobe_r("xt_layer7");
1180 modprobe_r("xt_recent");
1181 modprobe_r("xt_HL");
1182 modprobe_r("xt_length");
1184 modprobe_r("ipt_layer7");
1185 modprobe_r("ipt_recent");
1186 modprobe_r("ipt_TTL");
1188 modprobe_r("ipt_ipp2p");
1189 modprobe_r("ipt_web");
1190 modprobe_r("ipt_webmon");
1192 unlink("/var/webmon/domain");
1193 unlink("/var/webmon/search");
1195 #ifdef TCONFIG_OPENVPN
1196 run_vpn_firewall_scripts();
1198 run_nvscript("script_fire", NULL
, 1);
1200 simple_unlock("firewall");
1204 int stop_firewall(void)
1210 #ifdef DEBUG_IPTFILE
1211 void create_test_iptfile(void)