🎉 No more use a costly dynDNS service to update DNS when your IP changes!
This repo rely on an AWS CDK stack to update your A record in Amazon Route 53 with an API endpoint. It also provides a script to automatically call this API whenever your IP changes.
Suppose you host your own NAS server and want to access it at my-server.com
you have bought on AWS. You need to add a A record to make my-server.com
point to your server public IP. In general, if you rely on an Internet provider to get an IP, you are not guaranteed to have a one static, even if in practice they don't often change (at router reboot for instance). If you want to keep your A record up-to-date when your dynamic IP changes, this project is made for you!
... and it is (almost) free!
Node.js
- An AWS account and credentials (to deploy the CDK stack)
- An hosted zone in AWS Route53, i.e. a domain that you want to point to your own server IP.
-
Install the project
npm install
-
Copy
.env.example
to.env
and fill the valuescp .env.example .env
REGION
: AWS region to deploy your stackDOMAIN_NAME
: name (subdomain.domain.extension) of the A record you want to keep updatedHOSTED_ZONE_ID
: Id of the hosted zone you ownFETCH_IP_API_PATH
: Path of the API to get your current public IP on Internet. Must start with "/".API_INTEGRATION_PATH
: Path of the API to update the A record. Must start with "/".
-
Deploy your stack
npm run deploy
If you need to use an AWS profile, you can run
AWS_PROFILE=my-profile npm run deploy
instead.At the end, you are asked if you want to add a cron job to automatically call the API to update your IP. Answer yes only if you are deploying from the server which will need the update.
-
Make it work!
If you are not deploying from your server, you will need to:
-
copy the folder
scripts/domain-auto-update
(scripts and*.cfg
files) to the target server -
create a cron job to run the script regularly, for instance, once per hour:
0 * * * * /home/my-user/domain-auto-update/update-ip.sh
⚠️ NB: this means that if your IP changes, you will need to wait one hour to get back to your website. Feel free to increase the frequency depending on your needs!
-
-
Make it more secure!
- The API key stored in an unencrypted file. Consider using a password manager, or at least encrypt your session data.
- The APIs are public and unauthenticated (only with an API key for integration API). Consider adding authentication.
- To avoid brute-force or deny-of-wallet attacks, you can choose an API path difficult to guess or even setup a WAF.
You can edit the stack props in bin/auto-update-ip-aws.ts
:
fetchIpApi
(defined by default): if not defined, you will need to call a third party API to get your IP address, like https://api.ipify.org?format=json or https://ipinfo.io/ip.apiIntegration
(defined by default): if not defined, you will need to call the state machine directly through the AWS API. But in this case, it is simpler to call the route53 API directly!user
(not defined by default): if defined, it will create an IAM user allowed to start the state machine synchronously. Not recommended.
Want more options? Feel free to contribute!
The script deploy.sh
does multiple steps:
- Deploy the CloudFormation stack with AWS CDK
- Store the outputs to
.cfg
files inscripts/domain-auto-update
folder - Create a cron job (ask user confirmation) to run
domain-auto-update/update-ip.sh
once a day at 1 am.
The script update-ip.sh
does multiple steps:
- Fetch the current IP address (rely on the url in
get_current_ip_api_url.cfg
file) - Compare it to the latest one stored locally in
current_ip
file - If it has changed, call the API to update the A record in Route 53 (rely on the url in
update_ip_api_url.cfg
file and the API key inapi_key.cfg
)
In case of error when calling the update ip API, the error is kept in a dedicated log file. Keep in mind to delete these error files to avoid to saturate the server.
npm run build
compile typescript to jsnpm run watch
watch for changes and compilenpm run test
perform the jest unit testsnpx cdk deploy
deploy this stack to your default AWS account/regionnpx cdk diff
compare deployed stack with current statenpx cdk synth
emits the synthesized CloudFormation template
The deployed stack uses AWS resources at really low cost, supposing the script is run every hour and the IP changes every day:
Check the IP (every hour)
- API Gateway V2: ~ $0.00083 = 31 days x 24h x 1.11/million requests. NB: free tier the first year
- Lambda: ~ $0.00126 / month = 31 days x 24h x 1000 milliseconds x $0.0000000017 (architecture ARM, memory: 128 MB, region eu-west-1, Jan. 2024)
Update the IP (every day)
- Step Functions: ~ $0.033 / month = 31 days x ($0.000001 (price per request, Jan. 2024) + 1000 milliseconds x 64 MB x $0.00001667 )
- CloudWatch: Free tier = 6 months x 31 days x (2 kB (Step Functions) + 500 B (Lambda)) = 0.5 MB < 5 GB of free tier
- API Gateway V1: ~ $0.00003 = 31 x 3.50/million requests. NB: free tier the first year
- Route 53 : ~ $0.00001 / month = 31 queries x $0.40 per million queries
- CloudFormation : free
- IAM: free
=> TOTAL: < 0.5$ per year!
NB: you need to add the domain name cost (~$12 per year (depending on the name chosen) + $0.50 per hosted zone per month).