Talk:Security Handbook/Firewalls and Network Security
Before creating a discussion or leaving a comment, please read about using talk pages. To create a new discussion, click here. Comments on an existing discussion should be signed using
~~~~
:
A comment [[User:Larry|Larry]] 13:52, 13 May 2024 (UTC) : A reply [[User:Sally|Sally]] 10:37, 5 November 2024 (UTC) :: Your reply ~~~~
A single firewall or firewall type is generally insufficient to secure an entire network
I am not happy with this statement ... because it is wrong. In nearly every small company, with a small network this solution is active:
https://en.wikipedia.org/wiki/DMZ_(computing)#Single_firewall
I have even created an example configuration for this design:
https://forums.gentoo.org/viewtopic-t-1114432.html
Yes, it is a SPOF but with a correct configuration it is a very secure solution. Think how many samll companies have the money for an edge and a core firewall ?
pietinger 07:40, 31 August 2023 (UTC)
- Sentence removed, and I improved some of the other phrasing around it.
- JM01085758 (talk) 00:27, 6 September 2023 (UTC)
Firewall script audit
In 2015, M. Marchese published a firewall script that creates the chain check-flags
. The context says, Port scans should be detected and logged, but in reality the chain will never be executed. The problem is that the chain is attached after this rule:
$IPTABLES -A INPUT -m state --state INVALID -j DROP
which is equivalent [1] to:
$IPTABLES -A INPUT -m conntrack --ctstate INVALID -j DROP
Here is the code that demonstrates what decision conntrack will make based on the flags provided in the firewall script:
#include <stdio.h>
#include <stdint.h>
/**
* The code block is taken from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp.h
* @license GPL-2.0-or-later
*/
#define TCPHDR_FIN 0x01
#define TCPHDR_SYN 0x02
#define TCPHDR_RST 0x04
#define TCPHDR_PSH 0x08
#define TCPHDR_ACK 0x10
#define TCPHDR_URG 0x20
/**
* The code block is taken from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/netfilter/nf_conntrack_proto_tcp.c
* @license GPL-2.0-only
*/
static const uint8_t tcp_valid_flags[(TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST | TCPHDR_ACK | TCPHDR_URG) + 1] =
{
[TCPHDR_SYN] = 1,
[TCPHDR_SYN|TCPHDR_URG] = 1,
[TCPHDR_SYN|TCPHDR_ACK] = 1,
[TCPHDR_RST] = 1,
[TCPHDR_RST|TCPHDR_ACK] = 1,
[TCPHDR_FIN|TCPHDR_ACK] = 1,
[TCPHDR_FIN|TCPHDR_ACK|TCPHDR_URG] = 1,
[TCPHDR_ACK] = 1,
[TCPHDR_ACK|TCPHDR_URG] = 1,
};
void print(const char* string, uint8_t flags) {
const uint8_t result = tcp_valid_flags[flags];
printf("%s: %d: %d \n", string, flags, result);
}
/**
* 01
* 01 01
* 01 01 01 01
* 01 01 01 01 01 01 01 01
*/
void combine(const char* string, const uint8_t any[], uint8_t result, int index) {
if (index < 4) {
const uint8_t new_result = result | any[index];
print(string, new_result);
combine(string, any, new_result, index + 1);
combine(string, any, result, index + 1);
}
}
void main() {
// "ALL <BLAH>" means everyhing is zero except <BLAH> (see iptables man page (--tcp-flags))
print("ALL FIN,URG,PSH", TCPHDR_FIN | TCPHDR_URG | TCPHDR_PSH);
print("ALL ALL", TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST | TCPHDR_PSH | TCPHDR_ACK | TCPHDR_URG); // ACCEPTED (63)
print("ALL SYN,RST,ACK,FIN,URG", TCPHDR_SYN | TCPHDR_RST | TCPHDR_ACK | TCPHDR_FIN | TCPHDR_URG);
print("ALL NONE", 0);
// SYN,RST SYN,RST (63 and 62 are ACCEPTED)
const uint8_t any[] = { TCPHDR_FIN, TCPHDR_PSH, TCPHDR_ACK, TCPHDR_URG };
combine("SYN,RST SYN,RST", any, TCPHDR_SYN | TCPHDR_RST, 0);
// SYN,FIN SYN,FIN (63 and 59 are ACCEPTED)
const uint8_t any2[] = { TCPHDR_RST, TCPHDR_PSH, TCPHDR_ACK, TCPHDR_URG };
combine("SYN,FIN SYN,FIN", any2, TCPHDR_SYN | TCPHDR_FIN, 0);
}
The above code demonstrates that tcp_valid_flags
filters all provided flags except 59
, 62
, 63
. But conntrack has additional checks, so these packages are also dropped.
Here is a demonstration of the drop:
Firewall:
root #
iptables --append INPUT --in-interface lo --protocol tcp --dport www --match conntrack --ctstate INVALID --jump DROP
root #
iptables --append INPUT --in-interface lo --protocol tcp --dport www --jump ACCEPT
Scan:
root #
nmap --scanflags 63 -p 80 localhost
Result:
root #
iptables --list INPUT --verbose
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2 88 DROP tcp -- lo any anywhere anywhere tcp dpt:http ctstate INVALID 0 0 ACCEPT tcp -- lo any anywhere anywhere tcp dpt:http
pkts
shows that packets were dropped.