<acronym id='z2oaz'><em id='z2oaz'></em><td id='z2oaz'><div id='z2oaz'></div></td></acronym><address id='z2oaz'><big id='z2oaz'><big id='z2oaz'></big><legend id='z2oaz'></legend></big></address>

        <dl id='z2oaz'></dl>
      1. <tr id='z2oaz'><strong id='z2oaz'></strong><small id='z2oaz'></small><button id='z2oaz'></button><li id='z2oaz'><noscript id='z2oaz'><big id='z2oaz'></big><dt id='z2oaz'></dt></noscript></li></tr><ol id='z2oaz'><table id='z2oaz'><blockquote id='z2oaz'><tbody id='z2oaz'></tbody></blockquote></table></ol><u id='z2oaz'></u><kbd id='z2oaz'><kbd id='z2oaz'></kbd></kbd>
          <span id='z2oaz'></span><ins id='z2oaz'></ins>

          <code id='z2oaz'><strong id='z2oaz'></strong></code>

            <i id='z2oaz'><div id='z2oaz'><ins id='z2oaz'></ins></div></i>
            <i id='z2oaz'></i>
          1. <fieldset id='z2oaz'></fieldset>

            LIDS精通与进阶(一)

            • 时间:
            • 浏览:9
            • 来源:124软件资讯网

              一、系统入侵
                
                  随着Internet上的Linux主机的增添  ,越来越多的宁静毛病在当前的GNU/Linux系统上发现  。你也许在Internet上听说过在Linux下发现Bug  ,它会导致系统很容易的被黑客攻击  。
                


                  由于Linux是一个开放源代码的系统  ,毛病很容易发现  ,而且也会很快的有补丁出来 。可是当毛病没有宣布的时间 ,而且治理员很懒  ,没有去打补丁  。黑客就会很容易的攻击这个系统  ,取得root权限 ,在现有的GNU/Linux下  ,他就可以做任何他想做的事情  。现在你可以问  ,我们现在到底可以做些什么呢 ?
                
                1、现在的GNU/Linux错误在那里  ?
                
                超级用户会滥用职权 ,他能够做所有他要做的事情  。作为root  。他会改变所有的工具  。
                许多系统文件很容易被更改  。这些文件可能是很主要的文件 ,如/bin/login ,若是一个黑客进入  ,他可以上传一个login法式来笼罩/bin/login  ,这样他就可以不用上岸名和密码来上岸系统  。可是这些文件不需要经常改动  ,除非你要升级系统  。
                模块modules很容易用来中止内核  。模块是为了让Linux内核更模块话和更高效而设计的  。可是当模块加入到内核  ,它就会成为内核的一部门而且能做原始内核能做的事情  。因此 ,一些不友好的代码可以写成模块来加入到内核里 ,这些代码就会重定向系统挪用而且作为一个病毒来运行  。
                历程是不受掩护的  ,一些历程  ,如后台的Web服务器  ,一直都以为是没有严酷掩护的法式  。因此 ,他们就会很容易被黑客攻击  。
                2、LIDS的设想是什么 。
                
                掩护主要文件  。由于文件很容易被root更改 ,为什么不严酷文件操作呢  ?因此  ,LIDS改变了文件系统在内核里的宁静系统挪用  。若是某个时间一些人会见一个文件 ,他就会进入系统挪用然后我们就可以检查文件名而且看她们是否被掩护 。若是它已经被掩护  ,我们就可以拒绝这个会见者的要求  。
                掩护主要的历程  。这个和上面的掩护历程的想法不是一样的 。当一个系统里运行一个历程  ,它会在/proc 文件系统里有一个用pid作为路径名的入口 。以是 ,若是你用"ps -axf"你就可以显示出当前运行的历程  。你可以问若是掩护这些历程  。若是你要杀死一个历程的话  ,首先  ,你键入"ps"来获得历程的PID  ,然后  ,你键入"kill 〈pid〉"来杀死它  。可是  ,若是我不让你看到历程  ,你怎么来杀死这个历程呢  ?因此  ,LIDS是用隐藏历程来掩护它的 。 另外一个主要的要领就是不让任何人可以杀死历程  ,包罗root用户  。LIDS能够掩护父历程是init(pid=1)的所有历程 。
                封装内核 。有时间我们需要要把一些须要的模块加入到内核里来使用  ,另外 ,我们也要拒绝任何人包罗root用户向内核插入模块 。那么怎样来平衡这个矛盾的问题呢 ?我们可以只允许在系统启动的时间插入模块  ,然后我们封装模块 ,在封装后  ,内核不允许任何人插入模块到内核里  。通过这种封装功效  ,我们能用它来掩护主要的文件  ,历程  ,我们可以在系统启动的时间只允许须要的历程  ,只改变须要的文件 。在封装内核后  ,我们就不能在对文件有任何的修改  。
                
                二、掩护文件系统
                
                1、掩护文件系统是LIDS的主要功效之一  。这个功效是在内核的VFS(虚拟文件系统)层实现的  ,我们可以掩护任何种类的文件系统  ,如EXT2  ,FAT  。 在LIDS  ,掩护的文件按种类分为以下几种:
                
                只读的文件或目录 。只读文件意味着它们不被允许改写  ,如 ,在目录/usr/bin  ,/sbin 。这些类型的文件大多数都是二进制系统法式或是系统设置文件  ,除了在升级系统的时间  ,我们不需要改变它们 。
                只可增添文件或目录 。这些文件是那些只可以增添巨细的文件 。大多数是系统的日值文件  ,如在/var/log里的只可增添文件  。
                分外的文件或目录  ,这些文件没有被掩护  。一样平常来说 ,你想要掩护目录下的所有文件  ,可是  ,还需要有一些特殊的文件不要被掩护 。以是我们可以界说这些文件作为分外的其他的只读文件  。
                掩护挂载或卸载文件系统 。当你在启动的时间挂载文件系统的时间  ,你可以克制所有人 ,甚至是root ,去卸载文件系统 。你也可以克制任何人在当前文件系统下挂载文件系统来笼罩它 。
                2、LIDS怎样在内核掩护文件
                
                在这部门  ,我们会看到一些内核的代码来明白LIDS是怎样掩护文件的  。
                
                (1)、Linux文件系统数据结构法式
                
                首先  ,我们必须相识Linux的虚拟文件系统  。
                
                在Linux里的每一个文件  ,不管是什么样子的  ,都有一个结点inode数  ,文件系统提供了以下数据结构 。
                
                在/usr/src/linux/include/linux/fs.h
                
                struct inode {
                struct list_head     i_hash;
                struct list_head     i_list;
                struct list_head     i_dentry;
                
                unsigned long       i_ino; ----> inode number.
                unsigned int       i_count;
                kdev_t          i_dev; ----> device number.
                umode_t          i_mode;
                nlink_t          i_nlink;
                uid_t           i_uid;
                ......
                }
                
                注重: 用来判定一个结点inode 。这个意思是你可以用一对 来获得一个系统里唯一无二的inode  。
                
                在/ur/src/linux/cinclude/linux/dcache.h里
                
                struct dentry {
                    int d_count;
                    unsigned int d_flags;
                    struct inode * d_inode;       
                    struct dentry * d_parent;     
                    struct dentry * d_mounts;     
                    struct dentry * d_covers; struct list_head d_hash;   
                    struct list_head d_lru;      
                    struct list_head d_child;     
                    struct list_head d_subdirs;    
                    kdev_t dev;          
                    };
                
                上面的结构用一对 来存储掩护文件或目录的结点  。"type"是用来标明掩护结点文件类型的  。
                
                LIDS有4种类型:
                
                在/usr/src/linux/include/linux/fs.h
                
                #define LIDS_APPEND    1    
                #define LIDS_READONLY   2    
                #define LIDS_DEVICE    3    
                #define LIDS_IGNORE    4    
                
                通过secure_ino结构 ,我们能很容易的初使化掩护的文件或是在内核里执行以下函数  。
                
                在/usr/src/linux/fs/lids.c
                
                int lids_add_inode(unsigned long int inode ,kdev_t dev , int type)
                {
                
                     if ( last_secure == (LIDS_MAX_INODE-1))
                     return 0;
                
                     secure[last_secure].ino = inode;
                     secure[last_secure].dev = dev;
                     secure[last_secure].type = type;
                     secure[++last_secure].ino = 0;
                
                #ifdef VFS_SECURITY_DEBUG
                     printk("lids_add_inode : return %dn",last_secure);
                #endif
                     return last_secure;
                }
                
                就象你在上面代码上可以看到的  ,给secure_ino加到一个结点上是很是容易的  。被掩护的结点会在系统启动的时间初使化  。初使化法式在/usr/src/linux/fs/lids.c的init_vfs_security()里 。
                
                现在 ,让我们看看LIDS是怎样来检查是否一个结点已经受到掩护  。
                
                在/usr/src/linux/fs/open.c
                
                int do_truncate(struct dentry *dentry, unsigned long length)
                {
                     struct inode *inode = dentry->d_inode;
                     int error;
                     struct iattr newattrs;
                     
                     if ((off_t) length < 0)
                     return -EINVAL;
                
                #ifdef CONFIG_LIDS
                     if (lids_load && lids_local_load) {
                     error =
                     lids_check_base(dentry,LIDS_READONLY);
                     if (error) {
                              lids_security_alert("Try to truncate a protected file (dev %d %d,inode %ld)",
                              MAJOR(dentry->d_inode->i_dev),
                              MINOR(dentry->d_inode->i_dev),
                              dentry->d_inode->i_ino);
                .....................
                
                这个是LIDS加到内核里做检测的一个例子  。你会看到lids_check_base()是LIDS掩护要领的一个焦点函数  。
                
                你可以在LIDS要掩护的地方看到许多LIDS掩护要领用到lids_check_base()函数  ,特殊是在linux内核的子目录下  。
                
                在/usr/src/linux/fs/lids.c
                
                int lids_check_base(struct dentry *base, int flag)
                {
                ..................
                inode = base->d_inode;     
                parent = base->d_parent;
                .................
                ---->  do {
                         if ( inode == parent->d_inode)
                         break;
                         if ((retval = lids_search_inode(inode))) {
                           if ( retval == LIDS_IGNORE || (retval == LIDS_DEVICE && flag != LIDS_DEVICE)) break;
                           if ( flag == LIDS_READONLY || ( flag == LIDS_APPEND && retval >flag ) || ( flag == LIDS_DEVICE && flag == retval )) {
                                         return -EROFS;
                                      } break; }
                                      inode = parent->d_inode;
                                  } while( ((parent = parent->d_parent ) != NULL) );
                            return 0;
                     }
                
                lids_check_base()会检查一个给定文件的dentry和它的父目录是否被掩护 。
                
                注重:若是它的父目录被掩护 ,它下面的文件也会被掩护  。
                
                例如  ,若是"/etc/"被掩护  ,"/etc/passwd"也一样被掩护  。
                
                (3)、在内核掩护系统挪用
                
                为了掩护系统 ,LIDS会在一些检查临界的系统挪用的时间做检查 。因此 ,我们可以掩护系统挪用和限制文件系统的用户挪用  。
                
                这些是一些例子:
                
                open()  ,open是通过克制一些权力来掩护文件的打开  。你可以在打开挪用open_namei()挪用的时间LIDS在检测它  。
                mknod() ,mknod是用来在指定目录下掩护mknod 。
                unlink() ,在内核代码检查do_unlink()  。
                
                三、掩护装备
                
                Linux的装备会在/dev/目录下以文件的形式列出  ,我们可以用上面掩护文件的要领来掩护装备 。可是在一些情形下 ,用户也可以用IO操作来旁路文件系统来读写装备 ,我们必须注重这个问题  。
                
                1、装备  ,内核I/O
                
                在GNU/Linux系统下的装备会以文件的形式表达  ,以是我们可以用掩护文件系统那样来掩护装备  。
                
                用户的I/O会见是通过系统挪用sys_operm和sys_iopl来实现的  。你可以看看/usr/src/linux/arch/i386/kernel/ioport. 。这个是要基于系统结构的  ,要是到其他平台  ,就需要注重它们的转变 。
                
                2、怎样用LIDS来掩护
                
                大多数情形下 ,法式不需要通过在/dev的装备文件名称来会见装备 。可是  ,一些特殊的法式需要直接会见  ,如X Server,这个会写到/dev/mem和甚至是I/O装备  。我们需要一些分外的工具来掩护装备  。LIDS会在设置内核的时间来界说这个功效  。
                
                CONFIG_LIDS_ALLOW_DEV_MEM,若是你选择了开启这个功效  ,你就可以允许一些特殊法式来会见/dev/men和/dev/kmen这些内核临界的装备 。若是你想要用内核的X Server  ,选择这个功效就会在设置内核的时间提供整个路径和文件名 。
                CONFIG_LIDS_ALLOW_RAW_DISKS ,若是选择这个开启  ,你就可以允许一些特殊的法式来会见物理磁盘 。
                CONFIG_LIDS_ALLOW_IO_PORTS  ,若是你选择了开启这个功效  ,你就可以允许一些特殊的法式来访I/O端口  。
                当系统运行fs/lids.c里的init_vfs_security()的时间初使化就被挪用  。
                
                #ifdef CONFIG_LIDS_ALLOW_DEV_MEM
                
                lids_fill_table(allow_dev_mem,&last_dev_mem,LIDS_MAX_ALLOWED,CONFIG_LIDS_DEV_MEM_PROGS);
                
                #endif
                
                #ifdef CONFIG_LIDS_ALLOW_RAW_DISKS
                
                lids_fill_table(allow_raw_disks,&last_raw_disks,LIDS_MAX_ALLOWED,CONFIG_LIDS_RAW_DISKS_PROGS);
                
                #endif
                
                #ifdef CONFIG_LIDS_ALLOW_IO_PORTS
                
                lids_fill_table(allow_io_ports,&last_io_ports,LIDS_MAX_ALLOWED,CONFIG_LIDS_IO_PORTS_PROGS);
                
                #endif
                
                若是一个历程或是法式要直接会见ip端口或是磁盘装备 ,LIDS就会检查它在数组allow_raw_disk,last_io_ports,等) 。这个检查是通过挪用lids_check_base()里的lids_search_inode(inode)来实现的  。
                
                如  ,让我们看看CONFIG_LIDS_ALLOW_DEV_MEM
                
                
                
                #ifdef CONFIG_LIDS_ALLOW_DEV_MEM
                
                for( i = 0 ; i < last_dev_mem ;i++ ) {
                
                if ( allow_dev_mem[i].ino == ino && allow_dev_mem[i].dev == dev) {
                
                return LIDS_READONLY;
                
                }
                
                }
                
                #endif
                
                #ifdef CONFIG_LIDS_ALLOW_RAW_DISKS
                
                在allow_dev_mem包罗了哪一个法式结点在系统启动的时间在init_vfs_security()里初使化  。用同样的要领  ,除了一些特殊法式  ,我们可以掩护装备  ,I/O会见等等