The main NoRouter process launches the remote subprocesses and transfer L3 packets using their stdio streams.
To translate unprivileged socket syscalls into L3 packets, TCP/IP is implemented in userspace using netstack from gVisor & Fuchsia.
uint8be Magic | 0x42
uint24be Len | Length of the packet in bytes, excluding Magic and Len itself
uint16be Type | 0x0001: L3, 0x0002: JSON (for configuration)
uint16be Reserved | 0x0000
[]byte L3OrJSON | L3 or JSON
JSON messages are used to configure the agent. There are 3 types of messages:
request
are sent from the manager to an agentresult
messages are sent from an agent to the manager as a response to a request
event
are messages sent from an agent to the manager to indicate an independent event.Messages always have the following structure:
{
"type": "request|response|event",
"body": { ... }
}
request
bodyThe request body has the following structure:
{
"id": 1, //Unique ID for this request
"op": "operator", //Currently the only operator supported is "configure"
"args": { ... }
}
configure
message argumentsThe configure
message has the following arguments:
{
"me": "192.168.42.100",
"forwards": [
// See Forward below
],
"others": [
// See IPPortProto below
],
"hostnameMap": {
"hostname": "ip"
},
"http": {
// See HTTP below
},
"socks": {
// See "Socks" below
},
"loopback": {
// See "Loopback" below
},
"statedir": {
"path": "/home/user/.norouter/agent",
"disable": false,
},
"writeEtcHosts": true,
"routes": [
// See "Route" below
],
"nameServers": [
// See IPPortProto below
]
}
Forward
objectThe forward object has the following fields:
{
"listen_port": 23
// ConnectIP can be either IP or hostname.
// Until NoRouter v0.4.0, it had to be IP.
// The field name stil contains "_ip" suffix for compatibility.
"connect_ip": "ip or hostname",
"connect_port": 23,
"proto": "tcp",
}
IPPortProto
objectThe IPPortProto
object contains the following fields:
{
"ip": "192.168.42.100",
"port": 23,
"proto": "tcp"
}
HTTP
object{
"listen": "127.0.0.1:80"
}
Socks
object{
"listen": "127.0.0.1:5000"
}
Loopback
object{
"disable": true
}
Route
object{
"toCIDR": "192.168.95.0/24",
"toHostnameGlob": "*.cloud1.example.com",
"via": "192.168.42.100"
}
result
body{
"request_id": 1,
"op": "configure",
"error": {},
"data": {}
}
configure
result data
{
"features": [
// Listening on multiple loopback IPs such as 127.0.42.101, 127.0.42.102, ...
"loopback",
// TCPv4 stream
"tcp",
// HTTP proxy
"http",
//Disable loopback
"loopback.disable",
//SOCKS
"socks",
//Creating ~/.norouter/agent/hostaliases file
"hostaliases",
//hostaliases using xip.io
"hostaliases.\"xip.io\"",
//Writing /etc/hosts when possible
"etchosts",
// Drawing packets into a specific hosts. Only meaningful for HTTP and SOCKS proxy modes
"routes",
//Built-in DNS
"dns"
],
"version": "norouter version"
}
event
messageThe event JSON looks like this:
{
"type": "event type",
"data": { ... }
}
routeSuggestion
eventThis event suggests a route to the manager. The data
field is as follows:
{
"ip": [
// List of IP addresses
],
"route": "192.168.42.100"
}
Further information: