我有一个包含多个网关的网络,其中一个网关被设置为服务器上的默认网关。我想要一个特定的命令来为所有流量使用一个单独的网关。我该如何实现?
不幸的是,使用目标 IP 路由是不可能的,因为我事先不知道该命令将联系的 IP。
我真正想要做的是将所有流量通过我的默认网关发送,并使用单独的网关来处理将某些内容上传到 Amazon S3 的脚本。我通过从以下位置获取 Amazon 的 IP 来实现此目的https://ip-ranges.amazonaws.com/ip-ranges.json并定期用我想要的网关更新路由表,但这感觉太糟糕了。
我意识到没有办法通过域名路由流量,所以我可以用其他方法吗?也许用 iptables 或类似的东西?
以下是我编写的供参考的脚本:
#!/usr/bin/env bash
set -eo pipefail
IFS=$'\n\t'
amazon_gateway='XXX.XXX.XXX.XXX'
amazon_ips_url='https://ip-ranges.amazonaws.com/ip-ranges.json'
route="$(which route)"
curl="$(which curl)"
jq="$(which jq)"
awk="$(which awk)"
netstat="$(which netstat)"
# taken from https://forums.gentoo.org/viewtopic-t-888736-start-0.html
mask2cdr ()
{
# Assumes there's no "255." after a non-255 byte in the mask
set -- 0^^^128^192^224^240^248^252^254^ ${#1} ${1##*255.}
set -- $(( ($2 - ${#3})*2 )) ${1%%${3%%.*}*}
echo $(( $1 + (${#2}/4) ))
}
# get amazon ips
amazon_ips=$("${curl}" "${amazon_ips_url}" | "${jq}" -r '.prefixes | map(select(.service == "AMAZON"))[].ip_prefix')
# get networks routed to requested gateway
routed_networks=$("${netstat}" -nr | "${awk}" '{ if ($2 == "'"${amazon_gateway}"'") print $1"/"$3 }')
# convert masks to cdrs
routed_networks=$(for network in ${routed_networks}; do echo "${network%\/*}/$(mask2cdr ${network#*\/})"; done)
# remove routes for all these networks
for network in ${routed_networks}; do "${route}" del -net "${network}" gw "${amazon_gateway}"; done
# add a route for each amazon ip
for amazon_ip in ${amazon_ips}; do "${route}" add -net "${amazon_ip}" gw "${amazon_gateway}"; done