当前位置:  建站>运营/SEO
本页文章导读:
    ▪系统运维——日志处理      日志主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等等!也有利于将这些信息进行持久化,否则信息便会丢失。很多时候,系统出现的异常都是碰巧的,很难再现的,所以.........
    ▪ip_conntrack缓存neighbour      在我的ip_conntrack版本中,它目前已经可以缓存路由,filter规则等,还可以平滑生效最新配置的NAT,它越来越像真正的SDN了,唯一有待完善的就是将5元组的tuple进化成N元组的tuple了,其余的更新.........
    ▪关键在封装并发出了帧-IP冲突也无所谓      最近有点走火入魔了!本文所用技术非标准,较真儿者慎入!!一个局域网内,两台机器拥有同样的IP,可以吗?这不就是IP地址冲突吗?当然不行!可是要知道,如果搞点旁门左道,还是可.........

[1]系统运维——日志处理
    来源: 互联网  发布时间: 2013-11-01

日志主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等等!也有利于将这些信息进行持久化,否则信息便会丢失。很多时候,系统出现的异常都是碰巧的,很难再现的,所以需要实时监控,记录运行日志信息。

 

介绍下日志工具:logging,log4j,commons-logging。

logging是java自带的,在JDK中java.util.logging.*包是日志记录API。

Log4j比JDK Logging更加成熟,是日志记录标准。

 

commons-logging,是一个接口抽象,底层的实现可以自动替换:

如果当前存在log4j,则使用log4j来实现

否则,使用JDKlogging来实现

否则,使用其自身的简单实现

 

通常使用Commons-log接口,使用log4j实现

 

一个日志工具,至少应该包括以下几个组成部分:

1、Logger

Logger按照布局中指定的格式把日志信息写入一个或多个输出源,Log4j 允许开发人员定义多个Logger,每个Logger拥有自己的名字,Logger之间通过名字来表明隶属关系。

 

2、Level

它还有一个重要的属性——日志级别。不管何种日志记录工具,大概包含如下几种日志级别,优先级由低到高:DEBUG,INFO,WARN,ERROR,FATAL。

 

在程序中打印日志信息时,优先级别低于配置文件中指定的级别时,将不做任何处理;比如配置文件中指定优先级别是WARN,当程序中有代码logger.info(message),则对message不会进行处理(输出到控制台或者文件)

 

     在log4j中,使用

log4j.rootLogger=[级别],[使用哪个appender]

log4.logger.[logger的名称]=[级别],[使用哪个appender]

     来对logger进行配置。如果某个logger没有进行配置,那么就会使用rootLogger的配置信息。

 

3、Appender

       一个Appender表示一个输出的目的地。Appendr可以是控制台、文本文件、XML文件或Socket。一个Logger可以拥有多个Appender ,即可以将种信息输出到多个位置。

 

在log4j中,使用

log4j.appender.[appender的名称]=[appender类名]

