name: network-security-groups description: 配置网络安全组和防火墙规则以控制入站/出站流量并实现网络分段。
网络安全组
概览
实施网络安全组和防火墙规则以强制执行最小权限访问,分段网络,并保护基础设施免受未经授权的访问。
使用场景
- 入站流量控制
- 出站流量过滤
- 网络分段
- 零信任网络
- DDoS缓解
- 数据库访问限制
- VPN访问控制
- 多层应用安全
实施示例
1. AWS安全组
# aws-security-groups.yaml
Resources:
# VPC安全组
VPCSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: VPC安全组
VpcId: vpc-12345678
SecurityGroupIngress:
# 允许任何地方的HTTP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: "来自任何地方的HTTP"
# 允许任何地方的HTTPS
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: "来自任何地方的HTTPS"
# 仅允许管理员网络的SSH
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8
Description: "来自管理员网络的SSH"
SecurityGroupEgress:
# 允许所有出站
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Description: "所有出站流量"
Tags:
- Key: Name
Value: vpc-security-group
# 数据库安全组
DatabaseSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 数据库安全组
VpcId: vpc-12345678
SecurityGroupIngress:
# 仅允许应用层的PostgreSQL
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref AppSecurityGroup
Description: "来自应用层的PostgreSQL"
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: database-security-group
# 应用层安全组
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 应用层安全组
VpcId: vpc-12345678
SecurityGroupIngress:
# 允许来自负载均衡器的流量
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
SourceSecurityGroupId: !Ref LBSecurityGroup
Description: "来自LB的应用流量"
SecurityGroupEgress:
# 允许访问数据库
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
DestinationSecurityGroupId: !Ref DatabaseSecurityGroup
Description: "数据库访问"
# 允许访问外部APIs
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: "HTTPS外部APIs"
Tags:
- Key: Name
Value: app-security-group
# 负载均衡器安全组
LBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 负载均衡器安全组
VpcId: vpc-12345678
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
DestinationSecurityGroupId: !Ref AppSecurityGroup
Tags:
- Key: Name
Value: lb-security-group
2. Kubernetes网络策略
# kubernetes-network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: production
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-database
namespace: production
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 5432
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-cache
namespace: production
spec:
podSelector:
matchLabels:
tier: cache
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 6379
---
# Egress policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-egress
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Egress
egress:
# Allow to database
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
# Allow to cache
- to:
- podSelector:
matchLabels:
tier: cache
ports:
- protocol: TCP
port: 6379
# Allow DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# Allow external APIs
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443
3. GCP防火墙规则
# gcp-firewall-rules.yaml
apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeFirewall
metadata:
name: allow-http-https
spec:
network:
name: default
direction: INGRESS
priority: 1000
sourceRanges:
- 0.0.0.0/0
allowed:
- IPProtocol: tcp
ports:
- "80"
- "443"
targetTags:
- http-server
- https-server
---
apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeFirewall
metadata:
name: allow-ssh-internal
spec:
network:
name: default
direction: INGRESS
priority: 1000
sourceRanges:
- 10.0.0.0/8
allowed:
- IPProtocol: tcp
ports:
- "22"
targetTags:
- allow-ssh
---
apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeFirewall
metadata:
name: deny-all-ingress
spec:
network:
name: default
direction: INGRESS
priority: 65534
denied:
- IPProtocol: all
4. 安全组管理脚本
#!/bin/bash
# manage-security-groups.sh - 安全组管理工具
set -euo pipefail
ACTION="${1:-list}"
REGION="${2:-us-east-1}"
# 列出安全组
list_security_groups() {
echo "REGION中的安全组:"
aws ec2 describe-security-groups \
--region "$REGION" \
--query 'SecurityGroups[*].[GroupId,GroupName,VpcId]' \
--output table
}
# 显示安全组详情
show_security_group() {
local sg_id="$1"
echo "$sg_id的入站规则:"
aws ec2 describe-security-groups \
--group-ids "$sg_id" \
--region "$REGION" \
--query 'SecurityGroups[0].IpPermissions' \
--output table
echo -e "
$sg_id的出站规则:"
aws ec2 describe-security-groups \
--group-ids "$sg_id" \
--region "$REGION" \
--query 'SecurityGroups[0].IpPermissionsEgress' \
--output table
}
# 添加入站规则
add_inbound_rule() {
local sg_id="$1"
local protocol="$2"
local port="$3"
local cidr="$4"
local description="${5:-}"
aws ec2 authorize-security-group-ingress \
--group-id "$sg_id" \
--protocol "$protocol" \
--port "$port" \
--cidr "$cidr" \
--region "$REGION" \
${description:+--description "$description"}
echo "规则已添加到$sg_id"
}
# 审计安全组过于宽松的规则
audit_security_groups() {
echo "审计安全组过于宽松的规则..."
aws ec2 describe-security-groups \
--region "$REGION" \
--query 'SecurityGroups[*].[GroupId,IpPermissions]' \
--output text | while read sg_id; do
# 检查敏感端口是否对0.0.0.0/0开放
if aws ec2 describe-security-groups \
--group-ids "$sg_id" \
--region "$REGION" \
--query "SecurityGroups[0].IpPermissions[?FromPort==\`22\` || FromPort==\`3306\` || FromPort==\`5432\`]" \
--output json | grep -q "0.0.0.0/0"; then
echo "警告:$sg_id对0.0.0.0/0开放敏感端口"
fi
done
}
# 主函数
case "$ACTION" in
list)
list_security_groups
;;
show)
show_security_group "$3"
;;
add-rule)
add_inbound_rule "$3" "$4" "$5" "$6" "${7:-}"
;;
audit)
audit_security_groups
;;
*)
echo "用法:$0 {list|show|add-rule|audit} [参数]"
exit 1
;;
esac
最佳实践
✅ 执行
- 实施最小权限访问
- 使用安全组进行分段
- 记录规则目的
- 定期审计规则
- 分开入站和出站规则
- 使用安全组引用
- 监控规则变更
- 启用前测试访问
❌ 不执行
- 不要为数据库允许0.0.0.0/0
- 不要不必要地开放所有端口
- 不要在单个SG中混合环境
- 忽略出站规则
- 不允许所有协议
- 忘记记录规则
- 使用单个通用规则
- 无防火墙部署
常见规则
| 端口 | 协议 | 用途 |
|---|---|---|
| 22 | TCP | SSH(仅限管理员) |
| 80 | TCP | HTTP(公共) |
| 443 | TCP | HTTPS(公共) |
| 3306 | TCP | MySQL(仅限应用层) |
| 5432 | TCP | PostgreSQL(仅限应用层) |
| 6379 | TCP | Redis(仅限应用层) |