(CN) Firewall Exploration Lab
![](/post/seed_lab_4/featured_hu0eaaba4bfebe5127c9e3a92d3c000d7d_37089_629292ae6c940a802e8e45bdb28a7ece.webp)
Firewall Exploration Lab
Task 1 Implementing a Simple Firewall
Task A Implement a Simple Kernel Module
![image-20230209153856473](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302091538546.png)
![image-20230209153928425](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302091539486.png)
![image-20230209153956087](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302091539139.png)
![image-20230209154014203](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302091540262.png)
![image-20230209154036257](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302091540334.png)
Task B Implement a Simple Firewall Using Netfilter
- load
![image-20230216182135967](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161821053.png)
![image-20230216182329522](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161823598.png)
unload:
![image-20230216182408129](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161824206.png)
2.
![img](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161855765.gif)
3.
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/if_ether.h>
#include <linux/inet.h>
static struct nf_hook_ops hook1, hook2, hook3, hook4;
static struct nf_hook_ops hooks[NF_INET_NUMHOOKS];
unsigned int blockUDP(void *priv, struct sk_buff *skb,const struct nf_hook_state *state)
{
struct iphdr *iph;
struct udphdr *udph;
u16 port = 53;
char ip[16] = "8.8.8.8";
u32 ip_addr;
if (!skb) return NF_ACCEPT;
iph = ip_hdr(skb);
// Convert the IPv4 address from dotted decimal to 32-bit binary
in4_pton(ip, -1, (u8 *)&ip_addr, '\0', NULL);
if (iph->protocol == IPPROTO_UDP) {
udph = udp_hdr(skb);
if (iph->daddr == ip_addr && ntohs(udph->dest) == port){
printk(KERN_WARNING "*** Dropping %pI4 (UDP), port %d\n", &(iph->daddr), port);
return NF_DROP;
}
}
return NF_ACCEPT;
}
unsigned int blockPing(void *priv, struct sk_buff *skb,const struct nf_hook_state *state)
{
struct iphdr *iph;
if (!skb) return NF_ACCEPT;
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_ICMP) {
printk(KERN_WARNING "*** Dropping ICMP from %pI4 to %pI4\n", &(iph->saddr), &(iph->daddr));
return NF_DROP;
}
return NF_ACCEPT;
}
unsigned int blockTelnet(void *priv, struct sk_buff *skb,const struct nf_hook_state *state)
{
struct iphdr *iph;
struct tcphdr *tcph;
u16 port = 23;
if (!skb) return NF_ACCEPT;
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_TCP) {
tcph = tcp_hdr(skb);
if (ntohs(tcph->dest) == port) {
printk(KERN_WARNING "*** Dropping Telnet from %pI4:%d to %pI4:%d\n", &(iph->saddr), ntohs(tcph->source), &(iph->daddr), port);
return NF_DROP;
}
}
return NF_ACCEPT;
}
unsigned int printInfo(void *priv, struct sk_buff *skb,const struct nf_hook_state *state)
{
struct iphdr *iph;
char *hook;
char *protocol;
switch (state->hook){
case NF_INET_LOCAL_IN: hook = "LOCAL_IN"; break;
case NF_INET_LOCAL_OUT: hook = "LOCAL_OUT"; break;
case NF_INET_PRE_ROUTING: hook = "PRE_ROUTING"; break;
case NF_INET_POST_ROUTING: hook = "POST_ROUTING"; break;
case NF_INET_FORWARD: hook = "FORWARD"; break;
default: hook = "IMPOSSIBLE"; break;
}
printk(KERN_INFO "*** %s\n", hook); // Print out the hook info
iph = ip_hdr(skb);
switch (iph->protocol){
case IPPROTO_UDP: protocol = "UDP"; break;
case IPPROTO_TCP: protocol = "TCP"; break;
case IPPROTO_ICMP: protocol = "ICMP"; break;
default: protocol = "OTHER"; break;
}
// Print out the IP addresses and protocol
printk(KERN_INFO " %pI4 --> %pI4 (%s)\n", &(iph->saddr), &(iph->daddr), protocol);
return NF_ACCEPT;
}
int registerFilter(void) {
int i;
printk(KERN_INFO "Registering filters.\n");
// hook1.hook = printInfo;
// hook1.hooknum = NF_INET_LOCAL_OUT;
// hook1.pf = PF_INET;
// hook1.priority = NF_IP_PRI_FIRST;
// nf_register_net_hook(&init_net, &hook1);
hook2.hook = blockUDP;
hook2.hooknum = NF_INET_POST_ROUTING;
hook2.pf = PF_INET;
hook2.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &hook2);
hook3.hook = blockPing;
hook3.hooknum = NF_INET_LOCAL_IN;
hook3.pf = PF_INET;
hook3.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &hook3);
hook4.hook = blockTelnet;
hook4.hooknum = NF_INET_LOCAL_IN;
hook4.pf = PF_INET;
hook4.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &hook4);
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
hooks[i].hook = printInfo;
hooks[i].hooknum = i;
hooks[i].pf = PF_INET;
hooks[i].priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &hooks[i]);
}
return 0;
}
void removeFilter(void) {
int i;
printk(KERN_INFO "The filters are being removed.\n");
// nf_unregister_net_hook(&init_net, &hook1);
nf_unregister_net_hook(&init_net, &hook2);
nf_unregister_net_hook(&init_net, &hook3);
nf_unregister_net_hook(&init_net, &hook4);
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
nf_unregister_net_hook(&init_net, &hooks[i]);
}
}
module_init(registerFilter);
module_exit(removeFilter);
MODULE_LICENSE("GPL");
![image-20230216190223160](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161902228.png)
![image-20230216190254514](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161902568.png)
![image-20230216190613322](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161906374.png)
![image-20230216190716259](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161907337.png)
Task 2 Experimenting with Stateless Firewall Rules
Task A Protecting the Router
INPUT 和 OUTPUT 的默认 policy 为 DROP,仅仅对于ICMP可行,对于ping可以,但是无法telnet到seed-router
![image-20230216193258340](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161932401.png)
![image-20230216193952027](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161939092.png)
![image-20230216194022184](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161940240.png)
![image-20230216194251603](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302161942653.png)
Task B Protecting the Internal Network
要实现路由器所连的两网的相互隔离,仅允许内部主机ping 外部主机,需要添加FORWARD规则,用 -d/-s 参数指定来去的ip段
//task2 b
iptables -A FORWARD -p icmp --icmp-type echo-reply -d 192.168.60.0/24 -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -s 192.168.60.0/24 -j ACCEPT
iptables -A FORWARD -j DROP
![image-20230216200841007](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162008078.png)
测试是否成功:
![image-20230216201317614](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162013675.png)
![image-20230216201420467](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162014535.png)
udp报文也被drop
![image-20230216201718467](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162017527.png)
tcp报文也被drop
![image-20230216202205987](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162022050.png)
Task C Protecting Internal Servers
// task2 c
iptables -A FORWARD -p tcp -s 10.9.0.0/24 --dport 23 -d 192.168.60.5 -j ACCEPT
iptables -A FORWARD -p tcp -s 192.168.60.0/24 --dport 23 -d 192.168.60.0/24 -j ACCEPT
iptables -P FORWARD DROP
![image-20230216210709195](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162107272.png)
- All the internal hosts run a telnet server (listening to port 23). Outside hosts can only access the telnet server on 192.168.60.5, not the other internal hosts.
![image-20230216210216009](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162102079.png)
- Outside hosts cannot access other internal servers.
![](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162057614.png)
- Internal hosts can access all the internal servers.
![image-20230216205938547](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162059615.png)
- Internal hosts cannot access external servers.
![image-20230216205841862](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302162058923.png)
Task 3 Connection Tracking and Stateful Firewall
Task A Experiment with the Connection Tracking
icmp 30s左右
![image-20230217155759285](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171601841.png)
udp 30s左右
![image-20230217160039572](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171601994.png)
TCP在连接ESTABLISHED后,状态持续时间为432000秒,断开连接进入TIME_WAIT状态,持续时间为120秒。
![image-20230217160356018](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171603080.png)
Task B Setting Up a Stateful Firewall
iptables -A FORWARD -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -p tcp -i eth0 --dport 23 --syn -m conntrack --ctstate NEW -d 192.168.60.5 -j ACCEPT
iptables -A FORWARD -p tcp -i eth1 --dport 23 --syn -m conntrack --ctstate NEW -j ACCEPT
iptables -P FORWARD DROP
![image-20230217162358177](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171625442.png)
- All the internal hosts run a telnet server (listening to port 23). Outside hosts can only access the telnetserver on 192.168.60.5, not the other internal hosts.
![image-20230217161910077](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171619367.png)
- Outside hosts cannot access other internal servers.
![image-20230217162301894](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171623936.png)
- Internal hosts can access all the internal servers.
![image-20230217162025395](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171620461.png)
- Internal hosts can access external servers.
![image-20230217162122469](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302171622580.png)
- In this task, the connection tracking mechanism is allowed
我们将添加一条允许内部主机访问任何外部服务器的规则。使用conntrack模块,只放行新的TCP/SYN包和已有TCP连接的数据包,否则无法确定需要放行哪些传入内网的数据包。
Task 4 Limiting Network Traffic
iptables -A FORWARD -s 10.9.0.5 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT
iptables -A FORWARD -s 10.9.0.5 -j DROP
设置了drop
![image-20230218160445821](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181604908.png)
查看效果,可以看到前5个数据包都可以正常接收,那是因为limit默认初始包就是5个,因此没有任何问题,从第六个数据包开始后,每隔6秒才会正常处理一个数据包,因为1分钟限制10次数据包的接收,那就表示6秒收一个,效果如下图所示。也可以理解为是一开始可以快速通过5个数据报文,后面的数据报文是每分钟通过10个。
![image-20230218160644820](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181606891.png)
未设置drop:
![image-20230218160934312](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181609400.png)
![image-20230218161241495](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181612571.png)
添加第二条drop规则,超出10个报文后,其余的报文全部丢弃;不添加的话,对于超出的报文没有处理.
Task 5 Load Balancing
![image-20230218163152606](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181631793.png)
![image-20230218170720276](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181707535.png)
使用statistic模块负载均衡,使用-j DNAT –to-destination ip:port指定负载均衡目标,由于是UDP所以只用改destination。
![image-20230218170945961](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181709039.png)
iptables -t nat -A PREROUTING -p udp --dport 8080 -m statistic --mode random --probability 0.33 -j DNAT --to-destination 192.168.60.5:8080
![image-20230218171219306](https://typora-picgo-outis.oss-cn-shanghai.aliyuncs.com/img/202302181712357.png)