log4j.appender.[appender的名称].[appender的属性名]=[appender的属性Í

    
[2]ip_conntrack缓存neighbour
    来源: 互联网  发布时间: 2013-11-01
在我的ip_conntrack版本中,它目前已经可以缓存路由,filter规则等,还可以平滑生效最新配置的NAT,它越来越像真正的SDN了,唯一有待完善的就是将5元组的tuple进化成N元组的tuple了,其余的更新及修正都是些不会引发质变的量变。
        现在看一下,ip_conntrack还能缓存什么?当然了,在我的"路由cache in conntrack"版本中,我只是将dst_entry简单的从skb中拷贝到了ip_conntrack中,类似IPMARK那样,可以在skb和conntrack之间save和restore。数据包进入协议栈被处理的流程依然没变,优化掉的仅仅是一个路由缓存和路由表的查找过程。虽然迈出了决定性的一步,但是在编程接口上确实没有什么吸引人的地方,因此你也就不想基于此去写一些代码了。比如说,数据包依然要经过ip_rcv函数的处理,依然要经过FORWARD这个HOOK链,一切都像往常一样,不同的只是在查找路由之前,路由已经被从conntrack结构体里面restore到skb了。
        如果想实现真正的流式转发,并且基于硬卡实现这种逻辑,那么就必然要对真正负责转发的链路层以及物理层动手术,比如在PREROUTING中直接将数据包注入硬卡,然后由硬卡实现以下policy:
由tuple查找conntrack;
取出route;
取出neighbour;
直接ASIC转发。
返回HOOK NF_STOLEN
对了,正是这个逻辑,它不但解放了BOX的CPU,而且还使得转发更加灵活。我们已经可以取出route,并且由于neighbour就保存在route中(Linux网络栈如此设计真的很妙!),只要将此neighbour hold on,它就能保持一直不被释放,脱离ARP的timer管理,类似static设置的ARP映射一样。
        这个neighbour的cache很关键,它直接cache了“需要最终落实的信息”,那就是下一跳的MAC地址,它甚至可以cache上一跳的MAC地址,如此一来网络上的数据转发就真正退化(也许是进化)成了“基于流头的路由,策略匹配,MAC地址的下一跳解析"了!属于同一流的后续包无需做任何协议栈里面的常规操作,所有信息都可以从conntrack中取得,这难道不就是SDN的核心吗?
        从最开始完成”完全桥接“版本的conntrack(即那个不需要配置返回包路由的那个版本,直接将上一跳的MAC进行cache,返回包直接封装其MAC地址的版本),到接触到SDN,然后陆续完成各种基于SDN核心思想的conntrack版本,其间两个月有余,然而代码很不规范,也没有提交到任何地方...
        看看所做的这一切,通过iptables,通过自己编写HOOK函数,来实现自动路由,自动封装MAC地址,一切都是基于conntrack,这是什么行为?这其实正是在逐渐架空传统协议栈的路由逻辑,ARP解析逻辑啊!一个转发BOX竟然没有路由逻辑,没有ARP逻辑,这是不可想象的,它成了什么?或者问什么东西没有这些复杂的逻辑?答案显而易见!switch!对了,就是switch,终于,BOX退化成了一个交换机!仅仅负责数据的转发,而控制逻辑从哪里来?或者问,一个傻瓜switch究竟是如何知道该如何转发数据的,我的版本是预配置,这当然只是我的一种方式而已!标准做法是通过一个通信协议,从另一台机器上获取,这个所谓的另一台机器是什么?我把它称为控制器。也就是说,路由逻辑等控制模块全部移到了这个控制器中了。
        这便是我的SDN版本!一个不同于OpenFlow的,但是完全体现SDN思想的非标准化的SDN实现。接下来要证实的是,IP路由并不是根本,根本是什么?根本是”可以落实的“东西,那就是有封装以太帧的目标MAC地址!!!(走火入魔了!!!)
作者:dog250 发表于2013-8-18 13:02:52 原文链接
阅读:71 评论:0 查看评论

    
[3]关键在封装并发出了帧-IP冲突也无所谓
    来源: 互联网  发布时间: 2013-11-01
最近有点走火入魔了!本文所用技术非标准,较真儿者慎入!!
一个局域网内,两台机器拥有同样的IP,可以吗?
这不就是IP地址冲突吗?当然不行!
可是要知道,如果搞点旁门左道,还是可以做到的!
首先要明白的是,IP数据报在以太网中的收发特征:
对于发送来讲:只要你有一个目标MAC供你封装成帧,就可以发出去,而这个MAC地址是由ARP来获取的;
对于接收来讲:只要收到帧的目标MAC是接收到帧的网卡的MAC地址,就可以正确接收!
现在我们逐步的来实现一个局域网内拥有同样IP还能正常越过默认网关访问不同外网的情景。实际上,在我实现的简版SDN中,一切都是保存在conntrack中的,它甚至可以保存一个流的上一跳和下一跳neighbour,这就意味着完全架空了本机的路由逻辑和arp逻辑!使本机完全退化成了一个switch!专注于数据包的转发!neighbour的定义是次要的,完全没有必要照抄Linux内核的neighbour结构体,它的实质就是一个MAC地址而已,思路很简单:
1.流头进来在正方向的PREROUTING中将其源MAC地址保存在conntrack;
2.属于同一流的数据包在反方向的POSTROUTING中获取conntrack中的MAC地址封装为目标MAC;
3.发送并返回STOLEN。
就是这么简单!实际上如果能在Linux中实现Policy ARP就好了,也就是说,可以为同一个IP地址映射多条ARP项,每个项有不同的MAC地址。毕竟neighbour是和dst_entry即路由表项相关联的,因此只要保证同一个IP地址的多个ARP映射属于不同的路由表项即可,而这很容易通过IPMARK+Policy Routing来实现!
        不幸的是,Linux并没有实现如此让人走火入魔的Policy ARP,现有的隔离措施就是使用NET命名空间,然而它是用于虚拟化的,同一个网卡只能属于同一个命名空间,此场景不适用!那么怎么办?只能自己写Netfilter代码了啊,还好,由于这个逻辑超级清晰,因此所做的修改也是很容易的,实现了这个的话,仰天长啸,嘲笑一下地址冲突!
        保存源MAC地址在ipv4_conntrack_in的最后来做,而还原保存的MAC地址到目标MAC地址的操作在ipv4_confirm中来做。代码如下:
//继续偷梁换柱借用nat的extend
struct nf_conn_nat {
    //自动保存回复帧的目标MAC地址
    unsigned char reply_gw_mac[ETH_ALEN];
    //自动保存本机MAC地址
    unsigned char orig_gw_mac[ETH_ALEN];
    //自动保存设备
    struct net_device *dev;
};
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
                                      struct sk_buff *skb,
                                      const struct net_device *in,
                                      const struct net_device *out,
                                      int (*okfn)(struct sk_buff *))
{
                unsigned int ret = nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
                if (ret == NF_ACCEPT) {
                enum ip_conntrack_info ctinfo;
                struct nf_conn *ct;
                struct nf_conn_nat *automac;
                ct = nf_ct_get(skb, &ctinfo);
                if (!ct) {
                        goto out;
                }
                if (skb->dev->flags & IFF_LOOPBACK)
                        return ret;
                if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) {
                        goto out;
                }
                automac = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
                if (automac == NULL) {
                        automac = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
                        if (automac == NULL) {
                                goto out;
                        }
                        struct ethhdr *eth = (struct ethhdr*)(skb->data - ETH_HLEN);
                        memcpy(automac->reply_gw_mac, eth->h_source, ETH_ALEN);
                        memcpy(automac->orig_gw_mac, eth->h_dest, ETH_ALEN);
                        automac->dev = skb->dev;
                }
        }

