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 wanface_list_t wanfaces
;
33 char lanface
[IFNAMSIZ
+ 1];
35 char wan6face
[IFNAMSIZ
+ 1];
37 char lan_cclass
[sizeof("xxx.xxx.xxx.") + 1];
40 static int debug_only
= 0;
43 static int gateway_mode
;
44 static int remotemanage
;
47 const char *chain_in_drop
;
48 const char *chain_in_accept
;
49 const char *chain_out_drop
;
50 const char *chain_out_accept
;
51 const char *chain_out_reject
;
53 const char chain_wan_prerouting
[] = "WANPREROUTING";
54 const char ipt_fname
[] = "/etc/iptables";
58 const char ip6t_fname
[] = "/etc/ip6tables";
61 // RFC-4890, sec. 4.3.1
62 const int allowed_icmpv6
[] = { 1, 2, 3, 4, 128, 129 };
71 // -----------------------------------------------------------------------------
74 void enable_ip_forward(void)
78 0 - disabled (default)
81 Forward Packets between interfaces.
83 This variable is special, its change resets all configuration
84 parameters to their default state (RFC1122 for hosts, RFC1812
87 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
91 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
92 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
98 // -----------------------------------------------------------------------------
101 static int ip2cclass(char *ipaddr, char *new, int count)
105 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
106 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
111 static int dmz_dst(char *s
)
117 if (nvram_get_int("dmz_enable") <= 0) return 0;
119 p
= nvram_safe_get("dmz_ipaddr");
120 if ((ia
.s_addr
= inet_addr(p
)) == (in_addr_t
)-1) {
121 if (((n
= atoi(p
)) <= 0) || (n
>= 255)) return 0;
122 if (s
) sprintf(s
, "%s%d", lan_cclass
, n
);
126 if (s
) strcpy(s
, inet_ntoa(ia
));
130 void ipt_log_unresolved(const char *addr
, const char *addrtype
, const char *categ
, const char *name
)
134 pre
= (name
&& *name
) ? " for \"" : "";
135 post
= (name
&& *name
) ? "\"" : "";
137 syslog(LOG_WARNING
, "firewall: "
138 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
139 categ
, addr
, pre
, (name
) ? : "", post
, (addrtype
) ? : "IP");
142 int ipt_addr(char *addr
, int maxlen
, const char *s
, const char *dir
, int af
,
143 int strict
, const char *categ
, const char *name
)
145 char p
[INET6_ADDRSTRLEN
* 2];
148 if ((s
) && (*s
) && (*dir
))
150 if (sscanf(s
, "%[0-9.]-%[0-9.]", p
, p
) == 2) {
151 snprintf(addr
, maxlen
, "-m iprange --%s-range %s", dir
, s
);
155 else if (sscanf(s
, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p
, p
) == 2) {
156 snprintf(addr
, maxlen
, "-m iprange --%s-range %s", dir
, s
);
161 snprintf(addr
, maxlen
, "-%c %s", dir
[0], s
);
162 if (sscanf(s
, "%[^/]/", p
)) {
164 r
= host_addrtypes(p
, strict
? af
: (IPT_V4
| IPT_V6
));
166 r
= host_addrtypes(p
, IPT_V4
);
174 r
= (IPT_V4
| IPT_V6
);
177 if ((r
== 0 || (strict
&& ((r
& af
) != af
))) && (categ
&& *categ
)) {
178 ipt_log_unresolved(s
, categ
, name
,
179 (af
& IPT_V4
& ~r
) ? "IPv4" : ((af
& IPT_V6
& ~r
) ? "IPv6" : NULL
));
185 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
186 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
187 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
190 static void get_src(const char *nv, char *src)
194 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
195 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
203 void ipt_write(const char *format
, ...)
207 va_start(args
, format
);
208 vfprintf(ipt_file
, format
, args
);
212 void ip6t_write(const char *format
, ...)
217 va_start(args
, format
);
218 vfprintf(ip6t_file
, format
, args
);
223 // -----------------------------------------------------------------------------
225 int ipt_dscp(const char *v
, char *opt
)
234 n
= strtoul(v
, NULL
, 0);
236 sprintf(opt
, " -m dscp --dscp 0x%02X", n
);
241 modprobe("ipt_dscp");
246 // -----------------------------------------------------------------------------
249 int ipt_ipp2p(const char *v
, char *opt
)
258 strcpy(opt
, "-m ipp2p ");
259 if ((n
& 0xFFF) == 0xFFF) {
260 strcat(opt
, "--ipp2p");
264 if (n
& 0x0001) strcat(opt
, "--apple ");
265 if (n
& 0x0002) strcat(opt
, "--ares ");
266 if (n
& 0x0004) strcat(opt
, "--bit ");
267 if (n
& 0x0008) strcat(opt
, "--dc ");
268 if (n
& 0x0010) strcat(opt
, "--edk ");
269 if (n
& 0x0020) strcat(opt
, "--gnu ");
270 if (n
& 0x0040) strcat(opt
, "--kazaa ");
271 if (n
& 0x0080) strcat(opt
, "--mute ");
272 if (n
& 0x0100) strcat(opt
, "--soul ");
273 if (n
& 0x0200) strcat(opt
, "--waste ");
274 if (n
& 0x0400) strcat(opt
, "--winmx ");
275 if (n
& 0x0800) strcat(opt
, "--xdcc ");
278 modprobe("ipt_ipp2p");
283 // -----------------------------------------------------------------------------
288 // This L7 matches inbound traffic, caches the results, then the L7 outbound
289 // should read the cached result and set the appropriate marks -- zzz
290 void ipt_layer7_inbound(void)
295 if (!layer7_in
) return;
297 en
= nvram_match("nf_l7in", "1");
299 ipt_write(":L7in - [0:0]\n");
300 for (i
= 0; i
< wanfaces
.count
; ++i
) {
301 if (*(wanfaces
.iface
[i
].name
)) {
302 ipt_write("-A FORWARD -i %s -j L7in\n",
303 wanfaces
.iface
[i
].name
);
310 if (en
) ipt_write("-A L7in %s -j RETURN\n", *p
);
318 int ipt_layer7(const char *v
, char *opt
)
324 if (*v
== 0) return 0;
325 if (strlen(v
) > 32) return -1;
327 path
= "/etc/l7-extra";
328 sprintf(s
, "%s/%s.pat", path
, v
);
330 path
= "/etc/l7-protocols";
331 sprintf(s
, "%s/%s.pat", path
, v
);
333 syslog(LOG_ERR
, "L7 %s was not found", v
);
338 sprintf(opt
, "-m layer7 --l7dir %s --l7proto %s", path
, v
);
340 if (nvram_match("nf_l7in", "1")) {
341 if (!layer7_in
) layer7_in
= calloc(51, sizeof(char *));
347 if (strcmp(*p
, opt
) == 0) return 1;
350 if (((p
- layer7_in
) / sizeof(char *)) < 50) *p
= strdup(opt
);
355 modprobe("xt_layer7");
357 modprobe("ipt_layer7");
363 // -----------------------------------------------------------------------------
365 static void save_webmon(void)
367 system("cp /proc/webmon_recent_domains /var/webmon/domain");
368 system("cp /proc/webmon_recent_searches /var/webmon/search");
371 static void ipt_webmon()
373 int wmtype
, clear
, i
;
379 if (!nvram_get_int("log_wm")) return;
380 wmtype
= nvram_get_int("log_wmtype");
381 clear
= nvram_get_int("log_wmclear");
383 ip46t_write(":monitor - [0:0]\n");
386 strlcpy(t
, wmtype
== 1 ? nvram_safe_get("log_wmip") : "", sizeof(t
));
389 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
391 if ((ok
= ipt_addr(src
, sizeof(src
), p
, "src", IPT_V4
|IPT_V6
, 0, "webmon", NULL
))) {
393 if (*wan6face
&& (ok
& IPT_V6
))
394 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face
, src
);
397 for (i
= 0; i
< wanfaces
.count
; ++i
) {
398 if (*(wanfaces
.iface
[i
].name
)) {
399 ipt_write("-A FORWARD -o %s %s -j monitor\n",
400 wanfaces
.iface
[i
].name
, src
);
412 strlcpy(t
, nvram_safe_get("log_wmip"), sizeof(t
));
415 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
416 if ((ok
= ipt_addr(src
, sizeof(src
), p
, "src", IPT_V4
|IPT_V6
, 0, "webmon", NULL
))) {
418 ip46t_flagged_write(ok
, "-A monitor %s -j RETURN\n", src
);
426 "-A monitor -p tcp -m webmon "
427 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
428 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
429 (clear
& 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
430 (clear
& 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
433 modprobe("xt_webmon");
435 modprobe("ipt_webmon");
440 // -----------------------------------------------------------------------------
442 // -----------------------------------------------------------------------------
444 static void mangle_table(void)
451 ":PREROUTING ACCEPT [0:0]\n"
452 ":OUTPUT ACCEPT [0:0]\n");
458 p
= nvram_safe_get("nf_ttl");
459 if (strncmp(p
, "c:", 2) == 0) {
462 p
= (ttl
>= 0 && ttl
<= 255) ? "set" : NULL
;
464 else if ((ttl
= atoi(p
)) != 0) {
472 if (ttl
> 255) p
= NULL
;
482 // set TTL on primary WAN iface only
483 wanface
= wanfaces
.iface
[0].name
;
485 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
486 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
492 ip46t_write("COMMIT\n");
497 // -----------------------------------------------------------------------------
499 // -----------------------------------------------------------------------------
501 static void nat_table(void)
512 ":PREROUTING ACCEPT [0:0]\n"
513 ":POSTROUTING ACCEPT [0:0]\n"
514 ":OUTPUT ACCEPT [0:0]\n"
516 chain_wan_prerouting
);
519 strlcpy(lanaddr
, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr
));
520 strlcpy(lanmask
, nvram_safe_get("lan_netmask"), sizeof(lanmask
));
522 for (i
= 0; i
< wanfaces
.count
; ++i
) {
523 if (*(wanfaces
.iface
[i
].name
)) {
524 // chain_wan_prerouting
526 ipt_write("-A PREROUTING -d %s -j %s\n",
527 wanfaces
.iface
[i
].ip
, chain_wan_prerouting
);
529 // Drop incoming packets which destination IP address is to our LAN side directly
530 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
531 wanfaces
.iface
[i
].name
,
532 lanaddr
, lanmask
); // note: ipt will correct lanaddr
537 if (nvram_match("dns_intcpt", "1")) {
538 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
544 // ICMP packets are always redirected to INPUT chains
545 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting
, lanaddr
);
547 ipt_forward(IPT_TABLE_NAT
);
548 ipt_triggered(IPT_TABLE_NAT
);
551 if (nvram_get_int("upnp_enable") & 3) {
552 ipt_write(":upnp - [0:0]\n");
554 // ! for loopback (all) to work
555 ipt_write("-A %s -j upnp\n", chain_wan_prerouting
);
558 for (i
= 0; i
< wanfaces
.count
; ++i
) {
559 if (*(wanfaces
.iface
[i
].name
)) {
560 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces
.iface
[i
].name
);
568 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
571 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
572 if (ipt_source_strict(p
, src
, "dmz", NULL
))
573 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting
, src
, dst
);
582 switch (get_ipv6_service()) {
584 // avoid NATing proto-41 packets when using 6in4 tunnel
590 for (i
= 0; i
< wanfaces
.count
; ++i
) {
591 if (*(wanfaces
.iface
[i
].name
)) {
592 if ((!wanup
) || (nvram_get_int("net_snat") != 1))
593 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p
, wanfaces
.iface
[i
].name
);
595 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p
, wanfaces
.iface
[i
].name
, wanfaces
.iface
[i
].ip
);
599 switch (nvram_get_int("nf_loopback")) {
600 case 1: // 1 = forwarded-only
601 case 2: // 2 = disable
603 default: // 0 = all (same as block_loopback=0)
604 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
612 ipt_write("COMMIT\n");
615 // -----------------------------------------------------------------------------
617 // -----------------------------------------------------------------------------
619 static void filter_input(void)
629 if ((nvram_get_int("nf_loopback") != 0) && (wanup
)) { // 0 = all
630 for (n
= 0; n
< wanfaces
.count
; ++n
) {
631 if (*(wanfaces
.iface
[n
].name
)) {
632 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface
, wanfaces
.iface
[n
].ip
);
638 "-A INPUT -m state --state INVALID -j DROP\n"
639 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
641 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
642 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
644 ? what if the user uses the start button in GUI ?
645 if (nvram_get_int("telnetd_eas"))
646 if (nvram_get_int("sshd_eas"))
649 modprobe("xt_recent");
651 modprobe("ipt_recent");
656 "-A shlimit -m recent --set --name shlimit\n"
657 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
658 atoi(hit
) + 1, sec
, chain_in_drop
);
661 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
662 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
663 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
666 if (n
& 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
670 strlcpy(s
, nvram_safe_get("ftp_limit"), sizeof(s
));
671 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && (atoi(en
)) && (nvram_get_int("ftp_enable") == 1)) {
673 modprobe("xt_recent");
675 modprobe("ipt_recent");
680 "-A ftplimit -m recent --set --name ftp\n"
681 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
682 atoi(hit
) + 1, sec
, chain_in_drop
);
683 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
688 "-A INPUT -i %s -j ACCEPT\n"
689 "-A INPUT -i lo -j ACCEPT\n",
693 switch (get_ipv6_service()) {
695 // Accept ICMP requests from the remote tunnel endpoint
696 if ((p
= nvram_get("ipv6_tun_v4end")) && *p
&& strcmp(p
, "0.0.0.0") != 0)
697 ipt_write("-A INPUT -p icmp -s %s -j %s\n", p
, chain_in_accept
);
698 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept
);
703 // ICMP request from WAN interface
704 if (nvram_match("block_wan", "0")) {
705 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
706 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept
);
707 // allow udp traceroute packets
708 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept
);
711 /* Accept incoming packets from broken dhcp servers, which are sending replies
712 * from addresses other than used for query. This could lead to a lower level
713 * of security, so allow to disable it via nvram variable.
715 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
716 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept
);
719 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
722 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
724 if (ipt_source(p
, s
, "remote management", NULL
)) {
727 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
728 s
, nvram_safe_get("http_wanport"), chain_in_accept
);
731 if (nvram_get_int("sshd_remote")) {
732 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
733 s
, nvram_safe_get("sshd_rport"), chain_in_accept
);
741 #ifdef TCONFIG_FTP // !!TB - FTP Server
742 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
743 strlcpy(t
, nvram_safe_get("ftp_sip"), sizeof(t
));
746 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
747 if (ipt_source(p
, s
, "ftp", "remote access")) {
748 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
749 s
, nvram_safe_get("ftp_port"), chain_in_accept
);
757 // IGMP query from WAN interface
758 if (nvram_match("multicast_pass", "1")) {
759 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
760 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
763 // Routing protocol, RIP, accept
764 if (nvram_invmatch("dr_wan_rx", "0")) {
765 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
769 if (*chain_in_drop
== 'l') {
770 ipt_write( "-A INPUT -j %s\n", chain_in_drop
);
773 // default policy: DROP
776 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
777 static void clampmss(void)
780 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
782 int rmtu
= nvram_get_int("wan_run_mtu");
783 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu
- 39);
785 ipt_write("--clamp-mss-to-pmtu\n");
788 ipt_write("--set-mss %d\n", rmtu
- 40);
793 static void filter_forward(void)
803 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
807 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
812 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
814 // clamp tcp mss to pmtu
820 ipt_layer7_inbound();
828 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
831 // Filter out invalid WAN->WAN connections
833 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face
, lanface
, chain_in_drop
);
836 modprobe("xt_length");
837 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
841 for (i
= 0; i
< sizeof(allowed_icmpv6
)/sizeof(int); ++i
) {
842 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6
[i
], chain_in_accept
);
847 "-A FORWARD -i %s -j wanin\n" // generic from wan
848 "-A FORWARD -o %s -j wanout\n", // generic to wan
853 for (i
= 0; i
< wanfaces
.count
; ++i
) {
854 if (*(wanfaces
.iface
[i
].name
)) {
856 "-A FORWARD -i %s -j wanin\n" // generic from wan
857 "-A FORWARD -o %s -j wanout\n", // generic to wan
858 wanfaces
.iface
[i
].name
, wanfaces
.iface
[i
].name
);
862 ip46t_write("-A FORWARD -i %s -j %s\n", // from lan
863 lanface
, chain_out_accept
);
866 if (nvram_get_int("upnp_enable") & 3) {
867 ipt_write(":upnp - [0:0]\n");
868 for (i
= 0; i
< wanfaces
.count
; ++i
) {
869 if (*(wanfaces
.iface
[i
].name
)) {
870 ipt_write("-A FORWARD -i %s -j upnp\n",
871 wanfaces
.iface
[i
].name
);
877 if (nvram_match("multicast_pass", "1")) {
878 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept
);
880 ipt_triggered(IPT_TABLE_FILTER
);
881 ipt_forward(IPT_TABLE_FILTER
);
887 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
890 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
891 if (ipt_source_strict(p
, src
, "dmz", NULL
))
892 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface
, src
, dst
, chain_in_accept
);
899 // default policy: DROP
902 static void filter_log(void)
907 n
= nvram_get_int("log_limit");
908 if ((n
>= 1) && (n
<= 9999)) {
909 sprintf(limit
, "-m limit --limit %d/m", n
);
916 modprobe("ip6t_LOG");
918 if ((*chain_in_drop
== 'l') || (*chain_out_drop
== 'l')) {
921 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
925 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
926 "-A logdrop -j DROP\n"
927 ":logreject - [0:0]\n"
928 "-A logreject %s -j LOG --log-prefix \"REJECT \""
932 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
933 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
936 if ((*chain_in_accept
== 'l') || (*chain_out_accept
== 'l')) {
938 ":logaccept - [0:0]\n"
939 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
943 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
944 "-A logaccept -j ACCEPT\n",
950 static void filter6_input(void)
960 // RFC-4890, sec. 4.4.1
961 const int allowed_local_icmpv6
[] =
962 { 130, 131, 132, 133, 134, 135, 136,
964 148, 149, 151, 152, 153 };
967 "-A INPUT -m rt --rt-type 0 -j %s\n"
968 /* "-A INPUT -m state --state INVALID -j DROP\n" */
969 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
973 modprobe("xt_length");
974 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
977 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
978 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
980 modprobe("xt_recent");
982 modprobe("ipt_recent");
987 "-A shlimit -m recent --set --name shlimit\n"
988 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
989 atoi(hit
) + 1, sec
, chain_in_drop
);
992 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface
, nvram_safe_get("sshd_port"));
993 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
994 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
997 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"));
1001 strlcpy(s
, nvram_safe_get("ftp_limit"), sizeof(s
));
1002 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && (atoi(en
)) && (nvram_get_int("ftp_enable") == 1)) {
1004 modprobe("xt_recent");
1006 modprobe("ipt_recent");
1011 "-A ftplimit -m recent --set --name ftp\n"
1012 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1013 atoi(hit
) + 1, sec
, chain_in_drop
);
1014 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1016 #endif // TCONFIG_FTP
1019 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1020 "-A INPUT -i lo -j ACCEPT\n",
1023 switch (get_ipv6_service()) {
1024 case IPV6_NATIVE_DHCP
:
1025 // allow responses from the dhcpv6 server
1026 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept
);
1031 for (n
= 0; n
< sizeof(allowed_icmpv6
)/sizeof(int); n
++) {
1032 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6
[n
], chain_in_accept
);
1034 for (n
= 0; n
< sizeof(allowed_local_icmpv6
)/sizeof(int); n
++) {
1035 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6
[n
], chain_in_accept
);
1039 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
1042 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
1044 if (ip6t_source(p
, s
, "remote management", NULL
)) {
1047 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1048 s
, nvram_safe_get("http_wanport"), chain_in_accept
);
1051 if (nvram_get_int("sshd_remote")) {
1052 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1053 s
, nvram_safe_get("sshd_rport"), chain_in_accept
);
1063 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1064 strlcpy(t
, nvram_safe_get("ftp_sip"), sizeof(t
));
1067 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
1068 if (ip6t_source(p
, s
, "ftp", "remote access")) {
1069 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1070 s
, nvram_safe_get("ftp_port"), chain_in_accept
);
1079 if (*chain_in_drop
== 'l') {
1080 ip6t_write( "-A INPUT -j %s\n", chain_in_drop
);
1083 // default policy: DROP
1088 static void filter_table(void)
1092 ":INPUT DROP [0:0]\n"
1093 ":OUTPUT ACCEPT [0:0]\n"
1101 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop
);
1104 if ((gateway_mode
) || (nvram_match("wk_mode_x", "1"))) {
1105 ip46t_write(":FORWARD DROP [0:0]\n");
1109 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1112 ip46t_write("COMMIT\n");
1116 // -----------------------------------------------------------------------------
1118 int start_firewall(void)
1121 struct dirent
*dirent
;
1126 char *iptrestore_argv
[] = { "iptables-restore", (char *)ipt_fname
, NULL
};
1128 char *ip6trestore_argv
[] = { "ip6tables-restore", (char *)ip6t_fname
, NULL
};
1131 simple_lock("firewall");
1132 simple_lock("restrictions");
1134 wanup
= check_wanup();
1136 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1138 /* NAT performance tweaks
1139 * These values can be overriden later if needed via firewall script
1141 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1142 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1143 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1144 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1145 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1146 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1147 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1148 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1149 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1150 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1151 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1152 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1154 /* DoS-related tweaks */
1155 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1156 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1157 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1159 wanproto
= get_wan_proto();
1160 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto
== WP_DISABLED
|| wanproto
== WP_STATIC
) ? "0" : "1", 0, 0);
1163 /* Force IGMPv2 due EMF limitations */
1164 if (nvram_get_int("emf_enable")) {
1165 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1166 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1170 n
= nvram_get_int("log_in");
1171 chain_in_drop
= (n
& 1) ? "logdrop" : "DROP";
1172 chain_in_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1174 n
= nvram_get_int("log_out");
1175 chain_out_drop
= (n
& 1) ? "logdrop" : "DROP";
1176 chain_out_reject
= (n
& 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1177 chain_out_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1179 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1181 strlcpy(lanface
, nvram_safe_get("lan_ifname"), IFNAMSIZ
);
1183 memcpy(&wanfaces
, get_wanfaces(), sizeof(wanfaces
));
1184 wanface
= wanfaces
.iface
[0].name
;
1186 strlcpy(wan6face
, get_wan6face(), sizeof(wan6face
));
1189 strlcpy(s
, nvram_safe_get("lan_ipaddr"), sizeof(s
));
1190 if ((c
= strrchr(s
, '.')) != NULL
) *(c
+ 1) = 0;
1191 strlcpy(lan_cclass
, s
, sizeof(lan_cclass
));
1194 block obviously spoofed IP addresses
1197 1 - do source validation by reversed path, as specified in RFC1812
1198 Recommended option for single homed hosts and stub network
1199 routers. Could cause troubles for complicated (not loop free)
1200 networks running a slow unreliable protocol (sort of RIP),
1201 or using static routes.
1202 0 - No source validation.
1204 c
= nvram_get("wan_ifname");
1205 /* mcast needs rp filter to be turned off only for non default iface */
1206 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface
, c
) == 0) c
= NULL
;
1208 if ((dir
= opendir("/proc/sys/net/ipv4/conf")) != NULL
) {
1209 while ((dirent
= readdir(dir
)) != NULL
) {
1210 sprintf(s
, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent
->d_name
);
1211 f_write_string(s
, (c
&& strcmp(dirent
->d_name
, c
) == 0) ? "0" : "1", 0, 0);
1217 gateway_mode
= !nvram_match("wk_mode", "router");
1219 /* Remote management */
1220 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1221 nvram_invmatch("http_wanport", "0")) remotemanage
= 1;
1224 if ((ipt_file
= fopen(ipt_fname
, "w")) == NULL
) {
1225 notice_set("iptables", "Unable to create iptables restore file");
1226 simple_unlock("firewall");
1231 if ((ip6t_file
= fopen(ip6t_fname
, "w")) == NULL
) {
1232 notice_set("ip6tables", "Unable to create ip6tables restore file");
1233 simple_unlock("firewall");
1236 modprobe("nf_conntrack_ipv6");
1237 modprobe("ip6t_REJECT");
1252 #ifdef DEBUG_IPTFILE
1254 simple_unlock("firewall");
1255 simple_unlock("restrictions");
1262 if (nvram_get_int("upnp_enable") & 3) {
1263 f_write("/etc/upnp/save", NULL
, 0, 0, 0);
1264 if (killall("miniupnpd", SIGUSR2
) == 0) {
1265 f_wait_notexists("/etc/upnp/save", 5);
1269 notice_set("iptables", "");
1270 if (_eval(iptrestore_argv
, ">/var/notice/iptables", 0, NULL
) == 0) {
1272 notice_set("iptables", "");
1275 sprintf(s
, "%s.error", ipt_fname
);
1276 rename(ipt_fname
, s
);
1277 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1284 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1285 -A INPUT -i br0 -j ACCEPT
1289 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1290 -A FORWARD -i br0 -j ACCEPT
1296 if (ipv6_enabled()) {
1297 notice_set("ip6tables", "");
1298 if (_eval(ip6trestore_argv
, ">/var/notice/ip6tables", 0, NULL
) == 0) {
1299 notice_set("ip6tables", "");
1302 sprintf(s
, "%s.error", ip6t_fname
);
1303 rename(ip6t_fname
, s
);
1304 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1309 eval("ip6tables", "-F");
1310 eval("ip6tables", "-t", "mangle", "-F");
1314 if (nvram_get_int("upnp_enable") & 3) {
1315 f_write("/etc/upnp/load", NULL
, 0, 0, 0);
1316 killall("miniupnpd", SIGUSR2
);
1319 simple_unlock("restrictions");
1320 sched_restrictions();
1321 enable_ip_forward();
1323 led(LED_DMZ
, dmz_dst(NULL
));
1326 modprobe_r("nf_conntrack_ipv6");
1327 modprobe_r("ip6t_LOG");
1328 modprobe_r("ip6t_REJECT");
1331 modprobe_r("xt_layer7");
1332 modprobe_r("xt_recent");
1333 modprobe_r("xt_HL");
1334 modprobe_r("xt_length");
1335 modprobe_r("xt_web");
1336 modprobe_r("xt_webmon");
1337 modprobe_r("xt_dscp");
1339 modprobe_r("ipt_layer7");
1340 modprobe_r("ipt_recent");
1341 modprobe_r("ipt_TTL");
1342 modprobe_r("ipt_web");
1343 modprobe_r("ipt_webmon");
1344 modprobe_r("ipt_dscp");
1346 modprobe_r("ipt_ipp2p");
1348 unlink("/var/webmon/domain");
1349 unlink("/var/webmon/search");
1351 #ifdef TCONFIG_OPENVPN
1352 run_vpn_firewall_scripts();
1354 run_nvscript("script_fire", NULL
, 1);
1356 simple_unlock("firewall");
1360 int stop_firewall(void)
1366 #ifdef DEBUG_IPTFILE
1367 void create_test_iptfile(void)