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 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
368 eval("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");
460 p
= nvram_safe_get("nf_ttl");
461 if (strncmp(p
, "c:", 2) == 0) {
464 p
= (ttl
>= 0 && ttl
<= 255) ? "set" : NULL
;
466 else if ((ttl
= atoi(p
)) != 0) {
474 if (ttl
> 255) p
= NULL
;
484 // set TTL on primary WAN iface only
485 wanface
= wanfaces
.iface
[0].name
;
487 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
488 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
494 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
);
522 strlcpy(lanaddr
, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr
));
523 strlcpy(lanmask
, nvram_safe_get("lan_netmask"), sizeof(lanmask
));
525 for (i
= 0; i
< wanfaces
.count
; ++i
) {
526 if (*(wanfaces
.iface
[i
].name
)) {
527 // Drop incoming packets which destination IP address is to our LAN side directly
528 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
529 wanfaces
.iface
[i
].name
,
530 lanaddr
, lanmask
); // note: ipt will correct lanaddr
532 // chain_wan_prerouting
534 ipt_write("-A PREROUTING -d %s -j %s\n",
535 wanfaces
.iface
[i
].ip
, chain_wan_prerouting
);
541 if (nvram_match("dns_intcpt", "1")) {
542 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
548 // ICMP packets are always redirected to INPUT chains
549 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting
, lanaddr
);
551 ipt_forward(IPT_TABLE_NAT
);
552 ipt_triggered(IPT_TABLE_NAT
);
555 if (nvram_get_int("upnp_enable") & 3) {
556 ipt_write(":upnp - [0:0]\n");
558 for (i
= 0; i
< wanfaces
.count
; ++i
) {
559 if (*(wanfaces
.iface
[i
].name
)) {
561 // ! for loopback (all) to work
562 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces
.iface
[i
].ip
);
565 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces
.iface
[i
].name
);
573 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
576 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
577 if (ipt_source_strict(p
, src
, "dmz", NULL
))
578 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting
, src
, dst
);
587 switch (get_ipv6_service()) {
589 // avoid NATing proto-41 packets when using 6in4 tunnel
595 for (i
= 0; i
< wanfaces
.count
; ++i
) {
596 if (*(wanfaces
.iface
[i
].name
)) {
597 if ((!wanup
) || (nvram_get_int("net_snat") != 1))
598 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p
, wanfaces
.iface
[i
].name
);
600 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p
, wanfaces
.iface
[i
].name
, wanfaces
.iface
[i
].ip
);
604 switch (nvram_get_int("nf_loopback")) {
605 case 1: // 1 = forwarded-only
606 case 2: // 2 = disable
608 default: // 0 = all (same as block_loopback=0)
609 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
617 ipt_write("COMMIT\n");
620 // -----------------------------------------------------------------------------
622 // -----------------------------------------------------------------------------
624 static void filter_input(void)
634 if ((nvram_get_int("nf_loopback") != 0) && (wanup
)) { // 0 = all
635 for (n
= 0; n
< wanfaces
.count
; ++n
) {
636 if (*(wanfaces
.iface
[n
].name
)) {
637 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface
, wanfaces
.iface
[n
].ip
);
643 "-A INPUT -m state --state INVALID -j DROP\n"
644 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
646 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
647 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
649 ? what if the user uses the start button in GUI ?
650 if (nvram_get_int("telnetd_eas"))
651 if (nvram_get_int("sshd_eas"))
654 modprobe("xt_recent");
656 modprobe("ipt_recent");
661 "-A shlimit -m recent --set --name shlimit\n"
662 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
663 atoi(hit
) + 1, sec
, chain_in_drop
);
666 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
667 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
668 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
671 if (n
& 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
675 strlcpy(s
, nvram_safe_get("ftp_limit"), sizeof(s
));
676 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && (atoi(en
)) && (nvram_get_int("ftp_enable") == 1)) {
678 modprobe("xt_recent");
680 modprobe("ipt_recent");
685 "-A ftplimit -m recent --set --name ftp\n"
686 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
687 atoi(hit
) + 1, sec
, chain_in_drop
);
688 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
693 "-A INPUT -i %s -j ACCEPT\n"
694 "-A INPUT -i lo -j ACCEPT\n",
698 switch (get_ipv6_service()) {
700 // Accept ICMP requests from the remote tunnel endpoint
701 if ((p
= nvram_get("ipv6_tun_v4end")) && *p
&& strcmp(p
, "0.0.0.0") != 0)
702 ipt_write("-A INPUT -p icmp -s %s -j %s\n", p
, chain_in_accept
);
703 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept
);
708 // ICMP request from WAN interface
709 if (nvram_match("block_wan", "0")) {
710 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
711 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept
);
712 // allow udp traceroute packets
713 ipt_write("-A INPUT -p udp -m udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept
);
716 /* Accept incoming packets from broken dhcp servers, which are sending replies
717 * from addresses other than used for query. This could lead to a lower level
718 * of security, so allow to disable it via nvram variable.
720 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
721 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept
);
724 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
727 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
729 if (ipt_source(p
, s
, "remote management", NULL
)) {
732 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
733 s
, nvram_safe_get("http_wanport"), chain_in_accept
);
736 if (nvram_get_int("sshd_remote")) {
737 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
738 s
, nvram_safe_get("sshd_rport"), chain_in_accept
);
746 #ifdef TCONFIG_FTP // !!TB - FTP Server
747 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
748 strlcpy(t
, nvram_safe_get("ftp_sip"), sizeof(t
));
751 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
752 if (ipt_source(p
, s
, "ftp", "remote access")) {
753 ipt_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
754 s
, nvram_safe_get("ftp_port"), chain_in_accept
);
762 // IGMP query from WAN interface
763 if (nvram_match("multicast_pass", "1")) {
764 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
765 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
768 // Routing protocol, RIP, accept
769 if (nvram_invmatch("dr_wan_rx", "0")) {
770 ipt_write("-A INPUT -p udp -m udp --dport 520 -j ACCEPT\n");
774 if (*chain_in_drop
== 'l') {
775 ipt_write( "-A INPUT -j %s\n", chain_in_drop
);
778 // default policy: DROP
781 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
782 static void clampmss(void)
785 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
787 int rmtu
= nvram_get_int("wan_run_mtu");
788 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu
- 39);
790 ipt_write("--clamp-mss-to-pmtu\n");
793 ipt_write("--set-mss %d\n", rmtu
- 40);
798 static void filter_forward(void)
808 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
812 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
817 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
819 // clamp tcp mss to pmtu
825 ipt_layer7_inbound();
833 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
836 // Filter out invalid WAN->WAN connections
838 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face
, lanface
, chain_in_drop
);
841 modprobe("xt_length");
842 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
846 for (i
= 0; i
< sizeof(allowed_icmpv6
)/sizeof(int); ++i
) {
847 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6
[i
], chain_in_accept
);
852 "-A FORWARD -i %s -j wanin\n" // generic from wan
853 "-A FORWARD -o %s -j wanout\n", // generic to wan
858 for (i
= 0; i
< wanfaces
.count
; ++i
) {
859 if (*(wanfaces
.iface
[i
].name
)) {
861 "-A FORWARD -i %s -j wanin\n" // generic from wan
862 "-A FORWARD -o %s -j wanout\n", // generic to wan
863 wanfaces
.iface
[i
].name
, wanfaces
.iface
[i
].name
);
867 ip46t_write("-A FORWARD -i %s -j %s\n", // from lan
868 lanface
, chain_out_accept
);
871 if (nvram_get_int("upnp_enable") & 3) {
872 ipt_write(":upnp - [0:0]\n");
873 for (i
= 0; i
< wanfaces
.count
; ++i
) {
874 if (*(wanfaces
.iface
[i
].name
)) {
875 ipt_write("-A FORWARD -i %s -j upnp\n",
876 wanfaces
.iface
[i
].name
);
882 if (nvram_match("multicast_pass", "1")) {
883 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept
);
885 ipt_triggered(IPT_TABLE_FILTER
);
886 ipt_forward(IPT_TABLE_FILTER
);
892 strlcpy(t
, nvram_safe_get("dmz_sip"), sizeof(t
));
895 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
896 if (ipt_source_strict(p
, src
, "dmz", NULL
))
897 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface
, src
, dst
, chain_in_accept
);
904 // default policy: DROP
907 static void filter_log(void)
912 n
= nvram_get_int("log_limit");
913 if ((n
>= 1) && (n
<= 9999)) {
914 sprintf(limit
, "-m limit --limit %d/m", n
);
921 modprobe("ip6t_LOG");
923 if ((*chain_in_drop
== 'l') || (*chain_out_drop
== 'l')) {
926 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
930 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
931 "-A logdrop -j DROP\n"
932 ":logreject - [0:0]\n"
933 "-A logreject %s -j LOG --log-prefix \"REJECT \""
937 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
938 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
941 if ((*chain_in_accept
== 'l') || (*chain_out_accept
== 'l')) {
943 ":logaccept - [0:0]\n"
944 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
948 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
949 "-A logaccept -j ACCEPT\n",
955 static void filter6_input(void)
965 // RFC-4890, sec. 4.4.1
966 const int allowed_local_icmpv6
[] =
967 { 130, 131, 132, 133, 134, 135, 136,
969 148, 149, 151, 152, 153 };
972 "-A INPUT -m rt --rt-type 0 -j %s\n"
973 /* "-A INPUT -m state --state INVALID -j DROP\n" */
974 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
978 modprobe("xt_length");
979 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
982 strlcpy(s
, nvram_safe_get("ne_shlimit"), sizeof(s
));
983 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && ((n
= atoi(en
) & 3) != 0)) {
985 modprobe("xt_recent");
987 modprobe("ipt_recent");
992 "-A shlimit -m recent --set --name shlimit\n"
993 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
994 atoi(hit
) + 1, sec
, chain_in_drop
);
997 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface
, nvram_safe_get("sshd_port"));
998 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
999 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1002 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"));
1006 strlcpy(s
, nvram_safe_get("ftp_limit"), sizeof(s
));
1007 if ((vstrsep(s
, ",", &en
, &hit
, &sec
) == 3) && (atoi(en
)) && (nvram_get_int("ftp_enable") == 1)) {
1009 modprobe("xt_recent");
1011 modprobe("ipt_recent");
1016 "-A ftplimit -m recent --set --name ftp\n"
1017 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1018 atoi(hit
) + 1, sec
, chain_in_drop
);
1019 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1021 #endif // TCONFIG_FTP
1024 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1025 "-A INPUT -i lo -j ACCEPT\n",
1028 switch (get_ipv6_service()) {
1029 case IPV6_NATIVE_DHCP
:
1030 // allow responses from the dhcpv6 server
1031 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept
);
1036 for (n
= 0; n
< sizeof(allowed_icmpv6
)/sizeof(int); n
++) {
1037 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6
[n
], chain_in_accept
);
1039 for (n
= 0; n
< sizeof(allowed_local_icmpv6
)/sizeof(int); n
++) {
1040 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6
[n
], chain_in_accept
);
1044 strlcpy(t
, nvram_safe_get("rmgt_sip"), sizeof(t
));
1047 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
1049 if (ip6t_source(p
, s
, "remote management", NULL
)) {
1052 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1053 s
, nvram_safe_get("http_wanport"), chain_in_accept
);
1056 if (nvram_get_int("sshd_remote")) {
1057 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1058 s
, nvram_safe_get("sshd_rport"), chain_in_accept
);
1068 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1069 strlcpy(t
, nvram_safe_get("ftp_sip"), sizeof(t
));
1072 if ((c
= strchr(p
, ',')) != NULL
) *c
= 0;
1073 if (ip6t_source(p
, s
, "ftp", "remote access")) {
1074 ip6t_write("-A INPUT -p tcp %s -m tcp --dport %s -j %s\n",
1075 s
, nvram_safe_get("ftp_port"), chain_in_accept
);
1084 if (*chain_in_drop
== 'l') {
1085 ip6t_write( "-A INPUT -j %s\n", chain_in_drop
);
1088 // default policy: DROP
1093 static void filter_table(void)
1097 ":INPUT DROP [0:0]\n"
1098 ":OUTPUT ACCEPT [0:0]\n"
1106 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop
);
1109 if ((gateway_mode
) || (nvram_match("wk_mode_x", "1"))) {
1110 ip46t_write(":FORWARD DROP [0:0]\n");
1114 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1117 ip46t_write("COMMIT\n");
1121 // -----------------------------------------------------------------------------
1123 int start_firewall(void)
1126 struct dirent
*dirent
;
1131 char *iptrestore_argv
[] = { "iptables-restore", (char *)ipt_fname
, NULL
};
1133 char *ip6trestore_argv
[] = { "ip6tables-restore", (char *)ip6t_fname
, NULL
};
1136 simple_lock("firewall");
1137 simple_lock("restrictions");
1139 wanup
= check_wanup();
1141 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1143 /* NAT performance tweaks
1144 * These values can be overriden later if needed via firewall script
1146 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1147 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1148 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1149 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1150 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1151 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1152 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1153 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1154 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1155 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1156 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1157 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1159 /* DoS-related tweaks */
1160 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1161 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1162 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1164 wanproto
= get_wan_proto();
1165 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto
== WP_DISABLED
|| wanproto
== WP_STATIC
) ? "0" : "1", 0, 0);
1168 /* Force IGMPv2 due EMF limitations */
1169 if (nvram_get_int("emf_enable")) {
1170 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1171 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1175 n
= nvram_get_int("log_in");
1176 chain_in_drop
= (n
& 1) ? "logdrop" : "DROP";
1177 chain_in_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1179 n
= nvram_get_int("log_out");
1180 chain_out_drop
= (n
& 1) ? "logdrop" : "DROP";
1181 chain_out_reject
= (n
& 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1182 chain_out_accept
= (n
& 2) ? "logaccept" : "ACCEPT";
1184 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1186 strlcpy(lanface
, nvram_safe_get("lan_ifname"), IFNAMSIZ
);
1188 memcpy(&wanfaces
, get_wanfaces(), sizeof(wanfaces
));
1189 wanface
= wanfaces
.iface
[0].name
;
1191 strlcpy(wan6face
, get_wan6face(), sizeof(wan6face
));
1194 strlcpy(s
, nvram_safe_get("lan_ipaddr"), sizeof(s
));
1195 if ((c
= strrchr(s
, '.')) != NULL
) *(c
+ 1) = 0;
1196 strlcpy(lan_cclass
, s
, sizeof(lan_cclass
));
1199 block obviously spoofed IP addresses
1202 1 - do source validation by reversed path, as specified in RFC1812
1203 Recommended option for single homed hosts and stub network
1204 routers. Could cause troubles for complicated (not loop free)
1205 networks running a slow unreliable protocol (sort of RIP),
1206 or using static routes.
1207 0 - No source validation.
1209 c
= nvram_get("wan_ifname");
1210 /* mcast needs rp filter to be turned off only for non default iface */
1211 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface
, c
) == 0) c
= NULL
;
1213 if ((dir
= opendir("/proc/sys/net/ipv4/conf")) != NULL
) {
1214 while ((dirent
= readdir(dir
)) != NULL
) {
1215 sprintf(s
, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent
->d_name
);
1216 f_write_string(s
, (c
&& strcmp(dirent
->d_name
, c
) == 0) ? "0" : "1", 0, 0);
1222 gateway_mode
= !nvram_match("wk_mode", "router");
1224 /* Remote management */
1225 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1226 nvram_invmatch("http_wanport", "0")) remotemanage
= 1;
1229 if ((ipt_file
= fopen(ipt_fname
, "w")) == NULL
) {
1230 notice_set("iptables", "Unable to create iptables restore file");
1231 simple_unlock("firewall");
1236 if ((ip6t_file
= fopen(ip6t_fname
, "w")) == NULL
) {
1237 notice_set("ip6tables", "Unable to create ip6tables restore file");
1238 simple_unlock("firewall");
1241 modprobe("nf_conntrack_ipv6");
1242 modprobe("ip6t_REJECT");
1244 /*Deon Thomas attempt to start xt_IMQ and imq */
1245 /*shibby - fix modprobing IMQ for kernel 2.4 */
1250 modprobe("ipt_IMQ");
1265 #ifdef DEBUG_IPTFILE
1267 simple_unlock("firewall");
1268 simple_unlock("restrictions");
1275 if (nvram_get_int("upnp_enable") & 3) {
1276 f_write("/etc/upnp/save", NULL
, 0, 0, 0);
1277 if (killall("miniupnpd", SIGUSR2
) == 0) {
1278 f_wait_notexists("/etc/upnp/save", 5);
1282 notice_set("iptables", "");
1283 if (_eval(iptrestore_argv
, ">/var/notice/iptables", 0, NULL
) == 0) {
1285 notice_set("iptables", "");
1288 sprintf(s
, "%s.error", ipt_fname
);
1289 rename(ipt_fname
, s
);
1290 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1297 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1298 -A INPUT -i br0 -j ACCEPT
1302 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1303 -A FORWARD -i br0 -j ACCEPT
1309 if (ipv6_enabled()) {
1310 notice_set("ip6tables", "");
1311 if (_eval(ip6trestore_argv
, ">/var/notice/ip6tables", 0, NULL
) == 0) {
1312 notice_set("ip6tables", "");
1315 sprintf(s
, "%s.error", ip6t_fname
);
1316 rename(ip6t_fname
, s
);
1317 syslog(LOG_CRIT
, "Error while loading rules. See %s file.", s
);
1322 eval("ip6tables", "-F");
1323 eval("ip6tables", "-t", "mangle", "-F");
1327 if (nvram_get_int("upnp_enable") & 3) {
1328 f_write("/etc/upnp/load", NULL
, 0, 0, 0);
1329 killall("miniupnpd", SIGUSR2
);
1332 simple_unlock("restrictions");
1333 sched_restrictions();
1334 enable_ip_forward();
1336 led(LED_DMZ
, dmz_dst(NULL
));
1339 modprobe_r("nf_conntrack_ipv6");
1340 modprobe_r("ip6t_LOG");
1341 modprobe_r("ip6t_REJECT");
1344 modprobe_r("xt_layer7");
1345 modprobe_r("xt_recent");
1346 modprobe_r("xt_HL");
1347 modprobe_r("xt_length");
1348 modprobe_r("xt_web");
1349 modprobe_r("xt_webmon");
1350 modprobe_r("xt_dscp");
1352 modprobe_r("ipt_layer7");
1353 modprobe_r("ipt_recent");
1354 modprobe_r("ipt_TTL");
1355 modprobe_r("ipt_web");
1356 modprobe_r("ipt_webmon");
1357 modprobe_r("ipt_dscp");
1359 modprobe_r("ipt_ipp2p");
1361 unlink("/var/webmon/domain");
1362 unlink("/var/webmon/search");
1364 #ifdef TCONFIG_OPENVPN
1365 run_vpn_firewall_scripts();
1367 run_nvscript("script_fire", NULL
, 1);
1369 simple_unlock("firewall");
1373 int stop_firewall(void)
1379 #ifdef DEBUG_IPTFILE
1380 void create_test_iptfile(void)