out:
        return ret;;
}

static unsigned int ipv4_confirm(unsigned int hooknum,
                                 struct sk_buff *skb,
                                 const struct net_device *in,
                                 const struct net_device *out,
                                 int (*okfn)(struct sk_buff *))
{
               .............
out:
        /* We've seen it coming out the other side: confirm it */
        ret = nf_conntrack_confirm(skb);
        if (ret == NF_ACCEPT) {
                struct nf_conn_nat *automac = NULL;
                struct net_device *dev = NULL;
                unsigned int hh_len = 0;
                if (skb->dev->flags & IFF_LOOPBACK)
                        return ret;
                if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
                        return ret;
                if (hooknum != NF_INET_POST_ROUTING)
                        return ret;
                automac = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
                if (automac == NULL)
                        return ret;
                dev = automac->dev;
                skb->dev = dev;
                hh_len = LL_RESERVED_SPACE(dev);
                if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
                        struct sk_buff *skb2;

                        skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
                        if (skb2 == NULL) {
                                kfree_skb(skb);
                                return -ENOMEM;
                        }
                        if (skb->sk)
                                skb_set_owner_w(skb2, skb->sk);
                        kfree_skb(skb);
                        skb = skb2;
                }
                //填充以太帧头,注意偏移!
                char *header = skb->data - hh_len;
                header[0] = 0x0;
                header[1] = 0x0;
                struct ethhdr *eth = (struct ethhdr*)(header+2);
                memcpy(eth->h_dest, automac->reply_gw_mac, ETH_ALEN);
                memcpy(eth->h_source, automac->orig_gw_mac, ETH_ALEN);
                eth->h_proto = htons(ETH_P_IP);
                skb_push(skb, ETH_HLEN);
                skb->_skb_dst = NULL;
                dev_queue_xmit(skb);
                return NF_STOLEN;
        }
        return ret;
}

