一、安全组与iptables的关系
OpenStack的安全组(Security Group)默认是通过Linux的iptables
实现的。以下是其主要实现原理和机制:
-
安全组与iptables的关系
OpenStack的安全组规则通过
iptables
的规则链实现。每条安全组规则会被转换为相应的iptables
规则,这些规则会动态生成并应用到计算节点的iptables
中。 -
规则链的生成
安全组规则会根据虚拟机的网络接口(如虚拟机网卡)生成特定的
iptables
规则链。
二、回顾"启动一个实例"中的内容
在《OpenStack Yoga版安装笔记(十四)启动一个实例》中,执行了以下命令:
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1、创建network | root@osclient ~(admin/amdin)# openstack network create --share --external --provider-physical-network provider --provider-network-type flat provider |
| 2、创建subnet | root@osclient ~(admin/amdin)# openstack subnet create --network provider --allocation-pool start=203.0.113.101,end=203.0.113.250 --dns-nameserver 8.8.4.4 --gateway 203.0.113.1 --subnet-range 203.0.113.0/24 provider |
| 3、创建一个新的计算实例类型(flavor) | root@osclient ~(admin/amdin)# openstack flavor create --id 0 --vcpus 1 --ram 64 --disk 1 m1.nano |
| 4、user "myuser"登录到project "myproject" | root@osclient:~# cat demo-openrc export OS_PROJECT_DOMAIN_NAME=Default export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_NAME=myproject export OS_USERNAME=myuser export OS_PASSWORD=openstack export OS_AUTH_URL=http://controller:5000/v3 export OS_IDENTITY_API_VERSION=3 export OS_IMAGE_API_VERSION=2 export PS1='\u@\h \W(myproject/myuser)\$ ' root@osclient:~# source demo-openrc root@osclient ~(myproject/myuser)# pwd /root root@osclient ~(myproject/myuser)# |
| 5、生成一个 SSH 密钥对(公钥和私钥) | root@osclient ~(myproject/myuser)# ssh-keygen -q -N "" Enter file in which to save the key (/root/.ssh/id_rsa): root@osclient ~(myproject/myuser)# ls .ssh authorized_keys id_rsa id_rsa.pub known_hosts 注:id_rsa,私钥;id_rsa.pub,公钥。 |
| 6、用户myuser使用 OpenStack CLI 将公钥上传到项目 myproject 中 | root@osclient ~(myproject/myuser)# openstack keypair create --public-key ~/.ssh/id_rsa.pub mykey |
| 7、列出当前项目中所有已注册的 SSH 密钥对 | root@osclient ~(myproject/myuser)# openstack keypair list |
| 8、在project myporject中,为默认的安全组(default)添加一条允许 ICMP 流量的入向规则(缺省为入向) | root@osclient ~(myproject/myuser)# openstack security group rule create --proto icmp default |
| 9、在project myporject中,为默认的安全组(default)添加一条允许所有来源的 TCP 流量访问 22 端口(SSH)的入向规则(缺省为入向) | root@osclient ~(myproject/myuser)# openstack security group rule create --proto tcp --dst-port 22 default |
| 10、列出当前项目中所有安全组的规则 | root@osclient ~(myproject/myuser)# openstack security group rule list |
| 11、在 OpenStack 中创建一个新的云实例。通过指定 flavor、镜像、网络、安全组和 SSH 密钥对,可以配置实例的资源和访问权限。确保所有指定的资源(如 flavor、镜像、网络和密钥对)在当前项目中可用,并验证实例的状态以确保其正常运行。 可以使用之前产生的私钥(id_rsa)通过SSH登录到云实例: ssh -i ~/.ssh/id_rsa <username>@<instance_ip> | root@osclient ~(myproject/myuser)# openstack server create --flavor m1.nano --image cirros --nic net-id=48f2b88e-7740-4d94-a631-69e2abadf25b --security-group default --key-name mykey provider-instance |
三、创建虚机后的网络拓扑
创建虚机后,Openstack视角的抽象网络拓扑:

