Skip to content

Commit ec3d9eb

Browse files
committed
fix(rpm): avoid wildcard gateway listener
Signed-off-by: Evan Lezar <[email protected]>
1 parent 777b5c0 commit ec3d9eb

6 files changed

Lines changed: 36 additions & 45 deletions

File tree

‎crates/openshell-server/src/config_file.rs‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,8 @@ version = 2
720720
/// `load()` path that the gateway uses at runtime, catching:
721721
/// - template corruption or unknown fields (`deny_unknown_fields`)
722722
/// - schema drift (version bump or field renames)
723-
/// - accidental changes to the bind address or compute driver list
723+
/// - accidental addition of a wildcard bind-address override
724+
/// - accidental changes to the compute driver list
724725
#[test]
725726
fn rpm_default_config_parses_and_has_podman_defaults() {
726727
let path =
@@ -729,20 +730,12 @@ version = 2
729730
load(&path).expect("deploy/rpm/gateway.toml.default must parse against current schema");
730731
let gw = &config.openshell.gateway;
731732

732-
let addr = gw
733-
.bind_address
734-
.expect("bind_address must be explicitly set in the RPM default config");
735-
assert!(
736-
addr.ip().is_unspecified(),
737-
"RPM default bind_address must be 0.0.0.0 so Podman sandbox containers \
738-
can reach the gateway over the host network bridge, got {addr}"
739-
);
740-
assert_eq!(
741-
addr.port(),
742-
openshell_core::config::DEFAULT_SERVER_PORT,
743-
"RPM default port must match DEFAULT_SERVER_PORT ({})",
744-
openshell_core::config::DEFAULT_SERVER_PORT
745-
);
733+
if let Some(addr) = gw.bind_address {
734+
assert!(
735+
!addr.ip().is_unspecified(),
736+
"RPM default config must not expose the primary listener on every interface"
737+
);
738+
}
746739

747740
let drivers = gw
748741
.compute_drivers

‎deploy/rpm/CONFIGURATION.md‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ The defaults are tuned for rootless Podman use:
2020
version = 1
2121

2222
[openshell.gateway]
23-
bind_address = "0.0.0.0:17670"
2423
compute_drivers = ["podman"]
2524
```
2625

27-
`bind_address = "0.0.0.0:17670"` is required because Podman sandbox
28-
containers reach the gateway over the host network bridge and cannot
29-
connect to `127.0.0.1` inside the gateway's network namespace. mTLS is
30-
enabled by default and protects all connections.
26+
The RPM does not override `bind_address`. The primary listener uses the
27+
built-in `127.0.0.1:17670` default. The Podman driver reports the callback
28+
interface it needs, and the gateway adds a separate listener scoped to that
29+
interface. This keeps the general API off unrelated host interfaces.
3130

3231
`compute_drivers = ["podman"]` pins the compute driver to Podman. Without
3332
this, the gateway auto-detects in order: Kubernetes, Podman, Docker. Pinning
@@ -43,8 +42,8 @@ To apply environment variable overrides that persist across upgrades without
4342
editing the TOML file, add them to `~/.config/openshell/gateway.env`:
4443

4544
```shell
46-
# Example: restrict to loopback only
47-
OPENSHELL_BIND_ADDRESS=127.0.0.1
45+
# Example: explicitly expose the primary listener on one host interface
46+
OPENSHELL_BIND_ADDRESS=192.168.1.10
4847
```
4948

5049
To override the path to the TOML config file entirely:
@@ -63,8 +62,9 @@ systemctl --user edit openshell-gateway
6362
## TLS (mTLS)
6463

6564
The RPM enables mutual TLS by default. The gateway requires a valid
66-
client certificate for all API connections and listens on
67-
`0.0.0.0:17670` by default (see "Default configuration" above).
65+
client certificate for all API connections. Its primary listener uses
66+
`127.0.0.1:17670`; Podman callback traffic uses the additional listener
67+
described in "Default configuration" above.
6868

6969
### Auto-generated certificates
7070

@@ -214,7 +214,7 @@ overrides that persist across package upgrades.
214214

215215
| TOML option | Default | Description |
216216
|-------------|---------|-------------|
217-
| `bind_address` | `0.0.0.0:17670` (RPM default) | Address for the gRPC/HTTP API. |
217+
| `bind_address` | `127.0.0.1:17670` (gateway default) | Address for the primary gRPC/HTTP API listener. |
218218
| `compute_drivers` | `["podman"]` (RPM default) | When unset, the gateway auto-detects Kubernetes, then Podman, then Docker. The RPM default pins to Podman. |
219219
| `default_image` | `ghcr.io/nvidia/openshell-community/sandboxes/base:latest` | Default sandbox image. |
220220
| `supervisor_image` | `ghcr.io/nvidia/openshell/supervisor:latest` | Supervisor image mounted into Podman sandboxes. |
@@ -235,7 +235,6 @@ settings:
235235
version = 1
236236

237237
[openshell.gateway]
238-
bind_address = "0.0.0.0:17670"
239238
compute_drivers = ["podman"]
240239
default_image = "ghcr.io/nvidia/openshell-community/sandboxes/base:latest"
241240

‎deploy/rpm/QUICKSTART.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ On first start, the gateway automatically generates:
6565

6666
- A self-signed PKI bundle (CA, server cert, client cert) for mTLS
6767

68-
> **Note:** The RPM default configuration binds to `0.0.0.0:17670` so
69-
> Podman sandbox containers can reach the gateway over the host network
70-
> bridge. Mutual TLS (mTLS) is enabled automatically on first start,
71-
> requiring a valid client certificate for every connection. See
72-
> CONFIGURATION.md for details.
68+
> **Note:** The primary gateway listener uses the loopback default,
69+
> `127.0.0.1:17670`. The Podman driver requests a separate callback listener
70+
> scoped to the interface its sandboxes can reach. Mutual TLS (mTLS) is
71+
> enabled automatically on first start, requiring a valid client certificate
72+
> for every connection. See CONFIGURATION.md for details.
7373
7474
Verify the service is running:
7575

‎deploy/rpm/TROUBLESHOOTING.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Generate certificates that include the server's hostname or IP in the
8585
SANs. See "Using externally-managed certificates" in CONFIGURATION.md.
8686
Then change `bind_address` in
8787
`~/.config/openshell/gateway.toml` to the interface the remote CLI
88-
can reach, for example `0.0.0.0:17670`, and restart the gateway.
88+
can reach, for example `192.168.1.10:17670`, and restart the gateway.
8989

9090
After placing the server and client certs, register from the remote
9191
CLI:
@@ -274,11 +274,12 @@ Other breaking changes in this release:
274274

275275
- **Default bind address changed from `0.0.0.0` to `127.0.0.1`.** If
276276
you relied on network-accessible access without an explicit bind
277-
address, add the following to `~/.config/openshell/gateway.toml`:
277+
address, bind the specific reachable interface in
278+
`~/.config/openshell/gateway.toml`:
278279

279280
```toml
280281
[openshell.gateway]
281-
bind_address = "0.0.0.0:17670"
282+
bind_address = "192.168.1.10:17670"
282283
```
283284

284285
Also update your firewall rule if applicable:

‎deploy/rpm/gateway.toml.default‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818
version = 1
1919

2020
[openshell.gateway]
21-
# Podman sandbox containers reach the gateway over the host network bridge,
22-
# which requires binding to all interfaces. Override to 127.0.0.1:17670 if
23-
# you don't use Podman or want loopback-only access (e.g. behind a reverse
24-
# proxy). mTLS is enabled by default and protects all connections.
25-
bind_address = "0.0.0.0:17670"
21+
# Keep the primary listener on the built-in 127.0.0.1:17670 default. The
22+
# Podman driver reports the callback interface it needs, and the gateway
23+
# adds a separate listener scoped to that interface.
2624

2725
# Pin to the Podman compute driver. Without this, the gateway auto-detects
2826
# in order: Kubernetes, Podman, Docker. Pinning prevents unexpected driver

‎e2e/with-podman-gateway.sh‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,10 @@ toml_string() {
399399
GATEWAY_CONFIG="${STATE_DIR}/gateway.toml"
400400

401401
# Start from the RPM default template so this e2e test exercises the same
402-
# TOML config path that RPM users get on first start. The template sets
403-
# bind_address = "0.0.0.0:17670" and compute_drivers = ["podman"]; those
404-
# values must be correct for Podman e2e to pass, which means a regression
405-
# to the template (wrong bind address, wrong driver) will surface here.
402+
# TOML config path that RPM users get on first start. The template leaves
403+
# bind_address unset and sets compute_drivers = ["podman"], so this test
404+
# exercises the built-in loopback listener plus the callback listener
405+
# requested by the Podman driver.
406406
#
407407
# We append the driver-specific table and override the port via CLI flag
408408
# (CLI > TOML in the merge precedence) so the test can use an ephemeral port.
@@ -433,8 +433,8 @@ cp "${ROOT}/deploy/rpm/gateway.toml.default" "${GATEWAY_CONFIG}"
433433

434434
GATEWAY_ARGS=(
435435
--config "${GATEWAY_CONFIG}"
436-
# bind_address and compute_drivers come from the RPM template; no CLI flags
437-
# needed. Port is overridden via CLI (CLI > TOML) for ephemeral port selection.
436+
# compute_drivers comes from the RPM template, while bind_address uses the
437+
# built-in loopback default. Override only the port for ephemeral selection.
438438
--port "${HOST_PORT}"
439439
--health-port "${HEALTH_PORT}"
440440
--tls-cert "${PKI_DIR}/server/tls.crt"

0 commit comments

Comments
 (0)