diff --git a/README.md b/README.md index f109a20..527fc8c 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ curl 7.82 or newer; older versions take For demo purposes, let's first start the service *without authentication*. This mode is NOT SECURE! See below how to set up authentication. -`--insecure` also turns TLS off, hence the plain `http://` below. +`--insecure` also turns TLS off, hence the plain `http://` below. It +listens on `127.0.0.1:1031` only. Use `--bind=` if more is needed. ```console $ systemd-run --user ./target/debug/varlink-httpd --insecure @@ -297,7 +298,9 @@ authenticate the client; without mTLS the bridge refuses to start. mTLS is enabled separately (see below) and applies on top of whatever `--auth=` selects, so `--auth=ssh` together with mTLS requires both to pass. `--insecure` is the one way to serve with no authentication at -all, and implies `--auth=none`. +all, and implies `--auth=none`. Because nothing authenticates the +client, it defaults to listening on `127.0.0.1:1031` instead of the +usual `0.0.0.0:1031`. Use `--bind=` if more is needed. ### TLS / mTLS @@ -308,7 +311,8 @@ TLS flag names follow the systemd convention. --key=PATH path to TLS private key PEM file --trust=PATH path to CA certificate PEM for client verification (mTLS) --require-mtls require a verified client certificate ---insecure run over plain HTTP without any authentication (DANGEROUS) +--insecure run over plain HTTP without any authentication (DANGEROUS, + listens on localhost only unless --bind= says otherwise) ``` `--require-mtls` makes every client present a certificate signed by the diff --git a/src/bin/varlink-httpd/main.rs b/src/bin/varlink-httpd/main.rs index 2b9e9a4..777fea6 100644 --- a/src/bin/varlink-httpd/main.rs +++ b/src/bin/varlink-httpd/main.rs @@ -1620,7 +1620,8 @@ fn print_help() { VARLINK_SOCKETS_PATH directory of sockets or a single socket (default: /run/varlink/registry) --bind=ADDR address to bind to (repeatable; - default: 0.0.0.0:{DEFAULT_PORT}) + default: 0.0.0.0:{DEFAULT_PORT}, or + 127.0.0.1:{DEFAULT_PORT} with --insecure) use vsock::PORT for vsock (e.g. vsock::{DEFAULT_PORT}) --auth=MECHANISMS comma-separated per-request authentication ({auth}); required unless --insecure. @@ -1638,7 +1639,9 @@ fn print_help() { --authorized-keys=PATH authorized SSH public keys file --api-keys=PATH API key hashes file (see gen-api-key) --insecure run over plain HTTP without any - authentication (DANGEROUS) + authentication (DANGEROUS); listens + on localhost only unless --bind= says + otherwise --help display this help and exit ", auth = AuthMechanism::names(), @@ -1683,6 +1686,20 @@ fn check_mechanism_flags( Ok(()) } +fn default_bind(insecure: bool) -> (String, Option) { + if insecure { + ( + format!("127.0.0.1:{DEFAULT_PORT}"), + Some(format!( + "--insecure listens on 127.0.0.1:{DEFAULT_PORT} only, \ + pass --bind= if needed" + )), + ) + } else { + (format!("0.0.0.0:{DEFAULT_PORT}"), None) + } +} + fn parse_cli() -> anyhow::Result { use lexopt::prelude::*; @@ -1734,7 +1751,11 @@ fn parse_cli() -> anyhow::Result { } if bind_strs.is_empty() { - bind_strs.push(format!("0.0.0.0:{DEFAULT_PORT}")); + let (bind, note) = default_bind(insecure); + if let Some(note) = note { + warn!("{note}"); + } + bind_strs.push(bind); } let binds: Vec = bind_strs .iter() diff --git a/src/bin/varlink-httpd/tests.rs b/src/bin/varlink-httpd/tests.rs index 3909432..61e46d6 100644 --- a/src/bin/varlink-httpd/tests.rs +++ b/src/bin/varlink-httpd/tests.rs @@ -1689,6 +1689,21 @@ fn test_format_x509_subject_multiple_fields() { // --- bind address parsing tests --- +#[test] +fn test_default_bind_insecure_is_localhost_only() { + let (bind, note) = crate::default_bind(true); + assert_eq!(bind, format!("127.0.0.1:{DEFAULT_PORT}")); + let note = note.expect("--insecure should explain the narrowed default"); + assert!(note.contains("--bind="), "note: {note}"); +} + +#[test] +fn test_default_bind_authenticated_is_wildcard() { + let (bind, note) = crate::default_bind(false); + assert_eq!(bind, format!("0.0.0.0:{DEFAULT_PORT}")); + assert_eq!(note, None); +} + #[test] fn test_bind_addr_parse_defaults() { // "vsock" and "vsock:" both mean CID_ANY + default port