通过域名访问路由器配置界面的功能实现

需求背景:

目前路由器的配置界面是通过输入网关IP来访问,市面上其他的路由器可以通过域名来访问,例如腾达路由器的配置界面地址 routendawifi.com。
所以我们也希望支持域名访问路由器的配置界面。如在浏览器中输入www.9344base.cn 就可以访问路由器界面。

实现原理:

一次正常的域名访问流程如下:
(1) 客户端向DNS服务器发送域名解析请求,该请求会先发到路由器。
(2) 路由器收到DNS请求后会对其进行转发,发给外网的DNS服务器。
(3) 外网的DNS服务器收到请求后,进行解析,之后发出DNS应答,其中就包括了域名对应的IP。
(4) 路由器收到DNS服务器发来的应答包,将其转发给客户端。
(5) 客户端收到应答,按照对应IP进行访问。

我们的修改发生在第2步,当路由器收到客户端的DNS请求包后,筛选出特定域名的请求包,不对其进行转发,而是将其丢弃,然后生成一个DNS应答包发给客户端,该应答包中IP就是网关IP或者A20的IP。这样客户端收到应答包后就可以把特定域名和网关对应起来了。

这部分的实现主要是在iptables 和netfilter中,netfilter中对DNS数据包进行筛选、丢弃和生成。

源码介绍

对源码的修改主要分两部分:iptables 部分和netfilter 部分,关于iptables和netfilter关系以及match、target、hook点、iptables 表、iptables链的详细介绍参考如下资料 :
http://blog.chinaunix.net/uid-20775448-id-3504538.html

(1) iptables 部分

源码位置:apps/iptables/iptables-1.4.5-qos/extensions
主要添加了libipt_DNS.c 和 libipt_dnsurl.c 两个文件。其中libipt_DNS.c 是DNS功能的iptables 中的target模块。
核心代码如下:

static int DNS_parse(int c, char **argv, int invert, unsigned int *flags,
                     const void *entry, struct xt_entry_target **target)
{
    struct ipt_dns_info *dnsinfo = (struct ipt_dns_info *)(*target)->data;
    const struct in_addr *ip;

        xtables_check_inverse(optarg, &invert, &optind, 0); 
    switch (c) {
    case '1':
        ip = xtables_numeric_to_ipaddr(argv[optind-1]);
        if (!ip)
            xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
                   argv[optind-1]);
        dnsinfo->ip = ip->s_addr;
    
        //printf("ip = %x\n", dnsinfo->ip);
        break;

    default:
        return 0;
    }
    
    return 1;
}

主要功能就是将iptables 命令传入的IP参数进行解析,然后填充到ipt_dns_info结构体中,之后将该结构体传入内核,交个DNS 的netfilter target模块使用。
libipt_dnsurl.c 文件 是DNS功能的iptables 中的match模块,核心代码如下:

static int parse(int c, char **argv, int invert, unsigned int *flags,
      const void *entry,
      struct xt_entry_match **match)
{
    struct xt_dnsurl_info *info = (struct xt_dnsurl_info *)(*match)->data;

    xtables_check_inverse(optarg, &invert, &optind, 0); 
    if (invert) xtables_error(PARAMETER_PROBLEM, "Sorry, you can't have an inverted comment");

//  printf("dnsurl parse\n");

    if (c == '1')
    {   
        strcpy(info->url, argv[optind-1]);
        info->url_len = strlen(argv[optind-1]);
        if(!strcmp(argv[optind-1],"enforcedns"))
        {
            info->enforce_dns = 1;
        }
    }
    else
    {
        return 0;
    }

    if (*flags)
        xtables_error(PARAMETER_PROBLEM, "multiurl can only have one option");

    *flags = 2;


    return 1;
}

主要作用是将iptables 命令传入的URL参数进行解析,然后填充到xt_dnsurl_info 结构体中,之后将该结构体传入内核,交个DNS 的netfilter match模块使用。

(2)netfilter 部分

主要添加了netfilter 的match模块和target模块。
target模块源码位于 linux/kernels/mips-linux-2.6.31/net/ipv4/netfilter/ nf_nat_rule.c文件中,核心源码如下:

