Last active
November 23, 2022 21:11
-
-
Save cmdruid/4556564 to your computer and use it in GitHub Desktop.
This is my Ruby DNS Updater script. If you are using an .htaccess file to forward a domain or subdomain to your server's dynamic IP address, this script will make sure that .htaccess file stays updated with your server's current address. This script is an alternative to using services like Dynamic DNS or No-IP. This script uses SFTP and the 'net…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is my Ruby DNS Updater script. If you are using an .htaccess | |
# file to forward a domain or subdomain to your server's dynamic IP | |
# address, this script will make sure that file stays updated with | |
# your server's current address. This script is an alternative to | |
# using services like Dynamic DNS. | |
# This script uses SFTP and the 'net-sftp' gem to connect to your | |
# hosting via a secure connection. You must add all your relevant | |
# information below in order for this script to work. | |
# Make sure the three files (rubydns_updater.rb, rubydns_methods.rb, | |
# config.yml) are in the same directory. Run 'ruby rubydns_updater.rb' | |
# to execute the script. You can use cron to run this script every so | |
# often on a schedule. | |
# In order for this script to work, you need to have the forwarding | |
# configurations already setup in your .htaccess file. An example: | |
# # Ruby DNS Updater | |
# RewriteCond %{HTTP_HOST} ^subdomain.yourdomain.com [NC] | |
# RewriteRule ^(.*)$ 12.34.56.78$1 [L,R=301] | |
# This is my first ruby script, so there's still a lot of room for | |
# improvement. The script works for me, but there might be some | |
# bugs for you. Make sure to backup your .htaccess file before using | |
# this script!! If you have any suggestions, please let me know via | |
# e-mail at: suggestions@karmadragon.me. Thank you! | |
host: yourdoman.com # Your host's FTP/SFTP address | |
user: ftp_username # Your username | |
pass: ftp_password # Your password | |
file_path: /home/public/.htaccess # path to your .htacces file | |
# Your .htaccess file might have multiple IP addresses listed, which | |
# makes it hard to locate the one we need to check. To make sure we | |
# are checking the right address, you need to place a unique header | |
# above the forwarding rules for your server. The script will look | |
# for this header in your .htaccess file and use it as a reference | |
# when checking your address. An example would be "# Ruby DNS Updater" | |
# Leave out any "#" pound signs below, or it will break the script! | |
entry_header: Ruby DNS Updater | |
# The best way to update your .htaccess file is to save the changes | |
# to disk before uploading them to your host. This specifies the | |
# file path used for temporarily saving these changes. By default, | |
# this file is saved in the same local directory as the script. | |
temp_file: rdutemp | |
# We need an external website to give us our public IP. Some websites | |
# offer this service for free. The default site listed below should | |
# work, but if that service ever becomes unreliable, you can specify | |
# another site to use. Depending on the website, you might have to | |
# modify the 'publicAddress' method in the 'rubydns_methods.rb' file | |
# in order to parse the correct address out of the website data. | |
lookup_url: http://remote-ip.herokuapp.com |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/sftp' # The gem net-sftp must be installed | |
require 'net/http' | |
# Finds the current WAN IP of the machine and aborts if not present | |
def publicAddress(website) | |
public_ip = Net::HTTP.get(URI website) | |
if public_ip != nil | |
return public_ip | |
else | |
Kernel::raise("Public address not detected! Maybe you are in a test environment?") | |
# pubic_ip = '12.34.56.78' # If in a testing environment, use this line (and comment out the above line) to set a fake IP | |
end | |
end | |
# Connects to host and downloads file into array, aborts if not present | |
def fileDownload(host, user, pass, path) | |
Net::SFTP.start(host, user, :password => pass) do |sftp| | |
a = [] | |
s = sftp.download!(path) | |
s != nil ? s.each_line {|line| a.push line} : Kernel::raise("File download returned nil!") | |
puts "Reading settings from host..." | |
return a | |
end | |
end | |
# Parses file contents for header and returns IP, aborts if not present | |
def retrieveAddress(array, header) | |
i = array.index{|s| s.include?(header)} | |
i != nil ? i = i + 2 : Kernel::raise("Header not found in file!") | |
ip = array[i] | |
return ip[/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/] | |
end | |
# Write changes to a local file | |
def changeAddress(array, old_address, new_address, tempfile) | |
array != nil ? nil : Kernel::raise("Array is not supposed to equal nil!") | |
s = array.join.gsub(old_address, new_address) | |
File.exist?(tempfile) ? File.delete(tempfile) : nil | |
File.open(tempfile, 'w') {|f| f.write(s)} | |
puts "Changes saved and awaiting upload..." | |
end | |
# Upload temporary file to server | |
def fileUpload (host, user, pass, path, tempfile) | |
File.exist?(tempfile) ? nil : Kernel::raise("Cannot write to server, local file does not exist!") | |
Net::SFTP.start(host, user, :password => pass) {|sftp| sftp.upload!(tempfile, path)} | |
puts "Uploaded new settings to host!" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is my Ruby DNS Updater script. If you are using an .htaccess | |
# file to forward a domain or subdomain to your server's dynamic IP | |
# address, this script will make sure that file stays updated with | |
# your server's current address. This script is an alternative to | |
# using services like Dynamic DNS. | |
# This script uses SFTP and the 'net-sftp' gem to connect to your | |
# hosting via a secure connection. You must add your FTP login | |
# information to the config.yml file in order for this script to | |
# work. | |
# Make sure the three files (rubydns_updater.rb, rubydns_methods.rb, | |
# config.yml) are in the same directory. Run 'ruby rubydns_updater.rb' | |
# to execute the script. You can use cron to run this script every so | |
# often on a schedule. | |
# This is my first ruby script, so there's still a lot of room for | |
# improvement. The script works for me, but there might be some | |
# bugs for you. Make sure to backup your .htaccess file before using | |
# this script!! | |
# If you have any suggestions, please let me know via e-mail at | |
# suggestions@karmadragon.me. Thank you! | |
# List of things to do: | |
# * Add better error checking for the config file | |
# * Make better use of 'rescue' and improve error handling | |
# * Add an 'ensure' method to close the rdutmp file after write | |
# * Add an 'ensure' method to close the SFTP sessions | |
# * Add a method for generating the proper forwarding rules for | |
# you (if they don't exist) and appending it to your .htaccess. | |
require 'yaml' | |
require_relative 'rubydns_methods' | |
# Loads our configuration file | |
File.exist?('config.yml') ? nil : Process::abort("Couldn't read config.yml! Aborting!") | |
settings = YAML::load_file "config.yml" | |
puts "Configuration loaded!" | |
reCheck = false | |
loopCheck = 0 | |
while reCheck == false && loopCheck < 2 | |
# Download the file and set the addresses to values | |
fileArray = fileDownload(settings['host'], settings['user'], settings['pass'], settings['file_path']) | |
public_address = publicAddress(settings['lookup_url']) | |
forward_address = retrieveAddress(fileArray, settings['rules_header']) | |
# Compare the addresses to see if they match. If not, update new address to server. | |
if public_address != forward_address && public_address != nil && forward_address != nil | |
puts "Forwarding address #{forward_address} doesn't match server! (#{public_address})" | |
changeAddress(fileArray, forward_address, public_address, settings['temp_file']) | |
fileUpload(settings['host'], settings['user'], settings['pass'], settings['file_path'], settings['temp_file']) | |
puts loopCheck < 2 ? "Verifying the changes..." : "Unable to verify! Please check your forwarding settings!" | |
loopCheck += 1 | |
elsif forward_address == public_address && forward_address != nil | |
puts "Forwarding address matches server with #{forward_address}! We're good!" | |
reCheck = true | |
else | |
# If this message gets triggered, one of the addresses returned nil, which is bad | |
puts "Something went wrong! Detected forwarding address (#{forward_address}) and public address (#{public_address})!" | |
recheck = true | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment