Docs · Integrations

Network and outbound traffic

A sandbox can reach the internet. The internet can reach it through SSH, froog's public URLs, its own public IPv6 address, which answers SSH and the ports you open, and the ports you open over IPv4, each at a port of its own on the machine's shared address. Other inbound connections are refused. In detail:

OutboundOpen to the internet on any port, TCP and UDP, except outbound SMTP on TCP port 25, which is dropped. Send email through a provider's API or submission port (587 or 465). No egress charges.
BlockedOther sandboxes, the machine the sandbox runs on, and private and internal ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 and 100.64.0.0/10, and over IPv6 the machine's own range, fc00::/7, fe80::/10 and multicast.
Outbound addressIPv4 traffic leaves from the public IPv4 address of the machine the sandbox runs on, shared with the other sandboxes on it. IPv6 traffic leaves from the sandbox's own IPv6 address. froog has no dedicated or static outbound IPv4 addresses.
IPv6 addressEach sandbox has its own public IPv6 address (ipv6 in the API, froog info). It stays the same while the sandbox runs and across a warm resume. A start after a longer stop, and a fork, get a new one, so look it up after each start rather than saving it. A sandbox made before IPv6 was added gets one at its next start.
InboundOver IPv4: SSH (keys only, at the address and port froog info shows), the ports you open (each at its own public port of the machine's address, see Open ports), and replies to the sandbox's own connections. Over IPv6: SSH on port 22 (keys only), ping, replies, and the ports you open. Every other port is refused by froog's firewall, so a server listening on all addresses stays private until you open its port. For HTTPS with a hostname, use froog host NAME PORT: froog's edge reaches the port through an SSH tunnel and works for visitors without IPv6.
Open portsfroog port open NAME 27015/udp opens a raw TCP or UDP port (TCP when you leave out the protocol), for a game server, a database or anything else that isn't HTTPS. froog port close NAME 27015/udp closes it, and froog port list NAME lists what's open. The rule is in froog's firewall, outside the sandbox, so it works the same on every OS and needs no firewall setup inside. Open ports stay open across stops, starts and restores, and a fork gets the same ones. A --public URL also opens its TCP port on IPv6. At most 64 per sandbox, public URLs' ports included. Inside a sandbox: froog port open "$(hostname)" PORT. API: GET, PUT and POST /v1/sandboxes/{name}/ports, DELETE /v1/sandboxes/{name}/ports/{port}/{protocol} (an API key needs sandbox.update to change them).
Open ports over IPv6On the sandbox's own IPv6 address, at the same port number: [2a01:4f8:…::1:2]:27015.
Open ports over IPv4Sandboxes share the IPv4 address of the machine they run on, so each port you open also gets a public port of its own on that address, forwarded to your port. froog port list NAME shows it, for example 27015/udp at 203.0.113.7:40002, and so do froog info and ipv4 in the API (address is what to connect to). The public port is a different number than yours, from 40000 to 49999. TCP and UDP of one port get the same number when it's free. A stop and start on the same machine gets the same one back (a warm resume always does). A start on another machine gets a new one, so look it up after each start rather than saving it. A stopped sandbox's public ports can go to another sandbox if the machine runs out. A public URL's port gets none: IPv4 visitors use the URL. At most 16 per sandbox, and 64 at once across an account's running sandboxes. Ports past either limit, or opened when the machine has none free, stay on IPv6 only, and froog port list says why (ipv4_note). Each sandbox takes at most 4,096 tracked inbound IPv4 connections at once. More new ones are dropped.
DNSSandboxes resolve through 1.1.1.1 and 8.8.8.8.
Your computerA sandbox has no route back to it. froog forward NAME PORT --reverse opens one port over SSH while it runs.

Restricting outbound traffic

froog doesn't filter outbound traffic beyond the rules above. You have root in the sandbox, so you can add your own rules with nftables. Rules made by user can be undone by anything running as user, since it has passwordless sudo. To contain code you don't trust, run it as a second user without sudo and outside the docker group, and limit that user. This allows it only DNS and HTTPS:

$ froog ssh my-box
user@my-box:~$ command -v nft || sudo apt-get install -y nftables   # sudo pacman -S nftables on Omarchy
user@my-box:~$ sudo useradd -m -s /bin/bash agent
user@my-box:~$ sudo nft -f - <<EOF
table inet egress {
  chain out {
    type filter hook output priority 0; policy accept;
    meta skuid $(id -u agent) oifname "lo" accept
    meta skuid $(id -u agent) udp dport 53 accept
    meta skuid $(id -u agent) tcp dport 443 accept
    meta skuid $(id -u agent) drop
  }
}
EOF
user@my-box:~$ sudo -u agent -H bash -lc 'cd ~ && ./run-task.sh'

The rules last until the sandbox stops: every start boots afresh. To apply them at every start, put the commands in your setup script (it runs in the background at every start, so the rules apply a moment after the sandbox is up). The second user can't read ~/.froog (mode 700, with your variables and setup files) or the files froog writes with mode 600 (secret files, and the in-sandbox key in ~/.config/froog/config.json). To allow a list of hosts rather than ports, send that user's traffic through an HTTP proxy that checks host names, and allow only the proxy.