
一、前言一直跟Linux打交道,但是凡事多扰,一直未专门针对系统安全做过针对性总结,基于此,本文将记录总结一些Linux 安全配置过程中的常用实践,最后梳理成为安全最佳实践。Linux以其稳定,高并发,甚至免费等特点,经过多年的应用发展,如今,互联网很多的应用已在 Linux 操作系统上使用,国内BAT等互联网巨头也已建设成千上万台服务器,分布全国的数据及灾备中心,95%以上使用的都是Linux系统。而随着Linux大规模的应用带来的安全问题也越来越多,下面是一些给安全人员带来巨大挑战的知名漏洞:Struts2 远程代码执行漏洞通告(CVE-2017-5638);Linux 内核提权漏洞(Dirty Cow) (CVE-2016-5195);ElasticSearch 远程执行代码安全漏洞(CVE-2014-3120);Bash 远程执行命令漏洞(Bash破壳) (CVE-2014-6271);Nginx 远程执行代码安全漏洞(CVE-2014-0088);MongoDB 匿名登录漏洞;心脏流血漏洞;Linux内核漏洞:“Phoenix Talon”(高危:CVE-2017-8890、CVE-2017-9075、CVE-2017-9076、CVE-2017-9077,影响几乎所有Linux kernel 2.5.69 - Linux kernel 4.11的内核版本,Linux 4.12-rc1中被修复);二、防火墙配置Linux防火墙是由Netfilter组件/安全框架提供的,Netfilter工作在内核空间,Netfilter是Linux操作系统核心层内部的一个数据包处理模块,集成在linux内核中,Netfilter 是Linux2.4.x之后集成进的新一代的Linux防火墙机制,是linux内核的一个子系统。Netfilter采用模块化设计,具有良好的可扩充性,可提供扩展各种网络服务的结构化底层框架。Netfilter与IP协议栈可无缝契合,允许对数据报进行过滤、地址转换、处理等操作,而Linux终端通过软件包iptables提供的命令行工具,工作在用户空间,用来与用户交互已管理编写规则,之后这些规则被送往netfilter,告诉内核如何去处理通过Netfilter信息包,更多参看Netfilter官网文档;在Linux 7 版开始引入了新的前端管理工具,即firewall,程序包:firewalld和firewalld-config,命令行工具:firewall-cmd 命令行工具和firewall-config 图形工具;CentOS 8 中,引入Nftables;它在2013年末合并到Linux内核中,自2014年以来已在内核3.13中可用。它重用了netfilter框架的许多部分,例如连接跟踪和NAT功能。它还保留了命名法和基本iptables设计的几个部分,例如表,链和规则。就像iptables一样,表充当链的容器,并且链包含单独的规则,这些规则可以执行操作,例如丢弃数据包,移至下一个规则或跳至新链。nftables添加了一个名为nft的新工具,该工具替代了iptables,arptables和ebtables中的所有其他工具。从体系结构的角度来看,它还替换了内核中处理数据包过滤规则集运行时评估的那些部分。检查:rpm -qi nftables;systemctl status nftables.service ;因此,centos8中支持3种防火墙: iptables、firewalld和nftables。Netfilter在内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING),而这五个hook function向用户开放,用户可以通过一个命令工具(iptables)向其写入规则,由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则被分组放在链(chain)上;从 Linux kernel 4.2 版以后,Netfilter 在prerouting 前加了一个 ingress 勾子函数。可以使用这个新的入口挂钩来过滤来自第2层的流量,这个新挂钩比预路由要早,基本上是 tc 命令(流量控制工具)的替代品。防火墙按网络协议可划分为:网络层防火墙:OSI模型下四层,又称为包过滤防火墙应用层防火墙/代理服务器:代理网关,OSI模型七层2.1、包过滤防火墙Iptables● Linux 防火墙的过滤框架:● iptables四表:filter(实现实现数据过滤,内核模块:iptables_filter):三个链:INPUT,OUTPUT,FORWARDnat (实现实现网络地址转换,三个链,内核模块:iptable_nat):PREROUTING,OUTPUT,POSTROUTINGmangle(为数据打标记,五个链,修改数据包的服务类型、TTL、并且可以配置路由实现QOS;内核模块:iptable_mangle):INPUT,FORWARD,OUTPUT,PREROUTING,POSTROUTING;拆解报文 做出修改 并重新封装raw(数据跟踪的,两个链)PREROUTING,OUTPUT;关闭nat表上启用的连接追踪机制,决定数据包是否被状态跟踪机制处理1)添加规则iptables-A链名-p协议--dport端口号-jACCEPT //端口对外开放 iptables-A链名-p协议--dport端口号-jDROP //拒绝端口对外开放 iptables-A链名-p协议--dport端口号-jREJECT //拒绝端口对外开放,响应时间短 iptables-A链名-sIP/网段-p协议--dport端口号-jACCEPT //开放固定IP或者网段对端口的访问权限#修改规则iptables-RINPUT7-d192.168.10.1-picmp --icmp-type0-jACCEPT#修改规则7可ping2)查看规则iptables[-t filter]-NV[chain_name]--line-number //查看指定链规则信息,不写链名查看全部规则参数说明:-t:指定包经过安全过滤器要匹配的规则集/链表;filter默认可忽略,nat,mangle,raw,security(用于强制访问控制(MAC)网络规则;强制访问控制由Linux安全模块(如SELinux)实现。安全表被调用在筛选表之后,允许筛选表中的任意任意访问控制(DAC)规则在MAC之前生效规则。该表提供了以下内置链:INPUT(用于进入盒子本身的数据包)、OUTPUT(用于更改路由之前本地生成的分组)和FORWARD(用于改变通过盒子路由的分组)。)-A(append):在规则链末尾追加安全规则;-C(check):检查所选链中是否存在与规范匹配的规则。-R(replace):替换指定规则链中的某条规则,需指定规则号,从1开始;-Z(zero):置零指定规则链里规则中记录的包和字节数-N(new-chain):用户自定义新的规则链-X(delete-chain):删除规则链,前提该链中的规则需空,且不能被其他规则链引用-P(policy):对内建规则链配置策略规则-E:重命名规则链-m(match):一条规则先匹配match规则,如果匹配再匹配后面的参数,否则阻断-g(goto):定义跳转到继续处理的其他规则链-I:选项添加的防火墙规则则会默认插入到链中作为第一条规则使用“!”可以将条件取反3)删除规则iptables-F[chain_name]//清空指定链规则,链名不写则清空所有链规则 iptables[-t filter]-X[chain_name]//不写链名时,则清空指定表下自定义链,默认filter表,删除前需要清空规则 iptables-DINPUT34)规则导出导入iptables-save/opt/iptables //保存至指定路径 后期可以使用保存文件恢复配置信息 iptables-restore/opt/iptables //使用保存文件恢复配置信息#持久保存规则#CentOS 7,8iptables-save/PATH/TO/SOME_RULES_FILE#CentOS 6,将规则覆盖保存至/etc/sysconfig/iptables文件中serviceiptables save yuminstalliptables-services5)修改配置文件vi/etc/sysconfig/iptables#如下所示-AINPUT-mstate--stateRELATED,ESTABLISHED-jACCEPT-AINPUT-picmp-jACCEPT-AINPUT-ilo-jACCEPT-AINPUT-ptcp-mstate--stateNEW-mtcp--dport22-jACCEPT-AINPUT-mstate –state NEW-mtcp-ptcp –dport80-jACCEPT //允许80端口通过防火墙-AINPUT-mstate –state NEW-mtcp-ptcp –dport3306-jACCEPT //允许3306端口通过防火墙-AINPUT-mstate –state NEW-mtcp-ptcp –dport21-jACCEPT //允许21端口通过防火墙-AINPUT-mstate--stateNEW-mtcp-ptcp--dport80-jACCEPT-AINPUT-mstate--stateNEW-mtcp-ptcp--dport3306-jACCEPT-AINPUT-mstate--stateNEW-mtcp-ptcp--dport21-jACCEPT-AINPUT-mstate--stateNEW-mtcp-ptcp--dport443-jACCEPT-AINPUT-jREJECT --reject-with icmp-host-prohibited-AFORWARD-jREJECT --reject-with icmp-host-prohibited-AINPUT-mstate--stateESTABLISHED,RELATED-jACCEPT//允许所有已建立连接的、RELATED主动建立连接的 流量通过防火墙INPUT链,进允许进入;注意:iptables内有个名称为ip_conntrack_ftp的helper,可以针对连入与连外目的 port为21 的 ftp协定命令沟通进行拦截,执行modprobe ip_conntrack_ftpports=21,30000,就是允许ftp服务分别在port21与30000上,让ip_conntrack_ftp 这个ftp helper 能够正常提供ftp用户端使用passive mode存取而不会产生问题。#临时加载modprobe ip_tables modprobe iptable_filter modprobe iptable_nat modprobe ip_conntrack modprobe ip_conntrack_ftp modprobe ip_nat_ftp modprobe ipt_state#永久加载cat/etc/rc.localEOF modprobe ip_tables modprobe iptable_filter modprobe iptable_nat modprobe ip_conntrack modprobe ip_conntrack_ftp modprobe ip_nat_ftp modprobe ipt_state EOFlsmod|egrep'filter|nat|ipt'cat/etc/sysctl.conf net.ipv4.icmp_echo_ignore_all=1sysctl-p# 刷新6)iptables 模块1、multiport 多端口管理:-m multiport、–sports port1,port2,port3、–dports port1,port2,port3iptables-IINPUT-s192.168.10.1-d192.168.10.3-ptcp-mmultiport--dports446,6379,22-jACCEPT2、iprange使用:-m iprange --src-range IP1[-IP2](连续写多个连续的源ip) --dst-range IP1[-IP2](连续写多个连续的目的ip)iptables-AINPUT-miprange --src-range192.168.1.1-192.168.1.10-d192.168.10.1-10-ptcp--dport80-jACCEPT3、state 状态:用与参考连接的状态进行数据过滤-m state --state 状态 决定什么样状态接收,什么样状态拒绝,比如有些常用服务,ssh,ftp等,根据端口放行比较麻烦,使用-m state --state模块就简单很多,state状态:NEW状态:针对某个服务的首次访问,已经或将启动新的连接ESTABLISHED状态:已建立的连接,1、某服务的后续所有访问状态;2、表示服务器的响应数据;这样就不用每条都写OUTPUT的规则了,有一条ESTABLISHED就能全部能出去(响应)OUTPUTRELATED状态:相关联的连接,正在启动的新连接,给ftp用的。比如ftp服务器,只有命令连接完成,才能进行建立数据连接INVALID状态:无效的连接,非法或无法识别的iptables-IOUTPUT-s192.168.10.1-mstate--stateESTABLISHED-jACCEPT iptables-IINPUT-d192.168.10.3-ptcp--dport80-mstate--stateNEW,ESTABLISHED-jACCEPT#保证首次访问和后续的所有访问都可以正常iptables-IINPUT-d192.168.10.3-ptcp--dport22-mstate--stateNEW,ESTABLISHED-jACCEPT7)最佳实践注意:1.修改之前先导出备份一份2.修改的时候小心别把自己关在外面3.可以现在定时任务里添加一条定时清空的规则,等测试没问题再取消定时任务4、注意iptables -F不会对默认规则生效,当默认规则设置了拒绝所有,又执行了清除规则的语句-F那就意味着,所有的请求全部都拒绝了,务必小心;可在测试规则之前,先写个定时任务,每隔5分钟重启一次iptables#设置默认的 chain 策略iptables-PINPUT DROP iptables-PFORWARD DROP iptables-POUTPUT DROP iptables-IINPUT-picmp-jREJECT //禁ping iptables-AFORWARD-p!icmp-jACCEPT //转发除ICMP协议以外的所有数据包 iptables-AFORWARD-s192.168.1.11-jREJECT iptables-AFORWARD-s192.168.2.0/24-jACCEPT //拒绝转发来自192.168.1.11主机的数据,允许转发来自192.168.2.0/24网段的数据 iptables-AINPUT-ieth1-s192.168.0.0/16-jDROP iptables-AINPUT-ieth1-s172.16.0.0/12-jDROP iptables-AINPUT-ieth1-s10.0.0.0/8-jDROP //丢弃从外网接口(eth1)进入防火墙本机的源地址为私网地址的数据包 iptables-IINPUT-s10.20.30.0/24-jDROP iptables-IFORWARD-s10.20.30.0/24-jDROP //封堵网段(192.168.1.0/24) at now2hours atiptables-DINPUT1atiptables-DFORWARD1//两小时后解封 iptables-AINPUT-ptcp--dport22-s179.1.0/16-jACCEPT //只允许管理员从179.1.0.0/16使用SSH远程登录防火墙主机 iptables-AINPUT-ptcp--dport22-jDROP iptables-AINPUT-ptcp--dport20:1024-jACCEPT //允许本机开放从TCP端口20-1024提供的应用服务,分别加INPUT和OUTPUT2条 iptables-AOUTPUT-ptcp--sport20:1024-jACCEPT iptables-AFORWARD-s192.168.0.0/24-pudp--dport53-jACCEPT //允许转发来自192.168.0.0/24局域网段的DNS解析请求数据包 iptables-AFORWARD-d192.168.0.0/24-pudp--sport53-jACCEPT iptables-IINPUT-picmp --icmp-type Echo-Request-jDROP //禁止外部主机ping本网 iptables-IINPUT-picmp --icmp-type Echo-Reply-jACCEPT iptables-IINPUT-picmp --icmp-type destination-Unreachable-jACCEPT iptables-AFORWARD-mmac --mac-source 00:0c:29:27:55:3F-jDROP //使用“-m mac –mac-source”来表示数据包的源MAC地址 iptables-AINPUT-ptcp-mmultiport--dport20,21,25,110,1250:1280-jACCEPT //开放本机多个端口,用“-m multiport –dport”来指定目的端口及范围 iptables-AFORWARD-ptcp-miprange --src-range192.168.1.20-192.168.1.99-jDROP //禁止转发源IP地址为192.168.1.20-192.168.1.99的TCP数据包 iptables-AFORWARD-mstate--stateNEW-ptcp!--syn-jDROP //禁止转发与正常TCP连接无关的非syn请求数据包,“-m state”表示数据包的连接状态,“NEW”表示与任何连接无关的,后续新的 iptables-AINPUT-ptcp-mstate--stateNEW-jDROP iptables-AINPUT-ptcp-mstate--stateESTABLISHED,RELATED-jACCEPT //拒绝访问防火墙的新数据包,但允许响应连接或与已有连接相关的数据包,“ESTABLISHED”表示已经响应请求或者已经建立连接的数据包,“RELATED”表示与已建立的连接有相关性的,比如FTP数据连接等 iptables-IINPUT-ptcp-mmultiport--dport20,21,80-jACCEPT //非连续多端口 iptables-IINPUT-d192.168.2.100-ptcp-mmultiport--dport22,80-jACCEPT iptables-IINPUT-ptcp--dport20450:20480-jACCEPT iptables-IINPUT-ptcp-mstate--stateESTABLISHED-jACCEPT //放行外部主机发往本机的应答数据包 iptables-PINPUT DROP iptables-AINPUT-s“$BLOCK_THIS_IP”-jDROP //阻止某个特定的 IP 地址,配置文件里写BLOCK_THIS_IP=“x.x.x.x”#允许全部进来的(incoming)SSHiptables-AINPUT-ieth0-ptcp--dport22-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AOUTPUT-oeth0-ptcp--sport22-mstate--stateESTABLISHED-jACCEPT#只允许某个特定网络来SSHiptables-AINPUT-ieth0-ptcp-s192.168.10.0/24--dport22-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AOUTPUT-oeth0-ptcp--sport22-mstate--stateESTABLISHED-jACCEPT#允许进来的(incoming)HTTPiptables-AINPUT-ieth0-ptcp--dport80-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AOUTPUT-oeth0-ptcp--sport80-mstate--stateESTABLISHED-jACCEPT#允许进来的 SSH、HTTP 和 HTTPSiptables-AINPUT-ieth0-ptcp-mmultiport--dports22,80,443-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AOUTPUT-oeth0-ptcp-mmultiport--sports22,80,443-mstate--stateESTABLISHED-jACCEPT#允许出去的(outgoing)SSHiptables-AOUTPUT-oeth0-ptcp--dport22-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AINPUT-ieth0-ptcp--sport22-mstate--stateESTABLISHED-jACCEPT#除192.168.2.100的22端口能访问外,其他端口都禁止访问iptables-IINPUT-d192.168.2.100-ptcp!--dport22-jREJECT#允许外出的(outgoing)SSH,但仅可访问某个特定的网络iptables-AOUTPUT-oeth0-ptcp-d192.168.10.0/24--dport22-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AINPUT-ieth0-ptcp--sport22-mstate--stateESTABLISHED-jACCEPT#允许外出的(outgoing) HTTPSiptables-AOUTPUT-oeth0-ptcp--dport443-mstate--stateNEW,ESTABLISHED-jACCEPT iptables-AINPUT-ieth0-ptcp--sport443-mstate--stateESTABLISHED-jACCEPT#对HTTPS 流量做负载均衡iptables-APREROUTING-ieth0-ptcp--dport443-mstate--stateNEW-mnth--counter0--every3--packet0-jDNAT --to-destination192.168.1.101:443 iptables-APREROUTING-ieth0-ptcp--dport443-mstate--stateNEW-mnth--counter0--every3--packet1