iptables 规则允许 GitHub 操作中断(链默认为 DROP)
iptables rules to permit GitHub Actions from breaking (chains default to DROP)
假设我的 iptables 规则在 INPUT 和 OUTPUT 链上默认为 DROP,我必须添加到我的链中以防止脚本 运行ning 在 GitHub 中的最低限度规则集是什么无限期拖延的行动?
我正在为我的开源应用程序的 CI/CD 基础设施使用(免费)GitHub 操作。当我将更改推送到 github.com 时,它会自动启动 Microsoft 云中的 Ubuntu 18.04 linux 服务器,检查我的存储库并执行 BASH 脚本来构建我的应用程序.
出于安全原因,在我的构建脚本的早期,我安装并设置了一些非常严格的 iptables
规则,这些规则在 INPUT
和 OUTPUT
链上默认为 DROP
.我在 127.0.0.1
、RELATED/ESTABLISHED
INPUT
的防火墙上开了一个洞,只允许 _apt
用户通过 OUTPUT
.[=25= 发送流量]
当我在本地系统的 docker 容器中 运行 构建脚本时,这非常有效。但是——正如我刚刚了解到的——当它 运行 执行 GitHub 操作时,它会无限期地停止。显然,实例本身需要能够与 GitHub 的服务器通信才能完成。而我似乎已经打破了它。
所以问题是:我应该在 iptables
INPUT
和 OUTPUT
链中添加哪些 -j ACCEPT
规则,以仅允许 [=41= 的基本必需品] 行动处决照常进行?
作为参考,这里是我设置防火墙的构建脚本的片段:
##################
# SETUP IPTABLES #
##################
# We setup iptables so that only the apt user (and therefore the apt command)
# can access the internet. We don't want insecure tools like `pip` to download
# unsafe code from the internet.
${SUDO} iptables-save > /tmp/iptables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} iptables -A INPUT -i lo -j ACCEPT
${SUDO} iptables -A INPUT -s 127.0.0.1/32 -j DROP
${SUDO} iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A INPUT -j DROP
${SUDO} iptables -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
${SUDO} iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT # apt uid = 100
${SUDO} iptables -A OUTPUT -j DROP
${SUDO} ip6tables-save > /tmp/ip6tables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} ip6tables -A INPUT -i lo -j ACCEPT
${SUDO} ip6tables -A INPUT -s ::1/128 -j DROP
${SUDO} ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A INPUT -j DROP
${SUDO} ip6tables -A OUTPUT -s ::1/128 -d ::1/128 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -j DROP
# attempt to access the internet as root. If it works, exit 1
curl -s 1.1.1.1
if [ $? -eq 0 ]; then
echo "ERROR: iptables isn't blocking internet access to unsafe tools. You may need to run this as root (and you should do it inside a VM)"
exit 1
fi
你正在做的事情不会可靠地工作,你应该采用不同的解决方案。为了使其工作,您需要知道您正在运行的网络的布局以及相关 GitHub 操作处理 运行s 的用户,并且 GitHub 两者都不是文档也不保证该设置的一致性。
因此,即使您确实找到了解决方案,GitHub 也可能会因 运行将您的代码置于新的数据中心或不同的网络中,或者通过更改他们的进程所在的用户 运行,或与您的设置相关的其他一些属性。
如果您担心您正在 运行 下载您不想要的东西的代码,最好将其配置为不这样做,不要 运行 中的代码首先,或者验证您想要的代码是 运行。例如,在使用 C 库的 Rust 程序中,如果我担心的话,我可能会验证二进制文件是否动态链接到系统库,而不是让 Cargo 构建自己的版本。如果你只想使用系统包,你可以配置任何 per-language 包管理器来查看 localhost 的镜像,如果他们试图访问 Internet,这将失败,如果你愿意,甚至可以测试它。
这可以通过 运行在 docker 容器中构建您的构建脚本并在该容器内应用您的 iptables 规则来实现,这不会影响主机 runner
的连通性。
例如,如果下面的脚本在 GitHub Actions 作业中执行(在 Ubuntu 18.04 GitHub 共享 运行ner 中),它将 运行 debian docker 容器中的构建脚本 (docker_script.sh
) 没有互联网连接,_apt
用户除外。
#!/bin/bash
set -x
###################
# INSTALL DEPENDS #
###################
apt-get -y install docker.io
##################
# DOWNLOAD IMAGE #
##################
# At the time of writing, Docker Content Trust is 100% security theater without
# explicitly adding the root public keys to the $HOME/.docker/trust/ directory
#
# * https://github.com/BusKill/buskill-app/issues/6#issuecomment-700050760
# * https://security.stackexchange.com/questions/238529/how-to-list-all-of-the-known-root-keys-in-docker-docker-content-trust
# * https://github.com/docker/cli/issues/2752
docker -D pull debian:stable-slim
#################
# CREATE SCRIPT #
#################
tmpDir=`mktemp -d`
pushd "${tmpDir}"
cat << EOF > docker_script.sh
#!/bin/bash
set -x
# SETTINGS #
SUDO=/usr/bin/sudo
# DEPENDS #
${SUDO} apt-get update
${SUDO} apt-get install iptables curl
# IPTABLES #
# We setup iptables so that only the apt user (and therefore the apt command)
# can access the internet. We don't want insecure tools like `pip` to download
# unsafe code from the internet.
${SUDO} iptables-save > /tmp/iptables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} iptables -A INPUT -i lo -j ACCEPT
${SUDO} iptables -A INPUT -s 127.0.0.1/32 -j DROP
${SUDO} iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A INPUT -j DROP
${SUDO} iptables -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
${SUDO} iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT # apt uid = 100
${SUDO} iptables -A OUTPUT -j DROP
${SUDO} ip6tables-save > /tmp/ip6tables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} ip6tables -A INPUT -i lo -j ACCEPT
${SUDO} ip6tables -A INPUT -s ::1/128 -j DROP
${SUDO} ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A INPUT -j DROP
${SUDO} ip6tables -A OUTPUT -s ::1/128 -d ::1/128 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -j DROP
# attempt to access the internet as root. If it works, exit 1
curl 1.1.1.1
if [ $? -eq 0 ]; then
echo "ERROR: iptables isn't blocking internet access to unsafe tools. You may need to run this as root (and you should do it inside a VM)"
exit 1
fi
# BUILD #
# ...
# <DO BUILD HERE>
# ...
exit 0
EOF
chmod +x docker_script.sh
##############
# DOCKER RUN #
##############
docker run --rm --cap-add "NET_ADMIN" -v "${tmpDir}:/root/shared_volume" debian:stable-slim /bin/bash -c "cd /root/shared_volume && docker_script.sh"
# exit cleanly
exit 0
注意:
您必须手动执行 docker run
命令,而不仅仅是在 GitHub Actions yaml 文件中指定 container:
以添加 NET_ADMIN
能力。另见 How to run script in docker container with additional capabilities (docker exec ... --cap-add ...)
除非您在调用 docker pull
之前固定根签名密钥,否则这是一个安全风险。另见 https://security.stackexchange.com/questions/238529/how-to-list-all-of-the-known-root-keys-in-docker-docker-content-trust
以上脚本应该以root身份执行。例如,在 GitHub 操作工作流中的步骤的 run:
键中为它添加 sudo
。
假设我的 iptables 规则在 INPUT 和 OUTPUT 链上默认为 DROP,我必须添加到我的链中以防止脚本 运行ning 在 GitHub 中的最低限度规则集是什么无限期拖延的行动?
我正在为我的开源应用程序的 CI/CD 基础设施使用(免费)GitHub 操作。当我将更改推送到 github.com 时,它会自动启动 Microsoft 云中的 Ubuntu 18.04 linux 服务器,检查我的存储库并执行 BASH 脚本来构建我的应用程序.
出于安全原因,在我的构建脚本的早期,我安装并设置了一些非常严格的 iptables
规则,这些规则在 INPUT
和 OUTPUT
链上默认为 DROP
.我在 127.0.0.1
、RELATED/ESTABLISHED
INPUT
的防火墙上开了一个洞,只允许 _apt
用户通过 OUTPUT
.[=25= 发送流量]
当我在本地系统的 docker 容器中 运行 构建脚本时,这非常有效。但是——正如我刚刚了解到的——当它 运行 执行 GitHub 操作时,它会无限期地停止。显然,实例本身需要能够与 GitHub 的服务器通信才能完成。而我似乎已经打破了它。
所以问题是:我应该在 iptables
INPUT
和 OUTPUT
链中添加哪些 -j ACCEPT
规则,以仅允许 [=41= 的基本必需品] 行动处决照常进行?
作为参考,这里是我设置防火墙的构建脚本的片段:
##################
# SETUP IPTABLES #
##################
# We setup iptables so that only the apt user (and therefore the apt command)
# can access the internet. We don't want insecure tools like `pip` to download
# unsafe code from the internet.
${SUDO} iptables-save > /tmp/iptables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} iptables -A INPUT -i lo -j ACCEPT
${SUDO} iptables -A INPUT -s 127.0.0.1/32 -j DROP
${SUDO} iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A INPUT -j DROP
${SUDO} iptables -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
${SUDO} iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT # apt uid = 100
${SUDO} iptables -A OUTPUT -j DROP
${SUDO} ip6tables-save > /tmp/ip6tables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} ip6tables -A INPUT -i lo -j ACCEPT
${SUDO} ip6tables -A INPUT -s ::1/128 -j DROP
${SUDO} ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A INPUT -j DROP
${SUDO} ip6tables -A OUTPUT -s ::1/128 -d ::1/128 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -j DROP
# attempt to access the internet as root. If it works, exit 1
curl -s 1.1.1.1
if [ $? -eq 0 ]; then
echo "ERROR: iptables isn't blocking internet access to unsafe tools. You may need to run this as root (and you should do it inside a VM)"
exit 1
fi
你正在做的事情不会可靠地工作,你应该采用不同的解决方案。为了使其工作,您需要知道您正在运行的网络的布局以及相关 GitHub 操作处理 运行s 的用户,并且 GitHub 两者都不是文档也不保证该设置的一致性。
因此,即使您确实找到了解决方案,GitHub 也可能会因 运行将您的代码置于新的数据中心或不同的网络中,或者通过更改他们的进程所在的用户 运行,或与您的设置相关的其他一些属性。
如果您担心您正在 运行 下载您不想要的东西的代码,最好将其配置为不这样做,不要 运行 中的代码首先,或者验证您想要的代码是 运行。例如,在使用 C 库的 Rust 程序中,如果我担心的话,我可能会验证二进制文件是否动态链接到系统库,而不是让 Cargo 构建自己的版本。如果你只想使用系统包,你可以配置任何 per-language 包管理器来查看 localhost 的镜像,如果他们试图访问 Internet,这将失败,如果你愿意,甚至可以测试它。
这可以通过 运行在 docker 容器中构建您的构建脚本并在该容器内应用您的 iptables 规则来实现,这不会影响主机 runner
的连通性。
例如,如果下面的脚本在 GitHub Actions 作业中执行(在 Ubuntu 18.04 GitHub 共享 运行ner 中),它将 运行 debian docker 容器中的构建脚本 (docker_script.sh
) 没有互联网连接,_apt
用户除外。
#!/bin/bash
set -x
###################
# INSTALL DEPENDS #
###################
apt-get -y install docker.io
##################
# DOWNLOAD IMAGE #
##################
# At the time of writing, Docker Content Trust is 100% security theater without
# explicitly adding the root public keys to the $HOME/.docker/trust/ directory
#
# * https://github.com/BusKill/buskill-app/issues/6#issuecomment-700050760
# * https://security.stackexchange.com/questions/238529/how-to-list-all-of-the-known-root-keys-in-docker-docker-content-trust
# * https://github.com/docker/cli/issues/2752
docker -D pull debian:stable-slim
#################
# CREATE SCRIPT #
#################
tmpDir=`mktemp -d`
pushd "${tmpDir}"
cat << EOF > docker_script.sh
#!/bin/bash
set -x
# SETTINGS #
SUDO=/usr/bin/sudo
# DEPENDS #
${SUDO} apt-get update
${SUDO} apt-get install iptables curl
# IPTABLES #
# We setup iptables so that only the apt user (and therefore the apt command)
# can access the internet. We don't want insecure tools like `pip` to download
# unsafe code from the internet.
${SUDO} iptables-save > /tmp/iptables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} iptables -A INPUT -i lo -j ACCEPT
${SUDO} iptables -A INPUT -s 127.0.0.1/32 -j DROP
${SUDO} iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A INPUT -j DROP
${SUDO} iptables -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT
${SUDO} iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} iptables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT # apt uid = 100
${SUDO} iptables -A OUTPUT -j DROP
${SUDO} ip6tables-save > /tmp/ip6tables-save.`date "+%Y%m%d_%H%M%S"`
${SUDO} ip6tables -A INPUT -i lo -j ACCEPT
${SUDO} ip6tables -A INPUT -s ::1/128 -j DROP
${SUDO} ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A INPUT -j DROP
${SUDO} ip6tables -A OUTPUT -s ::1/128 -d ::1/128 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
${SUDO} ip6tables -A OUTPUT -m owner --uid-owner 100 -j ACCEPT
${SUDO} ip6tables -A OUTPUT -j DROP
# attempt to access the internet as root. If it works, exit 1
curl 1.1.1.1
if [ $? -eq 0 ]; then
echo "ERROR: iptables isn't blocking internet access to unsafe tools. You may need to run this as root (and you should do it inside a VM)"
exit 1
fi
# BUILD #
# ...
# <DO BUILD HERE>
# ...
exit 0
EOF
chmod +x docker_script.sh
##############
# DOCKER RUN #
##############
docker run --rm --cap-add "NET_ADMIN" -v "${tmpDir}:/root/shared_volume" debian:stable-slim /bin/bash -c "cd /root/shared_volume && docker_script.sh"
# exit cleanly
exit 0
注意:
您必须手动执行
docker run
命令,而不仅仅是在 GitHub Actions yaml 文件中指定container:
以添加NET_ADMIN
能力。另见 How to run script in docker container with additional capabilities (docker exec ... --cap-add ...)除非您在调用
docker pull
之前固定根签名密钥,否则这是一个安全风险。另见 https://security.stackexchange.com/questions/238529/how-to-list-all-of-the-known-root-keys-in-docker-docker-content-trust以上脚本应该以root身份执行。例如,在 GitHub 操作工作流中的步骤的
run:
键中为它添加sudo
。