RHCE8 资料整理(七)

第 七 篇 安全管理

第 25 章 防火墙

25.1 了解firewalld

防火墙技术的功能主要在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题,其中处理措施包括隔离与保护,同时可对计算机网络安全当中的各项操作实施记录与检测,以确保计算机网络运行的安全性,保障用户资料与信息的完整性,为用户提供更好、更安全的计算机网络使用体验。

在RHEL8中使用的防火墙是firewalld,在firewalld中涉及zone的概念。

zone类似地铁的安检入口,不同的zone制定了不同的规则。某个网卡要和某个zone进行关联,这样从网卡进入的数据包都要使用其相关联的zone的过滤规则。网卡不能同时和多个zone关联,最多只能和一个zone关联。如果网卡没有和任何zone关联,则使用默认的zone中的挂则。

25.2 firewalld的基本配置

查看系统中有多少个zone,命令如下:

[root@server ~]# firewall-cmd --get-zones
block dmz drop external home internal nm-shared public trusted work

其中,block拒绝所有的数据包通过,trusted允许所有的数据包通过。

查看系统默认的zone,

[root@server ~]# firewall-cmd --get-default-zone
public

把默认的zone修改为trusted,再改回去

[root@server ~]# firewall-cmd --set-default-zone=trusted
success
[root@server ~]# firewall-cmd --get-default-zone
trusted
[root@server ~]# firewall-cmd --set-default-zone=public
success
[root@server ~]# firewall-cmd --get-default-zone
public

查看某个网卡和其关联zone,

[root@server ~]# firewall-cmd --get-zone-of-interface=ens32
public
[root@server ~]# firewall-cmd --get-zone-of-interface=ens35
public

把网卡加入某个zone,

firewall-cmd --add-interface=网卡名 --zone=zone名

前面提到一张网卡只能和一个zone关联,所以当网卡加入zone出现冲突的时候,需要把网卡从当前的zone删除,然后再添加

[root@server ~]# firewall-cmd --remove-interface=ens35 --zone=public
success
[root@server ~]# firewall-cmd --get-zone-of-interface=ens35
no zone
[root@server ~]# firewall-cmd --add-interface=ens35 --zone=public
success
[root@server ~]# firewall-cmd --get-zone-of-interface=ens35
public

网卡更换zone可以使用,

[root@server ~]# firewall-cmd --change-interface=ens35 --zone=home
success
[root@server ~]# firewall-cmd --get-zone-of-interface=ens35
home
[root@server ~]# firewall-cmd --change-interface=ens35 --zone=public
success
[root@server ~]# firewall-cmd --get-zone-of-interface=ens35
public

25.3 配置firewalld的规则

查看某个zone的规则,

[root@server ~]# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens32 ens35
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 123/udp 323/udp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
25.3.1 icmp-blocks

关于icmp协议,参考 https://blog.csdn.net/u010230019/article/details/130880059

icmp有很多类型的数据包,ping的时候用的是以下两种:

  • echo-request:我ping对方时发送出去的包
  • echo-reply:对方回应我的包

一共有多少种类型的icmp包,可以通过firewall-cmd --get-icmptypes来查看

[root@server ~]# firewall-cmd --get-icmptypes
address-unreachable bad-header beyond-scope communication-prohibited destination-unreachable echo-reply echo-request failed-policy fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable ip-header-bad neighbour-advertisement neighbour-solicitation network-prohibited network-redirect network-unknown network-unreachable no-route packet-too-big parameter-problem port-unreachable precedence-cutoff protocol-unreachable redirect reject-route required-option-missing router-advertisement router-solicitation source-quench source-route-failed time-exceeded timestamp-reply timestamp-request tos-host-redirect tos-host-unreachable tos-network-redirect tos-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit unknown-header-type unknown-option

在sever上执行tcpdump命令进行抓包,

[root@server ~]# tcpdump -i ens35 icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens35, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:15:35.830231 IP node-138 > server.rhce.cc: ICMP echo request, id 21152, seq 17, length 64
15:15:35.830277 IP server.rhce.cc > node-138: ICMP echo reply, id 21152, seq 17, length 64
15:15:36.830327 IP node-138 > server.rhce.cc: ICMP echo request, id 21152, seq 18, length 64
15:15:36.830398 IP server.rhce.cc > node-138: ICMP echo reply, id 21152, seq 18, length 64
...
^C
20 packets captured
47 packets received by filter
26 packets dropped by kernel

这里node-138向server.rhce.cc发送了多个echo-request包,而server均回应了echo-reply包。

在server上用防火墙设置拒绝别人发过来的echo-request包,

