linux学习笔记.docx

上传人:b****8 文档编号:23756330 上传时间:2023-05-20 格式:DOCX 页数:25 大小:24.05KB
下载 相关 举报
linux学习笔记.docx_第1页
第1页 / 共25页
linux学习笔记.docx_第2页
第2页 / 共25页
linux学习笔记.docx_第3页
第3页 / 共25页
linux学习笔记.docx_第4页
第4页 / 共25页
linux学习笔记.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

linux学习笔记.docx

《linux学习笔记.docx》由会员分享,可在线阅读,更多相关《linux学习笔记.docx(25页珍藏版)》请在冰豆网上搜索。

linux学习笔记.docx

linux学习笔记

Linux下修改主机名

1、修改/etc/hosts

添加

192.168.0.1area

2、修改/etc/sysconfig/network

HOSTNAME=area

3、执行命令

hostname=zjq

4、退出终端,然后重新登录即可升效

Linux下NAT功能的实现

本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。

msn:

yfydz_no1@

来源:

1.前言

在2.4/2.6内核的Linux中的防火墙代码netfilter中支持源NAT(SNAT)和目的NAT

(DNAT),基本可以满足各种类型的NAT需求,本文介绍Linux下的NAT的具体实现过程,所引的内核代码版本2.4.26,NAT原理部分不在此介绍,有兴趣者可先看我的另一篇NAT原理介绍的文章。

2.NAThook

NAT操作也是以netfilter节点形式挂接在相应的处理点上的,DNAT挂接在NF_IP_PRE_ROUTING点上,优先级高于FILTER低于MANGLE,表示在mangle表后处理,但在filter表前处理数据包;SNAT挂接在NF_IP_POST_ROUTING点上,优先级低于FILTER,表示在filter表后面处理数据包。

在net/ipv4/netfilter/ip_nat_standalone.c中:

目的NAT的hook节点:

/*Beforepacketfiltering,changedestination*/

staticstructnf_hook_opsip_nat_in_ops

={{NULL,NULL},ip_nat_fn,PF_INET,NF_IP_PRE_ROUTING,NF_IP_PRI_NAT_DST};

源NAT的hook节点:

/*Afterpacketfiltering,changesource*/

staticstructnf_hook_opsip_nat_out_ops

={{NULL,NULL},ip_nat_out,PF_INET,NF_IP_POST_ROUTING,NF_IP_PRI_NAT_SRC};

include/linux/netfilter_ipv4.h

enumnf_ip_hook_priorities{

NF_IP_PRI_FIRST=INT_MIN,

NF_IP_PRI_CONNTRACK=-200,//连接跟踪

NF_IP_PRI_MANGLE=-150,    //mangletable

NF_IP_PRI_NAT_DST=-100,   //DNAT

NF_IP_PRI_FILTER=0,       //filtertable

NF_IP_PRI_NAT_SRC=100,    //SNAT

NF_IP_PRI_LAST=INT_MAX,

};

ip_nat_fn()是NAThook的主处理函数,ip_nat_out()函数也是在数据合法性检查后调用ip_nat_fn()函数。

3.NAT处理相关结构

在状态连接结构structip_conntrack中包含了关于NAT的相关结构(include/linux/netfilter/ip_conntrack.h):

structip_conntrack

{

......

#ifdefCONFIG_IP_NF_NAT_NEEDED

struct{

structip_nat_infoinfo;

unionip_conntrack_nat_helphelp;

#ifdefined(CONFIG_IP_NF_TARGET_MASQUERADE)||\

defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)

intmasq_index;

#endif

}nat;

#endif/*CONFIG_IP_NF_NAT_NEEDED*/

};

其中比较重要的是structip_nat_info结构,而unionip_conntrack_nat_help是各协议NAT时需要特殊处理的结构描述,不过在2.4.26内核中都没定义,联合为空。

#defineIP_NAT_MAX_MANIPS(2*3)

//此结构描述数据包中要修改部分的信息

structip_nat_info_manip

{

/*Thedirection.*/

u_int8_tdirection;

/*Whichhookthemanipulationhappenson.*/

u_int8_thooknum;

/*Themanipulationtype.*/

u_int8_tmaniptype;//修改类型:

SNAT/DNAT

//连接的数据包要修改的信息,包括地址和上层的协议信息

/*Manipulationstooccurateachconntrackinthisdirn.*/

structip_conntrack_manipmanip;

};

/*Thestructureembeddedintheconntrackstructure.*/

structip_nat_info

{

/*Settozerowhenconntrackcreated:

bitmaskofmaniptypes*/

intinitialized;//实际最多用两位

unsignedintnum_manips;

/*Manipulationstobedoneonthisconntrack.*/

//每个最多可以记录6个NAT信息

structip_nat_info_manipmanips[IP_NAT_MAX_MANIPS];

structip_nat_hashbysource,byipsproto;//按地址和协议的HASH表

/*Helper(NULLifnone).*/

structip_nat_helper*helper;//多连接协议的NAT时的helper

structip_nat_seqseq[IP_CT_DIR_MAX];//描述两个方向的序列号变化情况

};

