加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

域名白名单的设计与实现

(2016-02-25 09:45:21)
标签:

杂谈

内容来源于PPPCloud官网教程

1.前言

1.1.关于本篇文档

本文档描述如何实现域名白名单的功能。

1.2.背景知识

在阅读本文档前建议读者具有如下知识:

iptables 命令配置 IP_QUEUE 机制及libipq 库函数使用 Linux 防火墙实现netfilter

1.3.名词解释

域名:由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。

白名单:与黑名单相对应,默认所有数据都阻止,添加白名单的数据放行。

iptables:一种工具,它可以插入、修改和删除包过滤表的规则。

netfilterlinux内核实现数据包过滤、数据包处理、NAT等的功能框架

Json:是一种轻量级的数据交换格式。

2.整体描述

2.1.需求描述

默认情况下所有出口流量全部放行,入口流量全部禁止。当配置相应的域名白名单之后,放行入口方向的白名单,使它可以被外部用户访问。域名白名单只对入口方向起作用。

2.3.运行环境

软件环境:CentOSrelease 6.6 (Final)

硬件环境:X86_64

2.4.物理结构图

数据流出方向结构图

数据流入方向结构图

物理结构说明:

其中的剪头代表数据流的方向,HOST主机为物理设备,VM代表虚拟机,数据通过桥接口访问网络。因为使用桥接方式,iptables在桥模式下生效需要配置相应内容。白名单阻止入方向的数据,并不阻止出方向的数据。VM搭建WEB服务器,外部访问WEB服务器需要配置白名单,否则禁止域名访问。

2.5.服务结构图

采用客户端服务器架构。客户端下发数据,服务端配置数据并保存数据。采用json数据格式传输。Sqlite保存数据。

3.Netfilter/Iptables

概述

Netfilter/Iptables是继2.0.xIPfwadm2.2.xIPchains之后,新一代的Linux防火墙机制。Netfilter采用模块化设计,具有良好的可扩充性。其重要工具模块Iptables连接到Netfilter的架构中,并允许使用者对数据报进行过滤、地址转换、处理等操作。

Netfilter提供了一个框架,将对网络代码的直接干涉降到最低,并允许用规定的接口将其他包处理代码以模块的形式添加到内核中,具有极强的灵活性。

Netfilter主要通过表、链实现规则,可以这么说,Netfilter是表的容器,表是链的容器,链是规则的容器,最终形成对数据报处理规则的实现。

Iptables是基于Netfilter基本架构实现的一个可扩展的数据报高级管理系统,利用tablechainrule三级来存储数据报的各种规则。

简单地讲,tableschains组成,而chains又由rules组成。iptables 默认有四个表Filter,NAT, Mangle, Raw

规则表:

1.filter——三个链:INPUTFORWARDOUTPUT作用:过滤数据包  内核模块:iptables_filter.2.Nat——三个链:PREROUTINGPOSTROUTINGOUTPUT作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat3.Mangle——五个链:PREROUTINGPOSTROUTINGINPUTOUTPUTFORWARD作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)4.Raw——两个链:OUTPUTPREROUTING作用:决定数据包是否被状态跟踪机制处理  内核模块:iptable_raw(这个是REHL4没有的,不过不用怕,用的不多)

规则链:

1.INPUT——进来的数据包应用此规则链中的策略2.OUTPUT——外出的数据包应用此规则链中的策略3.FORWARD——转发数据包时应用此规则链中的策略4.PREROUTING——对数据包作路由选择前应用此链中的规则(记住!所有的数据包进来的时侯都先由这个链处理)5.POSTROUTING——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理)

目标值:

数据包控制方式包括四种为:

ACCEPT:允许数据包通过。 DROP:直接丢弃数据包,不给出任何回应信息。 REJECT:拒绝数据包通过,必须时会给数据发送端一个响应信息。 LOG:在/var/log/messages 文件中记录日志信息,然后将数据包传递给下一条规则。 QUEUE:防火墙将数据包移交到用户空间RETURN:防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)

白名单的功能就是利用的QUEUE

4.libipq

概述

libipq是一个iptables用户空间数据包排队开发库。

用户空间数据包排队机制

Netfilter提供一个机制,将数据包送到栈外在用户空间排队,然后这些数据包送回内核并附带上一个如何处理这个数据包的决定(比如ACCEPTDROP)。这些数据包在送回内核之前还可能在用户空间被修改。

对于每个支持的协议,内核模块调用一个Netfilter注册的队列handler以机械地将数据包送出到用户空间或从用户空间接回。

IPv4的标准的队列handlerip_queue。其被作为一个2.4内核的实验模块提供,使用一个Netlink套接字在内核/用户空间交换数据。

一旦载入ip_queue,可以通过QUEUE目标将IP数据包挑选出来排队到用户空间处理。例如,运行下面的命令:

# modprobe iptable_filter# modprobe ip_queue# iptables -A OUTPUT -p icmp -j QUEUE

