1 安全技術(shù)和防火墻
1.1 安全技術(shù)
- 入侵檢測(cè)與管理系統(tǒng)(Intrusion Detection Systems): 特點(diǎn)是不阻斷任何網(wǎng)絡(luò)訪問(wèn),量化,定位來(lái)自內(nèi)外網(wǎng)的威脅情況,主要以提供報(bào)告和事后監(jiān)督為主,提供有針對(duì)性的指導(dǎo)措施和安全決策依據(jù).一般采用旁路部署方式
- 入侵防御系統(tǒng)(Intrusion Prevention System): 以透明模式工作,
- 防火墻(Firewall):
1.2 防火墻的分類
按保護(hù)范圍劃分:
按實(shí)現(xiàn)方式劃分:
按網(wǎng)絡(luò)協(xié)議劃分:
包過(guò)濾防火墻:
網(wǎng)絡(luò)層對(duì)數(shù)據(jù)包進(jìn)行選擇,選擇的依據(jù)是系統(tǒng)內(nèi)設(shè)置的過(guò)濾邏輯,被稱為訪問(wèn)控制列表(ACL),通過(guò)檢查數(shù)據(jù)流中每個(gè)數(shù)據(jù)的源地址,目的地址,所用端口號(hào)和協(xié)議狀態(tài)等因素,或他們的組合來(lái)確定是否允許該數(shù)據(jù)包通過(guò)
2 Linux防火墻的基本認(rèn)識(shí)
2.1 Netfilter
Linux防火墻是由Netfilter組件提供的,Netfilter工作在內(nèi)核空間,集成在Linux內(nèi)核中
Netfilter是Linux 2.4.x 之后新一代的Linux防火墻機(jī)制,是Linux內(nèi)核的一個(gè)子系統(tǒng). Netfilter采用模塊化設(shè)計(jì),具有良好的可擴(kuò)展性,提供擴(kuò)展各種網(wǎng)段服務(wù)的結(jié)構(gòu)化底層框架. Netfilter與IP協(xié)議棧是無(wú)縫契合,并允許對(duì)數(shù)據(jù)報(bào)進(jìn)行過(guò)濾,地址轉(zhuǎn)換,處理等操作
Netfilter官方文檔: https://netfilter.org/documentation/
### 查看不同版本的Linux內(nèi)核特性 ###
Centos 8: 查看/boot/config-4.18.0-193.el8.x86_64,該文件記錄了內(nèi)核特性
[15:35:19 root@centos8 ~]#grep -m 10 NETFILTER /boot/config-4.18.0-193.el8.x86_64
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=m
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
# CONFIG_NETFILTER_NETLINK_ACCT is not set
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
Centos 7: 查看/boot/config-3.10.0-123.el7.x86_64,該文件記錄了內(nèi)核特性
[00:16:22 root@centos7 ~]#grep -m 10 NETFILTER /boot/config-3.10.0-123.el7.x86_64
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
CONFIG_NETFILTER_SYNPROXY=m
Centos 6: 查看/boot/config-2.6.32-754.el6.x86_64,該文件記錄了內(nèi)核特性
[root@centos6 ~]# grep -m 10 NETFILTER /boot/config-2.6.32-754.el6.x86_64
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
Ubuntu: 查看/boot/config-4.15.0-76-generic,該文件記錄了內(nèi)核特性
root@ubuntu1804:~# grep -m 10 NETFILTER /boot/config-4.15.0-76-generic
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=m
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NETFILTER_SYNPROXY=m
### y: 參數(shù)y表示被集成在內(nèi)核里 ###
[15:35:24 root@centos8 ~]#ll /boot
total 184576
-rw-r--r--. 1 root root 187648 May 8 21:07 config-4.18.0-193.el8.x86_64
drwxr-xr-x. 3 root root 4096 Jun 21 13:06 efi
drwx------. 4 root root 4096 Jun 21 13:16 grub2
-rw-------. 1 root root 98497217 Jun 21 13:14 initramfs-0-rescue-b988f85ba7c94883a5e03a0cbf150ea4.img
-rw-------. 1 root root 50928938 Jun 21 13:17 initramfs-4.18.0-193.el8.x86_64.img
-rw-------. 1 root root 17610940 Jun 21 13:21 initramfs-4.18.0-193.el8.x86_64kdump.img
drwxr-xr-x. 3 root root 4096 Jun 21 13:11 loader
drwx------. 2 root root 16384 Jun 21 13:04 lost+found
-rw-------. 1 root root 3909996 May 8 21:07 System.map-4.18.0-193.el8.x86_64
-rwxr-xr-x. 1 root root 8913656 Jun 21 13:13 vmlinuz-0-rescue-b988f85ba7c94883a5e03a0cbf150ea4
-rwxr-xr-x. 1 root root 8913656 May 8 21:07 vmlinuz-4.18.0-193.el8.x86_64
### m: 參數(shù)m表示功能被放在模塊里, 以模塊方式提供. 一般表示為各種ko文件 ###
[15:47:59 root@centos8 ~]#ll /lib/modules/4.18.0-193.el8.x86_64/
total 16432
-rw-r--r--. 1 root root 295 May 8 21:07 bls.conf
lrwxrwxrwx. 1 root root 38 May 8 21:07 build -> /usr/src/kernels/4.18.0-193.el8.x86_64
-rw-r--r--. 1 root root 187648 May 8 21:07 config
drwxr-xr-x. 12 root root 128 Jun 21 13:07 kernel
-rw-r--r--. 1 root root 865312 Jun 21 13:16 modules.alias
-rw-r--r--. 1 root root 827199 Jun 21 13:16 modules.alias.bin
-rw-r--r--. 1 root root 488 May 8 21:07 modules.block
-rw-r--r--. 1 root root 7534 May 8 21:07 modules.builtin
-rw-r--r--. 1 root root 9748 Jun 21 13:16 modules.builtin.bin
-rw-r--r--. 1 root root 287699 Jun 21 13:16 modules.dep
-rw-r--r--. 1 root root 397124 Jun 21 13:16 modules.dep.bin
-rw-r--r--. 1 root root 365 Jun 21 13:16 modules.devname
-rw-r--r--. 1 root root 140 May 8 21:07 modules.drm
-rw-r--r--. 1 root root 59 May 8 21:07 modules.modesetting
-rw-r--r--. 1 root root 1602 May 8 21:07 modules.networking
-rw-r--r--. 1 root root 100539 May 8 21:07 modules.order
-rw-r--r--. 1 root root 553 Jun 21 13:16 modules.softdep
-rw-r--r--. 1 root root 414722 Jun 21 13:16 modules.symbols
-rw-r--r--. 1 root root 505717 Jun 21 13:16 modules.symbols.bin
lrwxrwxrwx. 1 root root 5 May 8 21:07 source -> build
-rw-r--r--. 1 root root 347581 May 8 21:07 symvers.gz
-rw-------. 1 root root 3909996 May 8 21:07 System.map
drwxr-xr-x. 2 root root 6 May 8 21:06 updates
drwxr-xr-x. 2 root root 40 Jun 21 13:07 vdso
-rwxr-xr-x. 1 root root 8913656 May 8 21:07 vmlinuz
drwxr-xr-x. 3 root root 23 Jun 21 13:14 weak-updates
find /lib/modules/4.18.0-193.el8.x86_64/ -name "*.ko"
lsmod: 查看加載到內(nèi)核中的模塊
[15:52:56 root@centos8 ~]#lsmod | head -n 5
Module Size Used by
rfcomm 86016 6
nft_chain_route_ipv4 16384 1
xt_CHECKSUM 16384 1
nft_chain_nat_ipv4 16384 4
- 以模塊方式提供的好處就是想用就可用用不想用不用
- 如果放在內(nèi)核文件里那么一開機(jī)就會(huì)加載,內(nèi)核文件里放的都是必要的常用的功能,不太常用的都表現(xiàn)為模塊,按需加載
- Netfilter是內(nèi)核里的功能,對(duì)于普通用戶來(lái)說(shuō),如果想使用,并不能直接操控內(nèi)核,去干預(yù)系統(tǒng)內(nèi)核,而是需要通過(guò)系統(tǒng)調(diào)用,系統(tǒng)調(diào)用是操作系統(tǒng),內(nèi)核和用戶空間打交道的接口. 讓每個(gè)用戶去調(diào)系統(tǒng)調(diào)用是不現(xiàn)實(shí)的,因此Netfilter廠商研發(fā)了用戶空間的工具,這些工具可以直接通過(guò)系統(tǒng)調(diào)用連接到內(nèi)核里,去訪問(wèn)Netfilter內(nèi)核模塊,來(lái)進(jìn)行各種安全設(shè)置
- iptables 和 Firewalld 只能2選1,因?yàn)槎叨际敲钚泄ぞ?通過(guò)系統(tǒng)調(diào)用干預(yù)內(nèi)核,同時(shí)使用會(huì)產(chǎn)生沖突
2.2 防火墻工具介紹
2.2.1 iptables
- 由軟件包iptables提供的命令行工具,工作在用戶空間,用來(lái)編寫規(guī)則,寫好的規(guī)則被送往Netfilter,告訴內(nèi)核如何去處理數(shù)據(jù)包
- 不同版本的系統(tǒng),iptables包的版本不一樣
- iptables自身也是通過(guò)模塊來(lái)實(shí)現(xiàn)特定功能,可以根據(jù)需要做修改
- iptables也可以作為一種服務(wù),制定一些規(guī)則,讓它開機(jī)自動(dòng)加載
- 工作中firewalld和iptables會(huì)被直接禁用,因?yàn)槟J(rèn)規(guī)則不符合生產(chǎn)要求,可以自己寫規(guī)則不同系統(tǒng)自帶的
- 7和8上默認(rèn)安裝的是Firewalld服務(wù)和工具, 沒有安裝iptables服務(wù), 只安裝了工具. Firewalld工具和服務(wù),都由Firewalld包提供, iptables工具由iptables包提供, 而服務(wù)由iptables-services包提供,
- 6上只有iptables, 由iptables包提供
Centos 8:
[15:53:01 root@centos8 ~]#rpm -qi iptables
Name : iptables
Version : 1.8.4
Release : 10.el8
Architecture: x86_64
Install Date: Sun 21 Jun 2020 13:06:25 AEST
Group : Unspecified
Size : 1974473
License : GPLv2 and Artistic 2.0 and ISC
Signature : RSA/SHA256, Sun 26 Apr 2020 12:09:33 AEST, Key ID 05b555b38483c65d
Source RPM : iptables-1.8.4-10.el8.src.rpm
Build Date : Fri 24 Apr 2020 23:51:59 AEST
Build Host : x86-01.mbox.centos.org
Relocations : (not relocatable)
Packager : CentOS Buildsys <bugs@centos.org>
Vendor : CentOS
URL : http://www.netfilter.org/projects/iptables
Summary : Tools for managing Linux kernel packet filtering capabilities
Description :
The iptables utility controls the network packet filtering code in the
Linux kernel. If you need to set up firewalls and/or IP masquerading,
you should either install nftables or this package.
Note: This package contains the nftables-based variants of iptables and
ip6tables, which are drop-in replacements of the legacy tools.
Centos 7:
[01:36:33 root@centos7 ~]#rpm -qi iptables
Name : iptables
Version : 1.4.21
Release : 13.el7
Architecture: x86_64
Install Date: Mon 22 Jun 2020 06:51:08 EST
Group : System Environment/Base
Size : 1541839
License : GPLv2
Signature : RSA/SHA256, Fri 04 Jul 2014 12:08:31 EST, Key ID 24c6a8a7f4a80eb5
Source RPM : iptables-1.4.21-13.el7.src.rpm
Build Date : Tue 10 Jun 2014 15:02:48 EST
Build Host : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager : CentOS BuildSystem <http://bugs.centos.org>
Vendor : CentOS
URL : http://www.netfilter.org/
Summary : Tools for managing Linux kernel packet filtering capabilities
Description :
The iptables utility controls the network packet filtering code in the
Linux kernel. If you need to set up firewalls and/or IP masquerading,
you should install this package.
Centos 6:
[root@centos6 ~]# rpm -qi iptables
Name : iptables Relocations: (not relocatable)
Version : 1.4.7 Vendor: CentOS
Release : 19.el6 Build Date: Wed 20 Jun 2018 02:08:21 AM AEST
Install Date: Thu 02 Jul 2020 12:05:43 PM AEST Build Host: x86-01.bsys.centos.org
Group : System Environment/Base Source RPM: iptables-1.4.7-19.el6.src.rpm
Size : 861752 License: GPLv2
Signature : RSA/SHA1, Wed 20 Jun 2018 09:37:20 PM AEST, Key ID 0946fca2c105b9de
Packager : CentOS BuildSystem <http://bugs.centos.org>
URL : http://www.netfilter.org/
Summary : Tools for managing Linux kernel packet filtering capabilities
Description :
The iptables utility controls the network packet filtering code in the
Linux kernel. If you need to set up firewalls and/or IP masquerading,
you should install this package.
- 不同版本的iptables調(diào)用的實(shí)際命令也不一樣,但是為了兼容,基本命令都一樣,除非使用某些特性
[02:09:14 root@centos7 ~]#iptables --version
iptables v1.4.21
Centos 8:
[16:07:11 root@centos8 ~]#which iptables
/usr/sbin/iptables
[16:13:10 root@centos8 ~]#ll /usr/sbin/iptables
lrwxrwxrwx. 1 root root 17 Apr 24 23:51 /usr/sbin/iptables -> xtables-nft-multi
Centos 7:
[02:12:58 root@centos7 ~]#which iptables
/usr/sbin/iptables
[02:13:35 root@centos7 ~]#ll /usr/sbin/iptables
lrwxrwxrwx. 1 root root 13 Jun 22 06:51 /usr/sbin/iptables -> xtables-multi
Centos 6:
[root@centos6 ~]# which iptables
/sbin/iptables
[root@centos6 ~]# ll /sbin/iptables
lrwxrwxrwx. 1 root root 33 Jul 2 12:05 /sbin/iptables -> /etc/alternatives/iptables.x86_64
Ubuntu:
root@ubuntu1804:~# which iptables
/sbin/iptables
root@ubuntu1804:~# ll /sbin/iptables
lrwxrwxrwx 1 root root 13 Nov 12 2017 /sbin/iptables -> xtables-multi*
- iptables和Firewalld為什么沖突?
Centos 8:
[16:19:30 root@centos8 ~]#systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
[16:19:34 root@centos8 ~]#cat /usr/lib/systemd/system/firewalld.service
[Unit]
Description=firewalld - dynamic firewall daemon
Before=network-pre.target
Wants=network-pre.target
After=dbus.service
After=polkit.service
Conflicts=iptables.service ip6tables.service ebtables.service ipset.service
Documentation=man:firewalld(1)
[Service]
EnvironmentFile=-/etc/sysconfig/firewalld
ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS
ExecReload=/bin/kill -HUP $MAINPID
# supress to log debug and error output also to /var/log/messages
StandardOutput=null
StandardError=null
Type=dbus
BusName=org.fedoraproject.FirewallD1
KillMode=mixed
[Install]
WantedBy=multi-user.target
Alias=dbus-org.fedoraproject.FirewallD1.service
Conflicts=iptables.service ip6tables.service ebtables.service ipset.service
- 安裝iptables-services
[16:20:20 root@centos8 ~]#yum -y install iptables-services
[16:26:36 root@centos8 ~]#rpm -ql iptables-services
/etc/sysconfig/ip6tables
/etc/sysconfig/iptables
/usr/lib/systemd/system/ip6tables.service
/usr/lib/systemd/system/iptables.service
/usr/libexec/initscripts/legacy-actions/ip6tables
/usr/libexec/initscripts/legacy-actions/ip6tables/panic
/usr/libexec/initscripts/legacy-actions/ip6tables/save
/usr/libexec/initscripts/legacy-actions/iptables
/usr/libexec/initscripts/legacy-actions/iptables/panic
/usr/libexec/initscripts/legacy-actions/iptables/save
/usr/libexec/iptables
/usr/libexec/iptables/ip6tables.init
/usr/libexec/iptables/iptables.init
2.2.2 Firewalld
從Centos 7版開始引入了新的前端管理工具, Centos 7&8有Firewalld, 但是Ubuntu沒有
軟件包:
- firewalld
- firewalld-config
管理工具:
- firewall-cmd 命令行工具
- firewall-config 圖形工具
2.2.3 nftables
CentOS8添加的新的防火墻工具
2.2.4 關(guān)閉防火墻,并禁止開機(jī)自啟
Centos 6
service iptables stop
chkconfig iptables off
Centos 7&8
systemctl stop firewalld.service(iptables-services)
systemctl disable firewalld.service(iptables-services)
或者
systemctl disable --now firewalld.service(iptables-services)
Ubuntu
ufw disable
- Netfilter是Linux內(nèi)核的功能,并不是安裝應(yīng)用程序帶來(lái)的功能,是集成在內(nèi)核里的(Linux 2.4.x內(nèi)核之后)
- 很多硬件防火墻都是基于Linux內(nèi)核開發(fā),定制版的Linux系統(tǒng)
- 內(nèi)核是由不同的組件組成
- iptables并不是防火墻,而是命令,他引用了Linux內(nèi)核里的防火墻模塊Netfilter來(lái)配置防火墻功能,也可以使用Firewalld.不同工具調(diào)用的底層都是Netfilter,只不過(guò)是換了個(gè)命令,換了個(gè)格式
- 企業(yè)里大部分都是禁用服務(wù)器的防火墻,用專門的硬件防火墻,為了方便訪問(wèn)
- Centos 6 : iptables
Centos 7 & 8 : iptables,Firewalld(默認(rèn)使用Firewalld)
Ubuntu : iptables,默認(rèn)沒有
2.3 Netfilter中五個(gè)鉤子函數(shù)和報(bào)文流向
Netfilter在內(nèi)核中選取五個(gè)位置放了五個(gè)hook(勾子)function(INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING), 而這五個(gè)hook function向用戶開發(fā), 用戶可以通過(guò)一個(gè)命令工具(iptables)向其寫入規(guī)則
由信息過(guò)濾表(table)組成, 包含控制ip包處理的規(guī)則集(rules),規(guī)則被分組在鏈(chain)上
三種報(bào)文流向
- 流入本機(jī): PREROUTING - INPUT - 用戶空間進(jìn)程
- 流出本機(jī): 用戶空間進(jìn)程 - OUTPUT - POSTROUTING
- 轉(zhuǎn)發(fā): PREROUTING - FORWARD - POSTROUTING
服務(wù)器網(wǎng)卡接受到數(shù)據(jù)包后, 先進(jìn)入PREROUTING鏈, 根據(jù)數(shù)據(jù)包的目的IP來(lái)判斷數(shù)據(jù)包是發(fā)給本機(jī)還是需要轉(zhuǎn)發(fā)出去
經(jīng)過(guò)路由判斷后, 如果是發(fā)給本機(jī)的, 就會(huì)將數(shù)據(jù)包發(fā)給INPUT鏈
如果是轉(zhuǎn)發(fā)的就發(fā)給FORWARD鏈
prerouting并不會(huì)控制二層, 數(shù)據(jù)包一旦進(jìn)入了prerouting就說(shuō)明了數(shù)據(jù)包的目標(biāo)mac是本機(jī)
內(nèi)核4.2后推出了ingress函數(shù), 來(lái)控制二層
2.4 iptables的組成
iptables由五個(gè)表table和五個(gè)鏈chain以及一些規(guī)則組成
鏈chain
- 內(nèi)置鏈: 每個(gè)內(nèi)置鏈對(duì)應(yīng)于一個(gè)勾子函數(shù), prerouting, input, forward, output, postrouting
- 自定義鏈: 用于對(duì)內(nèi)置鏈進(jìn)行擴(kuò)展和補(bǔ)充, 可實(shí)現(xiàn)靈活的規(guī)則組織管理機(jī)制, 只有hook勾子調(diào)用自定義鏈時(shí)才會(huì)生效
五個(gè)內(nèi)置鏈
INPUT OUTPUT FORWARD PREROUTING POSTROUTING
五個(gè)表table
filter nat mangle raw security
- filter表: 過(guò)濾規(guī)則表, 根據(jù)預(yù)定義的規(guī)則過(guò)濾符合條件的數(shù)據(jù)包, 是默認(rèn)表
- nat表: 地址轉(zhuǎn)換規(guī)則表
- mangle: 修改數(shù)據(jù)標(biāo)記位規(guī)則表
- raw: 關(guān)閉啟用的連接跟蹤機(jī)制, 加快封包穿越防火墻速度
- security: 用于強(qiáng)制訪問(wèn)控制(MAC)網(wǎng)絡(luò)規(guī)則, 由Linux安全模塊(如SElinux)實(shí)現(xiàn)
表的優(yōu)先級(jí)
security - raw - mangel - nat - filter
- 不同的版本鏈和表的對(duì)應(yīng)關(guān)系不一樣,可以通過(guò)iptables -L -t 表名 來(lái)查看某個(gè)表可以作用在哪個(gè)鏈上,默認(rèn)的表名是filter表
- 無(wú)需記住所有的組合, 只要記住常用的組合即可
- 查看某個(gè)表可以放在哪個(gè)鏈上, 默認(rèn)不加-t顯示filter表
[16:19:30 root@centos8 ~]#iptables -L -t filter
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
3 iptables
3.1 iptables規(guī)則說(shuō)明
3.1.1 規(guī)則組成
規(guī)則rule: 根據(jù)規(guī)則的匹配條件嘗試匹配報(bào)文,對(duì)匹配成功的報(bào)文根據(jù)規(guī)則定義的處理動(dòng)作做出處理,規(guī)則在鏈接上的次序即為其檢查時(shí)的生效次序
匹配條件: 默認(rèn)為與條件,同時(shí)滿足
基本匹配: IP,端口,TCP的Flags(SYN,ACK等)
擴(kuò)展匹配: 通過(guò)復(fù)雜高級(jí)功能匹配
處理動(dòng)作: 稱為target,跳轉(zhuǎn)目標(biāo)
- 內(nèi)建處理動(dòng)作: ACCEPT,DROP,REJECT,SNAT,DNAT,MASQUERADE,MARK,LOG...
- 自定義處理動(dòng)作: 自定義chain,利用分類管理復(fù)雜情形
規(guī)則要添加在鏈上,才生效;添加在自定義鏈上不會(huì)自動(dòng)生效, 勾子函數(shù)調(diào)用時(shí)才會(huì)生效
3.1.2 iptables規(guī)則添加時(shí)考量點(diǎn)
- 要實(shí)現(xiàn)哪種功能: 判斷添加在哪張表上
- 報(bào)文流經(jīng)的路徑: 判斷添加在哪個(gè)鏈上
- 報(bào)文的流向: 判斷源和目的
- 匹配規(guī)則: 業(yè)務(wù)需要
3.1.3 環(huán)境準(zhǔn)備
- 關(guān)閉防火墻,并禁止開機(jī)自啟
Centos 6
service iptables stop
chkconfig iptables off
Centos 7&8
systemctl stop firewalld.service(iptables-services)
systemctl disable firewalld.service(iptables-services)
或者
systemctl disable --now firewalld.service(iptables-services)
3.2 iptables 用法說(shuō)明
范例: Filter表中INPUT規(guī)則
3.3 iptables 基本匹配條件
- -t 表名: 指明作用在哪個(gè)表上,表名小寫, -t filter, filter是默認(rèn)表
- INPUT: 指明作用在哪個(gè)鏈上,鏈名必須大寫
- -A: 表示在原有規(guī)則下面追加, Append, -A INPUT
- -s: 匹配的源地址, -s 192.168.0.1
- -d: 匹配的目標(biāo)地址,注意: 如果在INPUT上基于源IP做過(guò)濾,一般是不需要指定目標(biāo)IP地址的,因?yàn)榧热灰呀?jīng)作用在INPUT上了就說(shuō)明流量已經(jīng)過(guò)了PREROUTING, 報(bào)文就是要發(fā)給本機(jī)的,除非本機(jī)有多塊網(wǎng)卡
- -j: 處理動(dòng)作jump,動(dòng)作大寫, -j DROP, -j REJECT也是拒絕
DROP:不會(huì)返回信息
REJECT: 會(huì)返回信息 - -I: 插入, -I INPUT 2, 把新增的規(guī)則插入到第2條,原來(lái)的規(guī)則2就變成了規(guī)則3,默認(rèn)是直接加到第一條
- -R: 替換, -R INPUT 2
- -D: 刪除表中指定鏈的指定規(guī)則, ip tables -D INPUT 2,刪除INPUT鏈中第二條規(guī)則
- -P: 修改默認(rèn)規(guī)則,初始默認(rèn)都是ACCEPT, iptables -P INPUT DROP,將INPUT鏈默認(rèn)規(guī)則修改成DROP. 如果收到的包,沒有被任何一個(gè)規(guī)則匹配到,那么就執(zhí)行DROP. 但要注意,修改默認(rèn)規(guī)則前,一定要確保自己遠(yuǎn)程連接的主機(jī)是能通的,否則就連不上了
- F: 清空防火墻規(guī)則, iptables -t [表] -F [鏈]
注意: 同一網(wǎng)段有包含關(guān)系, 范圍小的規(guī)則放在前面, 范圍大的規(guī)則放在后面; 無(wú)包含關(guān)系,不同網(wǎng)段的規(guī)則, 范圍大的要放在前面, 加快效率.
#不同網(wǎng)點(diǎn), 沒有包含關(guān)系
172.16.0.0/16 #放前面
10.0.0.0/24 #放后面
范例: 在INPUT鏈拒絕10.0.0.202訪問(wèn)10.0.0.201
### DROP ###
[22:07:10 root@centos8 ~]#iptables [-t filter] -A INPUT -s 10.0.0.202 -j DROP
[07:47:57 root@centos7 ~]#ssh 10.0.0.201
[08:08:22 root@centos7 ~]#ping 10.0.0.201
PING 10.0.0.201 (10.0.0.201) 56(84) bytes of data.
### 清空表中的所有鏈的規(guī)則 ###
[22:10:26 root@centos8 ~]#iptables -F
### 清空表中指定鏈的規(guī)則 ###
[22:11:09 root@centos8 ~]#iptables -F INPUT
### REJECT ###
[22:12:51 root@centos8 ~]#iptables -A INPUT -s 10.0.0.202 -j REJECT
64 bytes from 10.0.0.201: icmp_seq=282 ttl=64 time=1.31 ms
From 10.0.0.201 icmp_seq=283 Destination Port Unreachable
范例: 禁止一個(gè)網(wǎng)段,或多個(gè)地址訪問(wèn)10.0.0.201
[22:14:33 root@centos8 ~]#iptables -A INPUT -s 10.0.0.0/24 -j REJECT
### 注意: 如果在INPUT鏈只基于源IP進(jìn)行過(guò)濾,當(dāng)遠(yuǎn)程主機(jī)和源IP在同一個(gè)網(wǎng)段時(shí),拒絕后就無(wú)法SSH遠(yuǎn)程登錄了.因此,一定添加規(guī)則時(shí)一定要注意,否則就會(huì)無(wú)法遠(yuǎn)程到服務(wù)器了. 因?yàn)?基于源IP進(jìn)行的過(guò)濾是過(guò)濾所有協(xié)議 ###
### 需要把規(guī)則清除,或者加一個(gè)新規(guī)則插入到全部拒絕的前面 ###
[22:23:04 root@centos8 ~]#iptables -I INPUT 1 -s 10.0.0.1 -j ACCEPT
[22:23:21 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
8 2005 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
615 51660 REJECT all -- * * 10.0.0.202 0.0.0.0/0 reject-with icmp-port-unreachable
106 13010 REJECT all -- * * 10.0.0.0/24 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination \
### 顯示規(guī)則編號(hào) ###
[22:23:38 root@centos8 ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 339 28825 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
2 772 64848 REJECT all -- * * 10.0.0.202 0.0.0.0/0 reject-with icmp-port-unreachable
3 245 25418 REJECT all -- * * 10.0.0.0/24 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
- 總結(jié): 基于源IP在INPUT鏈過(guò)濾時(shí),要注意規(guī)則順序
- 基于源IP過(guò)濾,如果源IP都是同一個(gè)網(wǎng)段的,要把嚴(yán)格的,范圍小的匹配條件往前放,范圍大的匹配條件往后放
- 如果源IP匹配的是不同的網(wǎng)段,要把范圍大的網(wǎng)段放在前面,范圍小的放在后面.
比如: 172.16.0.0/16 vs 10.0.0.0/24
要把172.16.0.0/16放在前面,因?yàn)樗烁嗟腎P地址. 如果把它放在10.0.0.0/24后面,那么每收到一個(gè)來(lái)自172.16.0.0/16的數(shù)據(jù),都要先在10.0.0.0/24中過(guò)濾一遍,會(huì)加大系統(tǒng)消耗
范例: 在OUTPUT鏈拒絕10.0.0.202訪問(wèn)10.0.0.201
[22:56:03 root@centos8 ~]#iptables -R OUTPUT 1 -d 10.0.0.202 -j REJECT
[22:56:15 root@centos8 ~]#iptables -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 504 REJECT all -- * * 0.0.0.0/0 10.0.0.202 reject-with icmp-port-unreachable
- 在INPUT和OUTPUT鏈上都可以指定規(guī)則,拒絕遠(yuǎn)程主機(jī)訪問(wèn)本地主機(jī),要把規(guī)則設(shè)定在INPUT鏈上.因?yàn)槿绻O(shè)定在OUTPUT上,數(shù)據(jù)會(huì)進(jìn)入到本地主機(jī)做處理,然后在出去的時(shí)候才做拒絕,浪費(fèi)資源.
- 在INPUT上利用遠(yuǎn)程主機(jī)的IP作為源IP進(jìn)行匹配,在OUTPUT上利用遠(yuǎn)程主機(jī)的IP作為目標(biāo)IP去匹配
企業(yè)常用白名單機(jī)制: 只有明確允許的流量才放行,其他統(tǒng)統(tǒng)拒絕
默認(rèn)拒絕所有非允許流量的兩種方法:
- 修改表中某個(gè)鏈的默認(rèn)規(guī)則: iptables -P INPUT DROP
- 追加一條拒絕所有,在表中某個(gè)鏈的規(guī)則中: iptables -A INPUT -j REJECT
注意: 不建議通過(guò)-P對(duì)整個(gè)鏈設(shè)定默認(rèn)規(guī)則,因?yàn)殒湵砑?jí)別的默認(rèn)規(guī)則是無(wú)法用iptables -F去清除的,建議以追加的形式,在規(guī)則列表末尾添加一條拒絕所有 - 如果添加了默認(rèn)拒絕,那么要把Loopback口放行,來(lái)完成本地測(cè)試,否則自己是ping不通自己的
[00:01:15 root@centos8 ~]#iptables -I INPUT -i lo -j ACCEPT
-i 表示, 從某個(gè)接口流入的報(bào)文都允許或拒絕
-o 表示, 從某個(gè)接口流程的報(bào)文都允許或拒絕
- 如果鏈的默認(rèn)規(guī)則設(shè)成ACCEPT但是規(guī)則里最后一條是拒絕所有,那么失效的是鏈的默認(rèn)允許所有
黑名單機(jī)制: 只有明確拒絕的才不允許,其他默認(rèn)都放行
3.4 iptables 擴(kuò)展匹配條件
擴(kuò)展匹配條件: 需要加載擴(kuò)展模塊(/usr/lib64/xtables/*.so)
擴(kuò)展模塊的查看幫助: man iptables-extensions
擴(kuò)展匹配條件:
- 隱式擴(kuò)展
- 顯式擴(kuò)展
3.4.1 隱式擴(kuò)展
iptables在使用-p選項(xiàng)指明了特定的協(xié)議時(shí),無(wú)需再用-m選項(xiàng)指明擴(kuò)展模塊的擴(kuò)展機(jī)制,不需要手動(dòng)加載擴(kuò)展模塊
tcp協(xié)議的擴(kuò)展選項(xiàng)
范例:
不允許任何主機(jī)向10.0.0.201發(fā)起新的ssh連接,但是已經(jīng)建立起的連接是不會(huì)受影響的
### 添加規(guī)則前 ###
[01:03:25 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 336 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
5729 493K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
### 此時(shí)10.0.0.202是可以ssh到10.0.0.201上的 ###
### 添加規(guī)則,不允許任何主機(jī)向10.0.0.201發(fā)起新的ssh連接,但是已建立起來(lái)的鏈接不受影響 ###
[01:06:16 root@centos8 ~]#iptables -A INPUT -p tcp --syn -j REJECT
### 從其他主機(jī)新建立ssh到10.0.0.201,訪問(wèn)拒絕 ###
[root@centos6 ~]# ssh 10.0.0.201
ssh: connect to host 10.0.0.201 port 22: Connection refused
### 此時(shí)如果退出已建立的連接,那么也無(wú)法再ssh 10.0.0.201 ###
[01:04:30 root@centos8 ~]#exit
logout
Connection to 10.0.0.201 closed.
[10:31:00 root@centos7 ~]#ssh 10.0.0.201
ssh: connect to host 10.0.0.201 port 22: Connection refused
- 系統(tǒng)維護(hù)時(shí)可以采用此方法,已登錄系統(tǒng)的用戶不受影響,但是新用戶無(wú)法連接到系統(tǒng)
udp協(xié)議的擴(kuò)展選項(xiàng)
范例:
允許10.0.0.0/24網(wǎng)段主機(jī)訪問(wèn)10.0.0.201的tcp 80端口
### 追加一條規(guī)則,拒絕所有用戶 ###
[01:12:05 root@centos8 ~]#iptables -A INPUT -j REJECT
[01:12:27 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 336 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
7092 597K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
### 此時(shí)除了lo和10.0.0.1其他任何主機(jī)都無(wú)法訪問(wèn)10.0.0.201 ###
### 添加規(guī)則 ###
[01:17:58 root@centos8 ~]#iptables -I INPUT 3 -s 10.0.0.0/24 -p tcp --dport 80 -j ACCEPT
[01:19:23 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 336 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
7831 656K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp dpt:80
6 676 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
### 這里要將允許規(guī)則添加到默認(rèn)拒絕所有的前面,也就是插入到第三條規(guī)則 ###
### 此時(shí)10.0.0.0/24網(wǎng)段多可以訪問(wèn)10.0.0.201的tcp 80端口,但是其他端口是無(wú)法訪問(wèn)的 ###
[root@centos6 ~]# curl http://10.0.0.201:80
welcome to website
[root@centos6 ~]# ssh 10.0.0.201
ssh: connect to host 10.0.0.201 port 22: Connection refused
[root@centos6 ~]# ping 10.0.0.201
PING 10.0.0.201 (10.0.0.201) 56(84) bytes of data.
From 10.0.0.201 icmp_seq=1 Destination Port Unreachable
注意: 此時(shí)10.0.0.201是無(wú)法ssh或者ping其他主機(jī)的,因?yàn)樵贗NPUT鏈上有默認(rèn)的拒絕所有流量,導(dǎo)致從其他主機(jī)的回包會(huì)被拒絕,但是從10.0.0.201發(fā)出去的包是不會(huì)被拒絕的,因?yàn)镺UTPUT上沒有規(guī)則. 此時(shí),如果想讓10.0.0.201能夠ssh到其他主機(jī),比如, 10.0.0.202,則需要再額外添加一條規(guī)則,來(lái)允許來(lái)自10.0.0.0/24網(wǎng)段,tcp源端口是22的流量,因?yàn)閟sh的回包的源端口號(hào)是對(duì)方的22端口,而從10.0.0.201發(fā)出的ssh請(qǐng)求包的目標(biāo)端口是對(duì)方的22端口. 回包時(shí)源目端口號(hào)對(duì)調(diào). 從10.0.0.0.201 ssh 10.0.0.202時(shí), 請(qǐng)求包, 源端口是201的隨機(jī)端口, 目標(biāo)端口是202的22端口, 而從202來(lái)的回報(bào), 源端口是202的22端口, 目標(biāo)端口是201上的隨機(jī)端口.
[01:26:59 root@centos8 ~]#iptables -I INPUT 4 -s 10.0.0.0/24 -p tcp --sport 22 -j ACCEPT
[01:33:09 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
14 1207 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
9085 763K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
12 877 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp spt:22
121 20933 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
[01:33:15 root@centos8 ~]#ssh 10.0.0.202
The authenticity of host '10.0.0.202 (10.0.0.202)' can't be established.
ECDSA key fingerprint is SHA256:kcsygyUEyDlk9lnQ3eVFN0Vf9v6ZUaxLFZICqknnpdw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.202' (ECDSA) to the list of known hosts.
root@10.0.0.202's password:
Last login: Tue Jul 14 10:08:50 2020 from 10.0.0.1
[10:56:29 root@centos7 ~]#
ICMP協(xié)議的擴(kuò)展選項(xiàng)
[!] --icmp-type {type[/code]|typename}
type/code
0/0 echo-reply icmp 應(yīng)答
8/0 echo-request icmp 請(qǐng)求
通過(guò)ICMP協(xié)議擴(kuò)展選項(xiàng),可以實(shí)現(xiàn)A主機(jī)能ping通B,但是B主機(jī)無(wú)法ping通A,實(shí)現(xiàn)單項(xiàng)控制
范例:
實(shí)現(xiàn)10.0.0.201可以ping通10.0.0.202但是10.0.0.202無(wú)法ping通10.0.0.201
### 此時(shí)10.0.0.202無(wú)任何iptables規(guī)則,10.0.0.201 iptables規(guī)則如下 ###
[01:42:42 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
14 1207 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
9861 830K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
12 877 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp dpt:80
27 4217 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp spt:22
122 21246 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
### 此時(shí)10.0.0.202無(wú)法ping通10.0.0.201,因?yàn)樵?01的INPUT上有默認(rèn)拒絕流量,而ping是ICMP協(xié)議,不滿足任何放行條件,所以202 ping 201的ping包可以從202出去,但是無(wú)法進(jìn)到201的 同時(shí)201 ping 202的ping包可以到達(dá)202,因?yàn)樵?01的OUTPUT和202的INPUT都沒有規(guī)則,但是202發(fā)給201的回包無(wú)法到打201,因?yàn)?01INPUT鏈有默認(rèn)拒絕所有 ###
### 要想實(shí)現(xiàn)題目功能,需要允許202給201的回包 ###
[01:53:02 root@centos8 ~]#iptables -I INPUT 5 -s 10.0.0.0/24 -p icmp --icmp-type 0/0 -j ACCEPT
3.4.2 顯式擴(kuò)展及相關(guān)模塊
3.4.2.1 multiport模塊
- 以離散方式定義多端口匹配,最多指定15個(gè)端口
范例:
拒絕10.0.0.0/24網(wǎng)段訪問(wèn)本地 tcp 22和80端口
[15:20:57 root@centos8 ~]#iptables -A INPUT -s 10.0.0.1 -j ACCEPT
[15:21:26 root@centos8 ~]#iptables -A INPUT -s 10.0.0.0/24 -p tcp -m multiport --dports 22,80 -j REJECT
[15:22:10 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
338 23816 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT tcp -- * * 10.0.0.0/24 0.0.0.0/0 multiport dports 22,80 reject-with icmp-port-unreachable
### 從 10.0.0.202, ping, ssh, curl 10.0.0.201 ###
[01:19:38 root@centos7 ~]#ping 10.0.0.201
PING 10.0.0.201 (10.0.0.201) 56(84) bytes of data.
64 bytes from 10.0.0.201: icmp_seq=1 ttl=64 time=0.794 ms
^C
--- 10.0.0.201 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.794/0.794/0.794/0.000 ms
[01:23:46 root@centos7 ~]#curl 10.0.0.201
curl: (7) Failed connect to 10.0.0.201:80; Connection refused
[01:23:50 root@centos7 ~]#ssh 10.0.0.201
ssh: connect to host 10.0.0.201 port 22: Connection refused
3.4.2.2 iprange擴(kuò)展
- 指明連續(xù)的(但一般不是整個(gè)網(wǎng)絡(luò)的)ip地址范圍
范例:
### 先添加拒絕所有規(guī)則 ###
[15:30:07 root@centos8 ~]#iptables -A INPUT -j REJECT
[15:30:14 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1071 85816 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
### 插入規(guī)則,允許10.0.0.204/24-10.0.0.210/24訪問(wèn)10.0.0.201本地 ###
[15:36:59 root@centos8 ~]#iptables -I INPUT 2 -m iprange --src-range 10.0.0.204-10.0.0.210 -j ACCEPT
[15:37:19 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1739 143K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
10 840 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 source IP range 10.0.0.204-10.0.0.210
806 68436 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
3.4.2.3 mac擴(kuò)展
- 可以用來(lái)基于源IP和源MAC綁定指定主機(jī)
- mac擴(kuò)展只需指定源MAC即可,因?yàn)槟繕?biāo)MAC必須是本機(jī)網(wǎng)卡MAC,否則就丟包了
- 特殊情況,當(dāng)網(wǎng)卡設(shè)置為混雜模式,那么收到的幀無(wú)論目標(biāo)MAC是不是本機(jī)MAC地址都會(huì)接收,適用與監(jiān)控情況
- 修改MAC地址, 可以在網(wǎng)卡配置文件添加MACADDR=XXXXXXXXXXXX
3.4.2.4 string擴(kuò)展
- 對(duì)報(bào)文中的應(yīng)用層數(shù)據(jù)做字符串模式匹配檢測(cè),只要訪問(wèn)頁(yè)面包含關(guān)鍵字就會(huì)被拒絕,容易誤殺
范例:
拒絕訪問(wèn)帶google字符的頁(yè)面,但是baidu可以, 在output鏈加, 禁止回包里有不讓訪問(wèn)的字符
Centos 6 IP 地址為 10.0.0.204/24
[root@centos6 ~]# curl 10.0.0.201/google.html
google
[root@centos6 ~]# curl 10.0.0.201/baidu.html
baidu
[root@centos6 ~]#
[16:04:57 root@centos8 /var/www/html]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4078 346K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3516 297K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 source IP range 10.0.0.204-10.0.0.210
2567 228K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
### 添加規(guī)則,如果web訪問(wèn)返回頁(yè)面包含google關(guān)鍵字,則拒絕 ###
### 此時(shí)要在OUTPUT鏈添加,因?yàn)槭腔匕琯oogle關(guān)鍵字會(huì)被拒絕 ###
### 客戶端發(fā)送請(qǐng)求訪問(wèn)帶有Google字樣的頁(yè)面, 防火墻收到網(wǎng)站回復(fù),給客戶端發(fā)回報(bào)時(shí), 如果發(fā)現(xiàn)有Google字符則拒絕 ###
[16:06:38 root@centos8 /var/www/html]#iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --from 62 --string "google" -j REJECT
[16:10:43 root@centos8 /var/www/html]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4590 387K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3528 298K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 source IP range 10.0.0.204-10.0.0.210
2571 229K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 STRING match "google" ALGO name bm FROM 62 TO 65535 reject-with icmp-port-unreachable
[root@centos6 ~]# curl 10.0.0.201/baidu.html
baidu
[root@centos6 ~]# curl 10.0.0.201/google.html
3.4.2.5 time擴(kuò)展
- 根據(jù)將報(bào)文到達(dá)的時(shí)間與指定的時(shí)間范文進(jìn)行匹配
3.4.2.6 connlimit擴(kuò)展
根據(jù)每客戶端IP做并發(fā)連接數(shù)數(shù)量匹配,每個(gè)IP并發(fā)最多能發(fā)起多少次連接請(qǐng)求
可防止DOS拒絕服務(wù)攻擊
--connlimit-upto #連接的數(shù)量小于等于#時(shí)匹配
--connlimit-above #連接的數(shù)量大于#時(shí)匹配
范例:
設(shè)定每IP最多并發(fā)10個(gè)連接到本地
[17:06:47 root@centos8 ~]#iptables -I INPUT 2 -m connlimit --connlimit-above 10 -j REJECT
[17:07:59 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
8866 760K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 #conn src/32 > 10 reject-with icmp-port-unreachable
149 12516 ACCEPT all -- * * 10.0.0.0/24 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
3.4.2.7 limit擴(kuò)展
基于收發(fā)報(bào)文的速率做匹配,令牌桶過(guò)濾器
范例:
[17:15:54 root@centos8 ~]#iptables -I INPUT 2 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT
[17:19:32 root@centos8 ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
353 28496 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
6 504 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 limit: avg 10/min burst 5
32 2688 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
3.4.2.8 state擴(kuò)展
可以監(jiān)控通過(guò)的數(shù)據(jù)報(bào)文, 是不是通訊過(guò), 如果通訊過(guò)會(huì)在內(nèi)存記錄下來(lái), 下次在訪問(wèn)就可以區(qū)分是新用戶還是老用戶, 之后做控制(老用戶可以連接, 新用戶不可以,和協(xié)議無(wú)關(guān), 只跟蹤狀態(tài)). --- 狀態(tài)跟蹤.
和TCP狀態(tài)機(jī)不一樣
缺點(diǎn): 消耗內(nèi)存資源
已經(jīng)追蹤到并且記錄下來(lái)的信息會(huì)放在數(shù)據(jù)庫(kù)
/proc/net/nf_conntrack
因?yàn)閮?nèi)存有限制:
記錄有時(shí)間限制, 規(guī)定在/proc/sys/net/netfilter/目錄
并不是來(lái)一條記錄就記錄一條
最大記錄狀態(tài)值, 放在
[07:13:44 root@c8prac ~]#cat /proc/sys/net/netfilter/nf_conntrack_max
26624
因此, 前端調(diào)度器需要增加最大記錄狀態(tài)值, 真正的后臺(tái)服務(wù)器可以適當(dāng)?shù)臏p少該最大值, 直接修改這個(gè)文件即可.
[06:55:11 root@c8prac ~]#cat /proc/net/nf_conntrack
ipv4 2 tcp 6 409305 ESTABLISHED src=10.0.0.1 dst=10.0.0.84 sport=57822 dport=22 src=10.0.0.84 dst=10.0.0.1 sport=22 dport=57822 [ASSURED] mark=0 zone=0 use=2
ipv4 2 tcp 6 409304 ESTABLISHED src=10.0.0.1 dst=10.0.0.84 sport=57522 dport=22 src=10.0.0.84 dst=10.0.0.1 sport=22 dport=57522 [ASSURED] mark=0 zone=0 use=2
需要注意狀態(tài)跟蹤的添加順序, 比如跟蹤ESTABLISHED, 如果先添加了默認(rèn)拒絕所有, 再添加ESTABLISHED,那么ESTABLISHED是不生效的
案例
實(shí)現(xiàn)10.0.0.71主機(jī)不能訪問(wèn)10.0.0.84, 但是84可以訪問(wèn)71, 包含任何協(xié)議.
ICMP可以基于type類型做控制(允許icmp的回應(yīng)報(bào)文), tcp可以基于三次握手的syn位做控制(input上拒絕對(duì)方的--syn請(qǐng)求)
但是udp和其他應(yīng)用層協(xié)議沒有這些功能, 所以需要基于STATE狀態(tài)跟蹤實(shí)現(xiàn)
在8上指定只允許ESTABLISHED的包進(jìn)入, 從8出去的包不需要控制
ESTABLISHED: 第一次發(fā)的請(qǐng)求報(bào)文是NEW, 對(duì)方給我的回包就是ESTABLISHED了.
10.0.0.84上的配置
[08:31:20 root@c8prac ~]#iptables -vnL
Chain INPUT (policy ACCEPT 35158 packets, 3296K bytes)
pkts bytes target prot opt in out source destination
1534 122K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0 #Windows本機(jī)允許.
48 4032 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED #該記錄只允許已經(jīng)建立連接的包回到84, 也就是84訪問(wèn)71時(shí), 從71回來(lái)的包
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable #該默認(rèn)記錄會(huì)拒絕從其他任何主機(jī)發(fā)起的請(qǐng)求
如果只想控制71不能主動(dòng)訪問(wèn)84, 可以在默認(rèn)規(guī)則前加一條規(guī)則, 允許非71的主機(jī)訪問(wèn)84
iptables -I INPUT 3 ! -s 10.0.0.71 -j ACCEPT
[20:37:18 root@c6node ~]#ping 10.0.0.84 #我的6的地址是10.0.0.61
PING 10.0.0.84 (10.0.0.84) 56(84) bytes of data.
64 bytes from 10.0.0.84: icmp_seq=1 ttl=64 time=0.348 ms
64 bytes from 10.0.0.84: icmp_seq=2 ttl=64 time=0.266 ms
最終規(guī)則:
[08:37:11 root@c8prac ~]#iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -s 10.0.0.1/32 -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT ! -s 10.0.0.71/32 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
自定義鏈
把規(guī)則分類, 單獨(dú)定義一個(gè)鏈 ,就是自定義鏈, 比如把和web服務(wù)相關(guān)的規(guī)則放在一個(gè)鏈里
定義自定義鏈后,要關(guān)聯(lián)到正常的鏈中, 才會(huì)有意義. 因?yàn)檎嬲行У?是5個(gè)鏈而不是自定義鏈.
自定義鏈相當(dāng)于自定義函數(shù), 需要被調(diào)用才能有效果
自定義鏈與其他鏈獨(dú)立, 互不影響
- 自定義鏈案例
- 創(chuàng)建自定義鏈, 用-N選項(xiàng)
[08:53:35 root@c8prac ~]#iptables -N WEB
[08:56:26 root@c8prac ~]#iptables -vnL
Chain INPUT (policy ACCEPT 35158 packets, 3296K bytes)
pkts bytes target prot opt in out source destination
3565 296K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
954 80136 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 38480 packets, 1976K bytes)
pkts bytes target prot opt in out source destination
Chain WEB (0 references)
pkts bytes target prot opt in out source destination
- 定義自定義鏈規(guī)則, 允許目標(biāo)端口是90,443和8080的流量
[09:01:39 root@c8prac ~]#iptables -A WEB -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
- 將自定義鏈, 關(guān)聯(lián)到內(nèi)置鏈中
如果源地址是10.0.0.0/24網(wǎng)段的流量, 就交給WEB自定義鏈去控制, 具體能不能訪問(wèn)就看自定義鏈里的規(guī)則了
換句話說(shuō), 如果是在內(nèi)置鏈中, 調(diào)用自定義鏈, 那么內(nèi)置鏈的作用就是規(guī)定哪些流量需要自定義鏈去控制
真正起到控制的是自定義鏈里的規(guī)則, 也就是自定義鏈只需控制允許還是拒絕, 無(wú)需關(guān)注匹配的是誰(shuí)
[09:01:56 root@c8prac ~]#iptables -I INPUT 2 -s 10.0.0.0/24 -j WEB
[09:04:37 root@c8prac ~]#iptables -vnL
Chain INPUT (policy ACCEPT 35158 packets, 3296K bytes)
pkts bytes target prot opt in out source destination
5066 425K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 WEB all -- * * 10.0.0.0/24 0.0.0.0/0
954 80136 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 39822 packets, 2052K bytes)
pkts bytes target prot opt in out source destination
Chain WEB (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443,8080
- 這時(shí)如果還想允許10.0.0.0/24網(wǎng)段不僅能訪問(wèn)本機(jī)的WEB服務(wù), 還能ping通本機(jī), 只需要修改WEB自定義鏈,添加允許icmp協(xié)議規(guī)則即可,而無(wú)需修改內(nèi)置鏈的條目, 達(dá)到模塊化控制
[09:19:11 root@c8prac ~]#iptables -A WEB -p icmp -j ACCEPT
[09:19:17 root@c8prac ~]#iptables -vnL
Chain INPUT (policy ACCEPT 35158 packets, 3296K bytes)
pkts bytes target prot opt in out source destination
5794 489K ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
0 0 WEB all -- * * 10.0.0.0/24 0.0.0.0/0
954 80136 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 40497 packets, 2091K bytes)
pkts bytes target prot opt in out source destination
Chain WEB (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443,8080
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
- 刪除自定義鏈用-X選項(xiàng)
- -F選項(xiàng)只能清除鏈里的規(guī)則, 并不能把自定義鏈刪了
iptables -X WEB
#1 先從內(nèi)置鏈中把自定義鏈刪了 iptables -t filter -D INPUT 2
#2 清空自定義鏈的規(guī)則 iptables -F WEB
#3 -X刪除自定義鏈 iptables -X WEB
- 直接刪除自定義鏈會(huì)報(bào)錯(cuò), 因此在內(nèi)置鏈中還被調(diào)用著
[09:27:59 root@c8prac ~]#iptables -X WEB
iptables v1.8.4 (nf_tables): CHAIN_USER_DEL failed (Device or resource busy): chain WEB
3.6 規(guī)則優(yōu)化最佳實(shí)踐
1. 安全放行所有入站和出站的狀態(tài)為ESTABLISHED狀態(tài)連接, 建議放在第一條, 效率更高
2. 謹(jǐn)慎放行入站的新請(qǐng)求
3. 有特殊目的的限制訪問(wèn)功能, 要在放行規(guī)則之前加以拒絕
4. 同類規(guī)則(訪問(wèn)同一應(yīng)用, 比如: http), 匹配范圍小的放在前面, 用于特殊處理
5. 不同類的規(guī)則(訪問(wèn)不同應(yīng)用, 一個(gè)是http, 另一個(gè)是mysql), 匹配范圍大的放在前面, 效率更高
6. 應(yīng)該將那些可由一條規(guī)則能夠描述的多個(gè)規(guī)則合并為一條
7. 設(shè)置默認(rèn)策略, 建議白名單(只放行特定連接)
# iptables -P, 設(shè)置鏈表級(jí)默認(rèn)規(guī)則, 不建議使用, 容易導(dǎo)致管理端無(wú)法ssh
# 規(guī)則的最后定義規(guī)則做為默認(rèn)策略, 推薦使用, 放在最后一條
3.7 持久保存iptables規(guī)則
3.7.1 持久保存規(guī)則
3.7.1.1 CentOS 7&8
利用iptables-save命令, 將系統(tǒng)當(dāng)前的規(guī)則存到一個(gè)文檔里, 文件路徑名字可以自己指定
iptables-save > /PATH/TO/RULES_FILE
iptables-save > /data/iptables.rule-`date +%F_%T`
3.7.1.2 CentOS 6
將規(guī)則覆蓋保存至/etc/sysconfig/iptables文件中
service iptables save
3.7.2 加載規(guī)則
3.7.2.1 手動(dòng)加載
CentOS 7&8
iptables-restore < /PATH/FROM/RULES_FILE
-n, --noflush: 不清楚原有規(guī)則
-t, --test: 僅分析生成規(guī)則集, 但不提交
iptables-restore < iptables.rule-2020-10-02_09:40:58
CentOS 6
重啟iptables會(huì)自動(dòng)從/etc/sysconfig/iptables 重新載入規(guī)則
service iptables restart
3.7.2.2 開機(jī)自動(dòng)加載
方法1. 在7和8上安裝iptables-services, 但是不建議, 因?yàn)楹蚮irewalld沖突
方法2. 將iptables-restore命令,放到/etc/rc.d/rc.local中. 這樣開機(jī)就會(huì)自動(dòng)運(yùn)行iptables-restore命令
iptables-restore < iptables.rule-2020-10-02_09\:40\:58
給rc.local添加執(zhí)行權(quán)限
chmod +x /etc/rc.d/rc.local
這樣就可以實(shí)現(xiàn)開機(jī)自動(dòng)加載rc.local里面的iptables-restore命令, 實(shí)現(xiàn)開機(jī)自動(dòng)加載定義好的iptables規(guī)則
自定義鏈的內(nèi)容, 也會(huì)開機(jī)自動(dòng)加載, 只要寫進(jìn)了文件里即可
3.8 網(wǎng)絡(luò)防火墻
iptables/netfilter 利用filter表的FORWARD鏈, 可以充當(dāng)網(wǎng)絡(luò)防火墻
- 請(qǐng)求和響應(yīng)報(bào)文均會(huì)經(jīng)過(guò)FORWARD鏈, 要注意規(guī)則的方向性
- 如果要啟用conntrack機(jī)制, 建議將雙方向的狀態(tài)為ESTABLISHED的報(bào)文直接放行
3.8.1 FORWARD鏈實(shí)現(xiàn)內(nèi)外網(wǎng)絡(luò)的流量控制
- 環(huán)境準(zhǔn)備
firewall
[13:10:11 root@firewall ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[13:10:08 root@firewall ~]#sysctl -p
net.ipv4.ip_forward = 1
internet
root@internet:~# vim /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [ 192.168.0.6/24 ]
gateway4: 192.168.0.8
root@internet:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.8 0.0.0.0 UG 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
lanserver1
[13:10:36 root@lanserver1 ~]#vinet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.7
NETMASK=255.255.255.0
GATEWAY=10.0.0.8
[13:12:34 root@lanserver1 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.8 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
lanserver2
[13:03:27 root@lanserver2 ~]#vinet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.17
NETMASK=255.255.255.0
GATEWAY=10.0.0.8
[13:13:10 root@lanserver2 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.8 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
- 訪問(wèn)測(cè)試, 確保內(nèi)外能互相ping通
root@internet:~# ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
64 bytes from 10.0.0.7: icmp_seq=1 ttl=63 time=10.3 ms
64 bytes from 10.0.0.7: icmp_seq=2 ttl=63 time=1.45 ms
root@internet:~# ping 10.0.0.17
PING 10.0.0.17 (10.0.0.17) 56(84) bytes of data.
64 bytes from 10.0.0.17: icmp_seq=1 ttl=63 time=1.52 ms
64 bytes from 10.0.0.17: icmp_seq=2 ttl=63 time=0.634 ms
- 實(shí)現(xiàn)內(nèi)網(wǎng)主機(jī)可以連接外網(wǎng),而外網(wǎng)無(wú)法主動(dòng)向內(nèi)網(wǎng)發(fā)起連接
[13:10:57 root@firewall ~]#iptables -A FORWARD -j REJECT
[13:39:43 root@firewall ~]#iptables -I FORWARD -s 10.0.0.0/24 -m state --state NEW -j ACCEPT
[13:40:10 root@firewall ~]#iptables -I FORWARD 2 -m state --state ESTABLISHED -j ACCEPT
[13:45:05 root@firewall ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 168 ACCEPT all -- * * 10.0.0.0/24 0.0.0.0/0 state NEW
133 11172 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
72 6048 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
- 訪問(wèn)測(cè)試
root@internet:~# ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 192.168.0.8 icmp_seq=1 Destination Port Unreachable
From 192.168.0.8 icmp_seq=2 Destination Port Unreachable
[13:46:17 root@lanserver1 ~]#ping 192.168.0.6
PING 192.168.0.6 (192.168.0.6) 56(84) bytes of data.
64 bytes from 192.168.0.6: icmp_seq=1 ttl=63 time=1.66 ms
64 bytes from 192.168.0.6: icmp_seq=2 ttl=63 time=1.14 ms
3.8.2 NAT表
NAT: Network Address Translation, 支持PREROUTING, INPUT, OUTPUT, POSTROUTING, 四個(gè)鏈
請(qǐng)求報(bào)文: 修改源/目標(biāo)IP, 定義如何修改
響應(yīng)報(bào)文: 修改源/目錄IP, 根據(jù)跟蹤機(jī)制自動(dòng)實(shí)現(xiàn)
NAT的實(shí)現(xiàn)分為下面類型:
SNAT: Source NAT, 支持POSTROUTING, INPUT, 讓本地網(wǎng)絡(luò)中的主機(jī)通過(guò)某一些特定地址訪問(wèn)外部網(wǎng)絡(luò), 實(shí)現(xiàn)地址偽裝, 請(qǐng)求報(bào)文: 修改源IP
DNAT: Destination NAT, 支持PREROUTING, OUTPUT, 把本地網(wǎng)絡(luò)中的主機(jī)上的某服務(wù)開放給外部網(wǎng)絡(luò)方位(發(fā)布服務(wù)和短褲映射), 但隱藏真實(shí)IP, 請(qǐng)求報(bào)文: 修改目標(biāo)IP
PNAT: Port NAT, 端口和IP都進(jìn)行修改
3.8.3 SNAT
SNAT: 基于nat表的target, 適用于固定的公網(wǎng)ip
SNAT選項(xiàng):
- --to-source [ipaddr[-ipaddr]][:port[-port]]
- random
iptables -t nat -A POSTROUTING -S LocalNET ! -d LocalNet -j SNAT --to-source ExtIP
范例:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9
MASQUERADE: 基于nat表的target, 適用于動(dòng)態(tài)的公網(wǎng)ip, 如: 撥號(hào)網(wǎng)絡(luò)
MASQUERADE選項(xiàng):
- --to-ports port[-port]
- --random
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE
范例:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j MASQUERADE
案例: SNAT, 模擬10.0.0.0/24網(wǎng)絡(luò)利用SNAT訪問(wèn)192.168.0.0/24網(wǎng)段
- 環(huán)境準(zhǔn)備
- 基于3.8.1環(huán)境
internet: 實(shí)驗(yàn)環(huán)境下, 主機(jī)是和防火墻左側(cè)端口直連的, 收到的報(bào)文源地址經(jīng)過(guò)SNAT轉(zhuǎn)換就是防火墻左側(cè)的ip地址, 所以也就不需要配網(wǎng)關(guān)了
root@internet:~# vim /etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [ 192.168.0.6/24 ]
lanserver1,lanserver2以及firewall保持不變
- 此時(shí), 由于internet主機(jī)沒有指定網(wǎng)關(guān), 內(nèi)外網(wǎng)是無(wú)法通訊的
[14:39:40 root@lanserver1 ~]#ping 192.168.0.6
PING 192.168.0.6 (192.168.0.6) 56(84) bytes of data # internet主機(jī)能收到內(nèi)網(wǎng)的icmp請(qǐng)求包, 但是無(wú)法回應(yīng)
root@internet:~# tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:44:41.432337 IP 10.0.0.7 > 192.168.0.6: ICMP echo request, id 26448, seq 30, length 64 # 沒有響應(yīng)報(bào)文
14:44:42.433447 IP 10.0.0.7 > 192.168.0.6: ICMP echo request, id 26448, seq 31, length 64
14:44:43.434869 IP 10.0.0.7 > 192.168.0.6: ICMP echo request, id 26448, seq 32, length 64
root@internet:~# ping 10.0.0.7
connect: Network is unreachable # 不同網(wǎng)絡(luò)通訊, 找不到網(wǎng)關(guān)
- firewall的nat表添加SNAT策略
SNAT需要在nat表的POSTROUTING設(shè)置, nat起到的是轉(zhuǎn)發(fā)作用, 因此, 無(wú)論SNAT還是DNAT都不涉及,INPUT和OUTPUT
如果SNAT設(shè)置在了PREROUTING上, 那么就會(huì)把所有剛進(jìn)入到防火墻的流量的源ip地址都做轉(zhuǎn)換, 如果某些報(bào)文是要訪問(wèn)防火墻自身數(shù)據(jù)的, 就會(huì)收影響
[13:45:08 root@firewall ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
[14:48:21 root@firewall ~]#iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
46 3864 MASQUERADE all -- * * 10.0.0.0/24 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
- 訪問(wèn)測(cè)試
[14:48:08 root@lanserver1 ~]#ping 192.168.0.6
PING 192.168.0.6 (192.168.0.6) 56(84) bytes of data.
64 bytes from 192.168.0.6: icmp_seq=1 ttl=63 time=1.00 ms
64 bytes from 192.168.0.6: icmp_seq=2 ttl=63 time=0.780 ms
添加了SNAT后, 內(nèi)網(wǎng)訪問(wèn)外網(wǎng)主機(jī), 在防火墻出口, 內(nèi)網(wǎng)的ip地址,會(huì)被替換成防火墻出口的ip, 實(shí)驗(yàn)環(huán)境中, 防火墻出口和外網(wǎng)主機(jī)是在一個(gè)網(wǎng)段, 因此外網(wǎng)主機(jī)可以收到
同時(shí), 因此SNAT會(huì)修改請(qǐng)求報(bào)文的源ip, 因?yàn)橥饩W(wǎng)主機(jī)收到的報(bào)文的源ip是防火墻出口的ip, 那么回應(yīng)也是給這個(gè)ip回應(yīng)
由于外網(wǎng)主機(jī)和防火墻出口ip是在同一個(gè)網(wǎng)段, 所以即使沒有網(wǎng)關(guān)也是能通的
root@internet:~# tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:49:07.749898 IP 192.168.0.8 > 192.168.0.6: ICMP echo request, id 26452, seq 1, length 64
14:49:07.749980 IP 192.168.0.6 > 192.168.0.8: ICMP echo reply, id 26452, seq 1, length 64
14:49:08.750987 IP 192.168.0.8 > 192.168.0.6: ICMP echo request, id 26452, seq 2, length 64
14:49:08.751014 IP 192.168.0.6 > 192.168.0.8: ICMP echo reply, id 26452, seq 2, length 64
- 查看SNAT轉(zhuǎn)換信息
[15:16:49 root@firewall ~]#tail -f /proc/net/nf_conntrack
ipv4 2 icmp 1 26 src=10.0.0.7 dst=192.168.0.6 type=8 code=0 id=26835 src=192.168.0.6 dst=192.168.0.8 type=0 code=0 id=26835 mark=0 zone=0 use=2
ipv4 2 tcp 6 299 ESTABLISHED src=10.0.0.8 dst=10.0.0.1 sport=22 dport=50494 src=10.0.0.1 dst=10.0.0.8 sport=50494 dport=22 [ASSURED] mark=0 zone=0 use=2
tail: /proc/net/nf_conntrack: file truncated
ipv4 2 icmp 1 26 src=10.0.0.7 dst=192.168.0.6 type=8 code=0 id=26835 src=192.168.0.6 dst=192.168.0.8 type=0 code=0 id=26835 mark=0 zone=0 use=2
ipv4 2 tcp 6 299 ESTABLISHED src=10.0.0.8 dst=10.0.0.1 sport=22 dport=50494 src=10.0.0.1 dst=10.0.0.8 sport=50494 dport=22 [ASSURED] mark=0 zone=0 use=2
3.8.4 DNAT
DNAT: nat表的target, 適用于端口映射, 既可重定向到本機(jī), 也可以支持重定向到不同主機(jī)的不同端口, 但不支持多目標(biāo), 既不支持負(fù)載均衡功能
DNAT選項(xiàng):
- --to-destination [ipaddr[-ipaddr]][:port[-port]]
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterServerIP[;PORT]
范例:
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 22 -j DNAT --to-destination 10.0.1.22
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080
案例: 實(shí)現(xiàn)DNAT, 公網(wǎng)客戶端可以訪問(wèn)到內(nèi)網(wǎng)的服務(wù)器
- 環(huán)境準(zhǔn)備
lanserver1: 安裝httpd服務(wù), 模擬公司內(nèi)的web服務(wù)器. 由于之前的實(shí)驗(yàn)把lanserver1的網(wǎng)關(guān)指向了防火墻內(nèi)網(wǎng)接口, DNS也刪除了, 因此, 安裝httpd前, 需要修改網(wǎng)關(guān),并且添加DNS. 安裝完httpd后再改回來(lái)
[15:10:45 root@lanserver1 ~]#vinet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.7
NETMASK=255.255.255.0
GATEWAY=10.0.0.2
DNS1=223.5.5.5
[15:06:03 root@lanserver1 ~]#yum -y install httpd; systemctl enable --now httpd; echo 'lanserver1-10.0.0.7' > /var/www/html/index.html
- firewall的nat表添加策略
DNAT需要在防火墻的PREROUTING鏈設(shè)置, 因?yàn)? 外網(wǎng)訪問(wèn)內(nèi)網(wǎng)服務(wù)器, 請(qǐng)求報(bào)文的目標(biāo)ip是防火墻的公網(wǎng)接口地址
如果不在PREROUTING做目標(biāo)地址轉(zhuǎn)換, 那么報(bào)文進(jìn)入了路由決策, 發(fā)現(xiàn)目標(biāo)ip是本機(jī), 就會(huì)把報(bào)文發(fā)到INPUT
[15:20:12 root@firewall ~]#iptables -t nat -A PREROUTING -d 192.168.0.8 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.7:80
- 訪問(wèn)測(cè)試
這里如果還保留了之前3.8.1的FORWARD策略, 那么訪問(wèn)會(huì)失敗, 因?yàn)橹暗腇ORWARD定義了只允許內(nèi)網(wǎng)通過(guò)firewall訪問(wèn)外網(wǎng). 因此, 測(cè)試之前需要把filter表FORWARD鏈清空
root@internet:~# curl 192.168.0.8
lanserver1-10.0.0.7
3.8.5 REDIRECT轉(zhuǎn)發(fā)
REDIRECT, 是NAT表的target, 通過(guò)改變目標(biāo)IP和端口, 將接受的包轉(zhuǎn)發(fā)至同一個(gè)主機(jī)的不同端口, 可用于PREROUTING, OUTPUT鏈
REDIRECT選項(xiàng):
- --to-ports port[-port]
范例:
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080
實(shí)現(xiàn)REDIRECT轉(zhuǎn)發(fā)
web服務(wù)器監(jiān)聽在8080端口, 防火墻還是基于DNAT實(shí)現(xiàn)192.168.0.8:80 > 10.0.0.7:80, 通過(guò)REDIRECT,把訪問(wèn)web服務(wù)器80端口的服務(wù), 重定向到web服務(wù)器的8080
- 修改web服務(wù)器的監(jiān)聽地址
[15:47:26 root@lanserver1 ~]#vim /etc/httpd/conf/httpd.conf
Listen 8080
[16:09:50 root@lanserver1 ~]#systemctl restart httpd
[16:09:54 root@lanserver1 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:8080 *:*
- 在web服務(wù)器上添加防火墻REDIRECT轉(zhuǎn)發(fā)
[16:10:05 root@lanserver1 ~]#iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
[16:11:10 root@lanserver1 ~]#iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 8080
- 測(cè)試訪問(wèn)
root@internet:~# curl 192.168.0.8
lanserver1-10.0.0.7