1.账户管理和认证授权
- 禁用Guest账户。
- 禁用或删除其他无用账户(建议先禁用账户三个月,待确认没有问题后删除。)
操作步骤
打开控制面板>管理工具>计算机管理,在系统工具>本地用户和组>用户中,双击Guest帐户,在属性中选中帐户已禁用,单击确定。
按照用户分配帐户。根据业务要求,设定不同的用户和用户组。例如,管理员用户,数据库用户,审计用户,来宾用户等。
操作步骤
打开控制面板>管理工具>计算机管理,在系统工具>本地用户和组中,根据您的业务要求设定不同的用户和用户组,包括管理员用户、数据库用户、审计用户、来宾用户等。
定期删除或锁定与设备运行、维护等与工作无关的帐户。
操作步骤
打开控制面板>管理工具>计算机管理,在系统工具>本地用户和组中,删除或锁定与设备运行、维护等与工作无关的帐户。
配置登录登出后,不显示用户名称。
操作步骤:
打开控制面板>管理工具>本地安全策略,在本地策略>安全选项中,双击交互式登录:不显示最后的用户名,选择已启用并单击确定。
1.2口令
密码复杂度要求必须满足以下策略:
- 最短密码长度要求八个字符。
- 启用本机组策略中密码必须符合复杂性要求的策略。
即密码至少包含以下四种类别的字符中的两种:- 英语大写字母A,B,C,…Z
- 英语小写字母a,b,c,…z
- 西方阿拉伯数字0,1,2,…9
- 非字母数字字符,如标点符号,@,#,$,%,&,*等
操作步骤
打开控制面板>管理工具>本地安全策略,在帐户策略>密码策略中,确认密码必须符合复杂性要求策略已启用。
对于采用静态口令认证技术的设备,帐户口令的留存期不应长于90天。
操作步骤打开控制面板>管理工具>本地安全策略,在帐户策略>密码策略中,配置密码最长使用期限不大于90天。
帐户锁定策略
对于采用静态口令认证技术的设备,应配置当用户连续认证失败次数超过10次后,锁定该用户使用的帐户。
操作步骤
打开控制面板>管理工具>本地安全策略,在帐户策略>帐户锁定策略中,配置帐户锁定阈值不大于10次。
配置样例:
在本地安全设置中,从远端系统强制关机权限只分配给Administrators组。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>用户权限分配中,配置从远端系统强制关机权限只分配给Administrators组。
在本地安全设置中关闭系统权限只分配给Administrators组。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>用户权限分配中,配置关闭系统权限只分配给Administrators组。
在本地安全设置中,取得文件或其它对象的所有权权限只分配给Administrators组。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>用户权限分配中,配置取得文件或其它对象的所有权权限只分配给Administrators组。
在本地安全设置中,配置指定授权用户允许本地登录此计算机。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>用户权限分配中,配置允许本地登录权限给指定授权用户。
在本地安全设置中,只允许授权帐号从网络访问(包括网络共享等,但不包括终端服务)此计算机。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>用户权限分配中,配置从网络访问此计算机权限给指定授权用户。
设备应配置日志功能,对用户登录进行记录。记录内容包括用户登录使用的帐户、登录是否成功、登录时间、以及远程登录时、及用户使用的IP地址。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核登录事件。
启用本地安全策略中对Windows系统的审核策略更改,成功和失败操作都需要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核策略更改。
启用本地安全策略中对Windows系统的审核对象访问,成功和失败操作都需要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核对象访问。
启用本地安全策略中对Windows系统的审核目录服务访问,仅需要审核失败操作。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核目录服务器访问。
启用本地安全策略中对Windows系统的审核特权使用,成功和失败操作都需要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核特权使用。
启用本地安全策略中对Windows系统的审核系统事件,成功和失败操作都需要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核系统事件。
启用本地安全策略中对Windows系统的审核帐户管理,成功和失败操作都要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核帐户管理。
启用本地安全策略中对Windows系统的审核进程追踪,仅失败操作需要审核。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>审核策略中,设置审核进程追踪。
设置应用日志文件大小至少为8192KB,可根据磁盘空间配置日志文件大小,记录的日志越多越好。并设置当达到最大的日志尺寸时,按需要轮询记录日志。
操作步骤
打开控制面板>管理工具>事件查看器,配置应用日志、系统日志、安全日志属性中的日志大小,以及设置当达到最大的日志尺寸时的相应策略。
启用SYN攻击保护。
- 指定触发SYN洪水攻击保护所必须超过的TCP连接请求数阈值为5。
- 指定处于SYN_RCVD状态的TCP连接数的阈值为500。
- 指定处于至少已发送一次重传的SYN_RCVD状态中的TCP连接数的阈值为400。
操作步骤
打开注册表编辑器,根据推荐值修改注册表键值。
WindowsServer2012
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\SynAttackProtect
推荐值:2 - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxHalfOpen
推荐值:500
WindowsServer2008
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SynAttackProtect
推荐值:2 - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpMaxPortsExhausted
推荐值:5 - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpMaxHalfOpen
推荐值:500 - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpMaxHalfOpenRetried
推荐值:400
非域环境中,关闭Windows硬盘默认共享,例如C$,D$。
操作步骤
打开注册表编辑器,根据推荐值修改注册表键值。
注意:WindowsServer2012版本已默认关闭Windows硬盘默认共享,且没有该注册表键值。
- HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters\AutoShareServer
推荐值:0
每个共享文件夹的共享权限,只允许授权的帐户拥有共享此文件夹的权限。
操作步骤
每个共享文件夹的共享权限仅限于业务需要,不要设置成为Everyone。打开控制面板>管理工具>计算机管理,在共享文件夹中,查看每个共享文件夹的共享权限。
禁用TCP/IP上的NetBIOS协议,可以关闭监听的UDP137(netbios-ns)、UDP138(netbios-dgm)以及TCP139(netbios-ssn)端口。
操作步骤
- 在计算机管理>服务和应用程序>服务中禁用TCP/IPNetBIOSHelper服务。
- 在网络连接属性中,双击Internet协议版本4(TCP/IPv4),单击高级。在WINS页签中,进行如下设置:
禁用不必要的服务,请参考:
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>安全选项中,进行如下设置:
6.2禁用未登录前关机
服务器默认是禁止在未登录系统前关机的。如果启用此设置,服务器安全性将会大大降低,给远程连接的黑客造成可乘之机,强烈建议禁用未登录前关机功能。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>安全选项中,禁用关机:允许系统在未登录前关机策略。
Windows系统需要安装防病毒软件。
操作步骤
安装企业级防病毒软件,并开启病毒库更新及实时防御功能。
设置从屏幕保护恢复时需要输入密码,并将屏幕保护自动开启时间设定为五分钟。
操作步骤
启用屏幕保护程序,设置等待时间为5分钟,并启用在恢复时使用密码保护。
对于远程登录的帐户,设置不活动超过时间15分钟自动断开连接。
操作步骤
打开控制面板>管理工具>本地安全策略,在本地策略>安全选项中,设置Microsoft网络服务器:暂停会话前所需的空闲时间数量属性为15分钟。
安装最新的操作系统Hotfix补丁。安装补丁时,应先对服务器系统进行兼容性测试。
操作步骤
安装最新的操作系统Hotfix补丁。安装补丁时,应先对服务器系统进行兼容性测试。
注意:对于实际业务环境服务器,建议使用通知并自动下载更新,但由管理员选择是否安装更新,而不是使用自动安装更新,防止自动更新补丁对实际业务环境产生影响。
Linux操作系统加固
1. 账号和口令
减少系统无用账号,降低安全风险。
操作步骤
- 使用命令 userdel <用户名> 删除不必要的账号。
- 使用命令 passwd -l <用户名> 锁定不必要的账号。
- 使用命令 passwd -u <用户名> 解锁必要的账号。
检查是否存在空口令和root权限的账号。
操作步骤
- 查看空口令和root权限账号,确认是否存在异常账号:
- 使用命令 awk -F: '($2=="")' /etc/shadow 查看空口令账号。
- 使用命令 awk -F: '($3==0)' /etc/passwd 查看UID为零的账号。
- 加固空口令账号:
- 使用命令 passwd <用户名> 为空口令账号设定密码。
- 确认UID为零的账号只有root账号。
加强口令的复杂度等,降低被猜解的可能性。
操作步骤
- 使用命令 vi /etc/login.defs 修改配置文件。
- PASS_MAX_DAYS 90 #新建用户的密码最长使用天数
- PASS_MIN_DAYS 0 #新建用户的密码最短使用天数
- PASS_WARN_AGE 7 #新建用户的密码到期提前提醒天数
- 使用chage命令修改用户设置。
例如,chage -m 0 -M 30 -E 2000-01-01 -W 7 <用户名>表示将此用户的密码最长使用天数设为30,最短使用天数设为0,密码2000年1月1日过期,过期前七天警告用户。 - 设置连续输错三次密码,账号锁定五分钟。使用命令 vi /etc/pam.d/common-auth修改配置文件,在配置文件中添加 auth required pam_tally.so onerr=fail deny=3 unlock_time=300。
限制能su到root的用户。
操作步骤
使用命令 vi /etc/pam.d/su修改配置文件,在配置文件中添加行。例如,只允许test组用户su到root,则添加 auth required pam_wheel.so group=test。
限制root用户直接登录。
操作步骤
- 创建普通权限账号并配置密码,防止无法远程登录;
- 使用命令 vi /etc/ssh/sshd_config修改配置文件将PermitRootLogin的值改成no,并保存,然后使用service sshd restart重启服务。
关闭不必要的服务(如普通服务和xinetd服务),降低风险。
操作步骤
使用命令systemctl disable <服务名>设置服务在开机时不自动启动。
说明: 对于部分老版本的Linux操作系统(如CentOS 6),可以使用命令chkconfig --level <init级别> <服务名> off设置服务在指定init级别下开机时不自动启动。
对SSH服务进行安全加固,防止暴力破解成功。
操作步骤
使用命令 vim /etc/ssh/sshd_config 编辑配置文件。
- 不允许root账号直接登录系统。
设置 PermitRootLogin 的值为 no。 - 修改SSH使用的协议版本。
设置 Protocol 的版本为 2。 - 修改允许密码错误次数(默认6次)。
设置 MaxAuthTries 的值为 3。
配置文件修改完成后,重启sshd服务生效。
设置默认的umask值,增强安全性。
操作步骤
使用命令 vi /etc/profile 修改配置文件,添加行 umask 027, 即新创建的文件属主拥有读写执行权限,同组用户拥有读和执行权限,其他用户无权限。
设置系统登录后,连接超时时间,增强安全性。
操作步骤
使用命令 vi /etc/profile 修改配置文件,将以 TMOUT= 开头的行注释,设置为TMOUT=180,即超时时间为三分钟。
启用日志功能,并配置日志记录。
操作步骤
Linux系统默认启用以下类型日志:
- 系统日志(默认)/var/log/messages
- cron日志(默认)/var/log/cron
- 安全日志(默认)/var/log/secure
注意:部分系统可能使用syslog-ng日志,配置文件为:/etc/syslog-ng/syslog-ng.conf。
您可以根据需求配置详细日志。
通过脚本代码实现记录所有用户的登录操作日志,防止出现安全事件后无据可查。
操作步骤
- 运行 [root@xxx /]# vim /etc/profile打开配置文件。
- 在配置文件中输入以下内容:
- history
- USER=`whoami`
- USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
- if [ "$USER_IP" = "" ]; then
- USER_IP=`hostname`
- fi
- if [ ! -d /var/log/history ]; then
- mkdir /var/log/history
- chmod 777 /var/log/history
- fi
- if [ ! -d /var/log/history/${LOGNAME} ]; then
- mkdir /var/log/history/${LOGNAME}
- chmod 300 /var/log/history/${LOGNAME}
- fi
- export HISTSIZE=4096
- DT=`date +"%Y%m%d_%H:%M:%S"`
- export HISTFILE="/var/log/history/${LOGNAME}/${USER}@${USER_IP}_$DT"
- chmod 600 /var/log/history/${LOGNAME}/*history* 2>/dev/null
- 运行 [root@xxx /]# source /etc/profile 加载配置生效。
注意: /var/log/history 是记录日志的存放位置,可以自定义。
通过上述步骤,可以在 /var/log/history 目录下以每个用户为名新建一个文件夹,每次用户退出后都会产生以用户名、登录IP、时间的日志文件,包含此用户本次的所有操作(root用户除外)。
同时,建议您使用OSS服务收集存储日志。
NFS服务安全加固
NFS(Network File System)是 FreeBSD 支持的一种文件系统,它允许网络中的计算机之间通过 TCP/IP 网络共享资源。不正确的配置和使用 NFS,会带来安全问题。
NFS 的不安全性,主要体现于以下 4 个方面:
- 缺少访问控制机制
- 没有真正的用户验证机制,只针对 RPC/Mount 请求进行过程验证
- 较早版本的 NFS 可以使未授权用户获得有效的文件句柄
- 在 RPC 远程调用中, SUID 程序具有超级用户权限
为有效应对以上安全隐患,推荐您使用下述加固方案。
使用 anonuid,anongid 配置共享目录,这样可以使挂载到 NFS 服务器的客户机仅具有最小权限。不要使用 no_root_squash。
使用 安全组策略 或 iptable 防火墙限制能够连接到 NFS 服务器的机器范围。
- iptables -A INPUT -i eth0 -p TCP -s 192.168.0.0/24 --dport 111 -j ACCEPT
- iptables -A INPUT -i eth0 -p UDP -s 192.168.0.0/24 --dport 111 -j ACCEPT
- iptables -A INPUT -i eth0 -p TCP -s 140.0.0.0/8 --dport 111 -j ACCEPT
- iptables -A INPUT -i eth0 -p UDP -s 140.0.0.0/8 --dport 111 -j ACCEPT
使用 Kerberos V5 作为登录验证系统,要求所有访问人员使用账号登录,提高安全性。
在 Linux 中,NFSD 的 COPY 数目定义在启动文件 /etc/rc.d/init.d/nfs 中,默认值为 8。
最佳的 COPY 数目一般取决于可能的客户机数目。您可以通过测试来找到 COPY 数目的近似最佳值,并手动设置该参数。
对于不同的网络情况,有针对地选择 UDP 或 TCP 传输协议。传输协议可以自动选择,也可以手动设置。
- mount -t nfs -o sync,tcp,noatime,rsize=1024,wsize=1024 EXPORT_MACHINE:/EXPORTED_DIR /DIR
UDP 协议传输速度快,非连接传输时便捷,但其传输稳定性不如 TCP,当网络不稳定或者黑客入侵时很容易使 NFS 性能大幅降低,甚至导致网络瘫痪。一般情况下,使用 TCP 的 NFS 比较稳定,使用 UDP 的 NFS 速度较快。
- 在机器较少,网络状况较好的情况下,使用 UDP 协议能带来较好的性能。
- 当机器较多,网络情况复杂时,推荐使用 TCP 协议(V2 只支持 UDP 协议)。
- 在局域网中使用 UDP 协议较好,因为局域网有比较稳定的网络保证,使用 UDP 可以带来更好的性能。
- 在广域网中推荐使用 TCP 协议,TCP 协议能让 NFS 在复杂的网络环境中保持最好的传输稳定性。
修改 /etc/hosts.allow 和 /etc /hosts.deny 来限制客户机数量。
- /etc/hosts.allow
- portmap: 192.168.0.0/255.255.255.0 : allow
- portmap: 140.116.44.125 : allow
- /etc/hosts.deny
- portmap: ALL : deny
NFS 默认使用的是 111 端口,使用 port 参数可以改变这个端口值。改变默认端口值能够在一定程度上增强安全性。
SUID (Set User ID) 或 SGID (Set Group ID) 程序可以让普通用户以超过自己权限来执行。很多 SUID/SGID 可执行程序是必须的,但也可能被一些恶意的本地用户利用,获取本不应有的权限。
尽量减少所有者是 root,或是在 root 组中却拥有 SUID/SGID 属性的文件。您可以删除这样的文件或更改其属性,如:
- 使用 nosuid 选项禁止 set-UID 程序在 NFS 服务器上运行,可以在 /etc/exports 加入一行:
- /www www.abc.com(rw, root_squash, nosuid)
- 使用 noexec 禁止直接执行其中的二进制文件。
如何在 Windows 和 Windows Server 中启用/禁用 SMBv1、SMBv2 和 SMBv3
禁用 SMBv2 和 SMBv3 的影响
我们建议不要禁用 SMBv2 或 SMBv3。禁用 SMBv2 或 SMBv3 只能作为临时故障排除措施。请勿使 SMBv2 或 SMBv3 保持禁用状态。
在 Windows 7 和 Windows Server 2008 R2 中,禁用 SMBv2 会停用以下功能:
- 请求复合 - 允许发送多个 SMB 2 请求作为单个网络请求
- 大型读写 - 更好地利用更快速的网络
- 文件夹和文件属性缓存 - 客户端保留文件夹和文件的本地副本
- 持久句柄 - 如果临时断开连接,则允许连接以透明方式重新连接到服务器
- 改进的消息签名 - HMAC SHA-256 代替 MD5 作为哈希算法
- 改进的文件共享扩展性 - 每个服务器的用户数量、共享数量和打开文件数量大大增加
- 支持符号链接
- 客户端 oplock 租赁模式 - 限制在客户端和服务器之间传输的数据,从而提高高延迟网络性能并增强 SMB 服务器的扩展性
- 大型 MTU 支持 - 可充分利用 10 千兆字节 (GB) 以太网
- 改进的能效 - 向服务器打开文件的客户端可以睡眠
在 Windows 8、Windows 8.1、Windows 10、Windows Server 2012 和 Windows Server 2016 中,禁用 SMBv3 会停用以下功能(以及以上列表中所述的 SMBv2 功能):
- 透明故障转移 - 在维护或故障转移期间,客户端会重新连接,不会干扰群集节点
- 扩展 – 并发访问所有文件群集节点上的共享数据
- 多通道 - 如果客户端和服务器之间有多个路径可用时,则聚合网络带宽和容错
- SMB 直通 – 增加 RDMA 网络支持,实现极高的性能、低延迟和低 CPU 利用率
- 加密 – 提供端到端加密,并防止不可靠网络上的窃听
- 目录租赁 - 通过缓存改进分支机构中应用程序的响应时间
- 性能优化 - 对小型随机读/写 I/O 的优化
Windows 8 和 Windows Server 2012
Windows 8 和 Windows Server 2012 引入了新的 Set-SMBServerConfiguration Windows PowerShell cmdlet。 通过此 cmdlet,你可以在服务器组件上启用或禁用 SMBv1、SMBv2 和 SMBv3 协议。
注意:因为 SMBv2 和 SMBv3 共用一个堆叠,所以在 Windows 8 或 Windows Server 2012 中启用或禁用 SMBv2 时,也会启用或禁用 SMBv3。
运行 Set-SMBServerConfiguration cmdlet 后,无须重启计算机。
- 若要获取 SMB 服务器协议配置的当前状态,请运行以下 cmdlet:试用
- Get-SmbServerConfiguration | Select EnableSMB1Protocol, EnableSMB2Protocol
- 若要在 SMB 服务器上禁用 SMBv1,请运行以下 cmdlet:试用
Set-SmbServerConfiguration -EnableSMB1Protocol $false
- 若要在 SMB 服务器上禁用 SMBv2 和 SMBv3,请运行以下 cmdlet:试用
Set-SmbServerConfiguration -EnableSMB2Protocol $false
- 若要在 SMB 服务器上启用 SMBv1,请运行以下 cmdlet:试用
Set-SmbServerConfiguration -EnableSMB1Protocol $true
- 若要在 SMB 服务器上启用 SMBv2 和 SMBv3,请运行以下 cmdlet:试用
Set-SmbServerConfiguration -EnableSMB2Protocol $true
Windows 7、Windows Server 2008 R2、Windows Vista 和 Windows Server 2008
若要在运行 Windows 7、Windows Server 2008 R2、Windows Vista 或 Windows Server 2008 的 SMB 服务器上启用或禁用 SMB 协议,请使用 Windows PowerShell 或注册表编辑器。
使用 Windows PowerShell 2.0 或更高版本的 PowerShell
- 若要在 SMB 服务器上禁用 SMBv1,请运行以下 cmdlet:试用
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB1 -Type DWORD -Value 0 -Force
- 若要在 SMB 服务器上禁用 SMBv2 和 SMBv3,请运行以下 cmdlet:试用
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB2 -Type DWORD -Value 0 -Force
- 若要在 SMB 服务器上启用 SMBv1,请运行以下 cmdlet:试用
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB1 -Type DWORD -Value 1 -Force
- 若要在 SMB 服务器上启用 SMBv2 和 SMBv3,请运行以下 cmdlet:试用
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB2 -Type DWORD -Value 1 -Force
注意:进行这些更改后,必须重启计算机。
注意:以下内容包含有关如何修改注册表的信息。修改注册表之前,一定要先对其进行备份。并且一定要知道在发生问题时如何还原注册表。有关如何备份、还原和修改注册表的更多信息,请查看 如何在 Windows 中备份和还原注册表。
- 若要在 SMB 服务器上启用或禁用 SMBv1,请配置以下注册表项:
- 注册表子项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters 注册表项: SMB1
- REG_DWORD: 0 = 已禁用
- REG_DWORD: 1 = 已启用
- 默认值: 1 = 已启用
- 若要在 SMB 服务器上启用或禁用 SMBv2,请配置以下注册表项:
- 注册表子项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters 注册表项: SMB2
- REG_DWORD: 0 = 已禁用
- REG_DWORD: 1 = 已启用
- 默认值: 1 = 已启用
Windows Vista、Windows Server 2008、Windows 7、Windows Server 2008 R2、Windows 8 和 Windows Server 2012
注意:因为 SMBv2 和 SMBv3 共用一个堆叠,所以在 Windows 8 或 Windows Server 2012 中启用或禁用 SMBv2 时,也会启用或禁用 SMBv3。
- 若要在 SMB 客户端上禁用 SMBv1,请运行以下命令:试用
sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi
sc.exe config mrxsmb10 start= disabled
- 若要在 SMB 客户端上启用 SMBv1,请运行以下命令:试用
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb10 start= auto
- 若要在 SMB 客户端上禁用 SMBv2 和 SMBv3,请运行以下命令:试用
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi
sc.exe config mrxsmb20 start= disabled
- 若要在 SMB 客户端上启用 SMBv2 和 SMBv3,请运行以下命令:试用
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb20 start= auto
注意:
- 必须在提升的命令提示符中运行这些命令。
- 进行这些更改后,必须重启计算机。
这将在注册表中配置以下新项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters 注册表项: SMB1 REG_DWORD: 0 = Disabled
- 打开组策略管理控制台。右键单击应包含新首选项的组策略对象 (GPO),然后单击 编辑。
- 在 计算机配置 下的控制台树中,展开 首选项 文件夹,然后展开 Windows 设置 文件夹。
- 右键单击 注册表 节点,指向 新建,然后选择 注册表项。
- 在 新建注册表属性 对话框中,选择以下内容:
- 操作: 创建
- Hive: HKEY_LOCAL_MACHINE
- 注册表项路径: SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
- 值名称: SMB1
- 值类型: REG_DWORD
- 值数据: 0
- 将此组策略应用到域中所有必需的工作站、服务器和域控制器,以禁用 SMBv1 服务器组件。也可以将 WMI 筛选器设置为不包含不受支持的操作系统或选中的排除项(如 Windows XP)。
注意:在旧版 Windows XP 或 Linux 早期版本以及第三方系统(不支持 SMBv2 或 SMBv3)需要访问 SYSVOL 或其他文件共享(已启用 SMB v1)的域控制器上进行这些更改时要谨慎小心。
若要禁用 SMBv1 客户端,需要将服务注册表项更新为禁止 MRxSMB10 启动,然后还需要将 MRxSMB10 的依赖项从 LanmanWorkstation 项中删除,以便它可以正常启动(无需首先启动 MRxSMB10)。
这将更新和替换注册表以下 2 个项中的默认值
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\mrxsmb10 注册表项: Start REG_DWORD: 4 = Disabled
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation 注册表项: DependOnService REG_MULTI_SZ: “Bowser”,”MRxSmb20″,”NSI”
注意:默认包含的 MRxSMB10 现已作为依赖项删除。
使用组策略配置流程
- 打开组策略管理控制台。右键单击应包含新首选项的组策略对象 (GPO),然后单击 编辑。
- 在 计算机配置 下的控制台树中,展开 首选项 文件夹,然后展开 Windows 设置 文件夹。
- 右键单击 注册表 节点,指向 新建,然后选择 注册表项。
- 在 新建注册表属性 对话框中,选择以下内容:
- 操作: 更新
- Hive: HKEY_LOCAL_MACHINE
- 注册表项路径: SYSTEM\CurrentControlSet\services\mrxsmb10
- 值名称: Start
- 值类型: REG_DWORD
- 值数据: 4
然后删除刚刚禁用的 MRxSMB10 的依赖项
- 在 新建注册表属性 对话框中,选择以下内容:
- 操作: 替换
- Hive: HKEY_LOCAL_MACHINE
- 注册表项路径: SYSTEM\CurrentControlSet\Services\LanmanWorkstation
- 值名称: DependOnService
- 值类型 REG_MULTI_SZ
- 值数据:
- Bowser
- MRxSmb20
- NSI
注意: 这 3 个字符串不带项目符号(具体如下)
在 Windows 的多个版本中,默认值包括 MRxSMB10,通过将其替换为此多值字符串,实际上就删除了作为 LanmanServer 依赖项的 MRxSMB10,结果是从四个默认值减少为上述这三个值。
注意:使用组策略管理控制台时,无需使用引号或逗号。只需在各行键入每个项,如上面所示。
应用策略且正确设置注册表后,必须重新启动目标系统,然后才能禁用 SMB v1。
如果所有设置均在同一组策略对象 (GPO) 中,组策略管理将显示以下设置。
配置完成后即允许策略进行复制和更新。作为测试的必要步骤,请从 CMD.EXE 提示符处运行 gpupdate/force,然后查看目标计算机,以确保注册表设置得以正确应用。确保 SMBv2 和 SMBv3 在环境中的所有其他系统中正常运行。
注意:请务必重新启动目标系统。
如何在 Windows 8.1、Windows 10、Windows 2012 R2 和 Windows Server 2016 中轻松删除 SMBv1
Windows Server:使用 PowerShell (Remove-WindowsFeature FS-SMB1)
Windows 客户端:使用 PowerShell (Disable-WindowsOptionalFeature -Online -FeatureName smb1protocol)
应用软件安全加固
FTP匿名登录或弱口令漏洞及服务加固
漏洞描述
FTP 弱口令或匿名登录漏洞,一般指使用 FTP 的用户启用了匿名登录功能,或系统口令的长度太短、复杂度不够、仅包含数字、或仅包含字母等,容易被黑客攻击,发生恶意文件上传或更严重的入侵行为。
黑客利用弱口令或匿名登录漏洞直接登录 FTP 服务,上传恶意文件,从而获取系统权限,并可能造成数据泄露。
加固方案
不同 FTP 服务软件可能有不同的防护程序,本修复方案以 Windows server 2008 中自带的 FTP 服务和 Linux 中的vsftpd服务为例,您可参考以下方案对您的 FTP 服务进行安全加固。
重要提示:
- 请确保您的 FTP 服务软件为官方最新版本。同时,建议您不定期关注官方发布的补丁,并及时进行更新。
- 强烈建议不要将此类型的服务在互联网开放,您可以使用 VPN 等安全接入手段连接到 FTP 服务器端,同时使用 安全组 来控制访问源IP。
打开 IIS 信息服务管理器,查看所有 FTP 服务相关的安全加固功能。
禁用匿名登录
-
- 创建 FTP 帐户。
在 开始 > 管理工具 > 计算机管理 > 本地用户和组 中,创建用户,设置强密码(密码建议八位以上,包括大小写字母、特殊字符、数字等混合体,不要使用生日、姓名拼音等常见字符串),并设置该用户属于 GUESTS 用户组。
-
- 禁用匿名登录。
- Windows 2008 系统 FTP 禁用匿名登录服务
- 禁用匿名登录。
-
-
- Windows 2012系统 FTP 禁用匿名登录服务。
-
- 启用强密码安全策略
在 Windows 系统中,强密码策略是通过组策略控制的。您可以打开本地组策略编辑器(gpedit.msc),计算机配置 > Windows 设置 > 安全设置 > 账户策略 > 密码策略,启用密码复杂策略。
启用 密码必须符合复杂性要求 策略后,在更改或创建用户密码时会执行复杂性策略检测,密码必须符合以下最低要求:
-
- 密码不能包含账户名
- 密码不能包含用户名中超过两个连续字符的部分
- 密码至少有六个字符长度
- 密码必须包含以下四类字符中的至少三类字符类型:英文大写字母(A-Z)、英文小写字母(a-z)、10个基本数字(0-9)、特殊字符(例如:!、¥、#、%)
注意: 推荐 Windows 所有需要进行用户认证的服务都采用上述复杂密码策略。
- 启用账户登录失败处理机制
该机制对登录失败的账户实施强处理,可有效防止暴力破解攻击事件。
- 启用 FTP 目录隔离机制
FTP 目录隔离功能可以防止用户查看其它用户目录的文件,防止数据泄露。
- 指定访问源 IP
- 启用授权机制
您可以根据业务需求配置授权规则,限制用户访问的权限。
- 启用 SSL 加密传输功能
- 启用 SSL 加密传输功能,需要先创建服务器证书:
-
- 在 FTP SSL 设置中,选定已创建的服务器证书即可。
- 启用日志功能
IIS 中的 FTP 日志是默认启用的,您可以根据磁盘空间情况配置日志空间大小和其他策略。
FileZilla FTP Server 是一个非常流行的开源的、免费的 FTP 客户端、服务器端软件,如果您使用该搭建 FTP 服务,FileZilla FTP Server 提供了相关的安全功能,您可以参考 FileZilla FTP Server 安全加固 方案加固您的 FileZilla FTP Server 的安全。
- 及时安装更新补丁
在安装更新补丁前,备份您的 vsftp 应用配置。从 VSFTPD官方网站 获取最新版本的 vsftp 软件安装包,完成升级安装。或者,您可以下载最新版 vsftp 源码包,自行编译后安装更新。您也可以执行yum update vsftpd命令通过 yum 源进行更新。
- 禁用匿名登录服务
- 添加一个新用户(test),并配置强密码。例如,执行useradd -d /home -s /sbin/nologin test命令。
- 其中,/sbin/nologin参数表示该用户不能登录 Linux shell 环境。
- test为用户名。
- 通过passwd test命令,为该用户配置强密码。密码长度建议八位以上,且密码应包括大小写字母、特殊字符、数字混合体,且不要使用生日、姓名拼音等常见字符串作为密码。
- 修改配置文件 vsftpd.conf,执行#vim /etc/vsftpd/vsftpd.conf命令。
- 添加一个新用户(test),并配置强密码。例如,执行useradd -d /home -s /sbin/nologin test命令。
anonymous_enable=NO,将该参数配置为 NO 表示禁止匿名登录,必须要创建用户认证后才能登录 FTP 服务。
- 禁止显示 banner 信息
修改 VSFTP 配置文件 vsftpd.conf,设置ftpd_banner=Welcome。重启 vsftp 服务后,即不显示 banner 信息。试用
-
- >ftp 192.168.10.200
- Connected to 192.168.10.200.
- 220 Welcome
- User (192.168.10.200:(none)):
- 限制 FTP 登录用户
在 ftpusers 和 user_list 文件中列举的用户都是不允许访问 FTP 服务的用户(例如 root、bin、daemon 等用户)。除了需要登录 FTP 的用户外,其余用户都应该添加至此拒绝列表中。
- 限制 FTP 用户目录
- 修改 VSFTP 配置文件 vsftpd.conf。试用
- chroot_list_enable=YES
- chroot_list_file=/etc/vsftpd/chroot_list
- 新建 /etc/vsftpd/chroot_list 文件,并添加用户名。例如,将 user1 添加至该文件,则 user1 登录 FTP 服务后,只允许在 user1 用户的 home 目录中活动。
- 修改 VSFTP 配置文件 vsftpd.conf。试用
- 修改监听地址和默认端口
例如,修改 VSFTP 配置文件 vsftpd.conf,设置监听 1.1.1.1 地址的 8888 端口。试用
listen_address=1.1.1.1
listen_port=8888
- 启用日志记录
修改 VSFTP 配置文件 vsftpd.conf,启用日志记录。试用
xferlog_enable=YES
xferlog_std_format=YES
如果您需要自定义日志存放位置,可以修改xferlog_file=/var/log/ftplog。
- 其他安全配置
修改 VSFTP 配置文件 vsftpd.conf。试用
//限制连接数
max_clients=100
max_per_ip=5
//限制传输速度
anon_max_rate=81920
local_max_rate=81920
注意: 如果您不需要使用 FTP 服务,建议您关闭该服务。
Docker服务安全加固
Docker是一个开源的引擎,可以轻松地为任何应用创建一个轻量级的、可移植的、自给自足的容器。本文介绍了使用Docker服务的安全加固方案,帮助您搭建一个安全可靠的容器集成环境。
在部署前需要对服务器操作系统进行安全加固,例如,更新所有软件补丁、配置强密码、关闭不必要的服务端口等。具体请参考以下内容:
- Windows操作系统安全加固
- Linux操作系统加固
启用强制访问控制(Mandatory Access Control (MAC)),根据业务场景的具体分析,对Docker中使用的各种资源设置访问控制。
启用AppAamor功能:
- docker run --interactive --tty --security-opt="apparmor:PROFILENAME" centos
- /bin/bash
启用SElinux功能:
- docker daemon --selinux-enabled
根据实际应用,对需要外网访问的端口(例如管理界面、API 2375端口等重要端口)、需要与外网交互的网络地址、端口、协议等进行梳理,使用iptables或ECS安全组策略对网络的出入设置严格的访问控制。
在软件使用中,有一些必须由root用户才能够进行的操作。但从安全角度,您需要将这一部分操作与仅使用普通用户权限即可执行的操作分离解耦。
在编写dockerfile时,您可以使用类似如下的命令创建一个普通权限用户,并设置创建的UID为以后运行程序的用户:
- RUN useradd noroot -u 1000 -s /bin/bash --no-create-home
- USER noroot
- RUN Application_name
Docker命令参考:
默认情况下,Docker容器是没有特权的,一个容器不允许访问任何设备;但当使用--privileged选项时,则该容器将能访问所有设备。
例如,当打开--privileged选项后,您就可以对Host中/dev/下的所有设备进行操作。但如果不是必须对host上的所有设备进行访问的话,您可以使用--device仅添加需要操作的设备。
控制CPU份额
- Docker提供–cpu-shares参数,用于在创建容器时指定容器所使用的CPU份额值。
使用示例: 当使用命令docker run -tid –cpu-shares 100 ubuntu:stress创建容器时,则最终生成的cgroup的CPU份额配置可以下面的文件中找到。
-
- root@ubuntu:~# cat /sys/fs/cgroup/cpu/docker/<容器的完整长ID>/cpu.shares
- 100
cpu-shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。
- Docker提供了–cpu-period、–cpu-quota两个参数,用来控制容器可以分配到的CPU时钟周期。
–cpu-period用来指定容器对CPU的使用要在多长时间内做一次重新分配,而–cpu-quota是用来指定在这个周期内,最多可以有多少时间用来运行这个容器。与–cpu-shares不同的是,这种配置是指定一个绝对值,而且没有弹性在里面,容器对CPU资源的使用绝对不会超过配置的值。
cpu-period和cpu-quota的单位为微秒(μs)。cpu-period的最小值为1000微秒,最大值为1秒(10^6 μs),默认值为0.1秒(100000 μs)。cpu-quota的值默认为-1,表示不做控制。
举例说明,如果容器进程需要每1秒使用单个CPU的0.2秒时间,可以将cpu-period设置为1000000(即1秒),cpu-quota设置为200000(0.2秒)。当然,在多核情况下,如果允许容器进程需要完全占用两个CPU,则可以将cpu-period设置为100000(即0.1秒),cpu-quota设置为200000(0.2秒)。
使用示例:使用如下命令来创建容器docker run -tid –cpu-period 100000 –cpu-quota 200000 ubuntu。
控制CPU内核
对于多核CPU的服务器,使用–cpuset-cpus和–cpuset-mems参数,可以限定容器运行使用哪些CPU内核和内存节点。
该功能可以对需要高性能计算的容器进行性能最优的配置,对具有NUMA拓扑(具有多CPU、多内存节点)的服务器尤其有用。而如果服务器只有一个内存节点,则–cpuset-mems的配置基本上不会有明显效果。
使用示例:使用命令docker run -tid –name cpu1 –cpuset-cpus 0-2 ubuntu,表示创建的容器只能用0、1、2这三个内核。
混合使用CPU配额控制参数
在上述参数中,cpu-shares控制只用在容器竞争同一个内核的时间片时。如果通过cpuset-cpus指定容器A使用内核0,容器B只使用内核1,则在主机上只有这两个容器使用对应内核的情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。
cpu-period、cpu-quota这两个参数一般联合使用。在单核或者通过cpuset-cpus强制容器使用一个CPU内核的情况下,即使cpu-quota超过cpu-period,也不会使容器使用更多的CPU资源。
cpuset-cpus、cpuset-mems只对多核、多内存节点上的服务器有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
和CPU控制一样,Docker也提供了若干参数来控制容器的内存使用配额,可以控制容器的swap大小、可用内存大小等。主要有以下参数:
- memory-swappiness:控制进程将物理内存交换到swap分区的倾向,默认系数为60。系数越小,就越倾向于使用物理内存。取值范围为0-100。当值为100时,表示尽量使用swap分区;当值为0时,表示禁用容器swap功能。这点不同于宿主机,宿主机swappiness设置为0时,也不会禁用swap。
- –kernel-memory:内核内存,不会被交换到swap上。一般情况下,不建议修改,可以直接参考Docker的官方文档。
- –memory:设置容器使用的最大内存上限。默认单位为byte,可以使用K、G、M等带单位的字符串。
- –memory-reservation:启用弹性的内存共享。当宿主机资源充足时,允许容器尽量多地使用内存,当检测到内存竞争或者低内存时,强制将容器的内存降低到memory-reservation所指定的内存大小。不设置此选项时,有可能出现某些容器长时间占用大量内存,带来性能上的损失。
- –memory-swap:等于内存和swap分区大小的总和。设置为-1时,表示swap分区的大小是无限的。默认单位为byte,可以使用K、G、M等带单位的字符串。如果–memory-swap的设置值小于–memory的值,则使用默认值,为–memory-swap值的两倍。
不要运行不可信的Docker镜像作为互联网服务器,避免运行不完全理解的Docker镜像作为互联网服务器。
Docker的日志可以分成两类,一类是stdout标准输出,另一类是文件日志。Dockerd支持的日志级别有debug、info、warn、error、fatal,默认的日志级别为info。
必要的情况下,您需要设置日志级别,这可以通过配置文件,或者启动参数-l或--log-level来完成。
方法一:修改配置文件/etc/docker/daemon.json。
- {
- "log-level": "debug"
- }
方法二:使用docker run的时候指定--log-driver=syslog --log-opt syslog-facility=daemon。
在生产环境中使用漏洞扫描工具可以检测镜像中的已知漏洞。
- 容器通常都不是从头开始构建的,所以一定要进行安全扫描,以便及时发现基础镜像中任何可能存在的漏洞,并及时更新补丁。
- 在应用程序交付生命周期中加入漏洞扫描的安全质量控制,防止部署易受攻击的容器。
通过采用以上积极的防范措施,即在整个容器的生命周期中建立和实施安全策略,可以有效地保证一个集成容器环境的安全性。
[1]. CIS Benchmarks
[2]. https://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/-
[3]. https://d3oypxn00j2a10.cloudfront.net/assets/img/Docker%20Security/WP_Intro_to_container_security_03.20.2015.pdf
[4]. https://docs.docker.com/edge/engine/reference/commandline/dockerd/
Jenkins服务安全加固
Jenkins早期版本的默认配置下没有安全检查。任何人都可以以匿名用户身份进入Jenkins,执行build操作。然而,对大多数Jenkins应用,尤其是暴露在互联网的应用,安全控制是非常重要的。从Jenkins 2.0开始,其默认配置中启用了许多安全选项,以确保Jenkins环境安全,除非管理员明确禁用某些保护。
本文介绍了Jenkins管理员可操作的各种安全选项,用来加固您的Jenkins服务,以防被黑客攻击。
Jenkins访问控制分为:安全域(即认证)与授权策略。
- 安全域决定Jenkins在认证的过程中从哪里寻找用户,默认选项有:Jenkins专有用户数据库,LDAP,和Servlet容器代理。
- 授权策略决定用户登录后可以做什么,默认选项有:任何用户可以做任何事(没有任何限制),安全矩阵,登录用户可以做任何事情,遗留模式,项目矩阵授权策略。
定期关注Jenkins官方安全公告,使用或更新到官方最新版本的Jenkins,防止部署存在安全漏洞的版本。
自2.0版本起,Jenkins默认勾选Enable security复选框。Jenkins管理员可以在Web UI的启用安全性部分启用,配置或禁用适用于整个Jenkins环境的关键安全功能。
默认情况下,匿名用户没有权限,而登录的用户具有完全的控制权。用户可以使用用户名和密码登录,以执行匿名用户不可用的操作。哪些操作要求用户登录取决于所选择的授权策略及其配置。对于任何非本地(测试)Jenkins环境,应始终启用此复选框。
Jenkins使用TCP端口与通过JNLP协议启动的代理(如基于Windows的代理)进行通信。截止Jenkins 2.0,默认情况下此端口被禁用。
对于希望使用基于JNLP代理的管理员,以下两种类型的端口可供选用:
- 随机:随机选择JNLP端口,避免Jenkins主机发生冲突 。该方式的缺点是在Jenkins主引导期间,难以管理允许JNLP流量的防火墙规则。
- 固定:由Jenkins管理员选择JNLP端口,端口在Jenkins主控器的重新启动之间是一致的。这使得管理防火墙规则更容易,允许基于JNLP的代理连接到主服务器。
访问控制是保护Jenkins环境免受未经授权使用的主要机制。在Jenkins中配置访问控制包括以下三个方面:
- 管理控制台。根据一般的管理方式,管理人员不需要直接在互联网上进行管理,仅需要根据业务资深需求,对管理控制台访问源IP、端口进行限制,防止被恶意人员访问后台。
- 安全域。通知Jenkins环境如何以及在哪里获取用户(或标识)的信息,也被称为“认证”。
- 授权配置。通知Jenkins环境,哪些用户和/或组在多大程度上可以访问Jenkins的哪些方面。
使用安全域和授权配置,可以在Jenkins中轻松地配置非常刚性的身份验证和授权方案。此外,一些插件(如基于角色的授权策略)可以扩展Jenkins的访问控制功能,以支持更细微的身份验证和授权方案。
安全领域或认证表明谁可以访问Jenkins环境,而授权解决的是他们可以在Jenkins环境中访问什么。
默认情况下,Jenkins支持以下的授权选项:
- 所有人都可以控制Jenkins。每个人都可以完全控制Jenkins,包括尚未登录的匿名用户。请勿将本设置用于本地测试Jenkins管理以外的任何其他设置。
- 传统模式。如果用户具有“admin”角色,他们将被授予对系统的完全控制权,否则该用户(包括匿名用户)将仅具有读访问权限。不要将本设置用于本地测试Jenkins管理以外的任何设置。
- 登录用户可以做任何事情。在这种模式下,每个登录的用户都可以完全控制Jenkins。根据高级选项,还可以允许或拒绝匿名用户读取Jenkins的访问权限。此模式有助于强制用户在执行操作之前登录,以便有用户操作的审计跟踪。
- 基于矩阵的安全性。该授权方案可以精确控制哪些用户和组能够在Jenkins环境中执行哪些操作。
- 基于项目的矩阵授权策略。此授权方案是基于Matrix的安全性的扩展,允许在项目配置屏幕中单独为每个项目定义附加的访问控制列表(ACL)。这允许授予特定用户或组访问指定的项目,而不是Jenkins环境中的所有项目。使用基于项目的矩阵授权定义的ACL是加法的,使得在“配置全局安全性”屏幕中定义的访问权限将与项目特定的ACL组合。
上图表中的每一行表示用户或组(也称为“角色”)。这包括名为“匿名”和“认证”的特殊条目。“匿名”条目表示授予访问Jenkins环境的所有未认证用户的权限。而“已认证”用于向访问环境的所有经过身份验证的用户授予权限。
矩阵中授予的权限是加法的。例如,如果用户“kohsuke”在“开发人员”和“管理员”组中,则授予“kohsuke”的权限将包含授予给“kohsuke”,“开发人员”,“管理员” ,“认证”和“匿名”的所有权限。
Jenkins提供一系列与认证和用户管理相关的插件,用户可以根据业务需求安装使用(https://plugins.jenkins.io/) 。例如:
- Active Directory Plugin:允许使用Microsoft Active Directory(即Windows域账号)进行认证。
- Crowd Plugin:允许使用Atlassian Crowd进行认证。
- Script Security Realm Plugin:允许使用自定义的脚本进行认证。
- Role Strategy Plugin:提供了基于角色的授权策略,允许定义全局的和项目集的角色,并为用户分配相应角色。
跨站点请求伪造(或CSRF/XSRF)是一种漏洞,它允许未经授权的第三方通过模仿另一个经过身份验证的用户对Web应用程序执行请求。在Jenkins环境的上下文中,CSRF攻击可能允许恶意actor删除项目,更改构建或修改Jenkins的系统配置。
为了防范此类漏洞,自2.0以来所有Jenkins版本,在默认情况下都已启用CSRF保护。
启用该选项后,Jenkins将会在可能更改Jenkins环境中的数据的任何请求上检查CSRF令牌或“crumb”。这包括任何表单提交和对远程API的调用,包括使用“基本”身份验证的表单。
但是,CSRF保护可能会对Jenkins更高级的使用带来挑战,例如:
- 某些Jenkins功能(如远程API)在启用此选项时变得更难使用。
- 通过配置不正确的反向代理访问Jenkins,可能使CSRF HTTP头被从请求中删除,导致受保护的操作失败。
- 未经过CSRF保护测试的过时插件可能无法正常工作。
Kubernetes服务安全加固
确保镜像没有安全漏洞
在部署前,应该确保所有的操作系统软件、Kubernetes软件为官方最新版本,防止部署后因为漏洞造成入侵事件。
在运维过程中,要不断执行持续安全漏洞扫描(Continuous Security Vulnerability Scanning),因为容器中可能存在包含已知漏洞(CVE)的过时包。新的漏洞每天都会出现,所以这不是一个一次性的工作,对镜像进行持续的安全评估是至关重要的。
定期对环境进行安全更新,一旦发现运行中容器的漏洞,您应该及时更新镜像并重新部署容器。尽量避免直接更新(例如,apt-update)到正在运行的容器,因为这样打破了镜像与容器的对应关系。
使用Kubernetes滚动升级功能可以方便地升级容器,该功能允许将镜像升级到最新版本来逐步更新正在运行的容器。
如果无法保证只运行符合组织策略的镜像,那么组织会面临运行脆弱甚至恶意容器的危险。从未知的来源下载和运行镜像是危险的,它相当于在生产服务器上运行未知服务商的软件。
使用私有镜像存储您的合法镜像,这样能大量减少可能进入到您的环境的镜像数量。建议您将安全评估(如漏洞扫描)加入持续集成(CI)中,使其成为构建流程的一部分。
持续集成应确保只使用审查通过的代码来构建镜像。当镜像构建成功后,要对它进行安全漏洞扫描,且只有在不存在问题时,才能将镜像推送到私有镜像仓库。在安全评估中失败的镜像不应该被推送到镜像仓库中。
Kubernetes镜像授权插件的工作已经完成,预计会随Kubernetes 1.4发布。该插件允许阻止未授权镜像的分发,单击查看详情。
应该限制SSH登录或SSH Key免登录Kubernetes节点,减少对主机资源未授权的访问。应该要求用户使用kubectl exec命令,此命令能够在不访问主机的情况下直接访问容器环境。
您可以使用Kubernetes授权插件来进一步控制用户对资源的访问。它允许设置对指定命名空间、容器和操作的细粒度访问控制规则。
Kubernets API Server进程提供Kuvernetes API。通常情况下,有一个进程运行在单一kubernetes-master节点上。
默认情况,Kubernetes API Server提供HTTP的两个端口:
本地主机端口
- HTTP服务默认端口8080,修改标识–insecure-port
- 默认IP是本地主机,修改标识—insecure-bind-address
- 在HTTP中没有认证和授权检查
- 主机访问受保护
安全端口
- 默认端口6443,修改标识—secure-port
- 默认IP是首个非本地主机的网络接口,修改标识—bind-address HTTPS服务。
- 设置证书和秘钥的标识,–tls-cert-file,–tls-private-key-file
- 认证方式,令牌文件或者客户端证书
- 使用基于策略的授权方式
基于安全考虑,会移除只读端口,使用Service Account代替。
在某些配置文件中有一个代理(nginx)作为API Server进程运行在同一台机器上。该代理是HTTPS服务,认证端口是443,访问API Server是本地主机8080端口。在这些配置文件里,Secure Port通常设置为6443。
您可以使用ECS安全组防火墙规则,限制外部HTTPS通过443端口访问。
以上都是默认配置,每个云提供商可能会有所不同,您可以根据不同的业务场景灵活配置和调整。
限制用户权限的范围可以减少错误或恶意活动的影响。Kubernetes命名空间允许将资源划分为逻辑命名组。在一个命名空间中创建的资源对其他命名空间是隐藏的。
默认情况下,用户在Kubernetes集群中创建的每个资源运行在名称为“default”的默认空间内。您也可以创建额外的命名空间并附加资源和用户给它们。您可以使用Kubernetes授权插件来创建策略,以便将不同用户的访问请求隔离到不同的命名空间中。
例如:以下策略将允许”alice”从命名空间”fronto”读取pods。试用
- {
- "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
- "kind": "Policy",
- "spec": {
- "user": "alice",
- "namespace": "fronto",
- "resource": "pods",
- "readonly": true
- }
- }
运行没有资源限制的容器会将您的系统置于DoS或被其他租户干扰的风险中。为了防止和最小化这些风险,您应该定义资源配额。
默认情况下,Kubernetes集群中的所有资源没有对CPU和内存的使用限制。您可以创建资源配额策略,并附加到Kubernetes命名空间中来限制Pod对CPU和内存的使用。
下面的例子将限制命名空间中Pod的数量为4个,CPU使用在1和2之间,内存使用在1GB 和2GB之间。
在compute-resources.yaml文件中:试用
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: compute-resources
- spec:
- hard:
- pods: "4"
- requests.cpu: "1"
- requests.memory: 1Gi
- limits.cpu: "2"
- limits.memory: 2Gi
分配资源配额到命名空间:试用
- kubectl create -f ./compute-resources.yaml --namespace=myspace
在相同的Kubernetes集群上运行不同的应用程序会带来恶意程序攻击其他应用程序的风险。所以网络分割对确保容器只与那些被允许的容器进行通信很重要。
Kubernetes部署的挑战之一是创建Pod、服务和容器之间的网络分段。原因在于容器网络标识符(IP地址)是动态变化的,且容器可以在同一节点或节点间进行通信。
为防止跨集群通信,用户可以使用网络防火墙或SDN解决方案部署。新的网络策略API应该解决Pod之间创建防火墙规则的需求,限制容器化可以进行的网络访问。下面展示了只允许前端(frontend)Pod访问后端(backend)Pod的网络策略:试用
- POST /apis/net.alpha.kubernetes.io/v1alpha1/namespaces/tenant-a/networkpolicys
- {
- "kind": "NetworkPolicy",
- "metadata": {
- "name": "pol1"
- },
- "spec": {
- "allowIncoming": {
- "from": [{
- "pods": { "segment": "frontend" }
- }],
- "toPorts": [{
- "port": 80,
- "protocol": "TCP"
- }]
- },
- "podSelector": {
- "segment": "backend"
- }
- }
- }
当设计您的容器和pods时,确保为您的pods、容器和存储卷配置安全环境。安全环境是定义在yaml文件中的一项属性。它控制分配给pod/容器/存储卷的安全参数。一些重要的参数有:
安全环境设置项 | 描述 |
SecurityContext > runAsNonRoot | 容器应该以非root用户运行 |
SecurityContext > Capabilities | 控制分配给容器的Linux能力 |
SecurityContext > readOnlyRootFilesystem | 控制容器对root文件系统是否只读 |
PodSecurityContext > runAsNonRoot | 防止root用户作为pod的一部分运行容器 |
以下是一个具有安全环境参数的pod定义示例:试用
- apiVersion: v1
- kind: Pod
- metadata:
- name: hello-world
- spec:
- containers:
- # specification of the pod’s containers
- # ...
- securityContext:
- readOnlyRootFilesystem: true
- runAsNonRoot: true
API Server权限控制分为三种:Authentication(身份认证)、Authorization(授权)、AdmissionControl(准入控制)。
当客户端向Kubernetes非只读端口发起API请求时,Kubernetes通过三种方式来认证用户的合法性(即验证用户是否有权限操作API):证书认证,Token认证,基本信息认证。
证书认证
设置APIServer的启动参数:--client_ca_file=SOMEFILE
验证被引用的文件中包含的client证书。如果被验证通过,那么这个验证记录中的主体对象将会作为请求的username。
Token认证
设置APIServer的启动参数:--token_auth_file=SOMEFILE
Token file的格式包含三列:token,username,userid。当使用Token作为验证方式时,需要在对APIServer的HTTP请求中增加一个Header字段Authorization,并将它的值设置为Bearer SOMETOKEN。
基本信息认证
设置APIServer的启动参数:--basic_auth_file=SOMEFILE
如果更改了文件中的密码,只有重新启动APIServer使其重新生效。该文件的基本格式包含三列:passwork,username,userid。当使用此作为认证方式时,需要在对APIServer的HTTP请求中增加一个Header字段Authorization,并将它的值设置为Basic BASE64ENCODEDUSER:PASSWORD。
在Kubernetes中,认证和授权是分开的,而且授权发生在认证完成之后。认证过程是检验发起API请求的用户是不是他所声称的那个人;而授权过程则判断此用户是否有执行该API请求的权限;因此授权是以认证的结果作为基础的。
Kubernetes授权模块应用于所有对APIServer的HTTP访问请求,而访问只读端口不需要认证和授权过程。APIServer启动时默认将authorization_mode设置为AlwaysAllow模式,即永远允许。
Kubernetes授权模块检查每个HTTP请求,并提取请求上下文中的所需属性(例如:user,resource kind,namespace)与访问控制规则进行比较。任何一个API请求在被处理前都需要通过一个或多个访问控制规则的验证。
目前,Kubernetes支持并实现了以下授权模式(authorization_mode),这些授权模式可以通过在APIServer启动时传入参数进行选择。试用
- --authorization_mode=AlwaysDeny
- --authorization_mode=AlwaysAllow
- --authorization_mode=ABAC
AlwaysDeny模式屏蔽所有的请求(一般用于测试)。AlwaysAllow模式允许所有请求,默认APIServer启动时采用的便是AlwaysAllow模式。ABAC(Attribute-Based Access Control,即基于属性的访问控制)模式则允许用户自定义授权访问控制规则。
ABAC模式
一个API请求中有4个属性被用于用户授权过程:
- UserName:String类型,用于标识发起请求的用户。如果不进行认证、授权操作,则该字符串为空。
- ReadOnly:Bool类型,标识该请求是否仅进行只读操作(GET就是只读操作)。
- Kind:String类型,用于标识要访问的Kubernetes资源对象的类型。当访问/api/v1beta1/pods等API endpoint时,Kind属性才非空,但访问其他endpoint时,例如/version,/healthz等,Kind属性为空。
- Namespace:String类型,用于标识要访问的Kubernetes资源对象所在的namespace。
对于ABAC模式,在APIServer启动时除了需要传入--authorization_mode=ABAC选项外,还需要指定--authorization_policy_file=SOME_FILENAME。authorization_policy_file文件的每一行都是一个JSON对象,该JSON对象是一个没有嵌套的Map数据结构,代表一个访问控制规则对象。一个访问控制规则对象是一个包含以下字段的Map:
- user:--token_auth_file指定的user字符串。
- readonly:true或false。true表明该规则只应用于GET请求。
- kind:Kubernetes内置资源对象类型,例如pods、events等。
- namespace:也可以缩写成ns。
一个简单的访问控制规则文件如下所示,每一行定义一条规则:
说明:缺省的字段与该字段类型的零值(空字符串,0,false等)等价。试用
- {"user":"admin"}
- ## admin可以做任何事情,不受namespace,资源类型,请求类型的限制。
- {"user":"alice", "ns": "projectCaribou"}
- ## alice能够在namespace "projectCaribou"中做任何事情,不受资源类型,请求类型的限制。
- {"user":"kubelet", "readonly": true, "kind": "pods"}
- ## kubelet有权限读任何一个pod的信息。
- {"user":"kubelet", "kind": "events"}
- ## kubelet有权限读写任何一个event。
- {"user":"bob", "kind": "pods", "readonly": true, "ns": "projectCaribou"}
- ## bob有权限读取在namespace "projectCaribou"中所有pod的信息。
一个授权过程就是一个比较API请求中各属性与访问控制规则文件中对应的各字段是否匹配的一个过程。当APIServer接收到一个API请求时,该请求的各属性就已经确定了,如果有一个属性未被设置,则APIServer将其设为该类型的空值(空字符串,0,false等)。匹配规则如下所示:
- 如果API请求中的某个属性为空值,则规定该属性与访问控制规则文件中对应的字段匹配。
- 如果访问控制规则的某个字段为空值,则规定该字段与API请求的对应属性匹配。
- 如果API请求中的属性值非空且访问控制规则的某个字段值也非空,则将这两个值进行比较,如果相同则匹配,反之则不匹配。
- API请求的属性元组(tuple)会与访问控制规则文件中的所有规则逐条匹配,只要有一条匹配则表示匹配成功,如若不然,则授权失败。
Kubernetes提供基于集群的日志,允许将容器活动日志记录到一个日志中心。当集群被创建时,每个容器的标准输出和标准错误都可以通过运行在每个节点上的Fluentd 服务记录到Stackdriver或Elasticsearch中,然后使用Kibana进行查看。
Kubernetes对创建安全部署提供多种选择,没有适合所有情况的万能解决方案,所以熟悉这些安全选项、了解它们如何提高应用程序安全性是很重要的。
本文提到的安全实践,将Kubernetes的灵活配置能力加入到持续集成中,自动将安全性无缝融合到整个流程中。
Hadoop环境安全加固
Hadoop 环境安全问题
Hadoop 默认开放了很多端口来提供 WebUI 服务。下表列举了相关的端口信息:
模块 | 节点 | 默认端口 |
HDFS | NameNode | 50070 |
SecondNameNode | 50090 | |
DataNode | 50075 | |
Backup/Checkpoint node | 50105 | |
MapReduce | JobTracker | 50030 |
TaskTracker | 50060 |
通过访问 NameNode WebUI 管理界面的 50070 端口,可以下载任意文件。而且,如果 DataNode 的默认端口 50075 开放,攻击者可以通过 HDSF 提供的 restful API 对 HDFS 存储的数据进行操作。
- Cloudera Manager 版本 <= 5.5
- Cloudera HUE 版本 <= 3.9.0
- Apache Ranger 版本 <= 0.5
- Unauthenticated policy download
- Authenticated SQL injection (CVE-2016-2174)
- Apache Group Hadoop 2.6.x
Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据的提取转化加载(ETL),是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,HQL 语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
HQL 语言可以通过 transform 命令自定义 Hive 使用的 Map/Reduce 脚本,从而调用 Shell、Python 等语言,导致攻击者可以通过 Hive 接口等相关操作方式直接获取服务器权限。
根据上述 Hadoop 环境安全问题可以发现,对外暴露服务端口会存在严重的安全风险。建议您按照以下方式为 Hadoop 环境进行安全加固。
使用 安全组防火墙 或本地操作系统防火墙对访问源 IP 进行控制。如果您的 Hadoop 环境仅对内网服务器提供服务,建议不要将 Hadoop 服务所有端口发布到互联网。
启用 Kerberos 认证功能。
不定期关注 Hadoop 官方发布的最新版本,并及时更新补丁。
- Hadoop 所有端口信息
FileZilla FTP Server 安全加固
设置管理密码
服务器的管理密码默认为空,建议您设置一个较复杂的密码。例如,应至少包含大小写字母、数字、特殊符号中的任意两种。
在访问 FTP 服务器时,默认会在 Banner 中显示服务器的版本信息,通过屏蔽版本信息显示,可以加大恶意攻击的时间成本。操作步骤如下:
- 前往 General settings > Welcome message。
- 从右侧的 Custom welcome message 输入框中删除 %v 变量,或者直接将全部文本替换为自定义的文字。
- 建议勾选下面的 Hide welcome message in log,以减少日志中的垃圾信息。
建议只在一个地址上启用 FTP 服务。例如,若您只需要在内网使用 FTP 服务时,就不必在服务器绑定的公网地址上开启 FTP 服务。操作步骤如下:
- 前往 General settings > IP Bindings。
- 在右侧窗口中将默认的 * 号修改为指定的地址。
设置全局 IP 过滤器,限制允许访问的 IP 地址。操作步骤如下:
- 前往 General settings > IP Filters。
- 在右侧上部窗口中填入要阻止访问的 IP 范围,在右侧下部窗口中填写允许访问的 IP 范围。
注意:通常采用阻止所有 IP(填写 *),然后仅允许部分 IP 的方式来进行有效的限制。例如,下图中仅允许 192.168.1.0/24 网段访问 FTP 服务。
另外,FileZilla 服务器也支持用户级和用户组级的 IP 过滤器。前往 Edit > Users/Groups 打开对应设置页,在设置页中找到 IP Filters,然后选择需要设置的用户,设置允许和拒绝的 IP 即可。设置方法与全局 IP 过滤器相同。
FTP Bounce 攻击是一种利用 FXP 功能的攻击形式,默认情况下服务器未关闭相关功能,建议将相关功能设置为阻止。
如果服务器需要在与某个特定 IP 的服务器之间使用该功能,建议使用 IPs must match exactly 选项,然后通过 IP Filters(见 使用访问控制)来进行限制来访 IP。操作步骤如下:
- 前往 General settings > Security settings。
- 如下图所示,默认选项已经启用了需要精确匹配连接地址,建议不要修改。
默认情况下,当出现多次用户认证失败后,服务器会断开与客户端的连接,但并没有严格的限制策略。通过下面的设置,可以对连续多次尝试登录失败的客户端 IP 进行阻止,干扰其连续尝试行为。
- 前往 General settings > Autoban。
- 下图中的设置会对一小时内连续 10 次登录失败的 IP 进行阻止,阻止时长为 1 个小时。
FileZilla 服务器未提供限制密码复杂度的选项,且服务器用户是由管理员通过管理接口来添加的,用户也无法通过 FTP 命令来修改密码。因此,建议管理员在添加用户时为用户配置复杂的密码。
FileZilla 支持目录级别的访问权限设置,可对某个目录设置文件读 、写、删除、添加、目录创建、删除、列举等权限。建议根据实际应用需要,结合用户权限最小化原则来分配文件夹的权限。
注意:该操作需要提前添加账号和组后才能配置。
FileZilla 服务器支持 TLS 加密功能,用户如果没有证书可以使用自带功能来创建。
也支持针对单个用户强制启用 TLS 加密访问。
FileZilla 服务器默认未开启日志记录,为了方便对各种事件的追查,建议开启日志记录功能,并将日志设置为每天一个日志文件,避免单文件过大。
默认情况下,日志已经设置不记录用户密码;但在加固的时候应检查此选项,确保其已启用,避免密码泄露。
Elasticsearch服务安全加固
漏洞详情
Elasticsearch 中存在以下高危漏洞。
类型 | CVE | 受影响版本 | 描述 |
远程命令执行 | CVE-2014-3120 | - | Elasticsearch 的脚本执行 (scripting) 功能,可以很方便地对查询出来的数据进行再加工处理。但是,其使用的 MVEL 脚本引擎没有做过任何防护(或者沙盒包装),可以直接执行任意代码。 |
远程代码执行 | - | 1.3.0-1.3.7,1.4.0-1.4 | Elasticsearch 使用 Groovy 作为脚本语言,虽然加入了沙盒进行控制,危险的代码会被拦截。但是由于沙盒限制不严格,仅通过黑白名单来判断,导致攻击者可以绕过沙盒,执行远程代码。 |
未授权访问 | - | - | Elasticsearch 在安装了 River 机制之后可以同步多种数据库数据(包括关系型的MySQL、MongoDB 等)。如果 http://localhost:9200/cat/indices中 indices 包含了 _river,则代表 Elasticsearch 已安装 River 机制。而通过泄露的 http://localhost:9200/_rvier/_search URL 地址,攻击者可以获取到敏感信息。 |
由于 Elasticsearch 的 HTTP 连接没有提供任何的权限控制措施,一旦部署在公共网络就容易有数据泄露的风险。
安全加固方案
通过正规渠道(如 Elastic 官网)下载 Elasticsearch 的最新版本。
- 下载完成后,将下载文件的 sha1 值和下载时官网页面提供的 sha1 值进行对比,避免下载过程中被恶意攻击者拦截破坏文件,甚至注入恶意代码。
- 不要随便安装第三方的插件,插件有可能引入安全漏洞甚至本身自带后门,需谨慎使用。
- 关注 Elastic 网站,及时更新 Elasticsearch 至最新版本。Elasticsearch 每次版本发布都会优化和改进一部分功能,尤其是安全漏洞的补丁。同时,仔细阅读 Elasticsearch 的版本更新记录。
注意:更新升级前,建议您先进行快照备份,及本地测试。
Elasticsearch 默认端口是 9200。
- 不要把 Elasticsearch 的 9200 端口服务发布到互联网上。
- 使用 阿里云安全组防火墙 或本地操作系统防火墙对访问源 IP 进行隔离控制。
进入 config 目录,修改 elasticsearch.yml 配置文件中以下参数:
- network.bind_host: 192.168.0.1
- # 设置绑定的 IP 地址,可以是 IPv4 或 IPv6 地址,默认为 0.0.0.0。
- network.publish_host: 192.168.0.1
- # 设置其它节点和该节点交互的 IP 地址,如果不设置它会自动判断,值必须是个真实的 IP 地址。
- network.host: 192.168.0.1
- # 同时设置上述两个参数:bind_host 和 publish_host。
修改默认端口
进入 config 目录,修改 elasticsearch.yml 配置文件中以下参数:
- ransport.tcp.port: 9300
- # 设置节点间交互的 TCP 端口,默认是 9300。
- transport.tcp.compress: true
- # 设置是否压缩 TCP 传输时的数据,默认为 false,即不压缩。
- http.port: 9200
- # 设置对外服务的 HTTP 端口,默认为 9200。
进入 config 目录,修改 elasticsearch.yml 配置文件中以下参数:
- http.enabled: false
- # 是否使用 HTTP 协议对外提供服务,默认为 true,即开启。
Shield 是 Elastic 公司为 Elasticsearch 开发的一个安全插件。在安装此插件后,Shield 会拦截所有对 Elasticsearch 的请求,并进行认证与加密,保障 Elasticsearch 及相关系统的安全性。Shield 是商业插件,需要 Elasticsearch 的商业许可。第一次安装许可的时候,会提供 30 天的免费试用权限。30 天后,Shield 将会屏蔽 clusterhealth, cluster stats, index stats 等 API,其余功能不受影响。
使用 Shield 可以定义一系列已知的用户,并用其认证用户请求。这些用户存在于抽象的“域”中。一个“域”可以是下面几种类型:
- LDAP 服务
- ActiveDirectory 服务
- 本地 esusers 配置文件(类似 /etc/passwd)
Shield 的权限控制包含下面几种元素:
- 被保护的资源 SecuredResource:权限所应用到的对象,比如某个 index,cluster 等。
- 特权 Priviliege:角色对对象可以执行的一种或多种操作,比如 read,write 等。还可以是 indicies:/data/read/perlocate 等对某种对象特有的操作。
- 许可 Permissions:对被保护的资源拥有的一个或多个特权,如 read on the"products" index。
- 角色 Role:一组许可的集成,具有独立的名称。
- 用户 Users:用户实体,可以被赋予多种角色,他们可以对被保护的资源执行相应角色所拥有的各种特权。
执行安装步骤前,请确保满足以下安装环境条件:
- 您安装了 Java7 或更新版本。
- 您将 Elasticsearch 1.5.0+ 解压安装到了本机上。如果您使用 APT 或 YUM 安装,默认的安装目录可能在 /usr/share/elasticsearch。
参照以下步骤完成安装:
- 进入 Elasticsearch 安装目录:
- cd /usr/share/elasticsearch
- 安装 Elasticsearch 许可插件:
bin/plugin -i elasticsearch/license/latest
- 安装 Shield 插件:
bin/plugin -i elasticsearch/shield/latest
- 将 Shield 配置文件移动或链接至 /etc/elasticsearch/shield 目录中:
ln -s /usr/share/elasticsearch/config/shield /etc/elasticsearch/shield
说明:Elasticsearch 服务在启动时会在 /etc/elasticsearch/shield 目录下寻找 Shield 配置文件,而这些配置文件在安装 Shield 时会出现在 /usr/share/elasticsearch/config/shield 中,因此需要将配置文件移动或链接至该目录。
- 重启 Elasticsearch 服务:
service elasticsearch restart
- 新建一个 Elasticsearch 管理员账户,填写新密码:
bin/shield/esusers
useradd es_admin -r admin
- 直接使用 RESTFUL API 访问 Elasticsearch 的请求都会被拒绝:
curl -XGET
'http://localhost:9200/'
需要在请求中添加用户名和密码:
curl -u es_admin -XGET 'http://localhost:9200/'
更多信息,请参考:
Elasticsearch 默认的集群名称是 elasticsearch,请在您的生产环境中将其修改成其他名称。确保在不同的环境和不同的集群下使用不同的名称;并且在监控集群节点时,如果有未知节点加入,一定要及时预警。
不要以 root 身份来运行 Elasticsearch,不要和其他服务共用相同的用户,并把用户的权限最小化。
应用示例:
- sudo -u es-user ES_JAVA_OPTS="-Xms1024m -Xmx1024m"
- /opt/elasticsearch/bin/elasticsearc
请确保为 Elasticsearch 的目录分配了合理的读写权限,避免使用共享文件系统。确保只有 Elasticsearch 的启动用户才有权访问目录。日志目录也需要正确配置,避免泄露敏感信息。
使用 Elasticsearch 提供的备份还原机制,定期对 Elasticsearch 的数据进行快照备份。
Elasticsearch 支持使用全部(_all)和通配符(*)来批量删除索引。在生产环境,该操作存在一定风险,你可以通过设置 action.destructive_requires_name: true 参数来禁用它。
Elasticsearch 的 config 文件夹里面有两个配置文件:
- elasticsearch.yml:基本配置文件。
- logging.yml:日志配置文件。由于 Elasticsearch 使用 log4j 来记录日志的,logging.yml 中的设置请按普通 log4j 配置文件进行设置。
启用日志功能需要修改 elasticsearch.yml 配置文件:
- path.logs: /path/to/logs
- # 设置日志文件的存储路径,默认是 Elasticsearch 根目录下的 logs 文件夹
更多信息
phpMyadmin 服务安全加固
加固方案
根据通常的业务需求,数据库管理后台主要方便地为数据库管理员、开发人员服务,使用人员范围小,一旦对外网全部开放,将可能会造成严重的数据泄露事件发生。所以在部署安装完毕后,我们建议您对 phpMyadmin 管理控制台进行安全加固,具体如下:
1.网络访问控制策略
限制访问人员 IP 配置 phpMyadmin。
- 您可以使用云服务器提供的 安全组防火墙策略 对访问源 IP 地址进行限制,避免不必要的人员访问数据库管理后台。
- phpMyadmin 也默认提供了访问控制功能,具体配置如下:
进入 phpMyAdmin 目录,找到 config.inc.php,如果没有,可以将根目录下的config.sample.inc.php 复制为 config.inc.php。
编辑 config.inc.php,添加下面两行代码,其中 192.168.0.1 是允许访问 phpMyAdmin 的 IP,Access denied 是未经授权访问时的提示信息:试用
-
- ?$ip_prefix = '192.168.0.1';
- if (substr($_SERVER['REMOTE_ADDR'], 0, strlen($ip_prefix)) != $ip_prefix ) die('Access denied');
2.账号与口令安全策略
- 设置强度复杂的口令,可以有效避免被攻击者轻易猜解成功,设置完毕后无需重启服务,及时生效;
- 根据使用人员角色对数据库账号进行精细化授权,防止运维风险;
具体可以参见 MySQL服务加固文档-“授权”部分。
3.安全检测和监控
- 阿里云云盾态势感知支持该漏洞的检测和监控告警功能,建议您到控制台开通基础版态势感知,可以实时检测和告警,帮助您及时了解安全漏洞,并指导您快速修复该问题。
数据库服务安全加固
MongoDB服务安全加固
漏洞详情
漏洞危害
开启MongoDB服务后,如不添加任何参数,默认是没有权限验证的。登录的用户可以通过默认端口无需密码对数据库进行任意操作(包括增、删、改、查等高危动作),而且可以远程访问数据库。
安装完MongoDB服务后默认有一个admin数据库,此时admin数据库是空的,没有记录任何权限相关的信息。当admin.system.users一个用户都没有时,即使MongoDB启动时添加了—auth参数,如果没有在admin数据库中添加用户,此时不进行任何认证还是可以做任何操作(不管是否以—auth 参数启动),直到在admin.system.users中添加一个用户。加固的核心方案是实现只有在admin.system.users中添加用户之后,MongoDB的认证、授权服务才能生效。
- 您可以登录到阿里云云盾控制台,使用云盾安骑士MongoDB检测是否存在此安全问题。
- 如果您是MongoDB管理员,也可以使用以下方式检查是否有进一步的入侵行为:
- 查看MongoDB的日志是否完整,并确认执行删除数据库的源IP地址和时间、行为。
- 检查MongoDB帐户,查看是否没有添加admin用户的密码(使用db.system.users.find()命令)。
- 检查GridFS,查看是否存储任何文件(使用db.fs.files.find()命令)。
- 检查日志文件,查看有哪些用户访问了MongoDB(使用show log global命令)。
重要提示: 如果您需要自己搭建MongoDB数据库,强烈推荐您使用yum rpm方式安装MongoDB Server 服务。
- 修改默认端口。
修改默认的MongoDB 端口(默认为:TCP 27017)为其他端口。
- 不要把MongoDB服务器直接部署在互联网或者DMZ上。
- 使用安全组防火墙或本地操作系统防火墙对访问源IP进行控制,如果仅对内网服务器提供服务,建议禁止将MongoDB服务发布到互联网。
- 安全组相当于防火墙功能,默认公网入安全组策略为允许在互联网上访问所有端口。
- 将默认安全组删除,添加拒绝所有规则,即可屏蔽服务。
- 根据您的业务情况添加服务的允许规则。
- 使用—bind_ip选项。
该选项可以限制监听接口IP。当在启动MongoDB的时候,使用--bind_ip 192.168.0.1表示启动IP地址绑定,数据库实例将只监听192.168.0.1的请求。
- 启动基于角色的登录认证功能。
在admin数据库中创建用户,如用户名supper,密码supWDxsf67%H(此处为举例说明,请勿使用此账号密码)。
-
- 在未开启认证的环境下,登录到数据库。
[mongodb@rac3 bin]$ ./mongo 127.0.0.1:27028 (此处修改了默认端口)
MongoDB shell version: 2.0.1
connecting to: 127.0.0.1:27028/test
-
- 切换到admin数据库。
> use admin
switched to db admin
>
-
- 创建管理员账号。
> db.addUser("supper", "supWDxsf67%H")或
>db.createUser({user:"supper",pwd:"supWDxsf67%H",roles:["root"]})
{ "n" : 0, "connectionId" : 4, "err" : null, "ok" : 1 }
{
"user" : "supper",
"readOnly" : false,
"pwd" : "51a481f72b8b8218df9fee50b3737c44",
"_id" : ObjectId("4f2bc0d357a309043c6947a4")
}
管理员账号将在system.users中。
> db.getCollectionNames()
[ "system.indexes", "system.users", "system.version" ]
说明
-
-
- MongoDB从V3版本开始取消使用addUser方法,采用db.createUser方法创建用户。
- 账号不要设置为常见账号,密码需要满足一定的复杂度,长度至少八位以上,并包括大小写字母、数字、特殊字符混合体,不要使用生日、姓名、身份证编号等常见密码。
- 验证用户是否创建成功。
-
> db.auth("supper","supWDxsf67%H")
> exit
bye
-
- 结束进程,重启MongoDB服务。
./mongod --dbpath=/path/mongodb --bind_ip=192.168.0.1 --port=27028 --fork=true logpath=/path/mongod.log &
说明
-
- admin.system.users中将会保存比在其它数据库中设置的用户权限更大的用户信息,拥有超级权限,也就是说在admin中创建的用户可以对mongodb中的其他数据库数据进行操作。
- MongoDB系统中,数据库是由超级用户来创建的,一个数据库可以包含多个用户,一个用户只能在一个数据库下,不同数据库中的用户可以同名。
- 特定数据库(比如DB1)的用户User1,不能够访问其他数据库DB2,但是可以访问本数据库下其他用户创建的数据。
- 不同数据库中同名的用户不能够登录其他数据库,比如DB1、DB2都有user1,以user1登录DB1后,不能够登录到DB2进行数据库操作。
- 在admin数据库创建的用户具有超级权限,可以对mongodb系统内的任何数据库的数据对象进行操作。
- 使用db.auth()可以对数据库中的用户进行验证,如果验证成功则返回1,否则返回0。 db.auth()只能针对登录用户所属的数据库的用户信息进行验证,不能验证其他数据库的用户信息。
- 禁用HTTP和REST端口。
MongoDB自身带有一个HTTP服务和并支持REST接口(在V2.6以后这些接口默认是关闭的)。MongoDB默认使用默认端口监听Web服务,一般不需要通过Web方式进行远程管理,建议禁用。
修改配置文件或在启动的时候选择–nohttpinterface参数即可。
nohttpinterface = false
- 开启日志审计功能。
审计功能可以用来记录用户对数据库的所有相关操作。这些记录可以让系统管理员在需要的时候分析数据库在什么时段发生了什么事情。
- 使用SSL加密功能。
MongoDB集群之间以及从客户端连接到MongoDB实例的连接应该使用SSL。使用SSL对性能没有影响并且可以防范类似于man-in-the-middle的攻击。
注意MongoDB社区版默认并不支持SSL。您可以选用MongoDB企业版(支持SSL),或者从源码重新编译MongoDB并使用—ssl选项来获得SSL功能。
以上所有配置,推荐以配置文件形式保存配置。试用
[mongodb@rac3 bin]$ vim /path/mongod.conf
port=27028-------端口。默认为27017端口,MongoDB的默认服务TCP端口,监听客户端连接。要是端口设置小于1024,比如1021,则需要root权限启动,不能用mongodb帐号启动,(普通帐号即使是27017也起不来)否则报错:[mongo --port=1021 连接]
bind_ip=192.168.0.1------绑定地址。默认127.0.0.1,只能通过本地连接。进程绑定和监听来自这个地址上的应用连接。要是需要给其他服务器连接,则需要注释掉这个或则把IP改成本机地址,如192.168.200.201[其他服务器用 mongo --host=192.168.200.201 连接] ,可以用一个逗号分隔的列表绑定多个IP地址。
logpath=/path/mongod.log------开启日志审计功能,此项为日志文件路径,可以自定义指定。
pidfilepath=/path/mongod.pid------进程ID,没有指定则启动时候就没有PID文件。
auth=true------用户认证,默认false。不需要认证。当设置为true时候,进入数据库需要auth验证,当数据库里没有用户,则不需要验证也可以操作。直到创建了第一个用户,之后操作都需要验证。
logappend=true------写日志的模式:设置为true为追加。默认是覆盖。如果未指定此设置,启动时MongoDB的将覆盖现有的日志文件。
fork=true------是否后台运行,设置为true 启动 进程在后台运行的守护进程模式。默认false。
nohttpinterface = false------是否禁止http接口,即28017 端口开启的服务。默认false,支持。
然后,启动MongoDB服务时加载配置文件。
[mongodb@rac3 bin]$ ./mongod -f /path/mongod.conf
- 对业务关键敏感数据进行加密存储。
建议您梳理业务数据,对关键的敏感数据加密后入库,例如:账号、密码、邮箱地址、手机号码、身份ID等其他数据。加密算法推荐选择国际通用加密算法和多次加盐组合自定义算法,防止加密算法被破解。
即使黑客获取数据后,也查看不了数据,通过“看不懂”的数据加密方式将损失降到最低。
- 对数据进行本地异地备份。
完善的备份策略是保证数据安全的最后一根救命稻草。
推荐:可靠的本地备份+远程备份存储方案
-
- 本地备份
MongoDB备份方式
>mongodump -h dbhost -d dbname -o dbdirectory
-h:
MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:
需要备份的数据库实例,例如:test
-o:
备份的数据存放位置,例如:c:\data\dump,该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
MongoDB数据恢复试用
mongodb使用 mongorestore 命令来恢复备份的数据。
语法
mongorestore命令脚本语法如下:
>mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
-h:
MongoDB所在服务器地址
-d:
需要恢复的数据库实例,例如:test,这个名称也可以和备份时候的不一样,比如test2。
--directoryperdb:
备份数据所在位置,例如:c:\data\dump\test。
--drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用!
Mongodump命令可选参数列表如下所示。
备份策略
全量备份:可以最快的时间快速恢复所有数据,缺点是备份成本大,时间长。
全量备份+增量备份:可以较快的恢复所有数据,缺点是恢复时间长,如果增量数据有问题,无法恢复所有数据。
搭建从库:直接切换到从库,前提是从库的数据安全可靠。
- 使用阿里云MongoDB云服务。
您可以使用更低的成本解决MongoDB的安全问题,阿里云MongoDB云数据库服务从设计之初就重点考虑了安全问题,比如完全不受针对删除数据库的勒索事件的影响。
MySQL服务安全加固
漏洞发现
您可以使用安骑士企业版自动检测您的服务器上是否存在 MySQL 漏洞问题,或者您也可以自己排查您服务器上的 MySQL 服务是否存在安全问题。
- 帐号安全
- 禁止 Mysql 以管理员帐号权限运行
以普通帐户安全运行 mysqld,禁止以管理员帐号权限运行 MySQL 服务。在 /etc/my.cnf 配置文件中进行以下设置。试用
-
-
- [mysql.server]
- user=mysql
- 避免不同用户间共享帐号
-
参考以下步骤。
-
-
- 创建用户。试用
- mysql> mysql> insert into
- mysql.user(Host,User,Password,ssl_cipher,x509_issuer,x509_sub
- ject) values("localhost","pppadmin",password("passwd"),'','','');
- 创建用户。试用
-
执行以上命令可以创建一个 phplamp 用户。
-
-
- 使用该用户登录 MySQL 服务。试用
-
mysql>exit;
@>mysql -u phplamp -p
@>输入密码
mysql>登录成功
-
- 删除无关帐号
DROP USER 语句可用于删除一个或多个 MySQL 账户。使用 DROP USER 命令时,必须确保当前账号拥有 MySQL 数据库的全局 CREATE USER 权限或 DELETE 权限。账户名称的用户和主机部分分别与用户表记录的 User 和 Host 列值相对应。
执行DROP USER user;语句,您可以取消一个账户和其权限,并删除来自所有授权表的帐户权限记录。
- 口令
检查账户默认密码和弱密码。口令长度需要至少八位,并包括数字、小写字母、大写字母和特殊符号四类中的至少两种类型,且五次以内不得设置相同的口令。密码应至少每 90 天进行一次更换。
您可以通过执行以下命令修改密码。
mysql> update user set password=password('test!p3') where user='root';
mysql> flush privileges;
- 授权
在数据库权限配置能力范围内,根据用户的业务需要,配置其所需的最小权限。
查看数据库授权情况。试用
mysql> use mysql;
mysql> select * from user;
mysql>select * from db;
mysql>select * from host;
mysql>select * from tables_priv;
mysql>select * from columns_priv;
通过 revoke 命令回收不必要的或危险的授权。试用
mysql> help revoke
Name: 'REVOKE'
Description:
Syntax:
REVOKE
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type]
{
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
}
FROM user [, user] ...
- 开启日志审计功能
数据库应配置日志功能,便于记录运行状况和操作行为。
MySQL服务有以下几种日志类型:
-
- 错误日志: -log-err
- 查询日志: -log (可选)
- 慢查询日志: -log-slow-queries (可选)
- 更新日志: -log-update
- 二进制日志: -log-bin
找到 MySQL 的安装目录,在 my.ini 配置文件中增加上述所需的日志类型参数,保存配置文件后,重启 MySQL 服务即可启用日志功能。例如,试用
#Enter a name for the binary log. Otherwise a default name will be used.
#log-bin=
#Enter a name for the query log file. Otherwise a default name will be used.
#log=
#Enter a name for the error log file. Otherwise a default name will be used.
log-error=
#Enter a name for the update log file. Otherwise a default name will be used.
#log-update=
该参数中启用错误日志。如果您需要启用其他的日志,只需把对应参数前面的 “#” 删除即可。
日志查询操作说明
-
-
- 执行show variables like 'log_%';命令可查看所有的 log。
- 执行show variables like 'log_bin';命令可查看具体的 log。
-
- 安装最新补丁
确保系统安装了最新的安全补丁。
注意: 在保证业务及网络安全的前提下,并经过兼容性测试后,安装更新补丁。
- 如果不需要,应禁止远程访问
禁止网络连接,防止猜解密码攻击、溢出攻击、和嗅探攻击。
注意: 仅限于应用和数据库在同一台主机的情况。
如果数据库不需要远程访问,可以禁止远程 TCP/IP 连接,通过在 MySQL 服务器的启动参数中添加--skip-networking参数使 MySQL 服务不监听任何 TCP/IP 连接,增加安全性。
您可以使用 安全组 进行内外网访问控制,建议不要将数据库高危服务对互联网开放。
- 设置可信 IP 访问控制
通过数据库所在操作系统的防火墙限制,实现只有信任的 IP 才能通过监听器访问数据库。试用
mysql> GRANT ALL PRIVILEGES ON db.*
-> -> TO 用户名@'IP子网/掩码';
- 连接数设置
根据您的机器性能和业务需求,设置最大、最小连接数。
在 MySQL 配置文件(my.conf 或 my.ini)的 [mysqld] 配置段中添加max_connections = 1000,保存配置文件,重启 MySQL 服务后即可生效。
预防数据库勒索事件
基线安全问题
从MongoDB和Elasticsearch,以及现在的MySQL数据库勒索案例中,可以发现受害数据库都是因为基线安全问题,才被黑客劫持而勒索。
这些被勒索的自建数据库服务都开放在公网上,并且存在空密码或者弱口令,使得攻击者可以轻易暴力破解出密码,连接数据库,下载并清空数据。再加上不正确的安全组配置,甚至没有配置任何网络访问控制策略,导致问题被放大。
基线安全问题已经成了Web漏洞之外入侵服务器的主要途径,特别是无网络访问控制、默认账号和空口令、默认账号弱口令、后台暴露、后台无口令、未授权访问等情况。错误的配置可以导致相关服务暴露在公网上,成为黑客攻击的目标;加上采用空密码和弱口令,更方便了黑客以极低的攻击成本入侵这些服务。
找到了原因,就可以”对症下药”,您可以通过自动检测攻击或人工两种方式对您的数据库进行排查。
阿里云安骑士提供默认的检测策略。您可以登录到控制台,查看安骑士检测的结果,并根据结果,来整改封堵漏洞。
您也可以使用类似NMap这样的端口扫描工具,直接针对被检查的服务器IP,在服务器外网执行扫描,以检查业务服务器开放在外网的端口和服务。
注意:需要在授权情况下对自身业务进行扫描,不要对其他不相关的业务进行非法扫描,以避免法律风险。
当您安装完服务,或在运维过程中发现对外开放了服务后,您可以使用Windows自带防火墙功能、Linux系统的iptables防火墙功能来配置必要的访问控制策略。
推荐您使用ECS安全组策略,控制内外网出入的流量,防止暴露更多不安全的服务。
必要的安全加固是确保业务在云上安全可靠运行的条件,您可以使用安骑士的自动化检测和人工加固指南对业务服务器进行安全加固。
参考更多的 安全加固指南。
语言运行环境加固
PHP环境安全加固
一、启用 PHP 的安全模式
PHP 环境提供的安全模式是一个非常重要的内嵌安全机制,PHP 安全模式能有效控制一些 PHP 环境中的函数(例如system()函数),对大部分的文件操作函数进行权限控制,同时不允许对某些关键文件进行修改(例如 /etc/passwd)。但是,默认的 php.ini 配置文件并没有启用安全模式。
您可以通过修改 php.ini 配置文件启用 PHP 安全模式:试用
- safe_mode = on
当您启用安全模式后,如果safe_mode_gid选项被关闭,PHP 脚本能够对文件进行访问,且相同用户组的用户也能够对该文件进行访问。
因此,建议您将该选项设置为关闭状态:试用
- safe_mode_gid = off
注意: 该选项参数仅适用于 Linux 操作系统。
如果不进行该设置,您可能无法对服务器网站目录下的文件进行操作。
如果启用了安全模式后,想要执行某些程序的时候,可以指定需要执行程序的主目录,例如:试用
- safe_mode_exec_dir = /usr/bin
一般情况下,如果不需要执行什么程序,建议您不要指定执行系统程序的目录。您可以指定一个目录,然后把需要执行的程序拷贝到这个目录即可,例如:试用
- safe_mode_exec_dir = /temp/cmd
但是,更推荐您不要执行任何程序。这种情况下,只需要将执行目录指向网页目录即可:试用
- safe_mode_exec_dir = /usr/www
注意:执行目录的路径以您实际操作系统目录路径为准。
如果您需要在安全模式下包含某些公共文件,您只需要修改以下选项即可:试用
- safe_mode_include_dir = /usr/www/include/
一般情况下,PHP 脚本中包含的文件都是在程序已经写好的,可以根据您的具体需要进行设置。
使用open_basedir选项能够控制 PHP 脚本只能访问指定的目录,这样能够避免 PHP 脚本访问不应该访问的文件,一定程度下降低了 phpshell 的危害。一般情况下,可以设置为只能访问网站目录:试用
- open_basedir = /usr/www
如果您启用了安全模式,那么可以不需要设置函数禁止,但为了安全考虑,还是建议您进行相关设置。例如,您不希望执行包括system()等在内的执行命令的 PHP 函数,以及能够查看 PHP 信息的phpinfo()等函数,那么您可以通过以下设置禁止这些函数:试用
- disable_functions = system, passthru, exec, shell_exec, popen, phpinfo, escapeshellarg, escapeshellcmd, proc_close, proc_open, dl
如果您想要禁止对于任何文件和目录的操作,那么您可以关闭以下文件相关操作。
- disable_functions = chdir, chroot, dir, getcwd, opendir, readdir, scandir, fopen, unlink, delete, copy, mkdir, rmdir, rename, file, file_get_contents, fputs, fwrite, chgrp,chmod, chown
注意: 以上设置中只列举了部分比较常用的文件处理函数,您也可以将上面的执行命令函数和这些文件处理函数相结合,就能给抵制大部分的 phpshell 威胁。
为了防止黑客获取服务器中 PHP 版本的信息,您可以禁止该信息在 HTTP 头部内容中泄露:试用
- expose_php = off
这样设置之后,黑客在执行telnet <domain> 80尝试连接您的服务器的时候,将无法看到 PHP 的版本信息。
在 PHP 环境中提交的变量,包括使用 POST 或者 GET 命令提交的变量,都将自动注册为全局变量,能够被直接访问。这对您的服务器是非常不安全的,因此建议您将注册全局变量的选项关闭,禁止将所提交的变量注册为全局变量。试用
- register_globals = off
注意: 该选项参数在 PHP 5.3 以后的版本中已被移除。
当然,如果这样设置之后,获取对应变量的时候就需要采取合理方式。例如,获取 GET 命令提交的变量 var,就需要使用$_GET['var']命令来进行获取,在进行 PHP 程序设计时需要注意。
SQL 注入是一个非常危险的问题,小则造成网站后台被入侵,重则导致整个服务器沦陷。
magic_quotes_gpc选项默认是关闭的。如果打开该选项,PHP 将自动把用户提交对 SQL 查询的请求进行转换(例如,把 ’ 转换为 \’ 等),这对于防止 SQL 注入攻击有很大作用,因此建议您将该选项设置为:试用
- magic_quotes_gpc = on
注意: 该选项参数在 PHP 5.4.0 以后的版本中已被移除。
一般 PHP 环境在没有连接到数据库或者其他情况下会有错误提示信息,错误信息中可能包含 PHP 脚本当前的路径信息或者查询的 SQL 语句等信息,这类信息如果暴露给黑客是不安全的,因此建议您禁止该错误提示:试用
- display_errors = Off
如果您确实要显示错误信息,一定要设置显示错误信息的级别。例如,只显示警告以上的错误信息:试用
- error_reporting = E_WARNING & E_ERROR
注意: 强烈建议您关闭错误提示信息。
建议您在关闭错误提示信息后,对于错误信息进行记录,便于排查服务器运行异常的原因:试用
- log_errors = On
同时,需要设置错误日志存放的目录,建议您将 PHP 错误日志与 Apache 的日志存放在同一目录下:试用
- error_log = /usr/local/apache2/logs/php_error.log
注意: 该文件必须设置允许 Apache 用户或用户组具有写的权限。
Web应用安全加固
Apache服务安全加固
一、账号设置
以专门的用户帐号和用户组运行 Apache 服务。
- 根据需要,为 Apache 服务创建用户及用户组。如果没有设置用户和组,则新建用户,并在 Apache 配置文件中进行指定。
- 创建 Apache 用户组。
groupadd apache
-
- 创建 Apache 用户并加入 Apache 用户组。
useradd apache –g apache
-
- 将下面两行设置参数加入 Apache 配置文件 httpd.conf 中:
User apache
Group apache
- 检查 httpd.conf 配置文件中是否允许使用非专用账户(如 root 用户)运行 Apache 服务。
默认设置一般即符合要求。Linux 系统中默认使用 apache 或者 nobody 用户,Unix 系统默认使用 daemon 用户。
严格控制 Apache 主目录的访问权限,非超级用户不能修改该目录中的内容。
- Apache 的 主目录对应于 Apache Server配置文件 httpd.conf 中的 Server Root 控制项,应设置为:
Server Root /usr/local/apache
-
- 判定条件: 非超级用户不能修改该目录中的内容。
- 检测操作: 尝试进行修改,看是否能修改该目录中的内容。
该目录一般设置为 /etc/httpd 目录,默认情况下属主为 root 用户,其它用户不能修改该目录中的文件。默认设置一般即符合要求。
- 严格设置配置文件和日志文件的权限,防止未授权访问。
- 执行
chmod 600 /etc/httpd/conf/httpd.conf
命令设置配置文件为属主可读写,其他用户无读写权限。 - 执行
chmod 644 /var/log/httpd/*.log
命令设置日志文件为属主可读写,其他用户拥有只读权限。
- 执行
注意:
-
-
- /etc/httpd/conf/httpd.conf 配置文件的默认权限是644,可根据需要修改权限为600。
- /var/log/httpd/*.log 日志文件的默认权限为644,默认设置即符合要求。
-
Apache 设备应配置日志功能,对运行错误、用户访问等事件进行记录,记录内容包括时间,用户使用的 IP 地址等内容。
修改 httpd.conf 配置文件,设置日志记录文件、记录内容、记录格式。
- 错误日志:
LogLevel notice #日志的级别
ErrorLog /…/logs/error_log #日志的保存位置(错误日志)
- 访问日志:
LogFormat %h %l %u %t \”%r\” %>s %b “%{Accept}i\”%{Referer}i\” \”%{User-Agent}i\””
combined
CustomLog /…/logs/access_log combined (访问日志)
注意:
ErrorLog
指令设置错误日志文件名和位置。错误日志是最重要的日志文件。Apache httpd 程序将在这个文件中存放诊断信息和处理请求中出现的错误。若要将错误日志传送到 Syslog,则执行ErrorLog syslog
命令。CustomLog
指令指定了保存日志文件的具体位置以及日志的格式。访问日志中会记录服务器所处理的所有请求。LogFormat
命令用于设置日志格式,建议设置为 combined 格式。LogLevel
命令用于调整记录在错误日志中的信息的详细程度,建议设置为 notice。日志的级别,默认是 warn 级别,notice 级别比较详细,但在实际中由于日志会占用大量硬盘空间。
禁止 Apache 访问 Web 目录之外的任何文件。
- 修改 httpd.conf 配置文件。
Order Deny,Allow
Deny from all
- 设置可访问的目录。
Order Allow,Deny
Allow from /web
说明: 其中 /web 为网站根目录。
- 默认配置如下,可根据您的业务需要进行设置。
Options FollowSymLinks
AllowOverride None
目录列出会导致明显信息泄露或下载,建议禁止 Apache 列表显示文件。在 /etc/httpd/httpd.conf 配置文件中删除 Options 的 Indexes 设置即可。
- 修改 httpd.conf 配置文件:
#Options Indexes FollowSymLinks #删掉Indexes
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
将Options Indexes FollowSymLinks
中的Indexes
去掉,就可以禁止 Apache 显示该目录结构。Indexes
的作用就是当该目录下没有 index.html 文件时,自动显示目录结构。
- 重新启动 Apache 服务。
Apache 错误页面重定向功能可以防止敏感信息泄露。
- 修改 httpd.conf 配置文件:
ErrorDocument 400 /custom400.html
ErrorDocument 401 /custom401.html
ErrorDocument 403 /custom403.html
ErrorDocument 404 /custom404.html
ErrorDocument 405 /custom405.html
ErrorDocument 500 /custom500.html
注意: Customxxx.html 为要设置的错误页面。
- 重新启动 Apache 服务。
注意: 此项配置需要应用系统设有错误页面,或者不在 httpd 中设置,而完全由业务逻辑实现。
根据业务需要,合理设置 session 时间,防止拒绝服务攻击。
- 修改 httpd.conf 配置文件:
Timeout 10 #客户端与服务器端建立连接前的时间间隔
KeepAlive On
-
- i. KeepAliveTimeout 15 #限制每个 session 的保持时间是 15 秒 注:此处为一建议值,具体的设定需要根据现实情况。
- 重新启动 Apache 服务。
注意: 默认值为Timeout 120
,KeepAlive Off
,KeepAliveTimeout 15
,该项设置涉及性能调整。
隐藏 Apache 的版本号及其它敏感信息。
修改 httpd.conf 配置文件:
- ServerSignature Off ServerTokens Prod
关闭 TRACE 功能,防止 TRACE 方法被访问者恶意利用。
在 /etc/httpd/conf/httpd.conf 配置文件中添加以下设置参数:
- TraceEnable Off
注意: 该参数适用于 Apache 2.0 以上版本。
如果服务器上不需要运行 CGI 程序,建议禁用 CGI。
如果没有CGI程序,可以修改 /etc/httpd/conf/httpd.conf 配置文件,把 cgi-bin 目录的配置和模块都进行注释。
- #LoadModule cgi_module modules/mod_cgi.so
- #ScriptAlias /cgi-bin/ “/var/www/cgi-bin/”
- #
- #AllowOverride None
- # Options None
- #Order allow,deny
- #Allow from all
- #
服务器有多个 IP 地址时,只监听提供服务的 IP 地址。
- 执行以下命令查看是否绑定 IP 地址。
cat /etc/httpd/conf/httpd.conf|grep Listen
- 修改 /etc/httpd/conf/httpd.conf 配置文件。
Listen x.x.x.x:80
监听功能默认监听所有地址,如果服务器只有一个 IP 地址可不修改该项设置,如果有多个 IP 可根据需要进行设置。
删除缺省安装的无用文件。
- 删除缺省 HTML 文件:
# rm -rf /usr/local/apache2/htdocs/*
- 删除缺省的 CGI 脚本:
# rm –rf /usr/local/apache2/cgi-bin/*
- 删除 Apache 说明文件:
# rm –rf /usr/local/apache2/manual
- 删除源代码文件:
# rm -rf /path/to/httpd-2.2.4*
- 删除 CGI。
可根据实际情况删除,一般情况下 /var/www/html /var/www/cgi-bin 默认就是空的。
注意: 根据安装步骤不同和版本不同,某些目录或文件可能不存在或位置不同。
禁用 PUT、DELETE 等危险的 HTTP 方法。
修改 httpd.conf 配置文件,只允许 get、post 方法。
- <Location />
- <LimitExcept GET POST CONNECT OPTIONS>
- Order Allow,Deny
- Deny from all
- </LimitExcept>
- </Location>
您可根据需要进行设置,如果需要用到 PUT 或 Delete 等 HTTP 方法的话,在 /etc/httpd/conf/httpd.conf 配置文件中相应添加即可。
Tomcat服务安全加固
安全加固方案
由于此类型漏洞可能对业务系统造成比较严重的危害,建议您针对 Tomcat 管理后台进行以下安全加固配置。
1. 网络访问控制
- 如果您的业务不需要使用 Tomcat 管理后台管理业务代码,建议您使用安全组防火墙功能对管理后台 URL 地址进行拦截,或直接将 Tomcat 部署目录中 webapps 文件夹中的 manager、host-manager 文件夹全部删除,并注释 Tomcat 目录中 conf 文件夹中的 tomcat-users.xml 文件中的所有代码。
- 如果您的业务系统确实需要使用 Tomcat 管理后台进行业务代码的发布和管理,建议为 Tomcat 管理后台配置强口令,并修改默认 admin 用户,且密码长度不低于10位,必须包含大写字母、特殊符号、数字组合。
修改 conf/server.xml 文件,将下列代码取消注释:
- <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
- prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
启用访问日志功能,重启 Tomcat 服务后,在 tomcat_home/logs 文件夹中就可以看到访问日志。
修改 Tomcat 安装目录 conf 下的 tomcat-user.xml 文件,重新设置复杂口令并保存文件。重启 Tomcat 服务后,新口令即生效。
修改 conf/server.xml 文件把默认的 8080 访问端口改成其它端口。
修改访问 Tomcat 错误页面的返回信息,在 webapps\manger 目录中创建相应的401.html、404.htm、500.htm 文件,然后在 conf/web.xml 文件的最后一行之前添加下列代码:
- <error-page>
- <error-code>401</error-code>
- <location>/401.htm</location>
- </error-page>
- <error-page>
- <error-code>404</error-code>
- <location>/404.htm</location>
- </error-page>
- <error-page>
- <error-code>500</error-code>
- <location>/500.htm</location>
- </error-page>
防止直接访问目录时由于找不到默认页面,而列出目录下的文件的情况。
在 web.xml 文件中,将<param-name>listings</param-name>
改成<param-name>false</param-name>
。
删除 webapps 目录下的 docs、examples、manager、ROOT、host-manager 文件夹。
网站被植入Webshell的解决方案
什么是Webshell
从字面上理解,”Web”指需要服务器开放Web服务,”shell”指取得对服务器的某种程度的操作权限。Webshell指匿名用户(入侵者)通过网站端口,获取网站服务器的一定操作权限。
Webshell通常是以ASP、PHP、JSP、ASA或者CGI等网页文件形式存在的一种命令执行环境,也称为网页后门。黑客在入侵网站后,通常会将Webshell后门文件与网站服务器Web目录下正常的网页文件混在一起;然后使用浏览器来访问这些后门,得到命令执行环境,以达到控制网站或者Web系统服务器的目的。
黑客如果想使用Webshell完成一些特殊的功能,就不可避免地用到一些特殊函数。通过对这些函数进行对照特征值检查,就能够定位Webshell,但是Webshell本身也会进行加密来躲避这种检测。
Webshell 样例
以下是一个ASP Webshell的样例。从界面看,它的功能还是比较全的,可以对服务器的文件目录进行读写操作。如果你是网站管理员的话,肯定不希望普通用户获得下面的权限。
常见的Webshell植入方式以下类型:
- 利用站点上传漏洞,上传Webshell。
系统前台的上传业务可被利用来上传Webshell脚本,而被上传的目录往往对用户开放可执行权限。在Web中有上传图像、资料文件的地方,上传完后通常会向客户端返回上传文件的完整URL信息;该URL一般是常见的image、upload等目录。
如果Web服务器对网站存取权限或者文件夹目录权限控制不严,就可能被利用来实现Webshell攻击。攻击者可以利用上传功能上传一个脚本文件,然后通过URL访问并执行这个脚本;然后攻击者就可以上传Webshell到网站的任意目录中,从而拿到网站的管理员控制权限。
- 黑客获取管理员的后台密码,登录到后台系统,利用后台的管理工具向配置文件写入Webshell木马;或者私自添加上传类型,允许上传类似ASP、PHP格式的脚本程序文件。
- 利用数据库备份与恢复功能获取Webshell。例如,备份时把备份文件的后缀改成 .asp;如果后台有MySQL数据查询功能,黑客可以执行select..in To outfile查询输出PHP文件,并把代码插入到MySQL,从而生成Webshell的木马。
- 系统中其他站点被攻击,或者服务器上还搭载了FTP服务器。FTP服务器被攻击时被注入了Webshell的木马,导致网站系统被感染。
- 黑客直接攻击Web服务器系统漏洞,实现入侵。Web服务器在系统层面也可能存在漏洞,如果黑客利用其漏洞攻击服务器系统;在获取其权限后,黑客就可以在Web服务器目录里上传Webshell文件。
综上,Webshell能够入侵到系统,一般是由于以下原因:
- 通过Web站点漏洞上传Webshell。
Webshell能够被注入,在很大程度是由于服务器或中间件的安全漏洞。例如,以下常见漏洞都可能被利用来注入Webshell:旧版本的IIS目录解析漏洞、文件名解析漏洞、应用后台暴露和弱口令、Fast-CGI解析漏洞、Apache文件解析漏洞、截断上传、后台数据库备份功能上传、数据库语句上传漏洞等。
- 站点部署时混入了Webshell文件。
大量的用户在使用从网上下载的第三方开源代码时,其代码本身已经混入了Webshell的恶意脚本,造成二次入侵或多次入侵。所以在部署前期,如果不是新开发的代码,都需要对代码进行恶意文件扫描查杀,防止上线后被入侵。
- 配置必要的防火墙并开启防火墙策略;防止暴露不必要的服务,为黑客提供利用条件。
- 对服务器进行 安全加固。例如,关闭远程桌面功能、定期更换密码、禁止使用最高权限用户运行程序、使用HTTPS加密协议。
- 加强权限管理,对敏感目录进行权限设置,限制上传目录的脚本执行权限,不允许配置执行权限等。
- 安装Webshell检测工具,发现检测结果后,立即隔离查杀,并排查漏洞。
- 排查程序存在的漏洞,并及时修补漏洞,同时可以选用阿里云商业Web应用防火墙进行防御,降低被入侵机率。