[root@server ~]# firewall-cmd --add-icmp-block=echo-request
success

这时从node-138服务器发送的echo-request包就将无法被接收

[root@node-138 yum.repos.d]# ping node-140
PING node-140 (192.168.17.140) 56(84) bytes of data.
From node-140 (192.168.17.140) icmp_seq=1 Packet filtered
...
From node-140 (192.168.17.140) icmp_seq=7 Packet filtered
^C
--- node-140 ping statistics ---
7 packets transmitted, 0 received, +7 errors, 100% packet loss, time 6002ms

恢复接收echo-request包,

[root@server ~]# firewall-cmd --remove-icmp-block=echo-request
success
25.3.2 services

两台主机通信必须使用某个协议,例如,浏览器访问网址使用http,远程登录linux服务器使用ssh协议等。默认情况下,public这个zone只允许很少的服务通过,

[root@server ~]# firewall-cmd --list-all
public (active)
  ...
  services: cockpit dhcpv6-client ssh
  ...

这里没有允许http通过,如果查看防火墙是否开放了某个协议,也可以通过如下,

[root@server ~]# firewall-cmd --query-service=http
no
[root@server ~]# firewall-cmd --query-service=ssh
yes

获取系统所支持的所有服务,

[root@server ~]# firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit collectd condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-api kube-apiserver kube-control-plane kube-controller-manager kube-scheduler kubelet-worker ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd netbios-ns nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wireguard wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
[root@server ~]# firewall-cmd --get-services |wc -w
182

开放某个协议,

firewall-cmd --add-service=http

移除某个协议,

firewall-cmd --remove-service=http
25.3.3 ports

前面介绍了对服务进行过滤与放行,这些服务使用的都是标准端口,例如,http使用80端口,ssh使用22端口。但有时服务会用用一个非标准端口,例如httpd端口更改为8080,在防火墙中只放行http服务,本质就是放行80端口,此时http无法提供web服务。所以我们要放行指定端口,常用语句:
firewall-cmd --add-port=端口/协议

[root@node-138 yum.repos.d]# firewall-cmd --query-port=8080/tcp
no
[root@node-138 yum.repos.d]# firewall-cmd --query-port=8080/udp
no
[root@node-138 yum.repos.d]# firewall-cmd --add-port=8080/tcp
success
[root@node-138 yum.repos.d]# firewall-cmd --add-port=8080/udp
success
[root@node-138 yum.repos.d]# firewall-cmd --remove-port=8080/tcp
success
[root@node-138 yum.repos.d]# firewall-cmd --remove-port=8080/udp
success

25.4 富规则

前面提到的,不管是对端口还是服务放行,都会遇到一个问题就是,如果允许则允许所有的客户端,拒绝则拒绝所有的客户端。
有时候需要设置只允许特定的客户端访问,其他客户端都不能访问,此时就需要使用到富规则。富规则可以对服务限制,也可以对端口限制。语法,

firewall-cmd --add-rich-rule='rule family=ipv4 source adddress=源网段 service name=服务名 accept'

这里单双引号均可,查看现有富规则,

[root@node-138 yum.repos.d]# firewall-cmd --list-rich-rules

移除前面在防火墙中添加的http服务和端口,创建【服务】相关的富规则,

[root@server ~]# curl 192.168.17.138
curl: (7) Failed to connect to 192.168.17.138 port 80: No route to host

[root@node-138 yum.repos.d]# firewall-cmd --add-rich-rule="rule family=ipv4 source address=192.168.17.140 service name=http accept"
success
[root@node-138 yum.repos.d]# firewall-cmd --list-rich-rules
rule family="ipv4" source address="192.168.17.140" service name="http" accept

[root@server ~]# curl 192.168.17.138
hello noob

[root@node-138 yum.repos.d]# firewall-cmd --remove-rich-rule="rule family=ipv4 source address=192.168.17.140 service name=http accept"
success
[root@node-138 yum.repos.d]# firewall-cmd --list-rich-rules


[root@server ~]# curl 192.168.17.138
curl: (7) Failed to connect to 192.168.17.138 port 80: No route to host

移除前面富规则,添加【端口】相关富规则,
firewall-cmd --add-rich-rule="rule family=ipv4 source address=源网段 port port=M-N protocol=协议 accept"
M-N为端口范围

[root@node-138 yum.repos.d]# firewall-cmd --add-rich-rule="rule family=ipv4 source address=192.168.17.140 port port=8080  protocol=tcp accept"
success

[root@server ~]# curl 192.168.17.138:8080
hello noob

