feat(relay): default portal URL (#1719)

Instead of having portal URL and token optional, we default the portal
URL and decide based on the presence of the token, whether we should
connect to the portal on startup. This allows the relay to be
used/tested standalone and keeps the number of config options and error
cases small.

We require the user to config the full path of the websocket and thus
avoid the need for duplicating the connlib function. Given that most
users will never need to override this option, this seems like a good
trade-off.

Resolves https://github.com/firezone/product/issues/614.
This commit is contained in:
Thomas Eizinger
2023-07-05 20:31:05 +01:00
committed by GitHub
parent eb5fc34f35
commit db4bdb0791

View File

@@ -30,11 +30,11 @@ struct Args {
#[arg(long, env)]
listen_ip4_addr: Ipv4Addr,
/// The websocket URL of the portal server to connect to.
#[arg(long, env, default_value = "wss://api.firezone.dev")]
portal_ws_url: Url,
/// Token generated by the portal to authorize websocket connection.
///
/// If omitted, the relay server will start immediately, otherwise we first log on and wait for the `init` message.
#[arg(long, env)]
portal_ws_url: Option<Url>,
/// Token generated by the portal to authorize websocket connection
/// If omitted, we won't connect to the portal on startup.
#[arg(long, env)]
portal_token: Option<String>,
/// Whether to allow connecting to the portal over an insecure connection.
@@ -47,28 +47,6 @@ struct Args {
rng_seed: Option<u64>,
}
// TODO: Code repetition from common
fn get_websocket_path(mut url: Url, token: String, ipv4: Ipv4Addr) -> Result<Url> {
{
let mut paths = url
.path_segments_mut()
.map_err(|_| anyhow!("invalid url"))
.context("No url base found while trying to format the portal's URL")?;
paths.pop_if_empty();
paths.push("relay");
paths.push("websocket");
}
{
let mut query_pairs = url.query_pairs_mut();
query_pairs.clear();
query_pairs.append_pair("token", &token);
query_pairs.append_pair("ipv4", &ipv4.to_string());
}
Ok(url)
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
@@ -83,23 +61,22 @@ async fn main() -> Result<()> {
let server = Server::new(args.public_ip4_addr, make_rng(args.rng_seed));
let channel = if let Some(mut portal_url) = args.portal_ws_url {
if portal_url.scheme() == "ws" && !args.allow_insecure_ws {
let channel = if let Some(token) = args.portal_token {
let mut url = args.portal_ws_url.clone();
if url.scheme() == "ws" && !args.allow_insecure_ws {
bail!("Refusing to connect to portal over insecure connection, pass --allow-insecure-ws to override")
}
if !url.path().is_empty() {
tracing::warn!("Overwriting path component of portal URL with '/relay/websocket'");
}
portal_url
.query_pairs_mut()
url.set_path("relay/websocket");
url.query_pairs_mut()
.append_pair("token", &token)
.append_pair("ipv4", &args.listen_ip4_addr.to_string());
let mut channel = PhoenixChannel::<InboundPortalMessage, ()>::connect(
get_websocket_path(
portal_url.clone(),
args.portal_token.ok_or(anyhow!(
"PORTAL_TOKEN must be set if you're setting a PORTAL_WS_URL"
))?,
args.listen_ip4_addr,
)?,
url,
format!("relay/{}", env!("CARGO_PKG_VERSION")),
)
.await