updated the documentation and validation for DDNS settings
This commit is contained in:
parent
cfaa8d4959
commit
6b2b91ba26
47
README.md
47
README.md
|
@ -403,17 +403,50 @@ tunnel_server:
|
||||||
- 'api.tunnel.example.com'
|
- 'api.tunnel.example.com'
|
||||||
```
|
```
|
||||||
|
|
||||||
### tunnel
|
### DDNS
|
||||||
|
|
||||||
The tunnel client is meant to be run from behind a firewalls, carrier-grade NAT,
|
The DDNS module watches the network environment of the unit and makes sure the
|
||||||
or otherwise inaccessible devices to allow them to be accessed publicly on the
|
device is always accessible on the internet using the domains listed in the
|
||||||
internet.
|
config. If the device has a public address or if it can automatically set up
|
||||||
|
port forwarding the device will periodically check its public address to ensure
|
||||||
|
the DNS records always point to it. Otherwise it will to connect to a tunnel
|
||||||
|
server and set the DNS records to point to that server.
|
||||||
|
|
||||||
### ddns
|
The `loopback` setting specifies how the unit will check its public IP address
|
||||||
|
and whether connections can reach it. Currently only `tunnel@oauth3.org` is
|
||||||
|
supported. If the loopback setting is not defined it will default to using
|
||||||
|
`oauth3.org`.
|
||||||
|
|
||||||
TODO
|
The `tunnel` setting can be used to specify how to connect to the tunnel.
|
||||||
|
Currently only `tunnel@oauth3.org` is supported. The token specified in the
|
||||||
|
`tunnel` setting will be used to acquire the tokens that are used directly with
|
||||||
|
the tunnel server. If the tunnel setting is not defined it will default to try
|
||||||
|
using the tokens in the modules for the relevant domains.
|
||||||
|
|
||||||
### mdns
|
If a particular DDNS module has been disabled the device will still try to set
|
||||||
|
up port forwarding (and connect to a tunnel if that doesn't work), but the DNS
|
||||||
|
records will not be updated to point to the device. This is to allow a setup to
|
||||||
|
be tested before transitioning services between devices.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ddns:
|
||||||
|
disabled: false
|
||||||
|
loopback:
|
||||||
|
type: 'tunnel@oauth3.org'
|
||||||
|
domain: oauth3.org
|
||||||
|
tunnel:
|
||||||
|
type: 'tunnel@oauth3.org'
|
||||||
|
token: user_token_id
|
||||||
|
modules:
|
||||||
|
- type: 'dns@oauth3.org'
|
||||||
|
token: user_token_id
|
||||||
|
domains:
|
||||||
|
- www.example.com
|
||||||
|
- api.example.com
|
||||||
|
- test.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### mDNS
|
||||||
|
|
||||||
enabled by default
|
enabled by default
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,6 @@ function fillConfig(config, args) {
|
||||||
config.debug = config.debug || args.debug;
|
config.debug = config.debug || args.debug;
|
||||||
|
|
||||||
config.socks5 = config.socks5 || { enabled: false };
|
config.socks5 = config.socks5 || { enabled: false };
|
||||||
config.ddns = config.ddns || { enabled: false };
|
|
||||||
|
|
||||||
// Use Object.assign to copy any real config values over the default values so we can
|
// Use Object.assign to copy any real config values over the default values so we can
|
||||||
// easily make sure all the fields we need exist .
|
// easily make sure all the fields we need exist .
|
||||||
|
@ -338,6 +337,7 @@ function fillConfig(config, args) {
|
||||||
fillComponent('tcp', true);
|
fillComponent('tcp', true);
|
||||||
fillComponent('http', false);
|
fillComponent('http', false);
|
||||||
fillComponent('tls', false);
|
fillComponent('tls', false);
|
||||||
|
fillComponent('ddns', false);
|
||||||
|
|
||||||
config.device = { hostname: require('os').hostname() };
|
config.device = { hostname: require('os').hostname() };
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,16 @@ tunnel_server:
|
||||||
- 'tunnel.localhost.com'
|
- 'tunnel.localhost.com'
|
||||||
|
|
||||||
ddns:
|
ddns:
|
||||||
enabled: true
|
loopback:
|
||||||
domains:
|
type: 'tunnel@oauth3.org'
|
||||||
- www.example.com
|
domain: oauth3.org
|
||||||
- api.example.com
|
tunnel:
|
||||||
- test.example.com
|
type: 'tunnel@oauth3.org'
|
||||||
|
token: user_token_id
|
||||||
|
modules:
|
||||||
|
- type: 'dns@oauth3.org'
|
||||||
|
token: user_token_id
|
||||||
|
domains:
|
||||||
|
- www.example.com
|
||||||
|
- api.example.com
|
||||||
|
- test.example.com
|
||||||
|
|
|
@ -48,6 +48,16 @@ var moduleSchemas = {
|
||||||
, challenge_type: { type: 'string' }
|
, challenge_type: { type: 'string' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the dns control modules for DDNS
|
||||||
|
, dns_oauth3_org: {
|
||||||
|
name: 'dns@oauth3.org'
|
||||||
|
, type: 'object'
|
||||||
|
, required: [ 'token' ]
|
||||||
|
, properties: {
|
||||||
|
token: { type: 'string' }
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// forward is basically the same as proxy, but specifies the relevant incoming port(s).
|
// forward is basically the same as proxy, but specifies the relevant incoming port(s).
|
||||||
// only allows for the raw transport layers (TCP/UDP)
|
// only allows for the raw transport layers (TCP/UDP)
|
||||||
|
@ -57,6 +67,10 @@ moduleSchemas.forward.properties.ports = { type: 'array', items: portSchema };
|
||||||
|
|
||||||
Object.keys(moduleSchemas).forEach(function (name) {
|
Object.keys(moduleSchemas).forEach(function (name) {
|
||||||
var schema = moduleSchemas[name];
|
var schema = moduleSchemas[name];
|
||||||
|
if (schema.name) {
|
||||||
|
name = schema.name;
|
||||||
|
delete schema.name;
|
||||||
|
}
|
||||||
schema.id = '/modules/'+name;
|
schema.id = '/modules/'+name;
|
||||||
schema.required = ['id', 'type'].concat(schema.required || []);
|
schema.required = ['id', 'type'].concat(schema.required || []);
|
||||||
schema.properties.id = { type: 'string' };
|
schema.properties.id = { type: 'string' };
|
||||||
|
@ -72,12 +86,13 @@ var moduleRefs = {
|
||||||
, tls: [ 'proxy', 'acme' ].map(toSchemaRef)
|
, tls: [ 'proxy', 'acme' ].map(toSchemaRef)
|
||||||
, tcp: [ 'forward' ].map(toSchemaRef)
|
, tcp: [ 'forward' ].map(toSchemaRef)
|
||||||
, udp: [ 'forward' ].map(toSchemaRef)
|
, udp: [ 'forward' ].map(toSchemaRef)
|
||||||
|
, ddns: [ 'dns@oauth3.org' ].map(toSchemaRef)
|
||||||
};
|
};
|
||||||
|
|
||||||
function addDomainRequirement(itemSchema) {
|
function addDomainRequirement(itemSchema) {
|
||||||
itemSchema.required = (itemSchema.required || []).concat('domains');
|
itemSchema.required = (itemSchema.required || []).concat('domains');
|
||||||
itemSchema.properties = itemSchema.properties || {};
|
itemSchema.properties = itemSchema.properties || {};
|
||||||
itemSchema.domains = { type: 'array', items: { type: 'string' }, minLength: 1};
|
itemSchema.properties.domains = { type: 'array', items: { type: 'string' }, minLength: 1};
|
||||||
return itemSchema;
|
return itemSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +108,7 @@ var domainSchema = {
|
||||||
, properties: {
|
, properties: {
|
||||||
tls: { type: 'array', items: { oneOf: moduleRefs.tls }}
|
tls: { type: 'array', items: { oneOf: moduleRefs.tls }}
|
||||||
, http: { type: 'array', items: { oneOf: moduleRefs.http }}
|
, http: { type: 'array', items: { oneOf: moduleRefs.http }}
|
||||||
|
, ddns: { type: 'array', items: { oneOf: moduleRefs.ddns }}
|
||||||
}
|
}
|
||||||
, additionalProperties: false
|
, additionalProperties: false
|
||||||
}
|
}
|
||||||
|
@ -158,7 +174,23 @@ var mdnsSchema = {
|
||||||
var ddnsSchema = {
|
var ddnsSchema = {
|
||||||
type: 'object'
|
type: 'object'
|
||||||
, properties: {
|
, properties: {
|
||||||
enabled: { type: 'boolean' }
|
loopback: {
|
||||||
|
type: 'object'
|
||||||
|
, required: [ 'type', 'domain' ]
|
||||||
|
, properties: {
|
||||||
|
type: { type: 'string', const: 'tunnel@oauth3.org' }
|
||||||
|
, domain: { type: 'string'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, tunnel: {
|
||||||
|
type: 'object'
|
||||||
|
, required: [ 'type', 'token' ]
|
||||||
|
, properties: {
|
||||||
|
type: { type: 'string', const: 'tunnel@oauth3.org' }
|
||||||
|
, token: { type: 'string'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, modules: { type: 'array', items: { oneOf: moduleRefs.ddns }}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var socks5Schema = {
|
var socks5Schema = {
|
||||||
|
@ -265,6 +297,7 @@ class DomainList extends IdList {
|
||||||
dom.modules = {
|
dom.modules = {
|
||||||
http: new ModuleList((dom.modules || {}).http)
|
http: new ModuleList((dom.modules || {}).http)
|
||||||
, tls: new ModuleList((dom.modules || {}).tls)
|
, tls: new ModuleList((dom.modules || {}).tls)
|
||||||
|
, ddns: new ModuleList((dom.modules || {}).ddns)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -280,14 +313,16 @@ class DomainList extends IdList {
|
||||||
var modLists = {
|
var modLists = {
|
||||||
http: new ModuleList()
|
http: new ModuleList()
|
||||||
, tls: new ModuleList()
|
, tls: new ModuleList()
|
||||||
|
, ddns: new ModuleList()
|
||||||
};
|
};
|
||||||
// We add these after instead of in the constructor to run the validation and manipulation
|
// We add these after instead of in the constructor to run the validation and manipulation
|
||||||
// in the ModList add function since these are all new modules.
|
// in the ModList add function since these are all new modules.
|
||||||
if (dom.modules && Array.isArray(dom.modules.http)) {
|
if (dom.modules) {
|
||||||
dom.modules.http.forEach(modLists.http.add, modLists.http);
|
Object.keys(modLists).forEach(function (key) {
|
||||||
}
|
if (Array.isArray(dom.modules[key])) {
|
||||||
if (dom.modules && Array.isArray(dom.modules.tls)) {
|
dom.modules[key].forEach(modLists[key].add, modLists[key]);
|
||||||
dom.modules.tls.forEach(modLists.tls.add, modLists.tls);
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.id = require('crypto').randomBytes(4).toString('hex');
|
dom.id = require('crypto').randomBytes(4).toString('hex');
|
||||||
|
@ -306,6 +341,7 @@ class ConfigChanger {
|
||||||
this.tls.modules = new ModuleList(this.tls.modules);
|
this.tls.modules = new ModuleList(this.tls.modules);
|
||||||
this.tcp.modules = new ModuleList(this.tcp.modules);
|
this.tcp.modules = new ModuleList(this.tcp.modules);
|
||||||
this.udp.modules = new ModuleList(this.udp.modules);
|
this.udp.modules = new ModuleList(this.udp.modules);
|
||||||
|
this.ddns.modules = new ModuleList(this.ddns.modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(update) {
|
update(update) {
|
||||||
|
@ -314,7 +350,7 @@ class ConfigChanger {
|
||||||
if (update.domains) {
|
if (update.domains) {
|
||||||
update.domains.forEach(self.domains.add, self.domains);
|
update.domains.forEach(self.domains.add, self.domains);
|
||||||
}
|
}
|
||||||
[ 'http', 'tls', 'tcp', 'udp' ].forEach(function (name) {
|
[ 'http', 'tls', 'tcp', 'udp', 'ddns' ].forEach(function (name) {
|
||||||
if (update[name] && update[name].modules) {
|
if (update[name] && update[name].modules) {
|
||||||
update[name].modules.forEach(self[name].modules.add, self[name].modules);
|
update[name].modules.forEach(self[name].modules.add, self[name].modules);
|
||||||
delete update[name].modules;
|
delete update[name].modules;
|
||||||
|
|
Loading…
Reference in New Issue