Using Proxy for FreeBSD ports

2025-01-15

Table of Contents:

FreeBSD's poudriere doesn't have a way to use ALL_PROXY when fetching source. As a result, go based package dependencies are not usable if you have bad Internet connection that has to be alleviated with a proxy server.

The following content records how I debugged it and my working solution.

Methods that won't work

Setting environmental variables for poudriere won't work, because according to the source code of /usr/local/bin/poudriere script:

# Special-case environment passthroughs.
while read envvar; do
    case "${envvar}" in
    FETCH_BIND_ADDRESS|FTP_*|ftp_*|HTTP_*|http_*|SSH_*|SSL_|NO_PROXY|no_proxy)
        case "${CMD}" in
        ports|jail) ;;
        *) continue ;;
        esac
        ;;
    MAKEOBJDIRPREFIX)
        case "${CMD}" in
        jail) ;;
        *) continue ;;
        esac
        ;;
    POUDRIERE_INTERACTIVE_NO_INSTALL)
        case "${CMD}" in
        bulk|testport) ;;
        *) continue ;;
        esac
        ;;
    *) continue ;;
    esac
    env_set "${envvar}"
done <<-EOF
$(export)
EOF

The environment variable is only passed if the sub-command is ports or jail

Setting environmental variables for make.conf is ugly and won't work for go based packages, since go handles the downloading of dependencies, rather than the package manager

Method that work

Since go doesn't respect the SOCKS5_PROXY or ALL_PROXY as in fetch(3) or even curl(1), we can only make use an HTTP proxy.

My setup is running an HTTP proxy on my PC, and the FreeBSD server connects to the proxy server via ssh reverse tunnel, this way my packets are encrypted, and people on LAN are not able to trespass.

Since poudriere has troubles passing the proxy variables, we use fetch manually on the ports directory

HTTP proxy server setup

On PC, enable HTTP listening on your proxy software:

{
    "type": "http",
    "tag": "http-in",
    "sniff": true,
    "domain_strategy": "prefer_ipv6",
    "listen": "127.0.0.1",
    "listen_port": 9091
},

Optionally test it on your PC:

https_proxy=http://127.0.0.1:9091 curl -lv https://checkip.amazonaws.com

ssh into your machine with reverse tunneling:

ssh -R 9091:localhost:9091 <user>@<addr>

In the server, su to someone who has write access to /usr/ports (or where the ports tree is located), and export the environment variable:

export https_proxy=http://127.0.0.1:9091
export http_proxy=$https_proxy

You can test it again on the server:

https_proxy=http://127.0.0.1:9091 fetch https://checkip.amazonaws.com

It should write a text file to your $PWD, if it works then fetch the packages manually:

cd /usr/ports/www/caddy
make fetch-list # This shows the shell command that is used to fetch direct distfiles,
                # you can run the commands manually, however it's not enough for go
make fetch # This fetches the package's direct distfile dependencies, and then downloads
            # from cargo or go module registry

Once the distfiles are downloaded, poudriere should pick them up, and use the cached version.