Closed Apachez- closed 12 years ago
Similar rules should be applied for ip6tables aswell when IPv6 support is confirmed:
I like your proposal in the sense, that we drop the 631 line. However that's yet to be tested.
I don't like that there are now two lines to regulate pings.
I also don't like the fact that "invalid (according to conntrack) packets", need to explicitly dropped. Why are invalid packets accepted in the first place?
1) Of course it has to be tested/verified that the UDP631 line is safe to remove. But to my knowledge when you print there is an OUTbound connection (from webconverger) who is made towards the printer and not INbound (to webconverger).
2) That is so the webconverger machine isnt being used as a ping relay (or limit the effect when its being used as one). For example if someone spoofs the srcip and send an echo-request towards the webconverger box the wenconverger will send an echo-reply back to the faked srcip. Its not uncommon that the faked srcip is the true vicitim (who will receive plenty of incoming icmp packets).
By adding a throttle to how many echo-requests webconverger will accept the effect of trying to use a webconverger box as a ping relay will be limited (but also that the resources of the webconverger box itself wont be exhausted).
3) Look at net/netfilter/nf_conntrack_proto_tcp.c:
752 /* table of valid flag combinations - PUSH, ECE and CWR are always valid */
753 static const u8 tcp_valid_flags[(TCPHDR_FIN|TCPHDR_SYN|TCPHDR_RST|TCPHDR_ACK|
754 TCPHDR_URG) + 1] =
755 {
756 [TCPHDR_SYN] = 1,
757 [TCPHDR_SYN|TCPHDR_URG] = 1,
758 [TCPHDR_SYN|TCPHDR_ACK] = 1,
759 [TCPHDR_RST] = 1,
760 [TCPHDR_RST|TCPHDR_ACK] = 1,
761 [TCPHDR_FIN|TCPHDR_ACK] = 1,
762 [TCPHDR_FIN|TCPHDR_ACK|TCPHDR_URG] = 1,
763 [TCPHDR_ACK] = 1,
764 [TCPHDR_ACK|TCPHDR_URG] = 1,
765 };
766
767 /* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
768 static int tcp_error(struct net *net, struct nf_conn *tmpl,
769 struct sk_buff *skb,
770 unsigned int dataoff,
771 enum ip_conntrack_info *ctinfo,
772 u_int8_t pf,
773 unsigned int hooknum)
774 {
775 const struct tcphdr *th;
776 struct tcphdr _tcph;
777 unsigned int tcplen = skb->len - dataoff;
778 u_int8_t tcpflags;
779
780 /* Smaller that minimal TCP header? */
781 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
782 if (th == NULL) {
783 if (LOG_INVALID(net, IPPROTO_TCP))
784 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
785 "nf_ct_tcp: short packet ");
786 return -NF_ACCEPT;
787 }
788
789 /* Not whole TCP header or malformed packet */
790 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
791 if (LOG_INVALID(net, IPPROTO_TCP))
792 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
793 "nf_ct_tcp: truncated/malformed packet ");
794 return -NF_ACCEPT;
795 }
796
797 /* Checksum invalid? Ignore.
798 * We skip checking packets on the outgoing path
799 * because the checksum is assumed to be correct.
800 */
801 /* FIXME: Source route IP option packets --RR */
802 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
803 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
804 if (LOG_INVALID(net, IPPROTO_TCP))
805 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
806 "nf_ct_tcp: bad TCP checksum ");
807 return -NF_ACCEPT;
808 }
809
810 /* Check TCP flags. */
811 tcpflags = (tcp_flag_byte(th) & ~(TCPHDR_ECE|TCPHDR_CWR|TCPHDR_PSH));
812 if (!tcp_valid_flags[tcpflags]) {
813 if (LOG_INVALID(net, IPPROTO_TCP))
814 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
815 "nf_ct_tcp: invalid TCP flag combination ");
816 return -NF_ACCEPT;
817 }
818
819 return NF_ACCEPT;
820 }
Droping invalid packets means that we will throw away packets who has a combination of tcp-flags which just isnt valid.
This can be done manually in iptables if one use Linux kernel older than v2.6.9:
iptables -N BADTCP_DROP
iptables -A BADTCP_DROP -m limit --limit 2/s --limit-burst 5 -j LOG --log-tcp-options --log-ip-options --log-level 7 --log-prefix "f=BADTCP a=DROP "
iptables -A BADTCP_DROP -j DROP
iptables -N BADTCP
iptables -A BADTCP -p tcp --tcp-flags PSH PSH -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL ACK -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL ACK,URG -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL SYN -m state --state NEW -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL SYN,ACK -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL FIN,ACK -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL FIN,ACK,URG -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL RST -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -p tcp --tcp-flags ALL RST,ACK -m state --state ESTABLISHED -j RETURN
iptables -A BADTCP -j BADTCP_DROP
iptables -A INPUT -i ${OUTSIDE_DEVICE} -p tcp -j BADTCP
iptables -A FORWARD -i ${OUTSIDE_DEVICE} -p tcp -j BADTCP
I have added two rules:
When the webconverger will use PMTU (enabled by default in linux kernel) we must allow incoming ICMP type destination-unreachable code fragmentation-needed for it to fully function. See http://en.wikipedia.org/wiki/Path_MTU_Discovery for more information.
Source Quench is one (of several) methods to inform the sender to send at a slower rate (for example if buffers are being exhausted on a router or host). See http://en.wikipedia.org/wiki/ICMP_Source_Quench for more information.
#!/usr/bin/env iptables-restore
*filter
:FORWARD DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Block invalid (according to conntrack) packets.
-A INPUT -m state --state INVALID -j DROP
# Block fragmented ICMP.
-A INPUT -p icmp --fragment -j DROP
# Allow keep state.
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow localhost (so Webconverger can speak to itself).
-A INPUT -i lo -j ACCEPT
# Allow incoming Path MTU Discovery (ICMP destination-unreachable/fragmentation-needed)
-A INPUT -p icmp --icmp-type 3/4 -m state --state NEW -j ACCEPT
# Allow incoming request to decrease rate of sent packets (ICMP Source Quench)
-A INPUT -p icmp --icmp-type 4 -m state --state NEW -j ACCEPT
# Allow and throttle incoming ping (ICMP Echo-Request).
-A INPUT -p icmp --icmp-type 8 -m state --state NEW -m limit --limit 2/s --limit-burst 5 -j ACCEPT
COMMIT
I will drop in your suggestions once I can confirm printer detection happens before and after these changes :) https://github.com/Webconverger/webc/issues/46
Do you have a printer queue at work you can try the latest upon http://build.webconverger.org/ ?
According to https://github.com/Webconverger/Debian-Live-config/blob/master/webconverger/config/includes.chroot/etc/iptables.conf the current iptables rules are:
I would like to suggest a cleanup/improvement so it will look like:
The above could also include various methods of logging but Im not sure if this is benefitial in Webconverger case.
As debugging one could use "iptables -L -v -n" (or "iptables -L -v -n -t nat") to look at counters for which rule gets a hit (since iptables is top-down first-match in its execution) unless one wants to manually include logging rules aswell.