[root@node-138 yum.repos.d]# firewall-cmd --remove-rich-rule="rule family=ipv4 source address=192.168.17.140 port port=8080 protocol=tcp accept"
success

[root@server ~]# curl 192.168.17.138:8080
curl: (7) Failed to connect to 192.168.17.138 port 8080: No route to host

注意:

前面提到的这些规则(包括服务,端口,富规则等)都只是临时生效,如果希望永久生效,需要添加--permanent选项,还需额外注意:

  • 添加--permanent,当前不生效,重启系统或firewalld之后生效
  • 不加--permanent,当前生效,重启系统或firewalld之后失效
    所以写规则的时候,可以添加两条,即包含--permanent和不包含的

第 26 章 SELinux介绍

SELinux 全称是 Security-Enhanced Linux,目的是提高系统的安全性。当我们执行某个操作时,如果SELinux认为此操作有危险,则会拒绝进一步的访问。
详细参考 https://blog.csdn.net/u010230019/article/details/132318781

临时开启和关闭selinux

setenforce 1 #开启
setenforcd 0 #关闭

永久开启或关闭

[root@node-138 ~]# cat /etc/selinux/config
...
SELINUX=enforcing	#开启
#SELINUX=disable #关闭
...

永久开启或关闭都需要重启机器,可能会很慢

26.1 了解上下文

在开启了selinux的情况下,selinux会为每个文件,每个进程都分配一个标签,这个标签我们称为上下文(context),后面说的标签和上下文是同一个概念,查看上下文需要加上Z选项,例如,

[root@node-138 yum.repos.d]# ps axZ|grep http|grep -v grep
...
system_u:system_r:httpd_t:s0      1713 ?        Ss     0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0      1714 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
...

其中,httpd进程的上下文为httpd_t,查看文件上下文,例如,

[root@node-138 yum.repos.d]# ll -Z /var/www/html/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

可以看到index.html的上下文是httpd_sys_content_t

特定上下文的进程只能访问特定上下文的文件,上下文为httpd_t的进程可以访问上下文为httpd_sys_content_t的文件或目录。

举个例子

[root@node-138 web]# mkdir /web
[root@node-138 web]# echo "new noob" > /web/index.html
[root@node-138 web]# ll -Z /web/index.html
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 /web/index.html
[root@node-138 web]# ln -s /web/index.html /var/www/html/www
[root@node-138 web]# ll -Z /var/www/html/www
lrwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/www -> /web/index.html

[root@server ~]# curl 192.168.17.138:8080/www/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /www/index.html
on this server.</p>
</body></html>

新建的文件上下文是default_t,上下文不匹配,所以网页无法显示。

修改上下文,命令为chcon

chcon -R -t 上下文 目录

上面的示例,我们来修改下

[root@node-138 web]# chcon -R -t httpd_sys_content_t /web
[root@node-138 web]# ll -Z /web/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

[root@server ~]# curl 192.168.17.138:8080/www
new noob

如果要恢复目录的默认上下文,使用restorecon -R 目录命令。

[root@node-138 web]# restorecon -R /web/

恢复后网页无法访问了

修改默认上下文,命令,
semanage fcontext -a -t httpd_sys_content_t "/目录(/.*)?" 添加默认上下文
semanage fcontext -d -t httpd_sys_content_t "/目录(/.*)?" 移除默认上下文

[root@node-138 web]# semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
[root@node-138 web]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 index.html

可以看到修改完,上下文仍是default_t。要使其生效,需要使用restorecon命令

[root@node-138 web]# restorecon -R /web/
[root@node-138 web]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 123
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
[root@node-138 web]# touch 321
[root@node-138 web]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 123
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 321
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

可以看到目录及其内文件上下文已经改变,并且新建文件上下文也发生变化。

26.2 端口上下文

端口也是有上下文的,如果一个端口没有上下文或者上下文和进程不匹配,则进程就无法访问此端口。

查看系统所有端口上下文使用semanage port -l

[root@node-138 web]# semanage port -l
SELinux Port Type              Proto    Port Number
...
afs_fs_port_t                  udp      7000, 7005
afs_ka_port_t                  udp      7004
...
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
...

我们把httpd的启动端口改为808,重启httpd,会有如下报错

Nov 22 15:15:14 node-138 setroubleshoot[3189]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 808. For complete SELinux messages run: sealert -l d26bbec0-a1ef-460e-b617-80f30cebfc2e
...

这里的意思是无法绑定端口808,因为808没有对应的端口上下文。可以通过修改端口上下文解决此问题,修改端口上下文语法,