实际的网络拓扑,其中openstack创建了qdhcpxxxx、brqxxxx、provider-instance:
实际网络拓扑示意
另外,本次环境中,还有一台运行openstack client的虚机(ip address: 10.0.20.100):
root@osclient:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ff:20:81 brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 10.0.20.100/24 brd 10.0.20.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feff:2081/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:44:6b:2d:6a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
root@osclient:~# ls
admin-openrc demo-openrc myproject-admin-openrc
root@osclient:~#
四、查看虚机运行所在的主机
1、普通role的user无法查看虚机所在的主机信息
user "myuser" 在project "myproject"中赋予role "myrole",这是普通权限。
root@osclient ~(admin/amdin)# source demo-openrc
root@osclient ~(myproject/myuser)# cat demo-openrc
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=myproject
export OS_USERNAME=myuser
export OS_PASSWORD=openstack
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
export PS1='\u@\h \W(myproject/myuser)\$ '
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
root@osclient ~(myproject/myuser)# openstack server show d2e4bc39-63c8-4c80-b33f-52f4e1891f50
+-----------------------------+----------------------------------------------------------+
| Field | Value |
+-----------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-STS:power_state | Shutdown |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | stopped |
| OS-SRV-USG:launched_at | 2024-09-28T03:28:51.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | provider=203.0.113.125 |
| config_drive | |
| created | 2024-09-28T02:49:20Z |
| flavor | m1.nano (0) |
| hostId | 892d1a79d804f6b0fbfb68938ec0df8a0abc8e3d52660529538123e4 |
| id | d2e4bc39-63c8-4c80-b33f-52f4e1891f50 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | provider-instance |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='default' |
| status | SHUTOFF |
| updated | 2025-03-28T22:36:21Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-----------------------------+----------------------------------------------------------+
root@osclient ~(myproject/myuser)#
2、"admin" role的用户可以查看虚机所在主机的信息
google关键字搜索"openstack server show hostId",查看到类似的问题和解决办法:
Question #246423 "host-ids and extended server attributes" : Questions : OpenStack Compute (nova)
将user"admin"在project "myproject" 中赋予"admin" role:
root@osclient ~(myproject/amdin)# source admin-openrc
root@osclient ~(admin/amdin)# openstack role list
+----------------------------------+----------+
| ID | Name |
+----------------------------------+----------+
| 17552c9a365d4944a50fd8ac271791c6 | member |
| 48fa6b74f7b74d8698fe20b21ae8a02b | testrole |
| 83144b48ff1b4c54bb21d1fcb15921b5 | myrole |
| be23525c20c44f05b3ba071455522fcb | reader |
| e434c66b7af647158bcaa77686ca6e93 | admin |
+----------------------------------+----------+
root@osclient ~(admin/amdin)# openstack role add --project myproject --user admin admin
root@osclient ~(admin/amdin)#
使用admin role的user可以查看虚机所在的主机信息,根据输出结果,这台虚机运行在host "compute1":
root@osclient ~(myproject/myuser)# source myproject-admin-openrc
root@osclient ~(myproject/admin)# cat myproject-admin-openrc
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=myproject
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
export PS1='\u@\h \W(myproject/admin)\$ '
root@osclient ~(myproject/admin)# openstack server list
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
root@osclient ~(myproject/admin)# openstack server show d2e4bc39-63c8-4c80-b33f-52f4e1891f50
+-------------------------------------+----------------------------------------------------------+
| Field | Value |
+-------------------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | compute1 |
| OS-EXT-SRV-ATTR:hypervisor_hostname | compute1 |
| OS-EXT-SRV-ATTR:instance_name | instance-00000004 |
| OS-EXT-STS:power_state | Shutdown |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | stopped |
| OS-SRV-USG:launched_at | 2024-09-28T03:28:51.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | provider=203.0.113.125 |
| config_drive | |
| created | 2024-09-28T02:49:20Z |
| flavor | m1.nano (0) |
| hostId | 892d1a79d804f6b0fbfb68938ec0df8a0abc8e3d52660529538123e4 |
| id | d2e4bc39-63c8-4c80-b33f-52f4e1891f50 |
| image | cirros (429decdd-9230-49c0-b735-70364c226eb5) |
| key_name | mykey |
| name | provider-instance |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| properties | |
| security_groups | name='default' |
| status | SHUTOFF |
| updated | 2025-03-28T22:36:21Z |
| user_id | 9382b59561c04dd1abf0a4cb7a8252ec |
| volumes_attached | |
+-------------------------------------+----------------------------------------------------------+
root@osclient ~(myproject/admin)#
字段 值 OS-EXT-AZ:availability_zone nova OS-EXT-SRV-ATTR:host compute1 OS-EXT-SRV-ATTR:hypervisor_hostname compute1 信息解读:
availability_zone: nova
实例部署在默认的可用区(Availability Zone)
nova
中。OpenStack中,nova是默认的可用区名称,表示实例运行在未特别配置的区域。
host: compute1
实例当前运行在名为
compute1
的计算节点(Compute Node)上。这是物理主机的名称,负责承载虚拟机实例。
hypervisor_hostname: compute1
该计算节点的虚拟化平台(如KVM、Xen)的主机名也是
compute1
。通常与
host
字段一致,表示实例运行在同一个物理节点上。
五、虚机关闭状态时查看iptables
1、查看虚机处于关闭状态
root@osclient ~(myproject/admin)# source demo-openrc
root@osclient ~(myproject/myuser)# cat demo-openrc
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=myproject
export OS_USERNAME=myuser
export OS_PASSWORD=openstack
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
export PS1='\u@\h \W(myproject/myuser)\$ '
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
root@osclient ~(myproject/myuser)#
2、 此时虚拟网络环境
root@compute1:~# virsh net-list
Name State Autostart Persistent
--------------------------------------------
default active yes yes
root@compute1:~# brctl show
bridge name bridge id STP enabled interfaces
brq48f2b88e-77 8000.ea99122ddd99 no
virbr0 8000.525400db7049 yes
root@compute1:~#
3、查看iptables
查看"provider-instance"虚机运行所在的主机compute1的iptables,由于虚机关闭,此时OpenStack Neutron没有为该虚机添加相应规则。
root@compute1:~# iptables-save
# Generated by iptables-save v1.8.7 on Sun Mar 30 05:56:29 2025
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:LIBVIRT_PRT - [0:0]
-A POSTROUTING -j LIBVIRT_PRT
-A LIBVIRT_PRT -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
COMMIT
# Completed on Sun Mar 30 05:56:29 2025
# Generated by iptables-save v1.8.7 on Sun Mar 30 05:56:29 2025
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LIBVIRT_FWI - [0:0]
:LIBVIRT_FWO - [0:0]
:LIBVIRT_FWX - [0:0]
:LIBVIRT_INP - [0:0]
:LIBVIRT_OUT - [0:0]
-A INPUT -j LIBVIRT_INP
-A FORWARD -j LIBVIRT_FWX
-A FORWARD -j LIBVIRT_FWI
-A FORWARD -j LIBVIRT_FWO
-A OUTPUT -j LIBVIRT_OUT
-A LIBVIRT_FWI -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A LIBVIRT_FWI -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A LIBVIRT_FWO -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A LIBVIRT_FWO -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A LIBVIRT_FWX -i virbr0 -o virbr0 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 68 -j ACCEPT
COMMIT
# Completed on Sun Mar 30 05:56:29 2025
# Generated by iptables-save v1.8.7 on Sun Mar 30 05:56:29 2025
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:LIBVIRT_PRT - [0:0]
-A POSTROUTING -j LIBVIRT_PRT
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
COMMIT
# Completed on Sun Mar 30 05:56:29 2025
root@compute1:~#
root@compute1:~# iptables -t filter -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13804 3614K LIBVIRT_INP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 LIBVIRT_FWX all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LIBVIRT_FWI all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LIBVIRT_FWO all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
12954 4090K LIBVIRT_OUT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain LIBVIRT_FWI (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain LIBVIRT_FWO (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain LIBVIRT_FWX (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
Chain LIBVIRT_INP (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
Chain LIBVIRT_OUT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68
0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:68
root@compute1:~#
LIBVIRT_FWI、LIBVIRT_FWO、LIBVIRT_FWX、LIBVIRT_INP、LIBVIRT_OUT是Libvirt在管理虚拟机网络时创建的
iptables
规则链,可参考<Ubuntu22.04 KVM安装笔记>相关内容。这些链表不属于Openstack Neutron管理。
六、虚机开启时查看iptables
1、开启虚机
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | SHUTOFF | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-------------------+---------+------------------------+--------+---------+
root@osclient ~(myproject/myuser)# openstack server start provider-instance
root@osclient ~(myproject/myuser)# openstack server list
+--------------------------------------+-------------------+--------+------------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+-------------------+--------+------------------------+--------+---------+
| d2e4bc39-63c8-4c80-b33f-52f4e1891f50 | provider-instance | ACTIVE | provider=203.0.113.125 | cirros | m1.nano |
+--------------------------------------+-------------------+--------+------------------------+--------+---------+
root@osclient ~(myproject/myuser)#
root@osclient ~(myproject/myuser)#
2、此时虚拟网络环境
root@compute1:~# virsh net-list
Name State Autostart Persistent
--------------------------------------------
default active yes yes
root@compute1:~# brctl show
bridge name bridge id STP enabled interfaces
brq48f2b88e-77 8000.ea99122ddd99 no ens35
tap2d863922-bc
virbr0 8000.525400db7049 yes
root@compute1:~#
root@compute1:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:51:16:68 brd ff:ff:ff:ff:ff:ff
altname enp2s0
inet 10.0.20.12/24 brd 10.0.20.255 scope global ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe51:1668/64 scope link
valid_lft forever preferred_lft forever
3: ens35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master brq48f2b88e-77 state UP group default qlen 1000
link/ether 00:0c:29:51:16:72 brd ff:ff:ff:ff:ff:ff
altname enp2s3
inet6 fe80::20c:29ff:fe51:1672/64 scope link
valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:db:70:49 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: brq48f2b88e-77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ea:99:12:2d:dd:99 brd ff:ff:ff:ff:ff:ff
6: tap2d863922-bc: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master brq48f2b88e-77 state UNKNOWN group default qlen 1000
link/ether fe:16:3e:60:78:cd brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc16:3eff:fe60:78cd/64 scope link
valid_lft forever preferred_lft forever
root@compute1:~#
3、查看iptables-save
开启虚机后,OpenStack Neutron根据安全组配置,在iptables中为该虚机插入相应的安全组规则。
root@compute1:~# iptables-save
# Generated by iptables-save v1.8.7 on Sun Mar 30 06:11:29 2025
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:LIBVIRT_PRT - [0:0]
-A POSTROUTING -j LIBVIRT_PRT
-A LIBVIRT_PRT -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
COMMIT
# Completed on Sun Mar 30 06:11:29 2025
# Generated by iptables-save v1.8.7 on Sun Mar 30 06:11:29 2025
*raw
:PREROUTING ACCEPT [1116:236588]
:OUTPUT ACCEPT [853:288723]
:neutron-linuxbri-OUTPUT - [0:0]
:neutron-linuxbri-PREROUTING - [0:0]
-A PREROUTING -j neutron-linuxbri-PREROUTING
-A OUTPUT -j neutron-linuxbri-OUTPUT
-A neutron-linuxbri-PREROUTING -m physdev --physdev-in brq48f2b88e-77 -m comment --comment "Set zone for d863922-bc" -j CT --zone 4097
-A neutron-linuxbri-PREROUTING -i brq48f2b88e-77 -m comment --comment "Set zone for d863922-bc" -j CT --zone 4097
-A neutron-linuxbri-PREROUTING -m physdev --physdev-in tap2d863922-bc -m comment --comment "Set zone for d863922-bc" -j CT --zone 4097
COMMIT
# Completed on Sun Mar 30 06:11:29 2025
# Generated by iptables-save v1.8.7 on Sun Mar 30 06:11:29 2025
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:LIBVIRT_FWI - [0:0]
:LIBVIRT_FWO - [0:0]
:LIBVIRT_FWX - [0:0]
:LIBVIRT_INP - [0:0]
:LIBVIRT_OUT - [0:0]
:neutron-filter-top - [0:0]
:neutron-linuxbri-FORWARD - [0:0]
:neutron-linuxbri-INPUT - [0:0]
:neutron-linuxbri-OUTPUT - [0:0]
:neutron-linuxbri-i2d863922-b - [0:0]
:neutron-linuxbri-local - [0:0]
:neutron-linuxbri-o2d863922-b - [0:0]
:neutron-linuxbri-s2d863922-b - [0:0]
:neutron-linuxbri-sg-chain - [0:0]
:neutron-linuxbri-sg-fallback - [0:0]
-A INPUT -j neutron-linuxbri-INPUT
-A INPUT -j LIBVIRT_INP
-A FORWARD -j neutron-filter-top
-A FORWARD -j neutron-linuxbri-FORWARD
-A FORWARD -j LIBVIRT_FWX
-A FORWARD -j LIBVIRT_FWI
-A FORWARD -j LIBVIRT_FWO
-A OUTPUT -j neutron-filter-top
-A OUTPUT -j neutron-linuxbri-OUTPUT
-A OUTPUT -j LIBVIRT_OUT
-A LIBVIRT_FWI -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A LIBVIRT_FWI -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A LIBVIRT_FWO -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A LIBVIRT_FWO -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A LIBVIRT_FWX -i virbr0 -o virbr0 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 68 -j ACCEPT
-A neutron-filter-top -j neutron-linuxbri-local
-A neutron-linuxbri-FORWARD -m physdev --physdev-out tap2d863922-bc --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-linuxbri-sg-chain
-A neutron-linuxbri-FORWARD -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-linuxbri-sg-chain
-A neutron-linuxbri-INPUT -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Direct incoming traffic from VM to the security group chain." -j neutron-linuxbri-o2d863922-b
-A neutron-linuxbri-i2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-linuxbri-i2d863922-b -d 203.0.113.125/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-linuxbri-i2d863922-b -d 255.255.255.255/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-linuxbri-i2d863922-b -m set --match-set NIPv415dfe688-d6fc-4231-a670- src -j RETURN
-A neutron-linuxbri-i2d863922-b -p icmp -j RETURN
-A neutron-linuxbri-i2d863922-b -p tcp -m tcp --dport 22 -j RETURN
-A neutron-linuxbri-i2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-linuxbri-i2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
-A neutron-linuxbri-o2d863922-b -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-linuxbri-o2d863922-b -j neutron-linuxbri-s2d863922-b
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 67 --dport 68 -m comment --comment "Prevent DHCP Spoofing by VM." -j DROP
-A neutron-linuxbri-o2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-linuxbri-o2d863922-b -j RETURN
-A neutron-linuxbri-o2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-linuxbri-o2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
-A neutron-linuxbri-s2d863922-b -s 203.0.113.125/32 -m mac --mac-source fa:16:3e:60:78:cd -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
-A neutron-linuxbri-s2d863922-b -m comment --comment "Drop traffic without an IP/MAC allow rule." -j DROP
-A neutron-linuxbri-sg-chain -m physdev --physdev-out tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-i2d863922-b
-A neutron-linuxbri-sg-chain -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-o2d863922-b
-A neutron-linuxbri-sg-chain -j ACCEPT
-A neutron-linuxbri-sg-fallback -m comment --comment "Default drop rule for unmatched traffic." -j DROP
COMMIT
# Completed on Sun Mar 30 06:11:29 2025
# Generated by iptables-save v1.8.7 on Sun Mar 30 06:11:29 2025
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:LIBVIRT_PRT - [0:0]
-A POSTROUTING -j LIBVIRT_PRT
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
COMMIT
# Completed on Sun Mar 30 06:11:29 2025
root@compute1:~#
root@compute1:~# iptables -t filter -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
77331 147M neutron-linuxbri-INPUT all -- * * 0.0.0.0/0 0.0.0.0/0
92507 151M LIBVIRT_INP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4387 679K neutron-filter-top all -- * * 0.0.0.0/0 0.0.0.0/0
4387 679K neutron-linuxbri-FORWARD all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LIBVIRT_FWX all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LIBVIRT_FWI all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 LIBVIRT_FWO all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
73417 18M neutron-filter-top all -- * * 0.0.0.0/0 0.0.0.0/0
73417 18M neutron-linuxbri-OUTPUT all -- * * 0.0.0.0/0 0.0.0.0/0
87631 23M LIBVIRT_OUT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain LIBVIRT_FWI (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain LIBVIRT_FWO (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain LIBVIRT_FWX (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
Chain LIBVIRT_INP (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
Chain LIBVIRT_OUT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68
0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:68
Chain neutron-filter-top (2 references)
pkts bytes target prot opt in out source destination
77804 19M neutron-linuxbri-local all -- * * 0.0.0.0/0 0.0.0.0/0
Chain neutron-linuxbri-FORWARD (1 references)
pkts bytes target prot opt in out source destination
4122 641K neutron-linuxbri-sg-chain all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out tap2d863922-bc --physdev-is-bridged /* Direct traffic from the VM interface to the security group chain. */
265 37986 neutron-linuxbri-sg-chain all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap2d863922-bc --physdev-is-bridged /* Direct traffic from the VM interface to the security group chain. */
Chain neutron-linuxbri-INPUT (1 references)
pkts bytes target prot opt in out source destination
0 0 neutron-linuxbri-o2d863922-b all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap2d863922-bc --physdev-is-bridged /* Direct incoming traffic from VM to the security group chain. */
Chain neutron-linuxbri-OUTPUT (1 references)
pkts bytes target prot opt in out source destination
Chain neutron-linuxbri-i2d863922-b (1 references)
pkts bytes target prot opt in out source destination
245 22997 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED /* Direct packets associated with a known session to the RETURN chain. */
2 732 RETURN udp -- * * 0.0.0.0/0 203.0.113.125 udp spt:67 dpt:68
0 0 RETURN udp -- * * 0.0.0.0/0 255.255.255.255 udp spt:67 dpt:68
0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 match-set NIPv415dfe688-d6fc-4231-a670- src
1 60 RETURN icmp -- * * 0.0.0.0/0 0.0.0.0/0
2 104 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID /* Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack. */
3872 617K neutron-linuxbri-sg-fallback all -- * * 0.0.0.0/0 0.0.0.0/0 /* Send unmatched traffic to the fallback chain. */
Chain neutron-linuxbri-local (1 references)
pkts bytes target prot opt in out source destination
Chain neutron-linuxbri-o2d863922-b (2 references)
pkts bytes target prot opt in out source destination
2 670 RETURN udp -- * * 0.0.0.0 255.255.255.255 udp spt:68 dpt:67 /* Allow DHCP client traffic. */
263 37316 neutron-linuxbri-s2d863922-b all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 RETURN udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:68 dpt:67 /* Allow DHCP client traffic. */
0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68 /* Prevent DHCP Spoofing by VM. */
246 36272 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED /* Direct packets associated with a known session to the RETURN chain. */
17 1044 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID /* Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack. */
0 0 neutron-linuxbri-sg-fallback all -- * * 0.0.0.0/0 0.0.0.0/0 /* Send unmatched traffic to the fallback chain. */
Chain neutron-linuxbri-s2d863922-b (1 references)
pkts bytes target prot opt in out source destination
263 37316 RETURN all -- * * 203.0.113.125 0.0.0.0/0 MACfa:16:3e:60:78:cd /* Allow traffic from defined IP/MAC pairs. */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 /* Drop traffic without an IP/MAC allow rule. */
Chain neutron-linuxbri-sg-chain (2 references)
pkts bytes target prot opt in out source destination
4122 641K neutron-linuxbri-i2d863922-b all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out tap2d863922-bc --physdev-is-bridged /* Jump to the VM specific chain. */
265 37986 neutron-linuxbri-o2d863922-b all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap2d863922-bc --physdev-is-bridged /* Jump to the VM specific chain. */
515 61879 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain neutron-linuxbri-sg-fallback (2 references)
pkts bytes target prot opt in out source destination
3872 617K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 /* Default drop rule for unmatched traffic. */
root@compute1:~#
neutron-XXX都是OpenStack Neutron配置的相关的链。
neutron-linuxbri-XXX 是 OpenStack Neutron 中与 Linux Bridge 插件相关的自定义链,是由 Neutron 在使用 Linux Bridge 网络驱动时自动创建和管理的。
OpenStack管理的虚机的流量都是需要经过FORWARD链。
OpenStack创建的安全组就是通过在filter表的FORWARD链插入相关规则实现。
1/ 虚机入站和出站流量首先送到安全组链(neutron-linuxbri-sg-chain)
-A FORWARD -j neutron-filter-top
-A FORWARD -j neutron-linuxbri-FORWARD
-A neutron-filter-top -j neutron-linuxbri-local
-A neutron-linuxbri-FORWARD -m physdev --physdev-out tap2d863922-bc --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-linuxbri-sg-chain
-A neutron-linuxbri-FORWARD -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-linuxbri-sg-chain
-A neutron-linuxbri-sg-chain -m physdev --physdev-out tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-i2d863922-b
-A neutron-linuxbri-sg-chain -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-o2d863922-b
-A neutron-linuxbri-sg-chain -j ACCEPT
neutron-filter-top
是一个顶层链,通常被插入到FORWARD
和OUTPUT
链中。它的主要功能是将流量转发到其他 Neutron 定义的链进行进一步处理。
neutron-linuxbri-local一般表示和本地(local)机器上的网络接口或规则有关,通常用于处理本地出入的流量。
- 本文中neutron-linuxbri-local有定义,但没有定义规则。"被跳转的链存在但没有任何规则,流量会"返回"到原来的链,继续后面的规则执行。"
neutron-linuxbri-FORWARD 是一个与 Linux Bridge 插件相关的链,用于处理虚拟机的转发流量。
-A neutron-linuxbri-FORWARD
-A
:表示将规则添加到一个已经存在的链中。
neutron-linuxbri-FORWARD
:这是一个已经存在的链,通常用于处理通过 Linux Bridge (linuxbridge
网络插件)转发的流量。
-m physdev
-m physdev
:这是一个用于匹配物理设备的扩展模块,用来标识和过滤基于 物理设备(比如虚拟机网卡、物理网卡等)的流量。
--physdev-out tap2d863922-bc
--physdev-out
:表示匹配流量从指定的物理接口出去。
tap2d863922-bc
:这是虚拟机的网络接口设备名,通常是 虚拟网卡 ,代表这条规则仅适用于通过此虚拟网卡发送的流量。这个tap
接口可能是由 Open vSwitch (OVS) 或 Linux Bridge(由 Neutron 管理)创建的。
tap2d863922-bc
可能是 Neutron 创建的某个虚拟机接口的名称,每个虚拟机都有类似的 tap 接口。注意:physdev-out是流量从网桥发往虚拟机的方向,即虚拟机入站流量;physdev-in是流量从虚拟机进入网桥的方向,即虚拟机出站流量。
--physdev-is-bridged
--physdev-is-bridged
:指定这个流量是通过 桥接网络 (即bridge
模式)发送的。此标志确保该规则仅匹配通过桥接设备转发的流量。这个标志通常在 Neutron 使用 Linux Bridge 或 OVS 作为网络插件时出现。
-m comment --comment "Direct traffic from the VM interface to the security group chain."
-m comment
:这是一个用于添加注释的模块,它可以帮助解释规则的目的。
--comment "Direct traffic from the VM interface to the security group chain."
:这段注释表明,这条规则的目的是将流量从虚拟机接口直接转发到安全组链(neutron-linuxbri-sg-chain)。
-j neutron-linuxbri-sg-chain
-j
:表示 跳转到(jump to)指定的链。
neutron-linuxbri-sg-chain
:表示将匹配到的流量转发到neutron-linuxbri-sg-chain
链,通常这个链是用来处理与安全组相关的规则。也就是说,所有来自虚拟机接口(如 tap2d863922-bc)的流量将被送往 安全组链 进行检查和处理
neutron-linuxbri-sg-chain对流量进行进一步处理,虚机的入站流量送到该虚机的入站流量安全组链处理(neutron-linuxbri-i2d863922-b),虚机的出站流量送到该虚机的出站流量安全组链处理(neutron-linuxbri-o2d863922-b),最后接受所有未被前面规则匹配的流量。
2/ 虚机的入站流量送到该虚机的入站流量安全组链处理(neutron-linuxbri-i2d863922-b)
-A neutron-linuxbri-sg-chain -m physdev --physdev-out tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-i2d863922-b
-A neutron-linuxbri-sg-chain
:将这条规则添加到neutron-linuxbri-sg-chain
链。
-m physdev --physdev-out tap2d863922-bc
:匹配来自虚拟机接口tap2d863922-bc
的虚拟机入站流量。
--physdev-is-bridged
:确保这个流量是通过桥接设备(bridge)发送的,表示该流量经过了桥接网络。
--comment "Jump to the VM specific chain."
:注释解释该规则的作用是跳转到虚拟机特定的链。
-j neutron-linuxbri-i2d863922-b
:这条规则将流量跳转到neutron-linuxbri-i2d863922-b
链。这个链的规则与虚拟机的入站流量相关(控制该虚拟机接收流量的安全组规则)。作用:
- 如果流量从虚拟机接口
tap2d863922-bc
发往虚拟机(即虚拟机入站流量),它会跳转到neutron-linuxbri-i2d863922-b
链进行进一步处理。
3/ 虚机的出站流量送到该虚机的出站流量安全组链处理(neutron-linuxbri-o2d863922-b)
-A neutron-linuxbri-sg-chain -m physdev --physdev-in tap2d863922-bc --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-linuxbri-o2d863922-b
-A neutron-linuxbri-sg-chain
:将这条规则添加到neutron-linuxbri-sg-chain
链。
-m physdev --physdev-in tap2d863922-bc
:匹配流量进入虚拟机接口tap2d863922-bc
的虚拟机出站流量。
--physdev-is-bridged
:确保这个流量是通过桥接设备发送的。
--comment "Jump to the VM specific chain."
:注释表示这条规则的作用是跳转到虚拟机特定的链。
-j neutron-linuxbri-o2d863922-b
:这条规则将流量跳转到neutron-linuxbri-o2d863922-b
链。这个链的规则与虚拟机的出站流量相关(控制该虚拟机发送流量的安全组规则)。作用:
- 如果流量是从虚拟机流入虚拟机接口
tap2d863922-bc(即虚拟机出站流量,虚拟机接口连接虚拟机的网卡)
,它会跳转到neutron-linuxbri-o2d863922-b
链进行进一步处理。
七、虚机入站流量安全组链规则解读(neutron-linuxbri-i2d863922-b)
-A neutron-linuxbri-i2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-linuxbri-i2d863922-b -d 203.0.113.125/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-linuxbri-i2d863922-b -d 255.255.255.255/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-linuxbri-i2d863922-b -m set --match-set NIPv415dfe688-d6fc-4231-a670- src -j RETURN
-A neutron-linuxbri-i2d863922-b -p icmp -j RETURN
-A neutron-linuxbri-i2d863922-b -p tcp -m tcp --dport 22 -j RETURN
-A neutron-linuxbri-i2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-linuxbri-i2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
neutron-linuxbri-i2d863922-b定义了针对来自虚拟机接口(tap2d863922-bc
)的虚拟机入站流量的处理方式。
- 第一条规则:
-A neutron-linuxbri-i2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-linuxbri-i2d863922-b
:将这条规则添加到neutron-linuxbri-i2d863922-b
链。
-m state --state RELATED,ESTABLISHED
:匹配已经建立的或相关的连接的流量。即这些流量属于一个已经存在的连接或会话。
--comment "Direct packets associated with a known session to the RETURN chain."
:注释表示该规则的作用是将已知会话的流量直接跳转到RETURN
链。
-j RETURN
:流量会跳转到RETURN
链,通常这意味着会话相关的流量被允许通过或交给上级链进行进一步处理。
- 第二条规则:
-A neutron-linuxbri-i2d863922-b -d 203.0.113.125/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-d 203.0.113.125/32
:匹配目的 IP 地址为203.0.113.125
的流量。
-p udp
:匹配 UDP 协议的流量。
--sport 67 --dport 68
:匹配源端口为 67,目标端口为 68 的流量,这通常是 DHCP 流量(DHCP 客户端与服务器之间的通信端口)。
-j RETURN
:该流量会被直接跳转到RETURN
链,通常表示允许或不做任何处理。
- 第三条规则:
-A neutron-linuxbri-i2d863922-b -d 255.255.255.255/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-d 255.255.255.255/32
:匹配目的地址为广播地址(255.255.255.255)的流量。
-p udp
:匹配 UDP 协议。
--sport 67 --dport 68
:匹配源端口为 67,目标端口为 68 的流量,同样是 DHCP 流量。
-j RETURN
:此流量也会跳转到RETURN
链,通常表示允许广播流量通过。
- 第四条规则:
-A neutron-linuxbri-i2d863922-b -m set --match-set NIPv415dfe688-d6fc-4231-a670- src -j RETURN
-m set --match-set NIPv415dfe688-d6fc-4231-a670- src
:匹配源 IP 地址属于NIPv415dfe688-d6fc-4231-a670-
这个 IP 地址集合的流量。这个集合可能是事先定义的 IP 地址池或范围。
-j RETURN
:这些流量会直接跳转到RETURN
链,可能是允许这些流量通过或跳过其他检查。
- 第五条规则:
-A neutron-linuxbri-i2d863922-b -p icmp -j RETURN
-p icmp
:匹配 ICMP 协议的流量(例如 Ping 请求)。
-j RETURN
:此类流量会直接跳转到RETURN
链,通常表示允许 ICMP 流量通过。
- 第六条规则:
-A neutron-linuxbri-i2d863922-b -p tcp -m tcp --dport 22 -j RETURN
-p tcp
:匹配 TCP 协议的流量。
--dport 22
:匹配目标端口为 22 的流量,通常是 SSH 流量。
-j RETURN
:允许目标端口为 22 的流量直接通过,跳转到RETURN
链。
- 第七条规则:
-A neutron-linuxbri-i2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-m state --state INVALID
:匹配无效状态的流量,通常这些流量与已知连接不匹配,可能是损坏或伪造的包。
--comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack."
:注释解释这条规则会丢弃看起来像是与现有连接相关的流量(例如,TCP ACK/FIN 包),但没有连接跟踪条目。
-j DROP
:丢弃这些无效的包。
- 第八条规则:
-A neutron-linuxbri-i2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
-j neutron-linuxbri-sg-fallback
:如果流量没有匹配到以上规则,它将跳转到neutron-linuxbri-sg-fallback
链。这个链可能包含其他的处理逻辑,例如安全组检查或丢弃流量。注1:其中5、6条虚拟机入站规则,是之前添加到default安全组当中的。
注2:第4条规则涉及的IP地址集合,可以通过以下命令查看:
root@compute1:~# ipset list Name: NIPv415dfe688-d6fc-4231-a670- Type: hash:net Revision: 7 Header: family inet hashsize 1024 maxelem 65536 bucketsize 12 initval 0xc7f31013 Size in memory: 504 References: 1 Number of entries: 1 Members: 203.0.113.125
注3:查看连接跟踪(connection tracking)信息,可以使用conntrack命令。这个工具用于查看和管理内核中的连接跟踪表。
root@compute1:~# conntrack -L tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59454 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59454 [ASSURED] mark=0 use=1 udp 17 2 src=203.0.113.90 dst=239.255.255.250 sport=49337 dport=1900 [UNREPLIED] src=239.255.255.250 dst=203.0.113.90 sport=1900 dport=49337 mark=0 zone=4097 use=1 tcp 6 112 TIME_WAIT src=10.0.20.12 dst=10.0.20.11 sport=41734 dport=8778 src=10.0.20.11 dst=10.0.20.12 sport=8778 dport=41734 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59474 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59474 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=47200 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=47200 [ASSURED] mark=0 use=1 tcp 6 300 ESTABLISHED src=10.0.20.1 dst=10.0.20.12 sport=9901 dport=22 src=10.0.20.12 dst=10.0.20.1 sport=22 dport=9901 [ASSURED] mark=0 use=1 tcp 6 431992 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59486 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59486 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59470 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59470 [ASSURED] mark=0 use=1 tcp 6 431991 ESTABLISHED src=203.0.113.90 dst=203.0.113.125 sport=2101 dport=22 src=203.0.113.125 dst=203.0.113.90 sport=22 dport=2101 [ASSURED] mark=0 zone=4097 use=1 tcp 6 51 TIME_WAIT src=10.0.20.12 dst=10.0.20.11 sport=47018 dport=8778 src=10.0.20.11 dst=10.0.20.12 sport=8778 dport=47018 [ASSURED] mark=0 use=1 tcp 6 431984 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59440 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59440 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59504 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59504 [ASSURED] mark=0 use=1 tcp 6 431984 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59432 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59432 [ASSURED] mark=0 use=1 udp 17 15 src=203.0.113.90 dst=224.0.0.251 sport=5353 dport=5353 [UNREPLIED] src=224.0.0.251 dst=203.0.113.90 sport=5353 dport=5353 mark=0 zone=4097 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59418 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59418 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=48460 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=48460 [ASSURED] mark=0 use=1 tcp 6 75 TIME_WAIT src=203.0.113.90 dst=203.0.113.125 sport=2078 dport=22 src=203.0.113.125 dst=203.0.113.90 sport=22 dport=2078 [ASSURED] mark=0 zone=4097 use=1 tcp 6 428627 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=55168 dport=3306 src=10.0.20.11 dst=10.0.20.12 sport=3306 dport=55168 [ASSURED] mark=0 use=1 tcp 6 431992 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59494 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59494 [ASSURED] mark=0 use=2 tcp 6 57 CLOSE_WAIT src=10.0.20.12 dst=10.0.20.11 sport=33748 dport=8778 src=10.0.20.11 dst=10.0.20.12 sport=8778 dport=33748 [ASSURED] mark=0 use=1 tcp 6 431987 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=41996 dport=9696 src=10.0.20.11 dst=10.0.20.12 sport=9696 dport=41996 [ASSURED] mark=0 use=1 udp 17 24 src=203.0.113.90 dst=239.255.255.250 sport=62791 dport=1900 [UNREPLIED] src=239.255.255.250 dst=203.0.113.90 sport=1900 dport=62791 mark=0 zone=4097 use=1 tcp 6 431992 ESTABLISHED src=127.0.0.1 dst=127.0.0.1 sport=37286 dport=38013 src=127.0.0.1 dst=127.0.0.1 sport=38013 dport=37286 [ASSURED] mark=0 use=1 tcp 6 431986 ESTABLISHED src=10.0.20.12 dst=10.0.20.11 sport=59512 dport=5672 src=10.0.20.11 dst=10.0.20.12 sport=5672 dport=59512 [ASSURED] mark=0 use=1 conntrack v1.4.6 (conntrack-tools): 24 flow entries have been shown. root@compute1:~# conntrack -L | grep 203.0.113.125 conntrack v1.4.6 (conntrack-tools): 22 flow entries have been shown. tcp 6 431960 ESTABLISHED src=203.0.113.90 dst=203.0.113.125 sport=2101 dport=22 src=203.0.113.125 dst=203.0.113.90 sport=22 dport=2101 [ASSURED] mark=0 zone=4097 use=1 tcp 6 44 TIME_WAIT src=203.0.113.90 dst=203.0.113.125 sport=2078 dport=22 src=203.0.113.125 dst=203.0.113.90 sport=22 dport=2078 [ASSURED] mark=0 zone=4097 use=1 root@compute1:~#
🧑💻 入站流量安全组链小结
这些规则在 neutron-linuxbri-i2d863922-b
链中处理虚拟机入站流量。根据不同的流量特征(如协议、端口、状态等),它们会:
-
允许已知会话的流量通过(如已经建立的连接)。
-
允许 DHCP、ICMP、SSH 等特定流量通过。
-
丢弃无效的、无法匹配连接的流量(如无效的 TCP 包)。
-
将未匹配的流量发送到回退链,以便进一步处理。
八、虚机出站流量安全组链规则解读(neutron-linuxbri-o2d863922-b)
-A neutron-linuxbri-o2d863922-b -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-linuxbri-o2d863922-b -j neutron-linuxbri-s2d863922-b
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 67 --dport 68 -m comment --comment "Prevent DHCP Spoofing by VM." -j DROP
-A neutron-linuxbri-o2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-linuxbri-o2d863922-b -j RETURN
-A neutron-linuxbri-o2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-linuxbri-o2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
其他相关安全组链:
-A neutron-linuxbri-s2d863922-b -s 203.0.113.125/32 -m mac --mac-source fa:16:3e:60:78:cd -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
-A neutron-linuxbri-s2d863922-b -m comment --comment "Drop traffic without an IP/MAC allow rule." -j DROP
-A neutron-linuxbri-sg-fallback -m comment --comment "Default drop rule for unmatched traffic." -j DROP
neutron-linuxbri-i2d863922-b定义了针对来自虚拟机接口(tap2d863922-bc
)的虚拟机出站流量的处理方式。
- 第一条规则:
-A neutron-linuxbri-o2d863922-b -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-s 0.0.0.0/32 -d 255.255.255.255/32
:匹配源地址为0.0.0.0
(通常是 DHCP 客户端的源地址)和目标地址为广播地址255.255.255.255
的流量。
-p udp
:匹配 UDP 协议。
--sport 68 --dport 67
:匹配源端口为 68,目标端口为 67 的流量,这是 DHCP 客户端与 DHCP 服务器之间的标准端口。
-j RETURN
:允许这类 DHCP 客户端的流量通过,跳转到RETURN
链。
- 第二条规则:
-A neutron-linuxbri-o2d863922-b -j neutron-linuxbri-s2d863922-b
-j neutron-linuxbri-s2d863922-b
:如果流量没有匹配前面规则,它将跳转到neutron-linuxbri-s2d863922-b
链,这可能是针对其他流量进行的进一步处理。
neutron-linuxbri-s2d863922-b
链,主要用于 基于 IP 地址和 MAC 地址的流量控制, 对于没有与 IP/MAC 地址对匹配的流量,直接丢弃。
- 第三条规则:
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
- 这条规则和第一条规则相同,允许源端口为 68,目标端口为 67 的 DHCP 客户端流量。
- 第四条规则:
-A neutron-linuxbri-o2d863922-b -p udp -m udp --sport 67 --dport 68 -m comment --comment "Prevent DHCP Spoofing by VM." -j DROP
-p udp
:匹配 UDP 协议。
--sport 67 --dport 68
:匹配源端口为 67,目标端口为 68 的流量,这是 DHCP 服务器与客户端的标准端口。
-j DROP
:丢弃任何源端口为 67,目标端口为 68 的流量,防止虚拟机进行 DHCP 欺骗(即伪造 DHCP 服务器响应)。
- 第五条规则:
-A neutron-linuxbri-o2d863922-b -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-m state --state RELATED,ESTABLISHED
:匹配与已知会话相关的流量(即已建立或相关的连接)。
-j RETURN
:流量会直接跳转到RETURN
链,表示这些流量可以继续通过(通常是已建立的连接或会话)。
- 第六条规则:
-A neutron-linuxbri-o2d863922-b -j RETURN
-j RETURN
:没有条件的RETURN
,这意味着流量直接返回,通常是默认的接受行为。由于这条规则没有指定任何过滤条件(如 -s、-d、-p 等),它会匹配所有流量。因此,只要流量经过了 neutron-linuxbri-o2d863922-b 链,它就会立即匹配到这一条规则,并且流量会跳转到 RETURN 链。这会使得其他规则(比如第 7 条和第 8 条规则)几乎没有机会被执行。。
- 第七条规则:
-A neutron-linuxbri-o2d863922-b -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-m state --state INVALID
:匹配无效状态的流量,通常是一些无法匹配已建立连接的包,例如非法的 TCP ACK/FIN 包。
-j DROP
:丢弃这些无效的流量包。
- 第八条规则:
-A neutron-linuxbri-o2d863922-b -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-linuxbri-sg-fallback
-j neutron-linuxbri-sg-fallback
:如果流量没有匹配前面所有的规则,它将跳转到neutron-linuxbri-sg-fallback
链,进行进一步的安全组处理。
🧑💻 出站流量安全组链小结
这些规则主要负责处理 虚拟机到外部网络的出站流量,特别关注 DHCP 流量和安全性。它们的作用包括:
-
允许 DHCP 客户端的流量通过(源端口 68,目标端口 67)。
-
防止虚拟机进行 DHCP 欺骗(丢弃源端口 67,目标端口 68 的流量)。
-
允许已知会话的流量通过 ,跳转到
RETURN
链。 -
丢弃无效的、无法匹配已知连接的流量(如无效的 TCP 包)。
-
未匹配的流量被送到回退链(fallback),进行额外的安全组处理。
九、总结
OpenStack安全组是在计算节点本机上,通过iptables实现,不是在虚机(实例)中实现。