如何在AWS ECS(Fargate/EC2)中实现Iptables透明代理流量转发?
在AWS ECS中实现Golang请求的透明代理拦截转发
一、EC2 模式实现方案
EC2模式下ECS Task的容器共享同一个网络命名空间(awsvpc网络模式),可直接用iptables实现类似Kubernetes的透明拦截逻辑:
Task Definition 配置
- 创建包含Golang应用容器和Envoy代理容器的Task Definition,指定
awsvpc网络模式 - 给Envoy容器(或初始化容器)开启
privileged: true权限,确保能操作iptables
- 创建包含Golang应用容器和Envoy代理容器的Task Definition,指定
配置iptables规则
在Envoy容器启动脚本中添加规则,将Golang应用发往site.com的80/443端口流量重定向到Envoy监听端口(示例用15001):# 转发HTTP流量 iptables -t nat -A OUTPUT -d site.com -p tcp --dport 80 -j REDIRECT --to-ports 15001 # 转发HTTPS流量 iptables -t nat -A OUTPUT -d site.com -p tcp --dport 443 -j REDIRECT --to-ports 15001注:使用OUTPUT链而非PREROUTING,因为流量来自Task内部容器,属于本地出站流量。
Envoy 代理配置
配置Envoy监听15001端口,拦截site.com请求并转发到newsite.com,核心配置片段:static_resources: listeners: - name: transparent_listener address: socket_address: { address: 0.0.0.0, port_value: 15001 } filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: site_redirect_route virtual_hosts: - name: site_proxy domains: ["site.com"] routes: - match: { prefix: "/" } route: { cluster: newsite_cluster } http_filters: - name: envoy.filters.http.router clusters: - name: newsite_cluster connect_timeout: 0.25s type: STRICT_DNS load_assignment: cluster_name: newsite_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: { address: newsite.com, port_value: 443 } transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
二、Fargate 模式实现方案
Fargate不允许特权容器,无法直接操作iptables,需用代理配置替代透明拦截:
方式1:通过环境变量配置全局代理
在Golang应用容器的Task Definition中添加环境变量,强制所有HTTP/HTTPS请求走Envoy代理:
HTTP_PROXY: http://localhost:15001HTTPS_PROXY: http://localhost:15001NO_PROXY: localhost,127.0.0.1(避免本地服务请求被代理)
Golang标准库的net/http会自动读取这些环境变量,无需修改代码。
方式2:代码层面指定代理
如果应用不支持环境变量代理,可在Golang代码中配置HTTP客户端的代理:
package main import ( "net/http" "net/url" ) func main() { proxyURL, _ := url.Parse("http://localhost:15001") client := &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyURL(proxyURL), }, } // 使用该client发起所有请求 resp, err := client.Get("http://site.com") // ...后续处理 }
Envoy 配置(Fargate通用)
Fargate模式下Envoy的配置和EC2模式基本一致,只需监听15001端口,将site.com的请求转发到newsite.com即可。
三、关键注意事项
- EC2模式下必须使用
awsvpc网络模式,确保Task内容器共享网络命名空间 - HTTPS请求需要Envoy配置上游TLS上下文,否则会出现证书验证问题
- Fargate模式下无法实现完全透明的iptables拦截,上述两种方式是最可行的替代方案
内容的提问来源于stack exchange,提问作者Ronaldo Lanhellas
相关产品推荐
相关产品推荐