精妙之处在于,只要有一个包到达该BOX,其源MAC地址就能被conntrack记住,当反方向的包到来并要发回去的时候,就能取出该源MAC地址作为目标MAC地址封装到以太帧中,然后无需经由ARP层直接发送出去。现在的问题是,两个相同IP地址的主机可以同时发包过来吗?答案无疑是肯定的,因为它们俩发包前解析BOX的MAC地址,该BOX无疑全部回复,它们总有个先来后到,唯一的副作用时后到的那个ARP请求会更新BOX的ARP表,将相同的那个IP的MAC地址覆盖成自己的MAC地址,然而这无所谓了,因为既然两台主机都得到了BOX的MAC地址,数据包肯定能发出去到达BOX,返回包在寻址这两台机器的时候,并不通过ARP来寻址,而是通过这两台机器自己携带过去的源MAC地址来作为目标MAC的,故而覆盖也无所谓了!
        只要保证没有五元组的冲突即可,而这种冲突的可能性是极其小的。
        严格来讲ARP属于IP的下层,是和链路层接口的协议,它是”下一跳解析协议“的一种,适用于IPv4到以太网的适配,ARP只是动态的帮你完成了映射,如果你知道该如何封装以太帧,完全可以不用ARP,要么手工设置static的映射,要么就是从某处得到一个映射,关键点不在ARP或者映射,关键点在于你能得到一个MAC地址!只要你能得到目标MAC地址,那么封装以太帧即可,此时是不关心源MAC的!
        我真的走火入魔了,不管是用MAC桥微端口搞定了OpenVPN的源地址选择,还是构造假网关在配置Windows路由时指定源地址,还是本文说的IP地址冲突情景下的数据通信,都不是标准的做法,希望较真的同学注意。如果想靠这个理解网络的行为,那是再好不过了...
