工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表全部文章

linux中ip tunnel的实现及协议简介

一.实现

Linux中,隧道的实现主要基于两个文件new_tunnel.cipip.c

同时Linux定义了一种新的协议类型--IPIPIPPROTO_IPIP),与上面所说封包类型类似。

基本思路
LinuxIP Tunnel的实现也分为两个部件:封装部件和解封部件,分别司职发送和接收。但这两个部分是在不同的层次以不同的方式实现的。封装部件是在数据链路层以虚设备的方式实现。所有源代码见

/usr/src/linux/drivers/net/new_tunnel.c


为实现封装,Linux实现一个称为tunl的网络设备(类似loopback设备),此设备具有其他网络设备共有的特征,对于使用此设备的上层应用来说,对这些网络设备不加区分,调用及处理方法当然也完全一样。


tunnel_init()
tunnel_xmit()new_tunnel.c中的两个主要过程。
tunnel_init()
初始化与设备tunl相关的device结构。



tunnel_xmit()在从tunl设备发送数据时被调用,tunl设备作为实现IP隧道技术的封装部分,在此过程中完成对相应的数据报进行封装所需的全部操作,形成IPIP类型的IP包,并重新转发此数据包(ip_forward())。

解码器在IP的上层实现,系统把它作为一个虚的传输层(实际上与传输层毫无关系),具体处理见文件

/usr/src/linux/net/ipv4/ipip.c



我们知道,每一个IP数据包均交由ip_rcv函数处理,在进行一些必要的判断后,ip_rcv对于发送给本机的数据包将交给上层处理程序。对于IPIP包来说,其处理函数是ipip_rcv(就如TCP包的处理函数是tcp_rcv一样,IP层不加区分)。也就是说,当一个目的地址为本机的封包到达后,ip_rcv函数进行一些基本检查并除去IP头,然后交由ipip_rcv解封。ipip_rcv所做的工作就是去掉封包头,还原数据包,然后把还原后的数据包放入相应的接收队列(netif_rx())。

从以上IP Tunnel实现的思想来看,思路十分清晰,但由于IP Tunnel的特殊性,其实现的层次并不单纯。实际上,它的封装和解封部件不能简单地象上面所说的那样分层。tunl设备虽应算进链路层,但其发送程序中做了更多的工作,如制作IPIP头及新的IP头(这些一般认为是传输层或网络层的工作),调用ip_forward转发新包也不是一个网络设备应当做的事。可以说,tunl借网络设备之名,一把抓干了不少工作,真是高效。而解封部件宏观上看在网络层之上,解出IPIP头,恢复原数据包是它分内的事,但在它解出数据包(即原完整的协议数据包)后,它把这个包放入相应的协议接收队列。这种事可不是一个上层协议干的,这是网络设备中断接收程序的义务。看到了,在这点上,它好象到了数据链路层。


二.协议

