-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathegress-proxy.conf
More file actions
66 lines (60 loc) · 4.66 KB
/
Copy pathegress-proxy.conf
File metadata and controls
66 lines (60 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# The egress policy's PROXY RULES (REQ-EGRESS-ALLOWLIST). Shipped by pi-dispatch. DO NOT EDIT.
#
# The list of hosts a job may reach is NOT here. It is `egress-allowlist.conf` in your deployment
# folder, one bare hostname per line, scaffolded by `pi-dispatch init` and read by the `allowed` acl
# below. That split is deliberate: the ordering of `http_access` rules is the security property and a
# misordered one silently allows everything, so the file an operator edits contains no ordering at all.
#
# What this policy is, and is not:
# - Hostname filtering on CONNECT, to port 443 only. The provider, the forge and the registry are
# ordinary entries in the allowlist, and nothing is special. The one address-based rule is a DENY:
# a listed name that resolves to a fixed loopback or link-local address of this host is refused.
# - TLS is NEVER terminated. This proxy sees the name a client asks for and no byte inside the tunnel,
# so it cannot read a credential and cannot account for a token. A proxy that decrypts provider
# traffic is OQ-011's mechanism, a materially larger change, and it is not this.
# - Deny by default. `http_access deny all` is the last word and every allow above it is explicit.
#
# No `access_log stdio:/dev/stdout`, and that is not an oversight: squid drops privileges to the `proxy`
# user after parsing, cannot open that path, and EXITS 1 -- after printing a clean, complete, successful
# config parse. It is the most confusing failure this file can have, so it is named here.
http_port 3128
# The operator's list. Bare hostnames, one per line; a leading dot matches subdomains (.github.com).
# `-n` (issue #428): without it squid answers an IP-literal request (CONNECT 93.184.215.14:443, or an
# IPv6 literal) that matches no entry by a REVERSE lookup of that address, and matches the name it
# gets back (measured: a PTR query per literal, then 403). A job choosing the address chooses whose
# reverse zone is asked, which is a DNS channel out. With `-n` no lookup is made: the request's host
# is compared as written, so a literal is still refused unless the list names that literal itself.
acl allowed dstdomain -n "/etc/pi-dispatch/allowlist.conf"
acl SSL_ports port 443
acl CONNECT method CONNECT
# The host's own services, by address (issue #428). On rootless Podman an account's containers.conf
# (pasta_options such as --map-host-loopback 169.254.1.2, or slirp4netns's allow_host_loopback=true,
# which answers on 10.0.2.2) gives the network this proxy sits on the host's 127.0.0.1 services, the
# job queue's Valkey among them, and a name in the allowlist that resolves (or is rebound) to one of
# these addresses would then reach them on a job's behalf. 0.0.0.0 and :: are loopback too on Linux.
# 10.0.2.2 is slirp4netns's host alias and only means the host there; elsewhere it is an ordinary
# private address, and an allowlisted service that really lives at it is refused (move it, or drop
# this entry in a copy you maintain).
# DEFENCE IN DEPTH, not the closure, and only for the FIXED addresses: the host can be mapped to any
# address (--map-host-loopback <address>, slirp4netns's cidr=, and --map-gw, which uses the default
# gateway's), and no fixed rule names those. The closure is the worker's: its podman venue refuses
# every job while the account's containers.conf sets pasta_options, network_cmd_options, annotations
# or env. That refusal reads the conf, not the live network: after a key is removed, a proxy started
# under the old conf keeps the old options until the account's containers on a bridge network restart,
# which the refusal's own text tells the operator to do.
acl to_host_local dst 127.0.0.0/8 0.0.0.0/32 169.254.0.0/16 10.0.2.2/32 ::1 ::/128 fe80::/10
# Order is the design, not a detail. Read top to bottom, first match wins.
# The deny names `allowed` FIRST, and that order is load-bearing: squid evaluates an http_access line's
# ACLs left to right and stops at the first that does not match, and `dst` resolves the requested name.
# A bare `deny to_host_local` resolved EVERY name a job asked for, listed or not (measured with
# debug_options 78,3: a CONNECT to an unlisted name sent a DNS query, where without the rule it sent
# none), which is a DNS channel out of an egress-armed job. With `allowed` first, only a listed name
# is ever resolved here, and it is the only kind the allows below could let through anyway.
http_access deny allowed to_host_local
http_access deny CONNECT !SSL_ports
http_access allow CONNECT allowed
http_access allow allowed
http_access deny all
# A cache would store bytes from an allowlisted host on behalf of a container running adversarial code,
# and serve them to the next job. Nothing here wants a cache.
cache deny all