semanage port -a -t 上下文 -p 协议 端口
[root@node-138 web]# semanage port -a -t http_port_t -p tcp 808
[root@node-138 web]# systemctl restart httpd
[root@node-138 web]# ss -nltp|grep 808
LISTEN     0      128       [::]:808                   [::]:*                   users:(("httpd",pid=3241,fd=4),("httpd",pid=3240,fd=4),("httpd",pid=3239,fd=4),("httpd",pid=3238,fd=4),("httpd",pid=3237,fd=4),("httpd",pid=3236,fd=4))

26.3 了解SELinux的布尔值

在这里插入图片描述
布尔值可以理解为一个功能开关,在没有SELinux的情况下,电灯完全由电源开关控制。现在有了SELinux,电灯亮不亮由电源开关和SELinux开关同时控制。

查看系统中所有的SELinux的布尔值可以使用getsebool -a

[root@node-138 web]# getsebool -a|grep ftp
ftpd_anon_write --> off
ftpd_connect_all_unreserved --> off
ftpd_connect_db --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_fusefs --> off
ftpd_use_nfs --> off
ftpd_use_passive_mode --> off
...

下面以vsftpd为例讲解SELinux布尔值的用途

  1. 启动server ftp服务
yum install -y vsftpd
cd /var/ftp/
mkdir incoming
chown ftp.ftp incoming/

[root@node-138 ftp]# cat /etc/vsftpd/vsftpd.conf |egrep -v '^$|^#'
anonymous_enable=YES
..
anon_upload_enable=YES
anon_mkdir_write_enable=YES
...
systemctl restart vsftpd
  1. 在客户端登录ftp
[root@node-137 ~]# lftp 192.168.17.138/incoming
cd ok, cwd=/incoming
lftp 192.168.17.138:/incoming> ls
lftp 192.168.17.138:/incoming> put /etc/hosts
put: Access failed: 553 Could not create file. (hosts)
  1. 查看server selinux的布尔值开关
[root@node-138 ftp]# getsebool -a|grep ftpd_full_access
ftpd_full_access --> off
[root@node-138 ftp]# setsebool -P ftpd_full_access on
[root@node-138 ftp]# getsebool -a|grep ftpd_full_access
ftpd_full_access --> on
  1. 再次上传文件
lftp 192.168.17.138:/incoming> put /etc/hosts
398 bytes transferred
lftp 192.168.17.138:/incoming> ls
-rw-------    1 14       50            398 Nov 22 08:28 hosts

设置布尔值语法,关闭,

setsebool [-P] 布尔值 off
#或
setsebool [-P] 布尔值 0

开启,

setsebool [-P] 布尔值 on
#或
setsebool [-P] 布尔值 1

-P表示永久生效,即重启后也生效

26.4 了解SELinux的模式

SELinux一共有三种模式:

  1. Enforcing:如果不满足SELinux条件,则SELinux会阻止访问服务并提供警报
  2. Permissive:宽容模式,如果不满足SELinux条件,则SELinux不会阻止访问服务,但会提供警报
  3. Disabled:关闭SElinux

想要切换模式,使用setenforce N

  • setenforce 1:切换到Enforcing模式
  • setenforce 0:切换到Permissive模式
[root@node-138 ftp]# getenforce
Enforcing
[root@node-138 ftp]# setenforce 0
[root@node-138 ftp]# getenforce
Permissive
[root@node-137 ~]# getenforce
Disabled

通过setenforce命令只能临时切换模式,重启后会恢复默认模式,通过修改/etc/selinux/config可以永久修改默认模式

[root@server yum.repos.d]# ll /etc/selinux/config
-rw-r--r-- 1 root root 1186 Oct 19 17:01 /etc/selinux/config
[root@server yum.repos.d]# ll /etc/sysconfig/selinux
lrwxrwxrwx. 1 root root 17 Sep  8 16:55 /etc/sysconfig/selinux -> ../selinux/config
[root@server yum.repos.d]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
# See also:
# https://docs.fedoraproject.org/en-US/quick-docs/getting-started-with-selinux/#getting-started-with-selinux-selinux-states-and-modes
#
# NOTE: In earlier Fedora kernel builds, SELINUX=disabled would also
# fully disable SELinux during boot. If you need a system with SELinux
# fully disabled instead of SELinux running with no policy loaded, you
# need to pass selinux=0 to the kernel command line. You can use grubby
# to persistently set the bootloader to boot with selinux=0:
#
#    grubby --update-kernel ALL --args selinux=0
#
# To revert back to SELinux enabled:
#
#    grubby --update-kernel ALL --remove-args selinux
#
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

前面提到过,修改后需要重启才能生效。

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值