From a local SCION network to a real network
To run the chat on your machine, start chat-dev. chat-dev starts a SCION network on
PocketSCION, a SCION network simulator, and starts the chat server in
that network. It also serves the /info endpoint, which gives a client every value that the client
needs to connect to the server: the endhost API, a credential, the URL and the SCION address of the
server, and the certificate of the server.
In a real deployment, no single place gives these values. The client gets each value from a different source. This page compares the local SCION network with a real deployment, value by value, and links to the page that explains each value.
The local SCION network
chat-dev starts three ASes on PocketSCION and puts the chat server
in the middle AS. Each AS gets an endhost API and a SNAP endpoint:
/// Starts the network. Each AS gets an endhost API and a SNAP endpoint.
pub async fn start(io_config: IoConfig) -> PsSetup {
let mut state = PocketScionState::new(Utc::now());
state.set_topology(definition().build().expect("a well-formed topology"));
let endhost_apis = BTreeMap::from([
(DEFAULT, state.add_endhost_api(vec![DEFAULT])),
(SERVER, state.add_endhost_api(vec![SERVER])),
(EMULATOR, state.add_endhost_api(vec![EMULATOR])),
]);
for isd_as in [DEFAULT, SERVER, EMULATOR] {
state.add_snap(isd_as).expect("a SNAP endpoint");
}
let runtime = PocketScionRuntimeBuilder::new()
.with_system_state(state)
.with_io_config(io_config)
.start()
.await
.expect("the network starts");
PsSetup {
runtime,
endhost_apis,
}
}
The topology has one link from each client AS to the AS of the server:
/// The three ASes, and one link from each client AS to the server's AS.
fn definition() -> ScionTopologyBuilder {
let mut topology = ScionTopologyBuilder::new();
topology
.add_as(ScionAs::new_core(SERVER))
.expect("the server's AS")
.add_as(ScionAs::new_core(DEFAULT))
.expect("the default AS")
.add_as(ScionAs::new_core(EMULATOR))
.expect("the emulator's AS")
.add_link(
ScionLink::new(DEFAULT, 1, ScionLinkType::Core, SERVER, 3).expect("a well-formed link"),
)
.expect("the default link")
.add_link(
ScionLink::new(EMULATOR, 2, ScionLinkType::Core, SERVER, 4)
.expect("a well-formed link"),
)
.expect("the emulator link");
topology
}
The network publishes one address for each AS. 1-ff00:0:132 publishes the address that chat-dev
binds, and every client that reaches that address attaches there. An Android emulator reaches your
machine at 10.0.2.2, and inside the emulator 127.0.0.1 is the emulator itself. Thus the
emulator gets its own AS, 2-ff00:0:222, which publishes 10.0.2.2.
The underlay is SNAP, so a client behind a NAT can join. Transport underlays explains the SNAP underlay.
What chat-dev gives a client
chat-dev runs the local SCION network and the chat server in one process. It also serves the
settings that a client needs at GET /info, on its control port, 8099. /info is plain HTTP, and
it belongs to chat-dev, not to the chat server. A real deployment has no /info. A client uses
it in three steps:
This is a sample of the response of /info:
{
"control_url": "http://127.0.0.1:8099",
"endhost_api_url": "http://127.0.0.1:65263/",
"client_isd_as": "1-ff00:0:132",
"auth_token": "eyJ0eXAiOiJKV1Qi...",
"base_url": "https://localhost:8443",
"target": "2-ff00:0:212,127.0.0.1",
"ca_path": "/tmp/.tmpTFIcwA/cert.pem",
"chat_server_args": ["--transport", "scion", "--listen", "127.0.0.1:8443", "..."]
}
A client reads five values from it:
endhost_api_urlis where the client discovers its SCION connectivity.auth_tokenis a SNAP token. Each read of/infomakes a new token.base_urlis the URL of the chat server.targetis the SCION address of the server, without a port.ca_pathis the self-signed certificate of the server.
What a real deployment gives
A real deployment gives a client the same values from other sources:
| A client needs | chat-dev gives | A real deployment gives | Explained on |
|---|---|---|---|
| An endhost API | endhost_api_url, over plain HTTP on your machine | the endhost API of the network operator, over HTTPS | The ScionStack model |
| A credential | auth_token, one SNAP token | an API key, which the Anapaya AA exchanges for tokens | Transport underlays |
| The URL of the server | base_url, https://localhost:8443 | the public URL of the server, with a host name that the certificate of the server names | The server |
| The address of the server | target | a TSAR record in DNS for the host of the server | The client |
| Trust in the server | ca_path, a certificate to pin | a publicly trusted certificate, which the system roots trust | The client |
The chat client takes each of these values from its configuration. Thus the move to a real network changes the configuration of the client, and the code stays the same.
Trust and credentials
In the local SCION network, the chat server makes a self-signed certificate and logs its
fingerprint, as The server shows. Each client pins that certificate.
chat-dev gives each client a SNAP token, and each client needs its own token. A token expires,
so a client with only a token stops working at that time.
In a real network, the server presents a publicly trusted certificate, and the clients trust it through the system roots. Each client holds an API key. The SDK exchanges the key with the Anapaya AA for a token, and renews the token while the client runs.
The server also uses the SNAP underlay, so it also needs a credential. In the local SCION network,
chat-dev writes a SNAP token to a file and gives the file to the server with --auth-token-file.
A SNAP token is short-lived, and an AA must issue a new token at regular intervals. Thus a token
file makes testing simple, but it is not a credential for a real network. In a real network, the
server gets an API key with --auth-api-key-file.
The AA URL uses https. The AA client accepts http only for a loopback host. The chat clients
and the chat server use the Anapaya AA at https://auth.scion.anapaya.net by default.
A phone on the same network
By default, chat-dev binds to 127.0.0.1, so only clients on your machine reach it. To connect a
phone on your local network, start chat-dev with --bind-ip and an address of your machine that
the phone reaches. Every part of the network then uses that address, and every client uses it too.
With such an address, an Android emulator reaches the default AS like every other client.
The README of the chat gives the commands, in From another machine.
Where to go next
- Testing against PocketSCION: the same building blocks, in a test.
- The topology in the README of the chat: the ASes and the addresses that they publish.