1. 点对点隧道协议(PPTP

PPTP协议允许对IPIPXNetBEUI数据流进行加密,然后封装在IP包头中通过企业IP网络或公共互联网络发送。

2. 2层隧道协议(L2TP

L2TP协议允许对IPIPXNetBEUI数据流进行加密,然后通过支持点对点数据报传递的任意网络发送,如IPX.25,桢中继或ATM

3.安全IPIPSec)隧道模式

IPSec隧道模式允许对IP负载数据进行加密,然后封装在IP包头中通过企业IP网络或公共IP互联网络如Internet发送。

隧道协议
为创建隧道,隧道的客户机和服务器双方必须使用相同的隧道协议。

隧道技术可以分别以第2层或第3层隧道协议为基础。上述分层按照开放系统互联(OSI)的参考模型划分。第2层隧道协议对应OSI模型中的数据链路层,使用桢作为数据交换单位。PPTPL2TPL2F(第2层转发)都属于第2层隧道协议,都是将数据封装在点对点协议(PPP)桢中通过互联网络发送。第3层隧道协议对应OSI模型中的网络层,使用包作为数据交换单位。IP overIP以及IPSec隧道模式都属于第3层隧道协议,都是将IP包封装在附加的IP包头中通过IP网络传送。

提供PPTP客户机和PPTP服务器之间的加密通信。PPTP客户机是指运行了该协议的PC机,如启动该协议的Windows95/98PPTP服务器是指运行该协议的服务器,如启动该协议的WindowsNT服务器。PPTPPPP协议的一种扩展。它提供了一种在互联网上建立多协议的安全虚拟专用网(VPN)的通信方式。远端用户能够透过任何支持PPTPISP访问公司的专用网。

通过PPTP,客户可采用拨号方式接入公用IP网。拨号用户首先按常规方式拨到ISP的接入服务器(NAS),建立PPP连接;在此基础上,用户进行二次拨号建立到PPTP服务器的连接,该连接称为PPTP隧道,实质上是基于IP协议的另一个PPP连接,其中的IP包可以封装多种协议数据,包括TCPIPIPXNetBEUIPPTP采用了基于RSA公司RC4的数据加密方法,保证了虚拟连接通道的安全。对于直接连到互联网的用户则不需要PPP的拨号连接,可以直接与PPTP服务器建立虚拟通道。PPTP把建立隧道的主动权交给了用户,但用户需要在其PC机上配置PPTP,这样做既增加了用户的工作量,又会给网络带来隐患。另外,PPTP只支持IP作为传输协议。

2层转发(L2F
L2FCisco公司提出隧道技术,作为一种传输协议L2F支持拨号接入服务器将拨号数据流封装在PPP桢内通过广域网链路传送到L2F服务器(路由器)。L2F服务器把数据包解包之重新注入(inject)网络。与PPTPL2TP不同,L2F没有确定的客户方。应当注意L2F只在强制隧道中有效。(自愿和强制隧道的介绍参看隧道类型)。

2层隧道协议(L2TP
L2TP隧道协议是典型的被动式隧道协议,它结合了L2FPPTP的优点,可以让用户从客户端或访问服务器端发起VPN连接。L2TP是把链路层PPP帧封装在公共网络设施如IPATM、帧中继中进行隧道传输的封装协议。

L2TP主要由LAC(L2TP Access Concentrator) LNS(L2TP Network Server) 构成,LAC支持客户端的L2TP,用于发起呼叫、接收呼叫和建立隧道;LNS是所有隧道的终点,LNS终止所有的PPP流。在传统的PPP连接中,用户拨号连接的终点是LACL2TP使得PPP协议的终点延伸到LNS

L2TP的好处在于支持多种协议,用户可以保留原有的IPXAppletalk等协议或公司原有的IP地址。L2TP还解决了多个PPP链路的捆绑问题,PPP链路捆绑要求其成员均指向同一个NAS(Network Access Server)L2TP可以使物理上连接到不同NASPPP链路,在逻辑上的终结点为同一个物理设备。L2TP还支持信道认证,并提供了差错和流量控制。

L2TP利用IPsec增强了安全性,支持数据包的认证、加密和密钥管理。L2TP/IPSec因此能为远程用户提供设计精巧并有互操作性的安全隧道连接。这对安全的远程访问和安全的网关之间连接来说,它是一个很好的解决方案。因此,安全的VPN需要同时解决好L2TPIPSec这两个不同的问题。L2TP协议解决了穿过IP网络的不同用户协议的转换问题;IPSec协议(加密/解密协议)解决了通过公共网络传输信息的保密问题。

IP网上的L2TP使用UDP和一系列的L2TP消息对隧道进行维护。L2TP同样使用UDPL2TP协议封装的PPP桢通过隧道发送。可以对封装PPP桢中的负载数据进行加密或压缩。 PPTPL2TP

PPTPL2TP都使用PPP协议对数据进行封装,然后添加附加包头用于数据在互联网络上的传输。尽管两个协议非常相似,但是仍存在以下几方面的不同:

PPTP
要求互联网络为IP网络。L2TP只要求隧道媒介提供面向数据包的点对点的连接。L2TP可以在IP(使用UDP),桢中继永久虚拟电路(PVCs),X.25虚拟电路(VCs)或ATM VCs网络上使用。

PPTP
只能在两端点间建立单一隧道。L2TP支持在两端点间使用多隧道。使用L2TP,用户可以针对不同的服务质量创建不同的隧道。

L2TP
可以提供包头压缩。当压缩包头时,系统开销(overhead)占用4个字节,而PPTP协议下要占用6个字节。

L2TP
可以提供隧道验证,而PPTP则不支持隧道验证。但是当L2TPPPTPIPSEC共同使用时,可以由IPSEC提供隧道验证,不需要在第2层协议上验证隧道。

IPSec
隧道模式
IPSecIP层上对数据包进行高强度的安全处理,提供数据源地验证、无连接数据完整性、数据机密性、抗重播和有限业务流机密性等安全服务。各种应用程序可以享用IP层提供的安全服务和密钥管理,而不必设计和实现自己的安全机制,因此减少密钥协商的开销,也降低了产生安全漏洞的可能性。IPSec可连续或递归应用,在路由器、防火墙、主机和通信链路上配置,实现端到端安全、虚拟专用网络(VPN)和安全隧道技术。

IPSEC是第3层的协议标准,支持IP网络上数据的安全传输。本文将在高级安全一部分中对IPSEC进行详细的总体介绍,此处仅结合隧道协议讨论IPSEC协议的一个方面。除了对IP数据流的加密机制进行了规定之外,IPSEC还制定了IPoverIP隧道模式的数据包格式,一般被称作IPSEC隧道模式。一个IPSEC隧道由一个隧道客户和隧道服务器组成,两端都配置使用IPSEC隧道技术,采用协商加密机制。

为实现在专用或公共IP网络上的安全传输,IPSEC隧道模式使用的安全方式封装和加密整个IP包。然后对加密的负载再次封装在明文IP包头内通过网络发送到隧道服务器端。隧道服务器对收到的数据报进行处理,在去除明文IP包头,对内容进行解密之后,获的最初的负载IP包。负载IP包在经过正常处理之后被路由到位于目标网络的目的地。

IPSEC
隧道模式具有以下功能和局限:
只能支持IP数据流
工作在IP栈(IPstack)的底层,因此,应用程序和高层协议可以继承IPSEC的行为。
由一个安全策略(一整套过滤机制)进行控制。安全策略按照优先级的先后顺序创建可供使用的加密和隧道机制以及验证方式。当需要建立通讯时,双方机器执行相互验证,然后协商使用何种加密方式。此后的所有数据流都将使用双方协商的加密机制进行加密,然后封装在隧道包头内。

Linux下的IP隧道研究

在Linux中,隧道的实现主要基于两个文件new_tunnel.c和ipip.c

同时Linux定义了一种新的协议类型--IPIP(IPPROTO_IPIP),与上面所说封包类型类似。

   基本思路
在Linux中IP Tunnel的实现也分为两个部件:封装部件和解封部件,分别司职发送和接收。但这两个部分是在不同的层次以不同的方式实现的。封装部件是在数据链路层以虚设备的方式实现。所有源代码见

/usr/src/linux/drivers/net/new_tunnel.c


为实现封装,Linux实现一个称为tunl的网络设备(类似loopback设备),此设备具有其他网络设备共有的特征,对于使用此设备的上层应用来说,对这些网络设备不加区分,调用及处理方法当然也完全一样。


tunnel_init()和tunnel_xmit()是new_tunnel.c中的两个主要过程。
tunnel_init()初始化与设备tunl相关的device结构。


而tunnel_xmit()在从tunl设备发送数据时被调用,tunl设备作为实现IP隧道技术的封装部分,在此过程中完成对相应的数据报进行封装所需的全部操作,形成IPIP类型的IP包,并重新转发此数据包(ip_forward())。

解码器在IP的上层实现,系统把它作为一个虚的传输层(实际上与传输层毫无关系),具体处理见文件

/usr/src/linux/net/ipv4/ipip.c。


我们知道,每一个IP数据包均交由ip_rcv函数处理,在进行一些必要的判断后,ip_rcv对于发送给本机的数据包将交给上层处理程序。对于 IPIP包来说,其处理函数是ipip_rcv(就如TCP包的处理函数是tcp_rcv一样,IP层不加区分)。也就是说,当一个目的地址为本机的封包 到达后,ip_rcv函数进行一些基本检查并除去IP头,然后交由ipip_rcv解封。ipip_rcv所做的工作就是去掉封包头,还原数据包,然后把 还原后的数据包放入相应的接收队列(netif_rx())。

从以上IP Tunnel实现的思想来看,思路十分清晰,但由于IP Tunnel的特殊性,其实现的层次并不单纯。实际上,它的封装和解封部件不能简单地象上面所说的那样分层。tunl设备虽应算进链路层,但其发送程序中 做了更多的工作,如制作IPIP头及新的IP头(这些一般认为是传输层或网络层的工作),调用ip_forward转发新包也不是一个网络设备应当做的 事。可以说,tunl借网络设备之名,一把抓干了不少工作,真是‘高效’。而解封部件宏观上看在网络层之上,解出IPIP头,恢复原数据包是它分内的事, 但在它解出数据包(即原完整的协议数据包)后,它把这个包放入相应的协议接收队列。这种事可不是一个上层协议干的,这是网络设备中断接收程序的义务。看到 了,在这点上,它好象到了数据链路层。

为实现VPN的扩展
实际上Linux只为实现隧道机制提供了一个框架,图二中的封包协议头在Linux中被忽略了,也就是说,封包头只含封包IP头,其后紧跟原IP数据 包。这样的结构用于传输公开数据没有关系,但对于一个VPN来说,安全保密是不可缺少的重要功能。我们希望通过隧道的数据可靠且不可窃取和冒充的,那么, 加密和认证就必不可少。为实现这一构想,设计以下封包协议头:


0 4 8 16 24 31
+-----+-----+-----------+------------------------+
| ver |type | hlen | OldPacketLen |
+-----------------------+------------------------+
| DeviceID | EncapID |
+-----------------------+------------------------+
| Flags | CheckSum |
+------------------------------------------------+
| IPIP Options( If any ) |
+------------------------------------------------+
. | padding |
. .
+------------------------------------------------+



图三、 IPIP头设想图

ver: 版本号,利于扩展
type: 用于建立不同目的的隧道(可能处理上有差别)
OldPacketLen: 进入隧道的原数据包长度
DeviceID: 对数据包进行封装的设备标识
EncapID: 此封包的ID号
Flags: 标志位,共16位,初步定义如下:
0 保留
1 有否加密
2 有否做摘要
3 有否签名
4 保留
5 有否传送消息密钥
6 消息密钥有否加密
7 消息密钥是否需保留
8-15 保留
CheckSum: 头校验
IPIP Options: 用来传送一些必要的数据,比如消息密钥、签名等
格式:
+-------------------------------------+
| 类型 | 长度 | 数据 ... |
+-------------------------------------+


好了,有了这个东西,我们就可以扩展Linux IP Tunnel为我们的VPN服务了。首先,改写new_tunnel.c和ipip.c两个文件,加入对IPIP头的处理。


接着,我们要实现一种密钥的管理和传送机制。

当然,对称密钥是必需的,而对IP数据包加密要使用序列密码。从全体考虑,

我们可以提出建立VPN的逻辑步骤;

    1、准备工作:建网安装系统完成配置等等
    2、隧道的两端分别向对方发送自己的公开密码和设备号
    3、如有必要,产生序列密码,后加密签名传给对方
    4、正常通信,----放心,你的数据已经很保险了。
在一个VPN的隧道中,一个封包的格式应如图四所示。


/ +-----------------+
| | 封包IP头 |
封包头 | +-----------------+
| | 封包协议头 |
+-----------------+
/ | |
| | 原协议头 |
| | 及 |
封包数据 | | 原协议数据 |
| . (密文) .
| . .
| | |
+-----------------+



图四. VPN封包结构

   你的几种使用方法
事情往往不能两全其美,你在安全强度和通信速度上必须作出选择,(不然你就需要在安全强度和Money的耗费中做选择。)使用这样的协议,根据你的需求不同,你可有不同的使用方法,下面列举一些:

    跨Internet的公司多个内部网之间进行通信,保密性并不重要直接使用原框架机制,无任何加密措施这样速度快、效率高,公司也不用申请多个IP地址,方便可行
    一般性的商业应用,具有保密要求利用事先产生的序列密码,每次对原数据包加密安全度提高了,是一种十分实用的方法。只要强度足够,一般很难破译速度快密码 不变的方式你认为不够安全你可以自己实现一种密码传送方法,每隔一段时间更换一次密码。其中一些握手关系需要完善,有兴趣的欢迎探讨。如果发展成熟,此法 相信很有前途。
    高度机密领域:敬请使用一次一密,并进行每次签名。每次产生新密钥和签名十分费时,在目前我国Internet网络的速度下几乎不可行。但相信有此需要的 部门也能够设法提高其网络带宽,让网络状况适合这种应用。另外,当然还可以就加密强度自身作出选择,比如选择128位,还是512位、1024位
    待完善
主要牵涉 到隧道的管理,在封包的传送过程中如果出现错误是十分正常的,当一台路由器检测到错误时,它会发送一个ICMP包给隧道的发送端,但遗憾的是ICMP返回 的数据除了IP头外,只含8个字节的上层协议信息。只凭这个难以对ICMP信息作出反应,因此,在隧道端保留一些状态信息是必须的。这些信息主要包括:

    隧道的另一端的可达性
    隧道的拥塞状况
    隧道的MTU
同时所发送的封包信息也是需要保留的,举例说,当一个路由不可达信息到来时,封包的发送者要能够找出所封装的数据来自何方,并发送相应的ICMP包。

MRTG Installation and Configuration in Debian based Distributions

This article is focusing installing and configure MRTG with CPU,Memory and Disk Usage Graphs examples for Debian Ubuntu and Kubuntu Users and may be work for some debian based distributions.

 

MRTG is Multi Router Traffic Grapher (MRTG) is a tool to monitor the traffic load on network links. MRTG generates HTML pages containing PNG images which provide a LIVE visual representation of this traffic.

 

MRTG Requirements

Apache webserver with perl support
NET-SNMP
GD
Libpng
zlib

If you want to download MRTG you can download from here

Preparing you System for MRTG Instalaltion

First you need to install the required compilers

#apt-get install gcc make g++

Apache 2 Installation with perl support

Follow these instructions to install apache2 with perl support

MRTG Installation

Now we need to install mrtg and snmp

Installing MRTG in Debian, Ubuntu and Kubuntu

#apt-get install mrtg snmpd

The installation will create an mrtg subdirectory where the Apache Web pages reside. On your Debian,ubnutu,kubuntu systems the path of this subdirectory is:

/var/www/mrtg

Now you need to edit the mrtg configuration file to edit the some of the settings

File is located at /etc/mrtg.cfg you need to change the global settings as follows

# Global Settings

RunAsDaemon: yes
EnableIPv6: no
WorkDir: /var/www/mrtg
Options[_]: bits,growright
WriteExpires: Yes

Title[^]: Traffic Analysis for

You will find a crontab running every 5 minutes as user root

# cat /etc/cron.d/mrtg
0-55/5 * * * * root if [ -x /usr/bin/mrtg ] && [ -r /etc/mrtg.cfg ]; then env LANG=C /usr/bin/mrtg /etc/mrtg.cfg >> /var/log/mrtg/mrtg.log 2>&1; fi

Now we need to assign the snmp community name in snmp configration file /etc/snmp/snmpd.conf

# sec.name source community
# com2sec paranoid default public
com2sec readonly default public
#com2sec readwrite default private

Now you need to restart the snmp service

#/etc/init.d/snmpd restart

The configuration file creating using

#cfgmaker public@localhost > /etc/mrtg.cfg

Creating a configuration file for a device using cfgmaker

#cfgmaker public@192.168.0.1 >> /etc/mrtg.cfg

With the configuration file created correctly there’s only one other thing you have to do and that’s to use the indexmaker utility to create the summary home page. Since you have to re-run this command every time you make certain changes to the /etc/mrtg.cfg configuration file.

Creating index file for the webserver using indexmaker

#indexmaker /etc/mrtg.cfg > /var/www/mrtg/index.html

Now you need to reboot your system wait for five minutes or so and then take a look at your summary home page. If your Debian,ubuntu,kubuntu system’s IP address is 192.168.0.1 then you’d type in the following in the address bar of a browser running on a system on the same network:

http://192.168.0.1/mrtg/

Your summary home page should come up with a graph for each target entry in the configuration file. If a graph looks like there’s no data on it, click on it and check the statistics to see if any traffic is being seen. Small amounts of traffic won’t show up on the graphs because we used the Unscaled statement

Some of examples how to monitor cpu , memory , Disk usage

CPU Usage

/etc/mrtg/cpu.cfg

WorkDir: /var/www/mrtg
LoadMIBs: /usr/share/snmp/mibs/UCD-SNMP-MIB.txt
Target[localhost.cpu]:ssCpuRawUser.0&ssCpuRawUser.0:public@127.0.0.1+ ssCpuRawSystem.0&ssCpuRawSystem.0:public@127.0.0.1+
ssCpuRawNice.0&ssCpuRawNice.0:public@127.0.0.1
RouterUptime[localhost.cpu]: public@127.0.0.1
MaxBytes[localhost.cpu]: 100
Title[localhost.cpu]: CPU Load
PageTop[localhost.cpu]: Active CPU Load %
Unscaled[localhost.cpu]: ymwd
ShortLegend[localhost.cpu]: %
YLegend[localhost.cpu]: CPU Utilization
Legend1[localhost.cpu]: Active CPU in % (Load)
Legend2[localhost.cpu]:
Legend3[localhost.cpu]:
Legend4[localhost.cpu]:
LegendI[localhost.cpu]: Active
LegendO[localhost.cpu]:
Options[localhost.cpu]: growright,nopercent

Memory Usage

/etc/mrtg/mem.cfg

LoadMIBs: /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt
Target[localhost.mem]: .1.3.6.1.4.1.2021.4.6.0&.1.3.6.1.4.1.2021.4.6.0:public@localhost
PageTop[localhost.mem]:Free Memory
WorkDir: /var/www/mrtg
Options[localhost.mem]: nopercent,growright,gauge,noinfo
Title[localhost.mem]: Free Memory
MaxBytes[localhost.mem]: 1000000
kMG[localhost.mem]: k,M,G,T,P,X
YLegend[localhost.mem]: bytes
ShortLegend[localhost.mem]: bytes
LegendI[localhost.mem]: Free Memory:
LegendO[localhost.mem]:
Legend1[localhost.mem]: Free memory, not including swap, in bytes

Memory Monitoring (Total Versus Available Memory)

/etc/mrtg/memfree.cfg

LoadMIBs: /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt
Target[server.memory]: memAvailReal.0&memTotalReal.0:public@localhost
Title[server.memory]: Free Memory
PageTop[server.memory]: < H1 >Free Memory< /H1 >
MaxBytes[server.memory]: 100000000000
ShortLegend[server.memory]: B
YLegend[server.memory]: Bytes
LegendI[server.memory]: Free
LegendO[server.memory]: Total
Legend1[server.memory]: Free memory, not including swap, in bytes
Legend2[server.memory]: Total memory
Options[server.memory]: gauge,growright,nopercent
kMG[server.memory]: k,M,G,T,P,X

Memory Monitoring (Percentage usage)

/etc/mrtg/mempercent.cfg

LoadMIBs: /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt
Title[server.mempercent]: Percentage Free Memory
PageTop[server.mempercent]: < H1 >Percentage Free Memory< /H1 >
Target[server.mempercent]: ( memAvailReal.0&memAvailReal.0:publicy@localhost ) * 100 / ( memTotalReal.0&memTotalReal.0:public@localhost )
options[server.mempercent]: growright,gauge,transparent,nopercent
Unscaled[server.mempercent]: ymwd
MaxBytes[server.mempercent]: 100
YLegend[server.mempercent]: Memory %
ShortLegend[server.mempercent]: Percent
LegendI[server.mempercent]: Free
LegendO[server.mempercent]: Free
Legend1[server.mempercent]: Percentage Free Memory
Legend2[server.mempercent]: Percentage Free Memory

Disk Usage

/etc/mrtg/disk.cfg

LoadMIBs: /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt
Target[server.disk]: dskPercent.1&dskPercent.2:public@localhost
Title[server.disk]: Disk Partition Usage
PageTop[server.disk]: < H1 >Disk Partition Usage /home and /var< /H1 >
MaxBytes[server.disk]: 100
ShortLegend[server.disk]: %
YLegend[server.disk]: Utilization
LegendI[server.disk]: /home
LegendO[server.disk]: /var
Options[server.disk]: gauge,growright,nopercent
Unscaled[server.disk]: ymwd

Creating jobs for CPU , Memory and Disk Usage

CPU

/etc/cron.mrtg/cpu

#!/bin/sh
/usr/bin/mrtg /etc/mrtg/cpu.cfg

Memory

/etc/cron.mrtg/mem

#!/bin/sh
/usr/bin/mrtg /etc/mrtg/mem.cfg

Memory Free

/etc/cron.mrtg/memfree

#!/bin/sh
/usr/bin/mrtg /etc/mrtg/memfree.cfg

Memory Percentage

/etc/cron.mrtg/mempercent

#!/bin/sh
/usr/bin/mrtg /etc/mrtg/mempercent.cfg

Disk

/etc/cron.mrtg/disk

#!/bin/sh
/usr/bin/mrtg /etc/mrtg/disk.cfg

Run each script 3 times (disregard the warnings)

/etc/cron.mrtg/cpu
/etc/cron.mrtg/mem
/etc/cron.mrtg/memfree
/etc/cron.mrtg/mempercent
/etc/cron.mrtg/disk

Make the Index Files

#/usr/bin/indexmaker --output=/var/www/mrtg/index.html \
--title=”Memory and CPU Usage ” \
--sort=name \
--enumerate \
/etc/mrtg/cpu.cfg \
/etc/mrtg/mem.cfg \
/etc/cron.mrtg/memfree \
/etc/cron.mrtg/mempercent \
/etc/cron.mrtg/disk

Make the mrtg.cfg file

#cfgmaker --global “WorkDir: /var/www/mrtg/” \
--global “Options[_]: growright,bits” \
--ifref=ip \
public@localhost > /etc/mrtg/mrtg.conf

Cronjob setup

/bin/cat >> /var/spool/cron/crontabs/root
*/5 * * * * /bin/run-parts /etc/cron.mrtg 1> /dev/null

Now you logon to your web browser http://192.168.0.1/mrtg/ and Now you should see CPU,Memory and Disk Usage graphs.

If you want more documentation about MRTG check here

SQUID-MIB

http://www.oidview.com/mibs/3495/SQUID-MIB.html

php反编译之路

http://hi.baidu.com/wizardchilde/blog/item/5d5b8738ffebd236b9998f26.html

总结SQLite不支持的SQL语法有哪些

1 TOP
这是一个大家经常问到的问题,例如在SQLSERVER中可以使用如下语句来取得记录集中的前十条记录:
SELECT TOP 10 * FROM [index] ORDER BY indexid DESC;
但是这条SQL语句在SQLite中是无法执行的,应该改为:
SELECT * FROM [index] ORDER BY indexid DESC limit 0,10;
其中limit 0,10表示从第0条记录开始,往后一共读取10条
2 创建视图(Create View)
SQLite在创建多表视图的时候有一个BUG,问题如下:
CREATE VIEW watch_single AS SELECT DISTINCTwatch_item.[watchid],watch_item.[itemid] FROM watch_item;
上面这条SQL语句执行后会显示成功,但是实际上除了
SELECT COUNT(*) FROM [watch_single ] WHERE watch_ single.watchid = 1;
能执行之外是无法执行其他任何语句的。其原因在于建立视图的时候指定了字段所在的表名,而SQLite并不能正确地识别它。所以上面的创建语句要改为:
CREATE VIEW watch_single AS SELECT DISTINCT [watchid],[itemid] FROM watch_item;
但是随之而来的问题是如果是多表的视图,且表间有重名字段的时候该怎么办?
3 COUNT(DISTINCT column)
SQLite在执行如下语句的时候会报错:
SELECT COUNT(DISTINCT watchid) FROM [watch_item] WHERE watch_item.watchid = 1;
其原因是SQLite的所有内置函数都不支持DISTINCT限定,所以如果要统计不重复的记录数的时候会出现一些麻烦。比较可行的做法是先建立一个不重复的记录表的视图,然后再对该视图进行计数。
4 外连接
虽然SQLite官方已经声称LEFT OUTER JOIN 已经实现,但还没有 RIGHT OUTER JOIN 和 FULL OUTER JOIN。但是实际测试表明似乎并不能够正常的工作。以下三条语句在执行的时候均会报错:
SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE tags.[tagid] = tag_rss.[tagid](*);
SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE LEFT OUTER JOIN tag_rss.[tagid] = tags.[tagid];
SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE LEFT JOIN tag_rss.[tagid] = tags.[tagid];
此外经过测试用+号代替*号也是不可行的。
 
收集SQLite与Sql Server的语法差异

1.返回最后插入的标识值
返回最后插入的标识值sql server用@@IDENTITY
sqlite用标量函数LAST_INSERT_ROWID()
返回通过当前的 SQLConnection 插入到数据库的最后一行的行标识符(生成的主键)。此值与 SQLConnection.lastInsertRowID 属性返回的值相同。
2.top n
在sql server中返回前2行可以这样:
select top 2 * from aa
order by ids desc
sqlite中用LIMIT,语句如下:
select * from aa
order by ids desc
LIMIT 2
3.GETDATE ( )
在sql server中GETDATE ( )返回当前系统日期和时间
sqlite中没有
4.EXISTS语句
sql server中判断插入(不存在ids=5的就插入)
IF NOT EXISTS (select * from aa where ids=5)
BEGIN
insert into aa(nickname)
select 't'
END
在sqlite中可以这样
insert into aa(nickname)
select 't'
where not exists(select * from aa where ids=5)
5.嵌套事务
sqlite仅允许单个活动的事务
6.RIGHT 和 FULL OUTER JOIN
sqlite不支持 RIGHT OUTER JOIN 或 FULL OUTER JOIN
7.可更新的视图
sqlite视图是只读的。不能对视图执行 DELETE、INSERT 或 UPDATE 语句,sql server是可以对视图 DELETE、INSERT 或 UPDATE

aufs 存储机制

aufs存储机制已经发展到超出了改进squid磁盘I/O响应时间的最初尝试。"a"代表着异步I/O。默认的ufs和aufs之间的唯一区别,在于I/O是否被squid主进程执行。数据格式都是一样的,所以你能在两者之间轻松选择,而不用丢失任何cache数据。

aufs使用大量线程进行磁盘I/O操作。每次squid需要读写,打开关闭,或删除cache文件时,I/O请求被分派到这些线程之一。当线程完成了I/O后,它给squid主进程发送信号,并且返回一个状态码。实际上在squid2.5中,某些文件操作默认不是异步执行的。最明显的,磁盘写总是同步执行。你可以修改src/fs/aufs/store_asyncufs.h文件,将ASYNC_WRITE设为1,并且重编译squid。

aufs代码需要pthreads库。这是POSIX定义的标准线程接口。尽管许多Unix系统支持pthreads库,但我经常遇到兼容性问题。aufs存储系统看起来仅仅在Linux和Solaris上运行良好。在其他操作系统上,尽管代码能编译,但也许会面临严重的问题。

为了使用aufs,可以在./configure时增加一个选项:
% ./configure --enable-storeio=aufs,ufs

严格讲,你不必在storeio模块列表中指定ufs。然而,假如你以后不喜欢aufs,那么就需要指定ufs,以便能重新使用稳定的ufs存储机制。
假如愿意,你也能使用—with-aio-threads=N选项。假如你忽略它,squid基于aufs cache_dir的数量,自动计算可使用的线程数量。表8-1显示了1-6个cache目录的默认线程数量。
Table 8-1. Default number of threads for up to six cache directories
cache_dirs Threads
1 16
2 26
3 32
4 36
5 40
6 44

将aufs支持编译进squid后,你能在squid.conf文件里的cache_dir行后指定它:
cache_dir aufs /cache0 4096 16 256

在激活了aufs并启动squid后,请确认每件事仍能工作正常。可以运行tail -f store.log一会儿,以确认缓存目标被交换到磁盘。也可以运行tail -f cache.log并且观察任何新的错误或警告。


8.4.1 aufs如何工作

Squid通过调用pthread_create来创建大量的线程。所有线程在任何磁盘活动之上创建。这样,即使squid空闲,你也能见到所有的线程。
无论何时,squid想执行某些磁盘I/O操作(例如打开文件读),它分配一对数据结构,并将I/O请求放进队列中。线程循环读取队列,取得I/O请求并执行它们。因为请求队列共享给所有线程,squid使用独享锁来保证仅仅一个线程能在给定时间内更新队列。

I/O操作阻塞线程直到它们被完成。然后,将操作状态放进一个完成队列里。作为完整的操作,squid主进程周期性的检查完成队列。请求磁盘I/O的模块被通知操作已完成,并获取结果。

你可能已猜想到,aufs在多CPU系统上优势更明显。唯一的锁操作发生在请求和结果队列。然而,所有其他的函数执行都是独立的。当主进程在一个CPU上执行时,其他的CPU处理实际的I/O系统调用。


8.4.2 aufs发行
线程的有趣特性是所有线程共享相同的资源,包括内存和文件描述符。例如,某个线程打开一个文件,文件描述符为27,所有其他线程能以相同的文件描述符来访问该文件。可能你已知道,在初次管理squid时,文件描述符短缺是较普遍问题。Unix内核典型的有两种文件描述符限制:
进程级的限制和系统级的限制。你也许认为每个进程拥有256个文件描述符足够了(因为使用线程),然而并非如此。在这样的情况下,所有线程共享少量的文件描述符。请确认增加系统的进程文件描述符限制到4096或更高,特别在使用aufs时。

调整线程数量有点棘手。在某些情况下,可在cache.log里见到如下警告:
2003/09/29 13:42:47| squidaio_queue_request: WARNING - Disk I/O overloading

这意味着squid有大量的I/O操作请求充满队列,等待着可用的线程。你首先会想到增加线程数量,然而我建议,你该减少线程数量。

增加线程数量也会增加队列的大小。超过一定数量,它不会改进aufs的负载能力。它仅仅意味着更多的操作变成队列。太长的队列导致响应时间变长,这绝不是你想要的。

减少线程数量和队列大小,意味着squid检测负载条件更快。当某个cache_dir超载,它会从选择算法里移除掉(见7.4章)。然后,squid选择其他的cache_dir或简单的不存储响应到磁盘。这可能是较好的解决方法。尽管命中率下降,响应时间却保持相对较低。


8.4.3 监视aufs操作

Cache管理器菜单里的Async IO Counters选项,可以显示涉及到aufs的统计信息。它显示打开,关闭,读写,stat,和删除接受到的请求的数量。例如:
% squidclient mgr:squidaio_counts
...
ASYNC IO Counters:
Operation       # Requests
open             15318822
close            15318813
cancel           15318813
write                   0
read             19237139
stat                    0
unlink            2484325
check_callback  311678364
queue                   0

取消(cancel)计数器正常情况下等同于关闭(close)计数器。这是因为close函数总是调用cancel函数,以确认任何未决的I/O操作被忽略。
写(write)计数器为0,因为该版本的squid执行同步写操作,即使是aufs。

check_callbak计数器显示squid主进程对完成队列检查了多少次。

queue值显示当前请求队列的长度。正常情况下,队列长度少于线程数量的5倍。假如你持续观察到队列长度大于这个值,说明squid配得有问题。增加更多的线程也许有帮助,但仅仅在特定范围内。

LVS+Keepalived构建高可用负载均衡

一、 LVS简介
   LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由章文嵩博士发起的自由软件项目,它的官方站点是www.linuxvirtualserver.org。现在LVS已经是 Linux标准内核的一部分,在Linux2.4内核以前,使用LVS时必须要重新编译内核以支持LVS功能模块,但是从Linux2.4内核以后,已经完全内置了LVS的各个功能模块,无需给内核打任何补丁,可以直接使用LVS提供的各种功能。使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。
      关于LVS的安装与介绍,在前面的文章中已经有过深入介绍,这里不再讲述。

本文讲解的环境如下:

操作系统:统一采用Centos5.3版本,地址规划如下:

 

图1

         图1中的VIP指的是虚拟IP地址,还可以叫做LVS集群的服务IP,在DR、TUN模式中,数据包是直接返回给用户的,所以,在Director Server上以及集群的每个节点上都需要设置这个地址。此IP在Real Server上一般绑定在回环地址上,例如lo:0,同样,在Director Server上,虚拟IP绑定在真实的网络接口设备上,例如eth0:0。
 各个Real Server可以是在同一个网段内,也可以是相互独立的网段,还可以是分布在internet上的多个服务器.

LVS+Keepalived高可用负载均衡集群拓扑结构如图2所示:

 

图2


二、安装Keepalived
keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,后来又加入了VRRP的功能,VRRP是Virtual Router Redundancy Protocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由出现的单点故障问题,它能够保证网络的不间断、稳定的运行。所以,keepalived一方面具有服务器健康检测功能,另一方面也具有HA cluster功能。 
 Keepalived的官方站点是http://www.keepalived.org,可以在这里下载到各种版本,我们这里下载的是keepalived-1.1.19.tar.gz,安装步骤如下:
[root@DR1 ~]#tar zxvf keepalived-1.1.19.tar.gz
[root@DR1 ~]#cd keepalived-1.1.19
[root@DR1 keepalived-1.1.19]#./configure   --sysconf=/etc \
> --with-kernel-dir=/usr/src/kernels/2.6.18-8.el5-i686
[root@DR1 keepalived-1.1.19]#make
[root@DR1 keepalived-1.1.19]#make install
[root@DR1 keepalived-1.1.19]#ln -s /usr/local/sbin/keepalived  /sbin/
 在编译选项中,“--sysconf”指定了Keepalived配置文件的安装路径,即路径为/etc/Keepalived/Keepalived.conf,“--with-kernel-dir”这是个很重要的参数,但这个参数并不是要把Keepalived编译进内核,而是指定使用内核源码里面的头文件,就是include目录。如果要使用LVS时,才需要用到此参数,否则是不需要的.

三、配置Keepalived
 Keepalived的配置非常简单,仅仅需要一个配置文件即可完成HA cluster和lvs服务节点监控功能,Keepalived的安装已经在上面章节进行了介绍,在通过Keepalived搭建高可用的LVS集群实例中,主、备Director Server都需要安装Keepalived软件,安装成功后,默认的配置文件路径为/etc/Keepalived/Keepalived.conf。一个完整的keepalived配置文件,有三个部分组成,分别是全局定义部分、vrrp实例定义部分以及虚拟服务器定义部分,下面详细介绍下这个配置文件中每个选项的详细含义和用法:
 

#全局定义部分
global_defs {
   notification_email {
     dba.gao@gmail.com     #设置报警邮件地址,可以设置多个,每行一个。注意,如果要开启邮件报警,需要开启本机的sendmail服务。
     ixdba@163.com
   }
   notification_email_from Keepalived@localhost     #设置邮件的发送地址。
   smtp_server 192.168.200.1 #设置smtp server地址。
   smtp_connect_timeout 30 #设置连接smtp服务器超时时间。
   router_id  LVS_MASTER    #运行Keepalived服务器的一个标识。发邮件时显示在邮件标题中的信息
}


#vrrp实例定义部分
vrrp_instance VI_1 {
state MASTER  #指定Keepalived的角色,MASTER表示此主机是主用服务器,BACKUP表示是备用服务器。
    interface eth0        #指定HA监测网络的接口。
    virtual_router_id 51 #虚拟路由标识,这个标识是一个数字,并且同一个vrrp实例使用唯一的标识,即同一个vrrp_instance下,MASTER和BACKUP必须是一致的。
priority 100 #定义优先级,数字越大,优先级越高,在一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级。
    advert_int 1   #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒。
    authentication {        #设定验证类型和密码。
        auth_type PASS     #设置验证类型,主要有PASS和AH两种。
        auth_pass 1111 #设置验证密码,在一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信。
    }
    virtual_ipaddress {  #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个。
        192.168.12.135
    }
}

#虚拟服务器定义部分
virtual_server 192.168.12.135 80 {       #设置虚拟服务器,需要指定虚拟ip地址和服务端口,ip与端口之间用空格隔开。
    delay_loop 6      #设置健康检查时间,单位是秒。
    lb_algo rr  #设置负载调度算法,这里设置为rr,即轮询算法。
    lb_kind DR                       #设置LVS实现负载均衡的机制,可以有NAT、TUN和DR三个模式可选。
persistence_timeout 50                  #会话保持时间,单位是秒,这个选项对于动态网页是非常有用的,为集群系统中session共享提供了一个很好的解决方案。有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话保持时间。需要注意的是,这个会话保持时间,是最大无响应超时时间,也就是说用户在操作动态页面时,如果在50秒内没有执行任何操作,那么接下来的操作会被分发到另外节点,但是如果一直在操作动态页面,则不受50秒的时间限制。
    protocol TCP       #指定转发协议类型,有tcp和udp两种。

real_server 192.168.12.246 80 { #配置服务节点1,需要指定real server的真实IP地址和端口,ip与端口之间用空格隔开。
weight 3 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值的大小可以为不同性能的服务器分配不同的负载,可以对性能高的服务器设置较高的权值,而对性能较低的服务器设置相对较低的权值,这样就合理的利用和分配了系统资源。
        TCP_CHECK {   #realserve的状态检测设置部分,单位是秒
            connect_timeout 10     #10秒无响应超时
            nb_get_retry 3  #重试次数
            delay_before_retry 3    #重试间隔
        }
    }

    real_server 192.168.12.237 80 {  #配置服务节点2
        weight 1   
        TCP_CHECK {
            connect_timeout 3   
            nb_get_retry 3           
            delay_before_retry 3
        }
    }
}

          在配置Keepalived.conf时,需要特别注意配置文件的语法格式,因为Keepalived在启动时并不检测配置文件的正确性,即使没有配置文件,Keepalived也照样能启动起来,因而配置文件一定要正确。
          在默认情况下,Keepalived在启动时会查找/etc/Keepalived/Keepalived.conf配置文件,如果你的配置文件放在了其它路径下,可以通过“Keepalived  -f”参数指定你所在的配置文件路径即可。
          Keepalived.conf配置完毕后,将此文件拷贝到备用Director Server对应的路径下,然后做两个简单的修改即可:
 将“state MASTER”更改为“state BACKUP”
 将priority 100更改为一个较小的值,这里改为“priority 80”
 最后,还要配置集群的Real server节点,以达到与Director Server相互广播通信并忽略arp的目的,脚本的内容已经在前面文章中进行过介绍,这里不做解释。