Abstract
This specification defines a simple JSON format and well known URL for firewalls and other devices to discover whats IP addresses, ports, and related transports a given cloud services uses.
Introduction
Simple Port and Address Discovery (SPAD) allows an web application to inform others of what ports and IP addresses it uses so that things like firewalls can correctly re-configure themsleves as the ports and addresses change. Applications are identified by a domain name which is used to form a URL in a well known location where a client can do a HTTP REST call to get a JSON file that describes information about what addresses and transport the service uses.
Terminology
In this document, the key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119 and indicate requirement levels for compliant implementations.
RAML is defined at https://github.com/raml-org.
JSON Schema is defined at http://json-schema.org/. Further information is available in .
Example
To figure out what IP addresses are used by the service example.com, the first step is to form the query URL by constructing an endpoint at ".well-known/spad/v0/spad".
Then an HTTPS GET query is done that to that URL.
curl https://example.com/.well-known/spad/v0/spad
The responses would be a JSON result that could looks like
{
"domain": "example.com",
"services": [
{
"name": "example-service",
"validTill": "Fri 11 Nov 2016 22:20:08 UTC",
"flows": [
{
"ips": [
"203.0.113.2"
],
"port": 443,
"protocol": "https"
}
]
}
]
}
The example above indicates that the "example.com" application has a single service with a single flow that uses only the HTTPS to connect to port 443 on the IP address "203.0.113.2". This SPAD information is not valid after "Fri 11 Nov 2016 22:20:08 UTC" and a new SPAD file should be retrieved before that point in time.
The following shows a more complex example result for an application that uses two flows. One is TLS to the SIP port of a server with an v4 and v6 address. The TLS connection will have a name of example.com in the SNI. The other flow is media sent over UDP to port 5004 on a few different ip addresses. If devices in the network are capable of remarking DSCP, the desired marking is "AF41".
{
"domain": "example.com",
"services": [
{
"name": "voice-example",
"validTill": "Fri 11 Nov 2016 22:20:08 UTC",
"flows": [
{
"ips": [
"203.0.113.2",
"2001:db8::1"
],
"port": 5061,
"name": "example.com",
"protocol": "tls"
},
{
"ips": [
"192.0.2.1",
"2001:db8::2"
],
"port": 5004,
"protocol": "udp",
"qos": "AF41"
}
]
}
]
}
Blueprint
The Bluprint specification for the API is:
FORMAT: 1A
# SPAD
# Group Flows
## Service Collection [/.well-known/spad/v0/spad]
### Get SPAD information for this application [GET]
+ Response 200 (application/json)
+ Attributes ( Application )
## Service Collection [/.well-known/spad/v0/{service}]
### Get SPAD information for this service [GET]
+ Parameters
+ service (string) -- service name to lookup
+ Response 200 (application/json)
+ Attributes ( Service )
# Data Structures
## Application
+ domain: example.com (string)
+ services (array[Service])
## Service (object)
+ name: message (string)
+ validTill: Fri 11 Nov 2016 22:20:08 UTC (string)
+ flows (array[Flow])
## Flow (object)
+ ips: 203.0.113.2, 2001:db8::1 (array[string], required) - All IP addresses used by this flow
+ port: 443 (number, required) - destination port number
+ name: example.com (string, optional) - names used in TLS SNI or Proxy connect
+ protocol: udp, tcp, http, tls, https, quic (enum, optional)
+ qos: CS1, DF, EF, AF11, AF21, AF41, AF42, AF43, AF31, AF32, AF33 (enum, optional)
Schemas
The JSON returned from MUST corespond to the following JSON schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "SPAD schema.",
"properties": {
"domain": {
"type": "string",
"title": "TODO"
},
"services": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "name of service"
},
"validTill": {
"type": "string",
"title": "Expiry time for this SPAD file"
},
"flows": {
"type": "array",
"uniqueItems": false,
"title": "Transport List",
"description": "List of transports used by the application.",
"items": {
"type": "object",
"title": "Flow",
"properties": {
"ips": {
"type": "array",
"uniqueItems": false,
"title": "IP addresses list",
"items": {
"type": "string",
"title": "IPv4 or v6 address"
}
},
"port": {
"type": "integer",
"maximum": 65535,
"minimum": 1,
"title": "port",
"description": "Destination ports used by the transport protocol."
},
"name": {
"type": "string",
"title": "DNS name",
"description": "DNS name that will be used to connect to."
},
"qos": {
"type": "string",
"title": "DSCP",
"description": "Differentiated Services Code Point to use.",
"enum": [
"CS1",
"DF",
"EF",
"AF11",
"AF21",
"AF41",
"AF42",
"AF43",
"AF31",
"AF32",
"AF33"
]
},
"protocols": {
"title": "Transport Protocol List",
"description": "Protocols used.",
"type": "string",
"title": "protocol",
"enum": [
"udp",
"tcp",
"http",
"tls",
"https",
"quic"
]
}
}
}
}
}
}
}
},
"required": [
"domain",
"services"
]
}
IANA Consideration
TODO - register well known URL usage
Security Considerations
TODO - explain importance of HTTPS
Discuss merging with existing ACL
Acknowledgements
Thank you for the contributions from: Cullen Jennings
Development of this Specification
Specification Style
The specification style is "less is more." If a reasonable developer who is fully up on modern web development practices could figure out how write an interoperable implementation after looking at some examples and code and asking a few questions, well that's good enough for us. If you can find it on Wikipedia, we don't need to explain it here.
The build chain allows for an internet draft to be produced from separate parts: a basic draft skeleton that includes narrative text; examples; an API specification; and a schema. Markdown is used for text. RAML and JSON Schema are used to describe the API. Examples play a central role in the specification. The build chain has the goal of being simple and obvious with no black magic.
Following Discussion
We welcome all contributions. Discussion takes place in a few places:
We discuss specific issues on the appropriate issues list in Github. If you don't want to use Github to follow these discussions, you can subscribe to the issue announce list.
Our mailing list is used for confirmation of consensus.
Resolving Issues
Consensus for the resolution of an issue can be established through discussion on the issues list. Once a resolution is found, the issue will be labeled as editor-ready. The editor will then write a pull request suggesting the specific changes to make to resolve the issue. Consensus to adopt the change will be judged on the mailing list. Once a pull request has consensus, the editor will merge it and close the issue.
Pull Requests
We welcome pull requests, both for editorial suggestions and to resolve open issues. In the latter case, please identify the relevant issue.
Please do not use a pull request to open a new design issue; it may not be noticed.
Published Versions
The web site at (https://coopdanger.github.io/spad/) provides an overview of the specification that is focused on a developer audience. However, all the key information to implement the specification that is used to generate the web site is also used to generate and internet draft that can be found at draft-jennings-dispatch-spad-v0.
Periodically the information on the master is branched to a versioned draft branch and the content of that branch is used to produce an updated version of the internet draft. A typical cadence for this is monthly so that the draft can receive broader review.
When the work is at a good point to form a stable version of the API, it is progressed through the IETF publication process with the goal of publishing an RFC. Once approved, the text of the RFC is used to form a released version of the API. The first version would be v1. The current working pre-standard version is always referred to as v0. The API includes the version in the URL so that developers can implement to a specific non-changing specification. Future versions attempt, but do not guarantee, to be backwards-compatible with the previous version.