Browse Source

New repo

master
rune 3 years ago
commit
2fe2aaf350
6 changed files with 288 additions and 0 deletions
  1. +63
    -0
      .gitignore
  2. +0
    -0
     
  3. +14
    -0
      config.json
  4. +157
    -0
      index.js
  5. +18
    -0
      package.json
  6. +36
    -0
      readme.md

+ 63
- 0
.gitignore View File

@@ -0,0 +1,63 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
.DS_Store

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.idea/dyndns.iml
.idea/workspace.xml
.idea/vcs.xml
.idea/dyndns.iml
.idea/modules.xml

+ 0
- 0
View File


+ 14
- 0
config.json View File

@@ -0,0 +1,14 @@
{
"api_key": "AN#EXAMPLE!API$KEY",
"domains":
[
{
"id": 00000,
"name": "example.com"
},
{
"id": 000000,
"name": "example.com"
}
]
}

+ 157
- 0
index.js View File

@@ -0,0 +1,157 @@
#!/usr/bin/env node
var request = require('request');
var fs = require('fs');
var args = process.argv;
var includeIP6 = false;
var IP6;
var updated = false;
try{
var configFileId = process.argv.indexOf('--config');
var config = JSON.parse(fs.readFileSync(process.argv[configFileId+1], 'utf8'));
} catch(error){
console.log(new Date()+' Error reading cofig file. File either missing or malformed.');
process.exit();
};

if(process.argv.indexOf('--list') !== -1 || process.argv.indexOf('-l') !== -1){
var domainInfo = JSON.parse(getDomainInfo());
console.dir(domainInfo, {depth: null, colors: true});
process.exit();
};

function getIPv4() {
var source;
request({
url: 'http://ip4.iurl.no' ,
method: 'GET',
headers: {
'Content-Type': 'application/text'
}
}, function(error, response, body){
if(error){
console.log(new Date()+' Error getting IP '+error.code+' ('+error.host+')');
process.exit();
}
source = body;
});
while(source === undefined) {
require('deasync').runLoopOnce();
}
return source;

};

function getIPv6() {
var source;
request({
url: 'http://ip6.iurl.no' ,
method: 'GET',
headers: {
'Content-Type': 'application/text'
}
}, function(error, response, body){
if(error){
console.log(new Date()+' Error getting IP '+error.code+' ('+error.host+')');
process.exit();
}
source = body;
});
while(source === undefined) {
require('deasync').runLoopOnce();
}
return source;

};

function updateIP(newIP,domain,API_KEY,domainid) {
request({
url: 'https://api.digitalocean.com/v2/domains/'+domain+'/records/' + domainid ,
qs: {"data": newIP},
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+API_KEY
}
}, function(error, response, body){
if(error){
console.log(new Date()+' Error uppdating IP '+error.code);
process.exit();
}
});
}

function getServerIP(i){
var remoteIP;
request({
url: 'https://api.digitalocean.com/v2/domains/'+config.domains[i].name+'/records/' + config.domains[i].id ,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+config.api_key
}
}, function(error, response, body){
try{
var data = (JSON.parse(body));
remoteIP = [data.domain_record.type, data.domain_record.data];
} catch(error){
console.log(new Date()+' Error getting remote IP '+error.code);
process.exit();
}
});
while(remoteIP === undefined) {
require('deasync').runLoopOnce();
}
return remoteIP;
}
function getDomainInfo(){
var domainInfo;
request({
url: 'https://api.digitalocean.com/v2/domains/'+config.domains[0].name+'/records/',
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+config.api_key
}
}, function(error, response, body){
try{
domainInfo = body;
} catch(error){
console.log(new Date()+' Error getting domaininfo '+error.code);
process.exit();
}
});
while(domainInfo === undefined) {
require('deasync').runLoopOnce();
}
return domainInfo;
}
if(process.argv.indexOf('--list') !== -1 || process.argv.indexOf('-l') !== -1){
var domainInfo = JSON.parse(getDomainInfo());
console.dir(domainInfo, {depth: null, colors: true});
process.exit();
};

if(process.argv.indexOf('-ip6') !== -1){
IP6 = getIPv6();
console.log('IP6');
includeIP6 = true
};

var IP4 = getIPv4();


for (var i = 0; i < config.domains.length; i++) {
var dnsIP = getServerIP(i);
if(dnsIP[0] === 'A' && IP4.localeCompare(dnsIP[1]) != 0){
updateIP(IP4,config.domains[i].name,config.api_key,config.domains[i].id);
updated = true;
console.log(new Date()+' Updated IP to '+IP4);
if(includeIP6 && dnsIP[0] === 'AAAA' && IP6.localeCompare(dnsIP[1]) != 0){
updateIP(IP6,config.domains[i].name,config.api_key,config.domains[i].id);
console.log(new Date()+' Updated IP to '+IP6);
};
};
};
if(!updated) console.log('['+new Date()+'] IP not updated.');
process.exit();

+ 18
- 0
package.json View File

@@ -0,0 +1,18 @@
{
"name": "dyndns",
"version": "1.0.5",
"description": "Dynamic DNS and DigitalOcean",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Rune G",
"license": "ISC",
"bin": {
"dyndns": "./index.js"
},
"dependencies": {
"deasync": "^0.1.10",
"request": "^2.81.0"
}
}

+ 36
- 0
readme.md View File

@@ -0,0 +1,36 @@
# DYNDNS
DYNDNS is a small Node CLI (command line) app that updates DNS records on you Digital Ocean account.

### Installation
Clone this repo with `git clone https://gitlab.no/rune/dyndns.git` edit the `config.json` file with your information. To get your API key, log in to your Digital Ocean account and click the API link at the top of the page. Follow the instructions!

If you don't know your subdomains ID, just fill in the parts with `api_key` and `name` and install as described below. The `name` parameter is the top level domain name, eg. `example.com`.

Then run the app `dyndns --config "/path/to/your/config.json" --list`

You will get a JSON looking something like this:

{ id: 000000, <-- The ID
type: 'A',
name: 'YOU SUB DOMAIN',
data: '127.0.0.1', <-- Current IP
priority: null,
port: null,
ttl: 1800,
weight: null,
flags: null,
tag: null },

Place the value of `id` in the correct place(s) in your `config.json` file.

### Use
As describe above, you use the app by runnig it with parameters. You _HAVE_ to include `--config "/path/to/your/config.json"`. The file can be anywhere on the system, but the user running the app should be able to read the file! You can name the file what you like as well.

To include IPv6 add `-ip6` to the command. eg. `dyndns --config "/path/to/your/config.json" -ip6`

I use it with Cron. My crontab contains the line `0 * * * * dyndns --config "/path/to/your/config.json" -ip6 >/dev/null 2>&1`. This runs the command once an hour with no logging. If you want a log, you can use `0 * * * * dyndns --config "/path/to/your/config.json" -ip6 >> /var/log/dyndns.log`in your crontab. This logs all events and errors to a log file (`dyndns.log`). You can of course name your log file as you wish! Digital Ocean has a rate limit on 5000 requests per hour.

### Development



Loading…
Cancel
Save