4.ip_nat_fn()函数

ip_nat_fn()是NAThook的基本处理函数(net/ipv4/netfilter/ip_nat_standalone.c),目的是建立连接的NATinfo信息,并修改数据包中的相应部分。

staticunsignedint

ip_nat_fn(unsignedinthooknum,

  structsk_buff**pskb,

  conststructnet_device*in,

  conststructnet_device*out,

  int(*okfn)(structsk_buff*))

{

structip_conntrack*ct;

enumip_conntrack_infoctinfo;

structip_nat_info*info;

/*maniptype==SRCforpostrouting.*/

//根据hooknum来确定进行哪种方式的NAT,netfilter在hook点是能进行哪种NAT是固定的:

//NF_IP_PRE_ROUTING点进行的是DNAT,maniptype=1

//NF_IP_POST_ROUTING点进行的是SNAT,maniptype=0

enumip_nat_manip_typemaniptype=HOOK2MANIP(hooknum);

/*Weneverseefragments:

conntrackdefragsonpre-routing

   andlocal-out,andip_nat_outprotectspost-routing.*/

IP_NF_ASSERT(!

((*pskb)->nh.iph->frag_off

        &htons(IP_MF|IP_OFFSET)));

(*pskb)->nfcache|=NFC_UNKNOWN;

/*Ifwehadahardwarechecksumbefore,it'snowinvalid*/

if((*pskb)->ip_summed==CHECKSUM_HW)

(*pskb)->ip_summed=CHECKSUM_NONE;

//进行NAT的包必须都经过的连接跟踪处理,如果找不到该包对应的连接,不对其进行NAT处理

//连接跟踪优先级最高,是数据包一进入netfilter就要进行处理的

ct=ip_conntrack_get(*pskb,&ctinfo);

/*Can'ttrack?

It'snotduetostress,orconntrackwould

   havedroppedit.Henceit'stheuser'sresponsibiltyto

   packetfilteritout,orimplementconntrack/NATforthat

   protocol.8)--RR*/

if(!

ct){

/*Exception:

ICMPredirecttonewconnection(notin

                  hashtableyet).Wemustnotletthisthrough,in

                  casewe'redoingNATtothesamenetwork.*/

structiphdr*iph=(*pskb)->nh.iph;

structicmphdr*hdr=(structicmphdr*)

  ((u_int32_t*)iph+iph->ihl);

if(iph->protocol==IPPROTO_ICMP

     &&hdr->type==ICMP_REDIRECT)

  returnNF_DROP;

returnNF_ACCEPT;

}

switch(ctinfo){

//对于相关连接、相关连接的回复、新连接的包进行NAT信息的构建

caseIP_CT_RELATED:

caseIP_CT_RELATED+IP_CT_IS_REPLY:

if((*pskb)->nh.iph->protocol==IPPROTO_ICMP){

  returnicmp_reply_translation(*pskb,ct,hooknum,

           CTINFO2DIR(ctinfo));

}

/*Fallthru...(OnlyICMPscanbeIP_CT_IS_REPLY)*/

caseIP_CT_NEW:

info=&ct->nat.info;

WRITE_LOCK(&ip_nat_lock);

/*Seenitbefore?

Thiscanhappenforloopback,retrans,

    orlocalpackets..*/

//检查是否已经进行相应方向的初始化,注意初始化可以是两个方向同时进行的

//这就是说一个数据包可以同时修改源和目的,这在服务器和内网在相同网段时会用到,

//netfilter已经能自动处理这种情况,根本不需要进行修改,以前我的理解有误,以为

//只能修改一个方向的数据

if(!

(info->initialized&(1<

#ifndefCONFIG_IP_NF_NAT_LOCAL

     /*Ifthissessionhasalreadybeenconfirmedwemustnot

      *touchitagainevenifthereisnomappingsetup.

      *Canonlyhappenonlocal->localtrafficwith

      *CONFIG_IP_NF_NAT_LOCALdisabled.

      */

     &&!

(ct->status&IPS_CONFIRMED)

#endif

     ){

  unsignedintret;

  if(ct->master

      &&master_ct(ct)->nat.info.helper

      &&master_ct(ct)->nat.info.helper->expect){

//多连接协议情况,如果是子连接,调用主连接相关的expect函数处理填写NATinfo信息

   ret=call_expect(master_ct(ct),pskb,

       hooknum,ct,info);

  }else{

#ifdefCONFIG_IP_NF_NAT_LOCAL

   /*LOCAL_INhookdoesn'thaveachain!

*/

   if(hooknum==NF_IP_LOCAL_IN)

    ret=alloc_null_binding(ct,info,

        hooknum);

   else

#endif

//否则根据NAT规则表查找规则,执行规则的动作:

SNAT或DNAT,填写NATinfo信息

   ret=ip_nat_rule_find(pskb,hooknum,in,out,

            ct,info);

  }

//返回值不是接受的话直接返回,数据包将被丢弃

  if(ret!

=NF_ACCEPT){

   WRITE_UNLOCK(&ip_nat_lock);

   returnret;

  }

}else

  DEBUGP("Alreadysetupmanip%sforct%p\n",

         maniptype==IP_NAT_MANIP_SRC?

"SRC":

"DST",

         ct);

WRITE_UNLOCK(&ip_nat_lock);

break;

default:

//连接的NAT信息已经填好,直接使用

/*ESTABLISHED*/

IP_NF_ASSERT(ctinfo==IP_CT_ESTABLISHED

       ||ctinfo==(IP_CT_ESTABLISHED+IP_CT_IS_REPLY));

info=&ct->nat.info;

}

IP_NF_ASSERT(info);

//根据NATinfo信息对数据包的相应部分进行修改

returndo_bindings(ct,ctinfo,info,hooknum,pskb);

}

4.do_bindings()函数

do_bindings()是完成具体的NAT操作部分的函数(net/ipv4/netfilter/ip_nat_core.c),修改地址端口等信息,必要时修改数据内容部分信息(这种情况下可能数据包长度会变,序列号/确认号相应会改变,这些都累计进NATinfo参数中),并重新各种校验和(TCP/UDP/ICMP校验和,IP头校验和):

/*Dopacketmanipulationsaccordingtobinding.*/

unsignedint

do_bindings(structip_conntrack*ct,

    enumip_conntrack_infoctinfo,

    structip_nat_info*info,

    unsignedinthooknum,

    structsk_buff**pskb)

{

unsignedinti;

structip_nat_helper*helper;

//数据方向:

originalorreply

enumip_conntrack_dirdir=CTINFO2DIR(ctinfo);

//是否是TCP协议,TCP协议要处理序列号/确认号

intis_tcp=(*pskb)->nh.iph->protocol==IPPROTO_TCP;

/*Neednatlocktoprotectagainstmodification,butneither

   conntrack(referenced)andhelper(deletedwith

   synchronize_bh())canvanish.*/

READ_LOCK(&ip_nat_lock);

for(i=0;inum_manips;i++){

/*rawsocket(tcpdump)mayhavecloneofincoming

                  skb:

don'tdisturbit--RR*/

if(skb_cloned(*pskb)&&!

(*pskb)->sk){

  structsk_buff*nskb=skb_copy(*pskb,GFP_ATOMIC);

  if(!

nskb){

   READ_UNLOCK(&ip_nat_lock);

   returnNF_DROP;

  }

  kfree_skb(*pskb);

  *pskb=nskb;

}

//检查数据包方向和hooknum是否是与NATinfo中规定的一致

if(info->manips[i].direction==dir

     &&info->manips[i].hooknum==hooknum){

  DEBUGP("Mangling%p:

%sto%u.%u.%u.%u%u\n",

         *pskb,

         info->manips[i].maniptype==IP_NAT_MANIP_SRC

         ?

"SRC":

"DST",

         NIPQUAD(info->manips[i].manip.ip),

         htons(info->manips[i].manip.u.all));

//进行具体的NAT操作,修改IP头的地址、TCP、UDP等的端口

  manip_pkt((*pskb)->nh.iph->protocol,

     (*pskb)->nh.iph,

     (*pskb)->len,

     &info->manips[i].manip,

     info->manips[i].maniptype,

     &(*pskb)->nfcache);

}

}

helper=info->helper;

READ_UNLOCK(&ip_nat_lock);

//多连接协议

if(helper){

structip_conntrack_expect*exp=NULL;

structlist_head*cur_item;

intret=NF_ACCEPT;

inthelper_called=0;

DEBUGP("do_bindings:

helperexistingfor(%p)\n",ct);

/*Alwaysdefraggedforhelpers*/

IP_NF_ASSERT(!

((*pskb)->nh.iph->frag_off

         &htons(IP_MF|IP_OFFSET)));

/*Havetograbreadlockbeforesibling_listtraversal*/

READ_LOCK(&ip_conntrack_lock);

//主连接的子连接链表是倒着搜索的

list_for_each_prev(cur_item,&ct->sibling_list){

//取得期待的连接信息

  exp=list_entry(cur_item,structip_conntrack_expect,

     expected_list);

     

  /*ifthisexpectationisalreadyestablished,skip*/

//期待的子连接已经到了,不用再处理

  if(exp->sibling)

   continue;

//检查数据包是否是要修改的数据包,对于UDP、ICMP函数返回始终是1,TCP协议是才可能返回0

  if(exp_for_packet(exp,pskb)){

   /*FIXME:

Maybetruemultipletimesinthe

    *caseofUDP!

!

*/

   DEBUGP("callingnathelper(exp=%p)forpacket\n",exp);

//调用多连接协议的help函数修改内容部分的相关数据

   ret=helper->help(ct,exp,info,ctinfo,

        hooknum,pskb);

   if(ret!

=NF_ACCEPT){

    READ_UNLOCK(&ip_conntrack_lock);

    returnret;

   }

   helper_called=1;

  }

}

/*Helpermightwanttomanipthepacketevenwhenthereisno

  *matchingexpectationforthispacket*/

if(!

helper_called&&helper->flags&IP_NAT_HELPER_F_ALWAYS){

  DEBUGP("callingnathelperforpacketwithoutexpectati

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1