linux钩子
⑴ 想实现一个linux内核安全功能模块的技术思路是怎样的
作者:橘子-实现网
链接:https://www.hu.com/question/21637060/answer/58362892
来源:知乎
着作权归作者所有,转载请联系作者获得授权。
用户在执行系统调用时,先通过原有的内核接口依次执行慧卜雹功能性的错误检查,接着进行传统的DAC检查,并在即将访问内核的内部对象之前,通过LSM钩子函数调用LSM。LSM再调用具体的访问控制策略来决定访问的合法性。访问控制整体构架:<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="804" data-rawheight="604" class="origin_image zh-lightbox-thumb" width="804" data-original="https://pic2.mg.com/_r.jpg">
LSM框架下访问决策模块包括selinux,smack,tomoyo,yama,apparmor.
每个决策模块都是通过各自的XXX_init函数调用register_security()函数,注册到LSM框架的模块被加载成功后,就可以进行访问控制操作。如果此时还有一个安全模块要使用register_security()函数进行加载,则会出现错误,直到使用框架注销后,下一个模块才可以载入。<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="420" data-rawheight="285" class="content_image" width="420">
Linux安全模块(LSM)提供了两类对安全钩子函数的调用:一类管理内核对象的安全域,另一类仲裁对这些内核对象的访问。对安全钩子函数的调用通过钩子来实现,钩子是全局表security_ops中的函数指针,这个全局表的类型是security_operations结构,这个结构定义在include/linux/security.h这个头文件中。
通过对security代码进行一番简单的分析,LSM启动过程流图:
<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="1011" data-rawheight="213" class="origin_image zh-lightbox-thumb" width="1011"弊知 data-original="https://pic2.mg.com/_r.jpg">security_initcall只能调用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一个,因为内核不允许多种安全机制同时一起工作。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,前帆直到这个安全模块被使用unregister_security()函数向框架注销。security_initcall只能调用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一个,因为内核不允许多种安全机制同时一起工作。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,直到这个安全模块被使用unregister_security()函数向框架注销。
因此LSM框架下只能开启一种安全机制,smack编译进Linux内核的配置和要求:
(1)要求smack和selinux不能够同时运行,不能同时存在于同一个运行中的内核;
查看内核是否开启以下的功能(如果没有则需要开启):
CONFIG_NETLABEL=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SELINUX should not be
set
步骤:
make menuconfig
<img src="https://pic1.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="461" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic1.mg.com/_r.jpg"><img src="https://pic3.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="464" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/_r.jpg"><img src="https://pic3.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/_r.jpg"><img src="https://pic4.mg.com/_b.jpg" data-rawwidth="662" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="662" data-original="https://pic4.mg.com/_r.jpg">
make moles_install
make install
查看/proc/filesystems
可以看到smackfs,说明smack已经编进内核
<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="146" data-rawheight="187" class="content_image" width="146">
执行如下的命令:
mkdir -p /smack
在文件/etc/fstab添加下面的一行
smackfs /smack smackfs defaults 0 0
然后执行下面的命令:
mount –a
然后就体验一下它的功能了:
1. 比如在用户test的home目录下(/home/test),新建文件夹 mkdir testdir
cd testdir/
touch testfile
2. 给新建的testfile 打上TheOther标签
setfattr
--name=security.SMACK64 --value=TheOther testfile
查看其标签
getfattr
--only-values -n security.SMACK64 -e text testfile
可以看到标签TheOther
<img src="https://pic3.mg.com/_b.jpg" data-rawwidth="698" data-rawheight="60" class="origin_image zh-lightbox-thumb" width="698" data-original="https://pic3.mg.com/_r.jpg">
3. echo TheOne
2>/dev/null > /proc/self/attr/current,当前执行的进程默认都会被打为/proc/self/attr/current下的标签
4.配置策略echo -n "TheOne TheOther r---"> /sma ck/load
因为当前进程只要是没有特殊配置过的都被打为TheOne,所以当转换到普通用户test下,cat testfile是可读的
5.现在我将当前进程打为NotTheOne ,echo NotTheOne 2>/dev/null >
/proc/self/attr/current
当转换到普通用户test下,cat testfile则变成不可读的了
6.如果你想单独对某个进程打标签,而不是对当前进程打,就
attr -s security.SMACK64 -V TheOne /bin/cat
此时cat被标为TheOne,根据策略可以看出,当转换到普通用户test下,cat testfile是可读的
若attr -s
security.SMACK64 –V Not TheOne /bin/cat
根据策略可以看出,当转换到普通用户test下,cat testfile是不可读的
(需要说明的一点是,当cat本身被标上标签和/proc/self/attr/current打入标签共存时,cat本身的标签生效,而/proc/self/attr/current打入标签没有生效)
⑵ 基于Linux与ip6的多机互联怎么解决
IPv6运用AH和ESP对所传输的数据进行认证和加密,保证了数竖燃据的机密性、完整性和可靠性,实现了信息在传输过程的安全性。但IPv6并不能保障网络系统本身的安全及其提供的服务的可用性,也不能防止黑客的非法入侵和窃取私有数据。面对IPv6将要广泛的应用,有必要将其和防火墙相结合来保障整个网络系统的安全。
目前Linux操作系统自2.2内核以来已提供对IPv6的支持,其性能稳定且安全性较高,因此本文以Linux为平台来研究设计针对IPv6的防火墙系统。
Linux内核对数据包的过滤处理
netfilter框架机制
netfilter是linux2.4内核以后实现数据包过滤处理的一个抽象的、通用化的功能框架,它提供了不同于BSD Socket接口的操作网络数据包的机制。在netfilter中,协议栈每种协议都定义了若干个钩子(HOOK),而对应协议的数据包将按照一定的规则通过一些钩子,每一个钩子都是处毕纤蔽理函数挂载点。内核模块可以在各个钩子上注册处理函数以操作经过对应钩子的数据包。数据包经过所注册的函数处理后,根据一定的策略返回给内核进行下一步的处理。
IPv6协议定义了五个钩子:
(1)NF_IPv6_PRE_ROUTING:数据包在抵达路由之前经过这个钩子。一般应用于防止拒绝服务攻击和NAT。
(2)NF_IPv6_LOCAL_IN:目的地为本地主机的数据包经过这个钩子,这个钩子可以应用于防火墙。
(3)NF_IPv6_FORWARD:目的地非本地主机的数据包经过这个钩子。
(4)NF_IPv6_POST_ROUTING:数据包在离开本地主机之前经过这个钩子,包括源地址为本地主机和非本地主机的数据包。
(5)NF_IPv6_LOCAL_OUT:本地主机发出的数据包经过这个钩子。这个钩子可以应用于防火墙。
数据包从左边进入系统,进行IP校验以后,数据包经过第一个钩子NF_IP6_PRE_ROUTING注册函数进行处理,然后就进入路由代码决定该数据包是需要转发还是发给本机。若该数据包是发给本机的,则该数据经过钩子NF_IP6_LOCAL_IN注册函数的处理以后传递给上层协议。若该数据包应该被转发则它被NF_IP6_FORWARD注册函数处理。经过转发的数据包经过最后一个钩子NF_IP6_POST_ROUTING注册函数的处理以后,再传输到网络上。本地产生的数据经过钩子NF_IP6_LOCAL_OUT注册函数处理以后,进行路由选择处理,然后经过NF_IP6_POST_ROUTING注册函数的处理以后发送到网络上。每个注册函数处理完后,将返回一个整形常量,内核根据这个返回值来对数据包作下一步的处理,现在内核共定义了以下五个常量:
(1)NF_DROP表示丢弃此数据包,而不进入此后的处理;
(2)NF_ACCEPT表示接受此数据包,进入下一步的处理;
(3)NF_STOLEN表示异常分组;
(4)NF_QUEUE表示排队到用户空间,等待用户处理;
(5)NF_REPEAT表示再次进入该钩子函数作处理。
ip6tables数据包过滤系统
目前,基于Netfilter框架的、称为ip6tables的IPv6数据包选择系统在Linux2.4以上的内核中被应用,它可以让用户访问内核过滤规则和命令。这种数据包选择主要用于实现数据包过滤(filter表)、网络地址转换(nat表)及数据包处理(mangle表)。Linux2.4内核提供的这三种数据包处理功能都基于Netfilter的钩子函数和IP表。它们相互之手州间是独立的模块,但完美的集成到由Netfilter提供的框架中。
filter表格不对数据包进行修改,只对数据包进行过滤。它通过钩子函数NF_IP6_LOCAL_IN、NF_IP6_FORWARD及NF_IP6_LOCAL_OUT接入Netfilter框架。NAT表格监听三个Netfilter钩子函数:
NF_IP6_PRE_ROUTING、NF_IP6_POST_ROUTING及NF_IP6_LOCAL_OUT,用于源NAT、目的NAT、伪装(是源NAT的一个特例)及透明代理(是目的NAT的一个特例)。mangle表格在NF_IP6_PRE_ROUTING和NF_IP6_LOCAL_OUT钩子中进行注册。使用mangle表,可以实现对数据包的修改或给数据包附上一些额外数据。
ip6tables用户命令基本上包含以下5部分:
(1)希望工作在哪个表(Filter、NAT、Mangle);
(2)希望使用⑴所指定的表的哪个链(INPUT、OUTPUT、FORWARD等);
(3)进行的操作(插入、添加、删除、修改);
(4)对特定规则的目标动作;
(5)匹配数据包条件。ip6tables的语法为:
#ip6tables[-ttable] command [match] [target] [-ttable]有三种可用的表选项:filter、nat和mangle。该选项如果未指定,则filter用作缺省表。filter表用于一般的信息包过滤,它包含INPUT、OUTPUT和FORWARD链。nat表用于要转发的信息包,它包含PREROUTING、OUTPUT和POSTROUTING链。
PREROUTING链由指定信息包一到达防火墙就改变它们的规则所组成,而POSTROUTING链由指定正当信息包打算离开防火墙时改变它们的规则所组成。如果信息包及其头内进行了任何更改,则使用mangle表。该表包含一些规则来标记用于高级路由的信息包,该表包含PREROUTING和OUTPUT链。
ip6tables的基本操作(command):-A表示在链尾添加一条规则,-I表示插入一条规则,-D表示删除一条规则,-R表示替代一条规则,-L表示列出所有规则。
ip6tables基本目标动作(target)(适用于所有的链):ACCEPT表示接收该数据包,DROP表示丢弃该数据包,QUEUE表示排队该数据包到用户空间,RETURN表示返回到前面调用的链,FOOBAR表示用户自定义链。
ip6tables基本匹配条件(match)(适用于所有的链):-p表示指定协议,-s表示源地址,-d表示目的地址,-i表示数据包输入接口,-o表示数据包输出接口。例如,识别IPv6的网络服务器上的SSH连接时可以使用以下规则:
#ip6tables-AINPUT-ieth0-ptcp-s3ffe:ffff:100::1/128--dport22-jACCEPT
当然,还有其他对规则进行操作的命令,如清空链表,设置链缺省策略,添加用户自定义的链等,这里不再详述。
INPUT、OUTPUT、FORWARD链是ip6tables内置的过滤链,每条链都可定义若干条过滤规则,构成了基本的ip6tables包过滤防火墙,
⑶ linux内核源码中如何加载自己的钩子函数
(但不总是)位于 /usr/src/linux-。我们不会研究得过于详细,因为 Linux 源代码经常会发生变化,但是,我们将尝试让给出的信息足以找出特定驱动程序或函数的位置。
Makefile:这个文件是整个源代码树的顶层 makefile。它定义了很多实用的变量和规则,比如默认的 gcc 编译标记。
Documentation/:这个目录中包含很多关于配置内核、运行 ramdisk 等任务的实用信息(但通常是过时的)。不过,与不同配置选项相应的帮助条目并不在这里 —— 它们在每个源代码目录的 Kconfig 文件中。
arch/:所有与体系结构相关的代码都在这个目录以及 include/asm- 目录中。在此目录中,每种体系结构都有自己的目录。例如,用于基于 PowerPC 的计算机的代码位于 arch/ppc 目录中。在这些目录里,可以找到底层内存管理、中断处理、早期初始化、汇编例程,等等。
crypto/:这是内核本身所用的加密 API。
drivers/:按照惯例,在此目录的子目录中可以找到运行外围设备的代码。包括视频驱动程序、网卡驱动程序、底层 SCSI 驱动程序,以及其他类似的驱动程序。例如,在 drivers/net 中可以找到大部分网卡驱动程序。将一类驱动程序组合在一起的某些更高层代码,可能会(也可能不会)像底层驱动程序本身那些包含在同一目录中。
fs/:通用文件系统的代码(称做 VFS,即 Virtual File System)和各个不同文件系统的代码都可以在这个目录中找到。ext2 文件系统是在 Linux 中最常广泛使用的文件系统之一;在 fs/ext2 中可以找到读取 ext2 格式的代码。并不是所有文件系统都会编译或运行;对某些寻找内核项目的人而言,更生僻的文件系统永远都是理想的候选者。
include/:在 .c 文件的开头所包含的大部分头文件都可以在这个目录中找到。 asm- 目录下是与体系结构相关的包含(include )文件。部分内核构建过程创建从 asm 指定 asm- 的符号链接。这样,无需将其固定编码到 .c 文件 #include 就可以获得用于那个体系结构的正确文件。其他目录中包含的是 非-体系结构-相关 的头文件。如果在不只一个 .c 文件中使用了某个结构体、常量或者变量,那么它可能应该放入其中一个头文件中。
init/:这个目录中的文件包括 main.c、创建 早期用户空间(early userspace) 的代码,以及其他初始化代码。可以认为 main.c 是内核“粘合剂(glue)”。在下一部分将深入讨论 main.c。早期用户空间提供了 Linux 内核引导起来时所需要的功能,而这些功能并不需要在内核本身运行。
ipc/:IPC 的意思是 进程间通信(interprocess communication)。它包含了共享内存、信号量以及其他形式 IPC 的代码。
kernel/:不适合放在任何其他位置的通用内核级代码位于此处。这里有高层系统调用代码,以及 printk() 代码、调度程序、信号处理代码,等等。文件名包含很多信息,所以可以使用 ls kernel/,并非能常准确地猜到每个文件的功能。
lib/:这里是对所有内核代码都通用的实用例程。常见的字符串操作、调试例程,以及命令行解析代码都位于此处。
mm/:这个目录中是高层次内核管理代码。联合使用这些例程以及底层的与体系结构相关的例程(通常位于 arch//mm/ 目录中)来实现虚拟内存(Virtual memory,VM)。在这里会完成早期内存管理(在内存子系统完全建立起来之前需要它),以及文件的内存映射、页高速缓存管理、内存分配、RAM 中页的清除(还有很多其他事情)。
net/:这里是高层网络代码。底层网络驱动程序与此层次代码交换数据包,这个层次的代码可以根据数据包将数据传递给用户层应用程序,或者丢弃数据,或者在内核中使用它。net/core 包含大部分不同的网络协议都可以使用的代码,和某些位于 net/ 目录本身中的文件一样。特定的网络协议在 net/ 的子目录下实现。例如,在 net/ipv4 目录中可以找到 IP(版本 4)代码。
scripts/:这个目录中包含的脚本可用于内核的构建,但并不将任何代码加入到内核本身之中。例如,各种配置工具可以将它们的文件放在这里。
security/:在这里可以找到不同 Linux 安全模型的代码,比如 NSA Security-Enhanced Linux 以及套接字和网络安全钩子函数(hooks),以及其他安全选项。
sound/:这里放置的是声卡驱动程序和其他与声音相关的代码。
usr/:此目录中的代码用于构建包含 root 文件系统映像的 cpio-格式 的归档文件,用于早期用户空间。
⑷ linux的iptables里的--reject-with type中这些type的区别是什么
iptables 的历史以及工作原理
1.iptables的发展:
iptables的前身叫ipfirewall (内核1.x时代),这是一个作者从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
作者一共在内核空间中选择了5个位置,
1.内核空间中:从一个网络接口进来,到另一个网络接口去的
2.数据包从内核流入用户空间的
3.数据包从用户空间流出的
4.进入/离开本机的外网接口
5.进入/离开本机的内网接口
2.iptables的工作机制
从上面的发展我们知道了作者选择了5个位置,来作为控制的地方,但是你有没有发现,其实前三个位置已经基本上能将路径彻底封锁了,但是为什么已经在进出的口设置了关卡之后还要在内部卡呢? 由于数据包尚未进行路由决策,还不知道数据要走向哪里,所以在进出口是没办法实现数据过滤的。所以要在内核空间里设置转发的关卡,进入用户空间的关卡,从用户空间出去的关卡。那么,既然他们没什么用,那我们为什么还要放置他们呢?因为我们在做NAT和DNAT的时候,目标地址转换必须在路由之前转换。所以我们必须在外网而后内网的接口处进行设置关卡。
这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)
这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。
3.防火墙的策略
防火墙策略一般分为两种,一种叫“通”策略,一种叫“堵”策略,通策略,默认门是关着的,必须要定义谁能进。堵策略则是,大门是洞开的,但是你必须有身份认证,否则不能进。所以我们要定义,让进来的进来,让出去的出去,所以通,是要全通,而堵,则是要选择。当我们定义的策略的时候,要分别定义多条功能,其中:定义数据包中允许或者不允许的策略,filter过滤的功能,而定义地址转换的功能的则是nat选项。为了让这些功能交替工作,我们制定出了“表”这个定义,来定义、区分各种不同的工作功能和处理方式。
我们现在用的比较多个功能有3个:
1.filter 定义允许或者不允许的
2.nat 定义地址转换的
3.mangle功能:修改报文原数据
我们修改报文原数据就是来修改TTL的。能够实现将数据包的元数据拆开,在里面做标记/修改内容的。而防火墙标记,其实就是靠mangle来实现的。
小扩展:
对于filter来讲一般只能做在3个链上:INPUT ,FORWARD ,OUTPUT
对于nat来讲一般也只能做在3个链上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
iptables/netfilter(这款软件)是工作在用户空间的,它可以让规则进行生效的,本身不是一种服务,而且规则是立即生效的。而我们iptables现在被做成了一个服务,可以进行启动,停止的。启动,则将规则直接生效,停止,则将规则撤销。
iptables还支持自己定义链。但是自己定义的链,必须是跟某种特定的链关联起来的。在一个关卡设定,指定当有数据的时候专门去找某个特定的链来处理,当那个链处理完之后,再返回。接着在特定的链中继续检查。
注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。
三.规则的写法:
iptables定义规则的方式比较复杂:
格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
-t table :3个filter nat mangle
COMMAND:定义如何对规则进行管理
chain:指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候,是可以省略的
CRETIRIA:指定匹配标准
-j ACTION :指定如何进行处理
比如:不允许172.16.0.0/24的进行访问。
iptables -t filter -A INPUT -s 172.16.0.0/16 -p udp --dport 53 -j DROP
当然你如果想拒绝的更彻底:
iptables -t filter -R INPUT 1 -s 172.16.0.0/16 -p udp --dport 53 -j REJECT
iptables -L -n -v #查看定义规则的详细信息
四:详解COMMAND:
1.链管理命令(这都是立即生效的)
-P :设置默认策略的(设定默认门是关着的还是开着的)
默认策略一般只有两种
iptables -P INPUT (DROP|ACCEPT) 默认是关的/默认是开的
比如:
iptables -P INPUT DROP 这就把默认规则给拒绝了。并且没有定义哪个动作,所以关于外界连接的所有规则包括Xshell连接之类的,远程连接都被拒绝了。
-F: FLASH,清空规则链的(注意每个链的管理权限)
iptables -t nat -F PREROUTING
iptables -t nat -F 清空nat表的所有链
-N:NEW 支持用户新建一个链
iptables -N inbound_tcp_web 表示附在tcp表上用于检查web的。
-X: 用于删除用户自定义的空链
使用方法跟-N相同,但是在删除之前必须要将里面的链给清空昂了
-E:用来Rename chain主要是用来给用户自定义的链重命名
-E oldname newname
-Z:清空链,及链中默认规则的计数器的(有两个计数器,被匹配到多少个数据包,多少个字节)
iptables -Z :清空
2.规则管理命令
-A:追加,在当前链的最后新增一个规则
-I num : 插入,把当前规则插入为第几条。
-I 3 :插入为第三条
-R num:Replays替换/修改第几条规则
格式:iptables -R 3 …………
-D num:删除,明确指定删除第几条规则
3.查看管理命令 “-L”
附加子命令
-n:以数字的方式显示ip,它会将ip直接显示出来,如果不加-n,则会将ip反向解析成主机名。
-v:显示详细信息
-vv
-vvv :越多越详细
-x:在计数器上显示精确值,不做单位换算
--line-numbers : 显示规则的行号
-t nat:显示所有的关卡的信息
五:详解匹配标准
1.通用匹配:源地址目标地址的匹配
-s:指定作为源地址匹配,这里不能指定主机名称,必须是IP
IP | IP/MASK | 0.0.0.0/0.0.0.0
而且地址可以取反,加一个“!”表示除了哪个IP之外
-d:表示匹配目标地址
-p:用于匹配协议的(这里的协议通常有3种,TCP/UDP/ICMP)
-i eth0:从这块网卡流入的数据
流入一般用在INPUT和PREROUTING上
-o eth0:从这块网卡流出的数据
流出一般在OUTPUT和POSTROUTING上
2.扩展匹配
2.1隐含扩展:对协议的扩展
-p tcp :TCP协议的扩展。一般有三种扩展
--dport XX-XX:指定目标端口,不能指定多个非连续端口,只能指定单个端口,比如
--dport 21 或者 --dport 21-23 (此时表示21,22,23)
--sport:指定源端口
--tcp-fiags:TCP的标志位(SYN,ACK,FIN,PSH,RST,URG)
对于它,一般要跟两个参数:
1.检查的标志位
2.必须为1的标志位
--tcpflags syn,ack,fin,rst syn = --syn
表示检查这4个位,这4个位中syn必须为1,其他的必须为0。所以这个意思就是用于检测三次握手的第一次包的。对于这种专门匹配第一包的SYN为1的包,还有一种简写方式,叫做--syn
-p udp:UDP协议的扩展
--dport
--sport
-p icmp:icmp数据报文的扩展
--icmp-type:
echo-request(请求回显),一般用8 来表示
所以 --icmp-type 8 匹配请求回显数据包
echo-reply (响应的数据包)一般用0来表示
2.2显式扩展(-m)
扩展各种模块
-m multiport:表示启用多端口扩展
之后我们就可以启用比如 --dports 21,23,80
六:详解-j ACTION
常用的ACTION:
DROP:悄悄丢弃
一般我们多用DROP来隐藏我们的身份,以及隐藏我们的链表
REJECT:明示拒绝
ACCEPT:接受
custom_chain:转向一个自定义的链
DNAT
SNAT
MASQUERADE:源地址伪装
REDIRECT:重定向:主要用于实现端口重定向
MARK:打防火墙标记的
RETURN:返回
在自定义链执行完毕后使用返回,来返回原规则链。
七:状态检测:
是一种显式扩展,用于检测会话之间的连接关系的,有了检测我们可以实现会话间功能的扩展
什么是状态检测?对于整个TCP协议来讲,它是一个有连接的协议,三次握手中,第一次握手,我们就叫NEW连接,而从第二次握手以后的,ack都为1,这是正常的数据传输,和tcp的第二次第三次握手,叫做已建立的连接(ESTABLISHED),还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于这种我们无法识别的,我们都称之为INVALID无法识别的。还有第四种,FTP这种古老的拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,他们之间是有关系的,这种关系我们称之为RELATED。
所以我们的状态一共有四种:
NEW
ESTABLISHED
RELATED
INVALID
八:SNAT和DNAT的实现
由于我们现在IP地址十分紧俏,已经分配完了,这就导致我们必须要进行地址转换,来节约我们仅剩的一点IP资源。那么通过iptables如何实现NAT的地址转换呢?
1.SNAT基于原地址的转换
基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能。
所以我们在iptables中就要定义到底如何转换:
定义的样式:
比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1
这样,只要是来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP.
那么,如果172.16.100.1不是固定的怎么办?
我们都知道当我们使用联通或者电信上网的时候,一般它都会在每次你开机的时候随机生成一个外网的IP,意思就是外网地址是动态变换的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
这里要注意:地址伪装并不适用于所有的地方。
2.DNAT目标地址转换
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,我们可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。
如何做目标地址转换呢?:
iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --todestination 172.16.100.2
目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上
九:控制规则的存放以及开启
注意:你所定义的所有内容,当你重启的时候都会失效,要想我们能够生效,需要使用一个命令将它保存起来
1.service iptables save 命令
它会保存在/etc/sysconfig/iptables这个文件中
2.iptables-save 命令
iptables-save > /etc/sysconfig/iptables
3.iptables-restore 命令
开机的时候,它会自动加载/etc/sysconfig/iptabels
如果开机不能加载或者没有加载,而你想让一个自己写的配置文件(假设为iptables.2)手动生效的话:
iptables-restore < /etc/sysconfig/iptables.2
则完成了将iptables中定义的规则手动生效
⑸ linux钩子函数处理时间
处理的时间是2到3分钟。
钩子(Hook)处理的时间是2到3分钟,是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
⑹ Linux网络 - 数据包在内核中接收和发送的过程(转)
本文将介绍在Linux系统中, 数据包是如何一步一步从网卡传到进程手中的 以及 数据包是如何一步一步从应用程序到网卡并最终发送出去的 。
如果英文没有问题,强烈建议阅读后面参考里的文章,里面介绍的更详细。
本文只讨论以太网的物理网卡,不涉及虚拟设备,并且以一个UDP包的接收过程作为示例.
网卡需要有驱动才能工作,驱动是加载到内核中的模块,负责衔接网卡和内核的网络模块,驱动在加载的时候将自己注册进网络模块,当相应的网卡收到数据包时,网络模块会调用相应的驱动程序处理数据。
下图展示了数据包(packet)如何进入内存,并被内核的网络模块开始处理:
软中断会触发内核网络模块中的软中断处理函数,后续流程如下
由于是UDP包,所以第一步会进入IP层,然后一级一级的函数往下调:
应用层一般有两种方式接收数据,一种是recvfrom函数阻塞在那里等着数据来,这种情况下当socket收到通知后,recvfrom就会被唤醒,然后读取接收队列的数据;另一种是通过epoll或者select监听相应的socket,当收到通知后,再调用recvfrom函数去读取接收队列的数据。两种情况都能正常的接收到相应的数据包。
了解数据包的接收流程有助于帮助我们搞清楚我们可以在哪些地方监控和修改数据包,哪些情况下数据包可能被丢弃,为我们处理网络问题提供了一些参考,同时了解netfilter中相应钩子的位置,对于了解iptables的用法有一定的帮助,同时也会帮助我们后续更好的理解Linux下的网络虚拟设备。
ndo_start_xmit会绑定到具体网卡驱动的相应函数,到这步之后,就归网卡驱动管了,不同的网卡驱动有不同的处理方式,这里不做详细介绍,其大概流程如下:
在网卡驱动发送数据包过程中,会有一些地方需要和netdevice子系统打交道,比如网卡的队列满了,需要告诉上层不要再发了,等队列有空闲的时候,再通知上层接着发数据。
⑺ Linux里面k8s里面kind:service代表什么意思
1 Service 含义
K8s service可以理解为对一组Pod的抽象。类似于Nginx能够把请求转发 的 对应的服务上。
2 Service作用
2.1 pod使用时因某些问题重启,从而导致pod 的IP发生变化,会导致旧的IP不能用,影响用户对系统使用。service的出现很好 的 解决此问题,客户端通过service 访问pod,当podIP有变化也不会影响(service通过Label Selector跟pod绑定)。
2.2 对外暴露pod访问请求端口。
2.3 固定IP。
2.4 负载均衡。
3 Service 工作机制
3.1 userspace代理模型流程
userspace指Linux操作系统的用户空间(物理上为内存)。对于service会对外暴露端口号,用户空间中的kube-proxy会监控service端口上请求,并把请求转发到对应的pod上。
请求到达内核空间后经由套接字送往用户空间的kube-proxy,并调度至后端pod。请求会在内核和用户空间之间来回转发导致效率不高。(如下图)
3.2 iptables代理模型流程
kube-proxy负责跟踪API Server上的Service和Endpoints对象的变动,并根据变动做出iptables的变动。
iptables捕捉到达clusterIP与端口的请求,并将请求转发到当前service后端pod。
iptables模型不用将流量在用户空间和内核空间来回切换,因而更加高效和可靠,不过其缺点是iptables代理模型不会在被挑中的后端Pod资源无响应时进行重定向。
3.3 ipvs代理模型
K8s从1.9版本引入ipvs代理模型,且从1.11版本起成为默认设置。
它和iptables模型很类似,唯一一点不同的是在其请求流量的调度功能由ipvs实现,余下的功能仍由iptables完成。
ipvs是建立在netfilter的钩子函数上,但它使用hash表作为底层数据结构并工作于内核空间,因此流量转发速度特别快、规则同步性很好,
而且它支持众多调度算法,rr(轮询)、lc(最小连接数)、dh(目标哈希)、sh(源哈希)、sed(最短期望延迟)、nq(不排队调度)。
3 Service 类型
3.1 ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP.
3.2 NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样可以通过NodeIP:NodePort来访问服务。
也可以这样理解在于在 node 上暴露了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步到给对应的 pod。
k8s配置好对外访问端口后,linux防火墙也需要通过命令配置(-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT)
3.3 LoadBalancer:在NodePort基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到NodeIP:NodePort。
另一种理解调用cloud provider 去创建 LB 来向节点导流
3.4 ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建,这只有kubernetes1.7 或更高版本的kube-dns才支持
4 port nodePort targetPod 区别
4.1 port service暴露在cluster ip上的端口,<cluster ip>:port 是提供给集群内部客户访问service的入口
4.2 nodePort 是kubernetes提供给集群外部客户访问service入口的一种方式(另一种方式是LoadBalancer),所以,<nodeIP>:nodePort 是提供给集群外部客户访问service的入口.
4.3 targetPort 是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器
4 Service脚本创建
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
selector:
app: tomcat
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
selector字段中指定了为哪一个标签的app进行负载均衡即暴露pod 的name为tomcat对外的访问端口。
⑻ linux内核态,在LSM框架中的文件操作hook接口中如何获取一个正在被操作的文件的内容(linux4.4版本)
LSM是Linux Secrity Mole的简称,即linux安全模块。其是一种轻量级通用访
问控制框架,适合于多种访问控制模型在它上面以内核可加载模块的形实现。用
户可以根据自己的需求选择合适的安全模块加载到内核上实现。
LSM设计思想:
LSM的设计思想:在最少改变内核代码的情况下,提供一个能够成功实现强制访
问控制模块需要的结构或者接口。LSM避免了利用如在systrace系统调用中的出
现过的系统调用干预,因为它不能扩展到多处理器内核,并且它受制于参数替换
攻击。还有LSM在设计时做了两点考虑:对不使用的人来说尽量少引入麻烦,对
使用的人来说要带来效率。以Linus Torvalds为代表的内核开发人员对Linux安
全模块(LSM)提出了三点要求:
1、真正的通用,当使用一个不同的安全模型的时候,只需要加载一个不同的内
核模块。
2、概念上简单,对Linux内核影响最小,高效,并且。
3、能够支持现存的POSIX.1e capabilities逻辑,作为一个可选的安全模块。
还有,针对linux上提出的各种不同的Linux安全增强系统对Linux安全模块(LSM
)提出的要求是:能够允许他们以可加载内核模块的形式重新实现其安全功能,
并且不会在安全性方面带来明显的损失,也不会带来额外的系统开销。
LSM框架结构:
LSM框架主要由五部分构成:
1、在特定的内核数据结构中加入安全域。
2、在内核源代码中不同的关键点插入对安全钩子函数的调用。
3、加入一个通用的安全系统调用。
4、提供了函数允许内核模块注册为安全模块或者注销。
5、5、将capabilities逻辑的大部分移植为一个可选的安全模块。
安全域是一个void*类型的指针,它使得安全模块把安全信息和内核内部对象联
系起来。下面列出被修改加入了安全域的内核数据结构,以及各自所代表的内核
内部对象:
task_struct结构:代表任务(进程)
linux_binprm结构:代表程序
super_block结构:代表文件系统
inode结构:代表管道,文件,或者Socket套接字
file结构:代表打开的文件
sk_buff结构:代表网络缓冲区(包)
net_device结构:代表网络设备
kern_ipc_perm结构:代表Semaphore信号,共享内存段,或者消息队列
msg_msg:代表单个的消息
Linux安全模块(LSM)提供了两类对安全钩子函数的调用:一类管理内核对象的
安全域,另一类仲裁对这些内核对象的访问。对安全钩子函数的调用通过钩子来
实现,钩子是全局表security_ops中的函数指针,这个全局表的类型是
security_operations结构,这个结构定义在include/linux/security.h这个头
文件中。
LSM接口的核心是security_ops,当系统启动时,他们被初始化为传统的DAC策略
。传统DAC访问控制是指控制系统中的主体(如进程)对系统中的客体(如文件
目录、文件)的访问(读、写和执行等)。自主访问控制DAC 是指主体(进程,
用户)对客体(文件、目录、特殊设备文件、IPC等)的访问权限是由客体的属
主或超级用户决定的,而且此权限一旦确定,将作为以后判断主体对客体是否有
访问权限的依据。
在加载安全模块时,我们必需先对模块进行注册,我们可以使用
register_security()函数向LSM注册一个安全模块。在我们的模块被加载成
功后,就可以进行访问控制操作。如果此时还有一个安全模块要使用
register_security()函数进行加载,则会出现错误,直到使用
unregister_security()函数向框架注销后,下一个模块才可以载入。当然LS
M还提供了mod_reg_security()函数和mod_unreg_security()函数,可以连续注
册多个安全模块。如果有其他后来的模块需要载入,可以通过mod_reg_security
()向第一个模块注册,形成支持不同策略的模块栈。
注:以上出现的函数均基于2.6.22以前的版本,对于后续的版本,出现了
register_security()函数未被导出或者取消掉了unregister_security()函数。
LSM执行过程:
根据下图的执行步骤:用户在执行系统调用时,先通过原有的内核接口依次执行
功能性的错误检查,接着进行传统的DAC检查,并在即将访问内核的内部对象之
前,通过LSM钩子函数调用LSM。LSM再调用具体的访问控制策略来决定访问的合
法性。图三显示了LSM钩子的调用:
图三:基于LSM的内核对象访问过程
Lilinux安全模块(LSM)主要支持"限制型"的访问控制决策:当Linux内核授予
文件或目录访问权限时,Linux安全模块(LSM)可能会拒绝,而当 Linux内核拒
绝访问时,可以跳过LSM。
========
使用LSM实现自己的访问控制
首先对LSM 进行简单介绍。虽然linux下的各位基本都知道一些,但是还要罗嗦
一下。
LSM中文全称是linux安全模块。英文全称:linux security mole.
LSM是一种轻量级、通用的访问控制框架,适合多种访问控制模型以内核模块的
形式实现。其特点是通用、简单、高效、支持POSIX。1e能力机制。
LSM的架构图如下:
通过系统调用进入内核之后,系统首先进行传统的权限检查(传统权限检查主要
是基于用户的,用户通过验证之后就可以访问资源),通过之后才会进行强制访
问控制。(强制访问控制是不允许主体干涉的一种访问控制,其采用安全标识、
信息分级等信息敏感性进行访问控制。并且通过比较主体的级别和资源的敏感性
来确定是否允许访问。比如说系统设置A用户不允许访问文件B,即便A是文件B的
所有者,访问也是受限制的。)从图上看来,LSM实现访问控制主要通过安全模
块的钩子函数实现。
LSM框架主要由五部分组成:这个网上资料很多。
在关键的特定内核数据结构中加入了安全域;
在内核源码中不同的关键点处插入对安全钩子函数的调用;
提供了一个通用的安全系统调用;
提供了注册和注销函数,使得访问控制策略可以以内核模块方式实现;
将capabilities逻辑的大部分功能移植为一个可选的安全模块。
我们这里重点结合源码对LSM框架进行解释。我使用的源码是3.5.4
首先介绍安全域字段,它是一个空类型的指针,在内核中的很多内核结构中都存
在,比如inode、superblock、dentry、file等等。类型字段为void *
security;
那么安全域怎么和安全模块中的信息关联起来?
当安全模块加载之后,安全域中的指针便指向安全模块中的安全信息。这里以
selinux为例进行介绍。
内核里面security/selinux/include/objsec.h中定义了不同对象的安全信息,
格式为XXX_security_strut.
上面的文件的安全信息里面包含打开文件描述符时的安全ID、文件所有者的安全
ID等等。
要联系安全模块中安全信息和安全域需要几个控制钩子函数。这些钩子函数实现
了对内核关键信息的设置和管理。这里主要介绍alloc_security、
free_security。
selinux里面通过实现安全信息空间分配实现关联。比如以文件安全信息为例
这里分配空间成功之后,通过file->f_security = fsec实现了关联。
撤销关联是在安全模块卸载之后调用file_free_security.
这里具体通过设置file->f_secrity为NULL,然后释放安全信息结构实现。
现在来看看内核如何实现selinux的访问控制。这里主要就是实现LSM里面的钩子
函数了。LSM里面给出了结构体security_operations,里面给出了很多钩子函数
,实现了相关钩子函数就可以实现访问控制了。
上面的函数就实现了file_permission钩子函数。可以看下inode结构体的获得,
感受内核是通过文件->目录项->inode。该函数主要实现自己的访问控制策略就
OK 了。
哪selinux来说,在获得文件安全ID之后,主要对掩码和文件打开时相关的安全
信息进行检测,符合就通过访问控制。
selinux基本实现了LSM里面的所有钩子函数,待钩子函数实现后,对LSM里面钩
子域进行填充就OK了。
做完以上这些还需要注册安全模块到LSM,这里注册和注销使用了
register_security和unregister_security。
比如selinux在注册时使用语句register_security(&selinux_ops)实现。
接下来通过上面的分析我们可以实现简单的基于LSM的访问控制。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mole.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/namei.h>
static int lsm_test_file_permission(struct file *file,int mask)
{
int path=0;
struct file *filp;
struct nameidata nd;
path = path_lookup(FILENAME,LOOKUP_FOLLOW,&nd);
if(!mask)
return 0;
if(path)
{
printk("lookup file failed!\n");
return -1;
}
filp = filp_open("/home/yuyunchao/code/sb.c",O_RDONLY,0);
{
printk("open failed!\n");
}
return 0;
}
static struct security_operations lsm_test_security_ops = {
.file_permission = lsm_test_file_permission,
};
static int __init lsm_file_init(void)
{
if(register_security(&lsm_test_security_ops)){
printk("register error ..........\n");
return -1;
}
printk("lsm_file init..\n ");
return 0;
}
static void __exit lsm_file_exit(void)
{
if(unregister_security(&lsm_test_security_ops)){
printk("unregister error................\n");
return ;
}
printk("mole exit.......\n");
}
MODULE_LICENSE("GPL");
mole_init(lsm_file_init);
mole_exit(lsm_file_exit);
========
LSM(Linux Security Mole)应用方法(简单例子)
LSM在内核中很多地方已经插入了hook函数,并且在security.c函数中声明了
security_ops结构,要实现你自己的安全模块,只需要定义你自己的struct
security_operations,并且用register_security注册即可,下面举个简单例子
:
test.c代码如下:
/*
* Test Linux Security Mole
*
* Author: penghuan <[email protected]>
*
* Copyright (C) 2010 UbuntuKylin, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
*/
#include <linux/security.h>
#include <linux/sysctl.h>
#include <linux/ptrace.h>
#include <linux/prctl.h>
#include <linux/ratelimit.h>
#include <linux/workqueue.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/dcache.h>
#include <linux/path.h>
int test_file_permission(struct file *file, int mask)
{
char *name = file->f_path.dentry->d_name.name;
if(!strcmp(name, "test.txt"))
{
file->f_flags |= O_RDONLY;
printk("you can have your control code here!\n");
}
return 0;
}
static struct security_operations test_security_ops = {
.name = "test",
.file_permission = test_file_permission,
};
static __init int test_init(void)
{
printk("enter test init!\n");
printk(KERN_INFO "Test: becoming......\n")
if (register_security(&test_security_ops))
panic("Test: kernel registration failed.\n");
return 0;
}
security_initcall(test_init);
将该文件以模块的形式放到security/下编译进内核,启用新的内核后,当你操
作文件test.txt时,通过dmesg命令就能再终端看到”you can have your
control code here!“输出
所以一般的做法是:定义你自己的struct security_operations,实现你自己的
hook函数,具体有哪些hook函数可以查询include/linux/security.h文件,然后
调用register_security来用你的test_security_ops初始化全局的security_ops
指针
楼主,我刚开始研究LSM,但网上资料太少,您这个代码,我编译成ko文件老是
有警告,并且insmod时,说Unknown symbol register_security。我最近看了看
内核模块变成,没有对内核进行太深入的了解。不知能否把LSM的实验步骤给出
的再详细点,谢谢。
你需要把代码编进内核
是需要把那段源码拷到内核目录下,然后重新编译内核?。。没有不编译内核的
方法吗?。。直接按照模块进行编译。另外那个test.txt放在哪个文件夹里?。
是需要把那段源码拷到内核目录下,然后重新编译内核?。。没有不编译内核的
方法吗?。。直接按照模块进行 ...
是的,你去网上找下怎么把模块编进内核,lsm模块不能以模块方式加载,涉及
安全;test.txt是测试文件,当你把代码编进内核后,用新内核启动,然后操作
test.txt文件,就会有输出,test.txt随便放哪里
楼主,您好,我刚开始学习lsm模块,把您的模块编译进内核,新的内核加载后
,register_security总是失败,请问下可能是什么原因导致的。我的内核版本
是3.13.11。
register_security的返回值是-11
========
LSM在Linux中的实现方式
LSM(Linux Secure Model)一种轻量级访问控制机制.
其实现方式有如在系统调用中加入一个后门....
方式如下:
static struct file *__dentry_open(struct dentry *dentry, struct
vfsmount *mnt,
struct file *f,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
{
struct inode *inode;
int error;
...............................................................
error = security_dentry_open(f, cred); //LSM机制实现方式,在此加入了
一个LSM函数.
//security_dentry_open的实现如下,相当于一个接口,对一个函数指针再
//封装一下.
//只返回是与否,这样的控制信息.
if (error)
goto cleanup_all;
................................................................
return f;
cleanup_all:
.................................................................
return ERR_PTR(error);
}
//========简单封装一个指针结构体===========================
int security_dentry_open(struct file *file, const struct cred *cred)
{
int ret;
ret = security_ops->dentry_open(file, cred);
if (ret)
return ret;
return fsnotify_perm(file, MAY_OPEN);
}
========
利用LSM实现更安全的linux
LSM的全称是Linux Security Moles,它是linux内核中用来支持更灵活的
安全策略的一个底层框架,虽然听起来比较复杂,但是可以就把它理解成一组安
插在linux内核的钩子函数和一些预留的被称为安全域的数据结构,下面先说说
这个框架的由来吧。
linux本身的机制就保证了linux拥有更好的安全机制,但是在这个机制下面
,还是隐藏了许多的问题:
1、权限粒度太大。用过linux的人应该对0644这样的访问权限设置不陌生,
它对能够操作这个文件的用户做了限制,但是这个只是限制到了组,而没有更进
一步的细分,当然,如果LSM只是用来限制这个的话,那么也就太没意思了,因
为实现文件更细的控制粒度,ACL就能够很出色的完成,顺便提一下,ACL有一个
分配的限制,如果哪位朋友需要用ACL进行粒度更细的访问权限控制的话,可能
需要注意一下这方面的东西。
2、root用户的权限太大。在linux中,root用户就是至高无上的,他拥有对
机器的完全控制权限,可以做他想做的一切事情。但是很多时候,我们可能并不
希望有root有这么大的权限,比如在现在比较流行的云存储中,用户肯定不希望
服务提供商能够随意访问我们的文件,那么这个时候,就需要对root用户进行一
定的设置了。
由于这些问题的存在,所以出现了像SE Linux(Securiy Enhanced Linux )
这样的增强补丁。但是每个系统对于具体安全细节的控制不尽相同, 所以Linus
Tovalds 提出应该要有一个 Linux 内核所能接受的安全框架来支持这些安全策
略,这个安全框架应该提供包含内核数据结构中的透明安全域以及用来控制、维
护安全域操作的安全钩子,于是就有了LSM。
LSM在内核中的位置,可以用下图来表示:
当用户态程序调用某些操作系统提供的函数的时候,比如read()函数,其会
对应于内核中的一个系统调用,然后该首先会进行一些常规的错误检测,接着进
行DAC(Discretionary Access Control)检测,再接着它会进行LSM检测。从上
图中能够看出来,LSM其实是一个非常底层的安全策略框架,利用LSM,可以接管
所有的系统调用,这样,我们就能对包括root在内的所有用户的权限进行控制,
并且实现粒度更细的访问权限控制。
当系统初始化的时候,LSM就是一个空的框架,它不提供任何的检测,其所
做的全部工作几乎就是返回0,当然,有些不带返回值的函数除外。而我们则可
以针对自己特定的需求来编写LSM,然后将我们编写的LSM钩子函数,通过其数据
结构struct security_operations注册到系统中去,这样,我们的LSM检测就开
始起作用了。
更多信息可参考《Linux就该这么学》
⑼ Gitlab+Jenkins通过钩子实现自动部署web项目,图文详细教程
扩展参考:Jenkins+Gitlab通过脚本自动部署回滚web项目至集群
1):Gitlab服务器:ubuntu 192.168.152.131 ---参考搭建:Linux安装gitlab,docker安装gitlab教程
2):Jenkins服务器:ubunu 192.168.152.130 ---参考搭建:linux安装Jenkins,或docker安装Jenkins教程
在服务器上生成ssh-keygen,用于配置web服务器和Gitlab服务器。
3):web服务器:centos 192.168.152.150 ---已搭建好LNMP环境
4):开发者电脑:Windows+key密钥 (用于提交代码)
1:在gitlab创建项目Test Project
2.1): 配置一个开发者电脑的ssh公钥到gitlab
配置一个开发者电脑的ssh公钥到gitlab,这样才能模拟开发上传代码到gitlab。
windows生成key过程及git安装,可参考:Windows下git和github的使用图文详细教程_the丶only的博客-CSDN博客_github win
在windows测试clone,和提交代码。
注:最新版git 已经将默认分支master改为main了。所以看到main,而不是master不要太奇怪
测试成功,在gitlab也显示有index.html文件。
2.2): 配置jenkins公钥到gitlab
同理,同样需要jenkins公钥,因为jenkins也需要拉去gitlab的代码。
在 jenkins服务器 上查看公钥并复制添加到gitlab,并命名为jekins。
1:插件管理,安装插件
jenkins本身没什么功能,主要是依靠插件来实现各种强大的功能。
基本需要添加的插件:Gitlab Hook、Build Authorization Token Root、Publish Over SSH、Gitlab Authentication、Gitlab、Git Parameter
可以在 Manage Jenkins >> Manage Plugins 查看管理插件。在Available 选项搜索安装插件即可。
安装完成后,重启Jenkins。
2:添加需要部署的web主机
在 Manage Jenkins >> Configure System 中往下翻,找到 Publish over SSH 选项,点击add ssh server。
在Jenkins服务器上,查看私钥,注,是私钥,不是公钥。
将私钥填写在key位置,还有添加web服务器相关信息。
注:如果测试报错如下
Failed to connect or change directory
jenkins.plugins.publish_over.BapPublisherException: Failed to add SSH key. Message [invalid privatekey: [B@2e54414f]
是因为默认用ssh-keygen命令,默认生成了OPENSSH 格式密钥。而Jenkins暂时不支持这种私钥,私钥开头结尾如下:
所以,需要生成rsa密钥格式的。用开头说的ssh-keygen加其他参数生成即可。
私钥开头结尾如下:
再次测试,显示success,则成功。然后点击save保存即可。
3:构建任务项目
首页创建任务或者一个项目
命名为web-project,选择为freestyle project 自由项目。然后ok确认。
3.1):源码管理 Source Code Management
选择源码管理,添加gitlab的项目clone地址。
注:最后路径选择分支,我gitlab主分支名字为main,如果是master,则写master,或者合并的其他分支。
在add添加用户
添加完成后,选择git用户,这时没有红色提醒,说明已成功连接
3.2):构建触发器 Build Triggers
现在Build Triggers,勾选build when....,其他默认,并记下链接 http://192.168.152.130:8080/project/web-project
点击高级 advance 选项。
勾选filter branches regex选择,填写分支,生产token。其他默认
3.3):构建 Build
选择Build 选项。选择ssh
添加web服务器
添加完毕,最后save保存。
1:添加钩子webhooks.
选择自己的项目Test Project,在设置setting里,选择钩子webhooks.
填写刚才记下的http://192.168.152.130:8080/project/web-project和token值。
最后Add webhook完成:
2:如添加失败,报错,更改Network
注:如填写失败提示Url is blocked: Requests to the local network are not allowed
还需更改Network选项。
3:测试钩子
添加完成后,下面会出现钩子选择。点击test中的,push event。
出现successful,即添加成功。
在Jenkins也可以看到刚才的测试时间信息。
在开发电脑上测试提交,我这里为Windows电脑测试。
打开Git Bash,输入以下命令:
提交成功,回到Jenkins,查看是否构建成功:
绿色显示构建成功,无错误显示。回到gitlab查看项目。
时间显示刚才也提交成功,无错误。最后在浏览器输入web地址测试,本人配置了web访问端口8082。所以输入IP加端口访问。
内容也已经自动更新成功。
完结撒花!!!