A Dynamic DNS system used to update DNS records based on Python.
This Python project contains the following three modules:
-
Upstream
The upstream unit has an ever-changing IP. To dynamically tracking the upstream machine's IP, we need to execute the
client/upstream
Python module on the upstream unit. Once theclient/upstream
module is executed, it either sends aGet /silos/silo_id
request to retrieve the IP of itself, or attempts to get an IP address from one of the network adaptors. If the IP address has changed, it will go ahead sending aPUT /silos/silo_id
request to update DNS records under the silo specified inclient/config.yml
.(Here, aSilo
means a group of DNS records. Each silo has a unique ID and one or more DNS record entry, and each DNS record entry contains a hostname and an IP address.) -
Downstream
The downstream unit usually needs to communiate with the upstream unit, so it needs to know the current IP address of the upstream unit. To achieve this, we need to executed the
client/downstream
module on the downstream unit. Once it is executed, it can get all DNS records of a silo. And then, it will modify the hosts file to update relevant DNS records on the downstream unit. -
Server
The server is the "central hub" where all DNS records are stored, updated, and communicated. Thus, it should have a static IP. Once the
server
module is executed on the server, it essentially starts a Web Service provider that constantly communiates with the upstream and downstream units.In parcicular, a YAML file named
client/config.yml
are located in the server module to store DB connection info. The server module uses web framework 'Flask' to build RESTful APIs, so that we can get client IP, get silos list or maintain each silo by these APIs. For more details about RESTful APIs inserver
, please read the "RESTful API Specification" section.
-
Make sure Python 3.x runtime is properly installed on all the paticipating units (i.e. the server, the upstream, and the downstream unit). Plus, a relational database should installed on the server unit.
-
Modify the
/server/config.yml
file to change DB setting, and/client/config.yml
file to specify Server and DNS details -
Execute following commands to install required Python packages and initialize your own database on server side:
pip install -r requirements.txt flask --app=server.app initdb
-
Execute following commands:
cd pyDDNS set PYTHONPATH=%PYTHONPATH%;. python server/app.py
-
Open your browser, visit
http://localhost:81/ping
, and you would get the ping-pong JSON.That means your server successfully started up -
Alternatively, use
curl
to get it:curl -X GET http://localhost:81/ping
On the downstream machine, execute following commands
cd pyDDNS
set PYTHONPATH=%PYTHONPATH%;.
python client/downstream.py
On the upstream machine, execute following commands:
cd pyDDNS
set PYTHONPATH=%PYTHONPATH%;.
python client/upstream.py
The set
command above is for Windows only. But under Linux, the command, reference, and separator for the PYTHONPATH
environment are different.
-
Windows
-
Use the
set
command; -
Use
%
to refer the environment variable; -
Use
;
as the separator; -
Example:
set PYTHONPATH=%PYTHONPATH%;.
-
-
Linux
-
Use the
export
command; -
Use
$
to refer the environment variable; -
Use
:
as the separator; -
Example:
export PYTHONPATH=$PYTHONPATH:.
-
Please use the correct command to set PYTHONPATH according to your system environment.
If you want to run the system automatically, please read this section and follow the instructions to set your computer settings.
Task Scheduler enables you to automatically perform routine tasks on a chosen computer. Task Scheduler does this by monitoring whatever criteria you choose to initiate the tasks and then executing the tasks when the criteria is met.
- Open Task Scheduler by clicking the Start button, then click following items: Control Panel, System and Security, Administrative Tools, and finally Task Scheduler.
- Click the Action menu, and then click Create Basic Task.
- Type a name for the task and an optional description, and then click Next.
- Do one of the following:
- To select a schedule based on the calendar, click Daily, Weekly, Monthly, or One time, click Next; specify the schedule you want to use, and then click Next.
- To select a schedule based on common recurring events, click When the computer starts or When I log on, and then click Next.
- To select a schedule based on specific events, click When a specific event is logged, click Next; specify the event log and other information using the drop-down lists, and then click Next.
- To schedule a program to start automatically, click Start a program, and then click Next.
- Click Browse to find the program you want to start, and then click Next.
- Click Finish.
The operations above are performed in Windows 7 environment. The procedure for other versions of Windows may be differnt. For further details on Task Scheduler, please click here.
Cron job is used to schedule commands to be executed periodically. You can setup commands or scripts, which will repeatedly run at a scheduled time. Cron is one of the most useful tool in Linux.
To edit your crontab file, type the following command at the Linux shell prompt:
$ crontab -e
The syntax is:
1 2 3 4 5 /path/to/command
Where,
- 1: Minute (0-59)
- 2: Hours (0-23)
- 3: Day (0-31)
- 4: Month (0-12 [12 == December])
- 5: Day of the week(0-7 [7 or 0 == sunday])
- /path/to/command - Script or command name to schedule
Operators allow you to specifying multiple values in a field. There are three types operators:
- The asterisk (*) : indicates all possible values for a field
- The comma (,) : usually used between a list of values
- The dash (-) : specifies a range of values
- The separator (/) : specifies a step value
For example, if we want client/downstream.py
to be executed every 2 hours, we should enter:
0 */2 * * * /path/to/command/client/downstream.py
For more details about cron, please click here.
This API does not provide any meaningful result, but the system administrator or end users can use it to see if the server is working.
-
Request
GET /ping
-
Parameters
None
-
JSON Result
{"message": "PONG"}
-
Curl Example
curl -X GET http://localhost:5000/ping
This RESTful API allows you to get your current public IP address. Plese note that this API may not return expected result when the API call are invoked through an HTTP proxy .
-
Request
GET /ip
-
Parameters
None
-
JSON Result
{"ip": "127.0.0.1"}
-
Curl Example
curl -X GET http://localhost:5000/ip
This RESTful API allows you to get a complete silos list.
-
Request
GET /silos
-
Parameters
None
-
JSON Result
[ {"id": "silo1", "dnsrecords": [ {"hostname": "dbserver", "ip": "127.0.0.1"}, {"hostname": "webserver", "ip": "127.0.0.1"} ]}. {"id": "silo2", "dnsrecords": [ {"hostname": "dbserver", "ip": "127.0.0.1"}, {"hostname": "webserver", "ip": "127.0.0.1"} ]} ]
-
Curl Example
curl -X GET http://localhost:5000/silos
This RESTful API allows you to get a single silo by silo ID.
-
Request
GET /silos/silo_id
-
Parameters
silo_id
-
JSON Result
{"id": "silo1", "dnsrecords": [ {"hostname": "dbserver", "ip": "127.0.0.1"}, {"hostname": "webserver", "ip": "127.0.0.1"} ]}
-
Curl Example
curl -X GET http://localhost:5000/silos/silo1
This RESTful API allows you to update a single silo by silo ID.
-
Request
PUT /silos/silo_id
-
Parameters
silo_id
-
JSON Result
{"id": "silo1", "dnsrecords": [ {"hostname": "dbserver", "ip": "127.0.0.1"}, {"hostname": "webserver", "ip": "127.0.0.1"} ]}
-
Curl Example
curl -X PUT http://localhost:5000/silos/silo1
This RESTful API allows you to delete a single silo by silo ID.
-
Request
DELETE /silos/silo_id
-
Parameters
silo_id
-
JSON Result
None
-
Curl Example
curl -X DELETE http://localhost:5000/silos/silo1