【问题标题】:iptables rules to permit GitHub Actions from breaking (chains default to DROP)iptables 规则以允许 GitHub Actions 中断(链默认为 DROP)
【发布时间】:2021-01-13 08:39:06
【问题描述】:

假设我的 iptables 规则在 INPUT 和 OUTPUT 链上默认为 DROP,我必须添加到链中以防止在 GitHub Actions 中运行的脚本无限期停止的最少规则集是多少?

我将(免费)GitHub Actions 用于我的开源应用程序的 CI/CD 基础架构。当我将更改推送到 github.com 时,它会自动在 Microsoft 的云中启动一个 Ubuntu 18.04 linux 服务器,用于签出我的存储库并执行 BASH 脚本来构建我的应用程序。

出于安全原因,在我的构建脚本的早期,我在INPUTOUTPUT 链上安装并设置了一些非常严格的iptables 规则,这些规则默认为DROP。我在INPUT 上为127.0.0.1RELATED/ESTABLISHED 在防火墙上戳了一个洞,并且只允许_apt 用户通过OUTPUT 发送流量。

当我在本地系统的 docker 容器中运行构建脚本时,这非常有用。但是——正如我刚刚了解到的——当它与 GitHub Actions 一起运行时,它会无限期地停止。显然,实例本身需要能够与 GitHub 的服务器进行通信才能完成。而我似乎已经打破了这一点。

所以问题是:我应该在我的 iptables INPUTOUTPUT 链中添加什么 -j ACCEPT 规则,以只允许 GitHub Actions 执行的基本必需品照常进行?

作为参考,这是我的构建脚本中设置防火墙的 sn-p:

##################
# 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

【问题讨论】:

    标签: ubuntu github continuous-integration iptables github-actions


    【解决方案1】:

    这可以通过在 docker 容器中运行构建脚本并在该容器中应用 iptables 规则来实现,这不会影响主机 runner 的连接。

    例如,如果在 GitHub Actions 作业中执行以下脚本(在 Ubuntu 18.04 GitHub 共享运行程序中),它将在没有互联网连接的 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
    

    注意:

    1. 您必须手动执行 docker run 命令,而不仅仅是在 GitHub Actions yaml 文件中指定 container: 以添加 NET_ADMIN 功能。另请参阅How to run script in docker container with additional capabilities (docker exec ... --cap-add ...)

    2. 这存在安全风险,除非您在调用 docker pull 之前固定根签名密钥。另见https://security.stackexchange.com/questions/238529/how-to-list-all-of-the-known-root-keys-in-docker-docker-content-trust

    3. 上面的脚本应该以root身份执行。例如,在 GitHub Actions 工作流程中的步骤的 run: 键中为其添加 sudo

    【讨论】:

      【解决方案2】:

      您正在做的事情不会可靠地工作,您应该采用不同的解决方案。为了使其工作,您需要知道您正在操作的网络的布局以及运行相关 GitHub Actions 进程的用户,而 GitHub 既不记录也不保证该设置的一致性。

      因此,即使您确实找到了解决方案,GitHub 也可能会通过在新数据中心或其他网络上运行您的代码,或者通过更改运行其进程的用户或其他属性来破坏它与您的设置相关。

      如果您担心正在运行的代码会下载您不想要的东西,最好将其配置为不这样做,首先不运行代码,或者验证您的代码打算运行。例如,在使用 C 库的 Rust 程序中,如果我担心的话,我可能会验证二进制文件是否动态链接到系统库,而不是让 Cargo 构建自己的版本。如果您只想使用系统包,您可以配置任何每种语言的包管理器以查看 localhost 的镜像,如果他们尝试访问 Internet,则会失败,如果您愿意,甚至可以进行测试。

      【讨论】:

        猜你喜欢
        • 2014-03-13
        • 2012-05-11
        • 1970-01-01
        • 2018-10-09
        • 1970-01-01
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多