作者:dog250 发表于2013-8-18 13:01:15 原文链接
阅读:74 评论:0 查看评论

    
最新技术文章:
▪SQVI和SAP查询QUERY的区别和使用注意事项    ▪彻底理解Cisco/Linux/Windows的IP路由    ▪Exchange 2010 处于禁止发送用户自动收到来自IT...
▪MB_CHANGE_DOCUMENT使用方法    ▪ALV的html表头    ▪【译】如何精确判断最终用户响应时间过长的...
▪apache2.4.4启用deflate压缩    ▪使用vmware 配置centos 6.0+ 网络出现的各种问题...    ▪十句话教你学会Linux数据流重定向
▪centos6.x已经安装的系统添加图形界面    ▪Linux查看CPU和内存使用情况    ▪win7问题解决,凭据管理器和无法访问,不允...
▪Dynamics CRM 2013 初体验(4):不再被支持的功...    ▪win7下制作ubuntu系统安装启动盘和U盘安装ubuntu...    ▪Linux cp -a用法
▪Windows Server时间服务器配置方法    ▪Tomcat+memcached实现Session共享    ▪Linux修改系统环境变量PATH路径的方法
▪Citrix 服务器虚拟化之二十七 XenApp6.5发布服务...    ▪搭建本地Ubuntu 镜像服务器    ▪Create local metadata resource of yum
▪tsm ANS0326E问题处理    ▪Windows SVN变化邮件通知(Python2.7实现)    ▪linux下的内核测试工具——perf使用简介
▪Nginx TCP Proxy模块的编译安装    ▪OSX: SSH密钥使用日记(2)    ▪OSX: SSH密钥使用日记(1)
▪Manually start and stop Oracle XE in Ubuntu    ▪Disable autostart of Oracle-xe in Ubuntu    ▪tar命令-linux
▪xtrabackup-2.1.2-611安装    ▪无废话ubuntu 13.4文件共享配置    ▪Unix文本处理工具之sed
▪hpux 操作系统 磁带备份与恢复    ▪HP DL360 G7通过iLO部署系统    ▪Redhat 6.0中VNC Server的配置方法
▪hpux 操作系统磁带备份与恢复    ▪用C++编程调用libvirt的API来创建KVM虚拟机    ▪hpux- hp小型机日常硬件故障处理case(一)
▪web集群时session同步的几种方法(统计)    ▪inux常用命令大全    ▪BAT 批处理实现循环备份N天文件夹
▪BIND9私有DNS服务器小环境搭建实验    ▪Exchange2013增量备份    ▪OSSEC Monitor your App log file
▪《深入理解Nginx》阅读与实践(三):使用upstre...    ▪如何给Fedora 15创建磁盘分区    ▪Packet Sniffer Code in C using sockets
▪Error, some other host already uses address    ▪修改uCOS_II以实现“优先级+时间片”联合调度    ▪weblogic开发模式与生产模式介绍
▪Wireshark 高级特性    ▪ubuntu13.04版本下安装RabbitVCS,类似windows的Tortoi...    ▪Apache 一台主机绑定多个域名及虚拟主机
▪linux安全设置    ▪RHEL双网卡绑定    ▪Linux shell if参数
▪Windows配置路由时可以指定源地址啦    ▪centos安装vim7.4    ▪S3C2410 实验三——块拷贝、字拷贝(寄存器的...
▪系统运维——日志处理    ▪ip_conntrack缓存neighbour    ▪关键在封装并发出了帧-IP冲突也无所谓
▪weblogic11g 安装——linux 无图形界面    ▪《数据通信与网络》笔记--SCTP    ▪《数据通信与网络》笔记--TCP中的拥塞控制
▪weblogic11g 安装集群 —— win2003 系统、单台主...    ▪weblogic11g 节点管理器 nodemanager    ▪Citrix 服务器虚拟化之二十六 应用程序虚拟化...
▪如何将windows下的文件夹挂载到linux虚拟机下    ▪在64位AIX6.1下安装SAP JCo    ▪Outlook启动时提示“找不到文件Outlook.pst文件”...
▪weblogic8.1 登陆5 ip 限制    ▪weblogic 内存 及 内存溢出    ▪手把手教你在Windows端搭建Redmine项目管理软件
▪启动及重新启动nginx,重启nginx后丢失nginx.pid问...    ▪Win7实现快速启动栏并实现靠左边的终极操作...    ▪《深入理解Nginx》阅读与实践(二):配置项...
▪显示grub引导菜单    ▪nagios监控主机    ▪linux各种数据流重定向
▪centOS安装chrome浏览器    ▪Slackware 14 安装完全指南    ▪SharePoint 2013的100个新功能之内容管理(三)
▪Citrix 服务器虚拟化之二十一 桌面虚拟化之部...    ▪[问,ask]ubuntu13.04安装vncserver后只显示桌面,不显...    ▪Win7中IIS出现“HTTP 错误 404.17 - Not Found 请求的...
▪CentOS快速安装最新版本的SaltStack    ▪CentOS 6.4 快速安装Nginx笔记    ▪磁盘管理——RAID 0
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3