将导致任意本地产生的ICMP数据包(比如,ping的输出)被发送到ip_queue模块,此模块将尝试将这些数据包递送到用户空间的应用。如果没有用户空间的应用来处理它们,它们将被丢弃。

一个应用可以通过libipq接收和处理这些数据包。

Libipq概述

Libipq提供一组API以于ip_queue交互。下面是API用法的一个概述,细节参看各函数的手册页。

初始化

为了初始化此库,调用ipq_create_handle(3)。这将尝试与ip_queue使用的Netlink套接字捆绑并返回一个上下文无关的句柄,此句柄用于接下来的库调用。

设置排队模式

ipq_set_mode(3)允许应用指定拷贝到用户空间的数据,是仅数据包的元数据还是数据包负载和数据包元数据。这也用于告诉ip_queue一个应用已经准备好接收排队消息。

从队列中接收数据包

ipq_read(3)等待ip_queue的队列消息,并将它们拷贝到指定的缓冲。队列消息可以是数据包消息或错误消息。

可以通过ipq_message_type(3)确定数据包类型。

如果收到一个数据包消息,元数据和可选的负载可以通过ipq_get_packet(3)获取。

通过ipq_get_msgerr(3)获取一个错误消息的值。

对数据包下发判决

做出如何处理数据包的决定,可选的返回一个修改过的数据包给内核,可以调用ipq_set_verdict(3)

错误处理

对应于内部错误变量ipq_errno的一个错误字符串可以通过ipq_errstr(3)获取。

对于简单的应用,调用ipq_perror(3)可以打印与ipq_errstr(3)相同的消息,还附带打印全局变量errno(如果设置了的话)的信息到stderr

清理

调用ipq_destroy_handle(3)以释放Netlink套接字并销毁上下文句柄相关的资源。

举例

下面是一个简单应用的例子,它获取数据包并对每个数据包下达NF_ACCEPT判决。

#include <stdio.h>#include <stdlib.h>#include <netinet/in.h>#include <linux/netfilter.h>#include <libipq.h> #define BUFSIZE 2048 static void die(struct ipq_handle *h) {    ipq_perror("passer");    ipq_destroy_handle(h);    exit(1);}int main(int argc, char **argv) {    int status;    unsigned char buf[BUFSIZE];    struct ipq_handle *h;     h = ipq_create_handle(0, NFPROTO_IPV4);    if (!h)    die(h);        status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);    if (status < 0)    die(h);        do {        status = ipq_read(h, buf, BUFSIZE, 0);        if (status < 0)        die(h);        switch (ipq_message_type(buf)) {        case NLMSG_ERROR:            fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(buf));            break;                case IPQM_PACKET: {            ipq_packet_msg_t *m = ipq_get_packet(buf);                    status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);            if (status < 0)                die(h);            break;        }            default:            fprintf(stderr, "Unknown message type!\n");            break;        }    } while (1);        ipq_destroy_handle(h);    return 0;}

编译

gcc example_ipq.c-lipq

详细内容请参考linuxman手册。

需要安装的数据包

yum install -y libnetfilter_queue-develyum install -y iptables-devel

需要设置过滤的iptables规则

iptables -A FORWARD -p tcp –i br0 –m tcp –d 172.16.0.0/16 --dport 80 -j QUEUE

为了区分内外网的入口流量和出口流量,需要配置虚机的ip地址段。

过滤桥接口数据的配置

请设置/etc/sysctl.conf

net.bridge.bridge-nf-call-iptables = 1

执行使配置生效

sysctl -p

查看是否配置成功

cat /proc/sys/net/bridge/bridge-nf-call-iptables

结果为1,说明配置成功。

5.匹配http协议的字段

匹配http协议的GET数据包的Host字段

如图所示为Wireshark抓取的数据包http协议截图。

我们只取Host字段进行匹配。图中的Host字段为www.testa.com。只比对testa.com是否与白名单中的数据相同,相同则放行,不同则阻止。

6.总结

通过iptables配置的“iptables -A FORWARD -p tcp –i br0 –m tcp –d 172.16.0.0/16--dport 80 -j QUEUE”来导入匹配的80端口的域名访问数据。使用libipq库编写的函数解析数据包,找到http协议的GET数据包的Host字段,并进行匹配。如果匹配成功则放行,如果匹配失败则阻止。这样就完成了域名白名单的功能。

客户端配置白名单向服务端下发命令。服务端接收命令设置白名单到内存和数据库。使用json格式进行数据传输。

目前最新的targetNFQUEUE,是QUEUE的扩展。相比于QUEUE,它可以由用户指定不同的queue number

了解更多的信息请参考以下网址:

http://www.netfilter.org/projects/libnetfilter_queue/doxygen/index.html

Libipqlibnetfilter_queue可以实现更多的包过滤功能,甚至实现防火墙的功能。有兴趣的朋友可以尝试下。

 

原文链接:https://www.pppcloud.cn/community_courseInfo.html?id=700028

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有