static unsigned int 
ipt_dns_target(struct sk_buff *skb, const struct xt_target_param *par)
{
    const struct ipt_dns_info *dnsinfo = par->targinfo;

    struct iphdr *iph = ip_hdr(skb);
    struct udphdr *udph = (void *)iph + iph->ihl*4; /* Might be TCP, UDP */
    int ret = 0;
    int addr = 0;
    u_int16_t port = 0;
    u_int16_t *flag = (void *)udph + 10; 
    char buff[50] = {0};
    char *buff_p = buff;
    enum ip_conntrack_info ctinfo;
    struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
    u_int16_t *udp_check = (void *)udph + 6;
    u_int8_t *url_len = (void *)udph + 20; 
    char *url = url_len+1;
    
    /*将DNS数据包的目的IP和源IP进行互换,源端口和目的端口互换,这样就可以将收的数据包又返回给发送者*/
    addr = iph->daddr;iph->daddr = iph->saddr; iph->saddr = addr; 
    port = udph->dest;
    udph->dest = udph->source;
    udph->source = port;
    /*修改flag将请求模式改成应答模式*/
    *flag ++= 0x8580;
     /*修改资源记录数为1,修改问题数为1*/
    *flag ++= 0x0001;
    *flag = 0x0001;

     /*填充应答包中资源记录部分数据,即要给客户端的DNS IP数据*/
    *buff_p++=0xc0;
    *buff_p++=0x0c;
    *(int *)buff_p = 0x00010001;
    buff_p +=4;
    *(int *)buff_p = 0x0;
    buff_p +=4;
    *(u_int16_t *)buff_p = 0x4;
    buff_p +=2;
     /*查询的URL对应的IP*/
    *(int *)buff_p = dnsinfo->ip;

     /*完成对UDP包的修改,进行相关的校验*/
    nf_nat_mangle_udp_packet_fw(skb, ct, ctinfo,
                                  udph->len-8, 0,
                                  &buff, 16);

    return 1;
}

主要作用是将match筛选过的数据包进行修改,填充DNS应答包,这样就可以把客户端发来的DNS请求包变成应答包,然后再返还给客户端,从而模拟了一次完整的DNS请求应答过程。
Match模块源码位于:linux/kernels/mips-linux-2.6.31/net/ipv4/netfilter/ ipt_multiurl.c文件中。核心代码如下:

static bool dnsmatch(const struct sk_buff *skb, 
      const struct xt_match_param *param)
{   
    const struct xt_dnsurl_info *info = param->matchinfo;    

    struct iphdr *iph = ip_hdr(skb);
        struct udphdr *udph = (void *)iph + iph->ihl*4; /* Might be TCP, UDP */
     u_int8_t *url_len = (void *)udph + 20; 
    char *url = url_len+1;
    if(info->enforce_dns)
    {   
        return 1;
    }   
    /*判断DNS请求包中的URL长度是不是和特定URL的长度一致*/
    if( *url_len == info->url_len)
    {   
            /*判断DNS请求包中的URL内容是不是和特定URL一致,如果一致将返回1,表明该数据包通过筛选*/
        if (!memcmp(url, info->url, info->url_len))
        {
    //      printk("yaomoon: match dnsurl url_len = %d\n",info->url_len);
            return 1;
        }
    }   
    if( (*url_len == 3)&&(*(url_len+4) == info->url_len))
    {   
        url_len +=4;
        url = url_len+1;
        if (!memcmp(url, info->url, info->url_len))
        {
    //      printk("yaomoon: match dnsurl url_len = %d\n",info->url_len);
            return 1;
        }
    }

    return 0;

}

主要作用就是筛选DNS请求包,DNS请求包中包含所请求的URL内容和长度,我们可以通过判断出是不是我们要改的DNS请求包。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
H3C路由器配置教程如下: 1. 进入路由器的命令行界面,输入用户名和密码进行登录。 2. 配置路由器的基本信息,包括主机名、域名、管理口IP地址等。 例如:[H3C]sysname Router1 [Router1]interface GigabitEthernet 0/0/0 [Router1-GigabitEthernet0/0/0]ip address 192.168.1.1 24 3. 配置路由器的路由功能,包括静态路由和动态路由。 静态路由配置示例: 添加缺省路由:[H3C]ip route-static 0.0.0.0 0.0.0.0 192.168.1.2 添加网络路由:[H3C]ip route-static 192.168.1.0 255.255.255.0 192.168.0.1 动态路由配置示例: 启用OSPF协议:[H3C]ospf 配置OSPF区域:[H3C-ospf-1]area 0 配置OSPF接口:[H3C-ospf-1-area-0.0.0.0]network 192.168.1.0 0.0.0.255 4. 配置路由器的安全功能,包括访问控制、防火墙等。 访问控制配置示例: 创建ACL规则:[H3C]acl number 2000 [H3C-acl-adv-2000]rule permit ip source 192.168.1.0 0.0.0.255 destination 192.168.2.0 0.0.0.255 应用ACL规则:[H3C]interface GigabitEthernet 0/0/0 [H3C-GigabitEthernet0/0/0]traffic-filter inbound acl 2000 防火墙配置示例: 创建防火墙策略:[H3C]firewall policy 1 [H3C-firewall-policy-1]rule permit ip source 192.168.1.0 0.0.0.255 destination 192.168.2.0 0.0.0.255 应用防火墙策略:[H3C]interface GigabitEthernet 0/0/0 [H3C-GigabitEthernet0/0/0]firewall packet-filter 1 inbound 5. 配置路由器的其他功能,包括NAT、***nat address-group 1 192.168.1.2 192.168.1.10 配置NAT规则:[H3C]acl number 3000 [H3C-acl-adv-3000]rule permit ip source 192.168.1.0 0.0.0.255 [H3C-acl-adv-3000]rule deny ip [H3C]nat outbound 3000 address-group 1 6. 保存配置并退出命令行界面。 保存配置:[H3C]save 退出界面:[H3C]quit

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

viqjeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值