Merge branch 'beta'
This commit is contained in:
commit
1dcb132af5
30
.gitignore
vendored
30
.gitignore
vendored
@ -1,3 +1,31 @@
|
||||
*.config
|
||||
*.conf
|
||||
!dist.config.sample
|
||||
nsupdate.sh.log
|
||||
*.log
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
93
README.md
93
README.md
@ -1,67 +1,78 @@
|
||||
# Nameserver update for INWX (nsupdate)
|
||||
|
||||
This shell script implements [dynamic DNS](https://en.wikipedia.org/wiki/Dynamic_DNS) using the [DomRobot XML-RPC API](https://www.inwx.de/de/help/apidoc/f/ch02s13.html#nameserver.updateRecord) by [INWX](https://www.inwx.de/).
|
||||
This script can update nameserver entries with your current WAN IPv4 and IPv6 addresses.
|
||||
It uses the `nameserver.updateRecord` method of the API.
|
||||
This script can update nameserver entries with your current WAN IPv4 and IPv6 addresses.
|
||||
|
||||
advantage: You don't need payed dynDNS-accounts for multiple domains.
|
||||
disadvantage: The minimum TTL is 300 (5 minutes). The dynDNS-Service allowes 60 (1 minute).
|
||||
This way you can update your DNS records directly utilizing the INWX API and don't need the payed DynDNS option from INWX which uses DDNS over HTTP/S.
|
||||
|
||||
There exists the `dyndns.updateRecord` method in the DomRobot API. Therefore you need a DynDNS-account by INWX. If you need this option, feel free to change the script to your needs.
|
||||
The minimum TTL when using the API is 300 seconds. The paid DynDNS option can go as low as 60 seconds.
|
||||
|
||||
## Requirements
|
||||
|
||||
In order to run the script you need to have installed the following command line tools:
|
||||
_nsupdate_ is fully POSIX compliant and should work in every shell.
|
||||
|
||||
- _curl_
|
||||
- _awk_
|
||||
- _nslookup_ or _drill_
|
||||
Nevertheless it has some dependencies to use it:
|
||||
- _xmllint_ (Look for _libxml2-utils_ (Debian, Ubuntu) or _libxml2_ (FreeBSD, CentOS)). It's used for Getting the ID and the current IP from the INWX API. This is the recommended way.
|
||||
|
||||
recommendation
|
||||
- If you don't have installed _xmllint_, you need either _nslookup_ or _drill_ to query the nameserver for the current IP. In this case you must define the specific INWX IDs in the config files for your INWX records.
|
||||
|
||||
- _xmllint_
|
||||
Look for _libxml2-utils_ (Debian, Ubuntu) or
|
||||
_libxml2_ (FreeBSD, CentOS),
|
||||
_xmlstarlet_ is also available on many systems and it gets _xmllint_.
|
||||
If _xmllint_ is not on your system you have to set the domain record id in your config files.
|
||||
- A hard requirement is _curl_ as it's used to make the API calls.
|
||||
|
||||
Note: 2-Factor-Authentification method (2FA) is not implemented.
|
||||
Note: 2-Factor-Authentification method (2FA) is not supported when using the INWX API.
|
||||
|
||||
## Installation
|
||||
|
||||
Simply clone this project or download the `master.zip` and extract it, e.g., using `wget` and `7z x master.zip`.
|
||||
|
||||
Place your config files in the `nsupdate.d` folder. A `dist.config.sample` file with all possible options is provided. At least one config file needs to exist, ending with `.config`.
|
||||
All .config files (one for each dns-record) will be processed by looping them.
|
||||
Move the included _nsupdate directory_, which holds the configuration files, to _/usr/local/etc/_ (see the config section if you want to use another path) and nsupdate.sh anywhere in your $PATH (e.g. /_usr/local/bin/_ or _~/bin/_).
|
||||
|
||||
### Log directory
|
||||
The default log directory is _/var/log/nsupdate_. You have to create this directory and ensure write access for the user that runs _nsupdate_ (e.g. `sudo mkdir -p /var/log/nsupdate && sudo chown $USER /var/log/nsupdate`). When you want to use another path, see the config section.
|
||||
|
||||
## Configuration
|
||||
|
||||
### nsupdate.conf
|
||||
|
||||
_nsupdate.conf_ is the main configuration file for _nsupdate_. Here you can set global defaults which can be used for all DNS records (e.g. INWX credentials, TTL, record type). These can be overwritten in the configuration files for your DNS records. There are also options to set the paths that are used by _nsupdate_.
|
||||
|
||||
See _/usr/local/etc/nsupdate/nsupdate.conf.dist_ for all available options and their defaults.
|
||||
|
||||
All options except the INWX credentials have sensible defaults and can be left untouched if they suit your needs.
|
||||
|
||||
### Configuring DNS records
|
||||
|
||||
The configuration files for your DNS belong to _/usr/local/etc/nsupdate/conf.d/_.
|
||||
|
||||
If you configured your INWX credentials in _nsupdate.conf_ and the other defaults are fine for your use case, all you have to do is to set **$MAIN_DOMAIN** and **$DOMAIN**.
|
||||
|
||||
See _/usr/local/etc/nsupdate/conf.d/sub.example.com_AAAA.conf.dist_ for an example with all available options.
|
||||
|
||||
### Backwards compatibility
|
||||
[TODO] Backwards compatibility
|
||||
|
||||
For home.example.com you may create:
|
||||
A-Record Update configuration e.g.
|
||||
`myV4.config`
|
||||
```
|
||||
INWX_USER="USERNAME"
|
||||
INWX_PASS="PASSWORD"
|
||||
MAIN_DOMAIN="example.de"
|
||||
DOMAIN="home.example.de"
|
||||
TYPE="A"
|
||||
IP_CHECK_SITE="https://api.ipify.org"
|
||||
```
|
||||
AAAA-Record Update configuration e.g.
|
||||
`myV6.config`
|
||||
```
|
||||
INWX_USER="USERNAME"
|
||||
INWX_PASS="PASSWORD"
|
||||
MAIN_DOMAIN="example.de"
|
||||
DOMAIN="home.example.de"
|
||||
TYPE="AAAA"
|
||||
IP_CHECK_SITE="https://api6.ipify.org"
|
||||
```
|
||||
|
||||
## Run nsupdate by cron
|
||||
With `crontab -e` you can add the following line for running the script every 5 minutes:
|
||||
`*/5 * * * * bash /home/$USER/nsupdate/nsupdate.sh`
|
||||
|
||||
The best way to use _nsupdate_ is by setting up a cron job (e.g. by running `crontab -e`).
|
||||
|
||||
To run the script every 5 minutes and suppress the output you can write something like `*/5 * * * * /usr/local/bin/nsupdate.sh > /dev/null 2>&1`.
|
||||
|
||||
## Changelog
|
||||
|
||||
**2022-10-18**
|
||||
|
||||
- Completly rewritten. nsupdate is now a POSIX compliant /bin/sh script 👍🏻
|
||||
- Backwards compatibility should be given (please test and report bugs!).
|
||||
- If using the xmmlint method, now also the IP for a record is retrieved this way
|
||||
- WAN IP now is only checked once per session instead of every time a new config is processed.
|
||||
- The script now automagically determines the best way to get the needed data (xmllint, nslookup, drill) and has some nice output options.
|
||||
- The code is now structured in functions which makes it more maintainable and modular.
|
||||
- Avoid using awk and get rid of dependency
|
||||
|
||||
**2021-12-11**
|
||||
|
||||
- Added the possibility to retrieve the WAN IP by a shell command (e.g. SSHing into your router and get the IP of the WAN interface)
|
||||
|
||||
**2020-07-03**
|
||||
|
||||
- Rearranged config.sample
|
||||
|
@ -1,56 +0,0 @@
|
||||
# nsupdate.config
|
||||
# The nsupdate.sh is processing all .config files by looping.
|
||||
# If you want to update an IPv4 and an IPv6 record you need two config files.
|
||||
|
||||
# Login credentials for the inwx admin interface
|
||||
INWX_USER="USERNAME"
|
||||
INWX_PASS="PASSWORD"
|
||||
|
||||
# The domain that you want to update AND its main/zone domain
|
||||
# The MAIN_DOMAIN is needed for the API-Request to get the record ID
|
||||
MAIN_DOMAIN="example.com"
|
||||
DOMAIN="home.example.com"
|
||||
# If it is the same domain:
|
||||
#DOMAIN="example.com"
|
||||
|
||||
# Set the record type to either A, AAAA or MX
|
||||
# For MX you would normaly just set a domain and not an ip, so this is just a option.
|
||||
TYPE="A"
|
||||
|
||||
# From which site should we get your WAN IP?
|
||||
# Note that for IPv4 or IPv6 the IP_CHECK_SITE should work
|
||||
# e.g. for IPv4 use api.ipify.org and for IPv6 use api6.ipify.org
|
||||
IP_CHECK_SITE="https://api.ipify.org/"
|
||||
|
||||
# TTL: Time to Live
|
||||
# default TTL setting by inwx is 3600 (1 hour)
|
||||
# minimum TTL allowed by inwx is 300 (5 minutes) for regular nameserver record updates
|
||||
# In this script the defaul setting is 300.
|
||||
#TTL=300
|
||||
|
||||
# Log file name.
|
||||
LOG="$0.log"
|
||||
|
||||
# Suppress all messages and deactivates logging.
|
||||
# default is SILENT="NO"
|
||||
#SILENT="YES"
|
||||
|
||||
# Use drill instead of nslookup for hostname lookup.
|
||||
#USE_DRILL="YES"
|
||||
|
||||
# The domain-Record-ID from the inwx interface.
|
||||
# If the command-line-tool "xmllint" is working you dont need to set this option.
|
||||
# Note: You can get the specific domain record ID while editing the given nameserver entry by
|
||||
# inspecting the target URL of the save button.
|
||||
#INWX_DOMAIN_ID="123456789"
|
||||
|
||||
# Provide a command to get the Ip instead of using Curl
|
||||
#IPCOMMAND=""
|
||||
|
||||
# Use IPv6 connection.
|
||||
# deprecated option for backward compatibility, use TYPE instead
|
||||
#IPV6="NO"
|
||||
|
||||
# Update an MX record.
|
||||
# deprecated option for backward compatibility, use TYPE instead
|
||||
#MX="NO"
|
501
nsupdate.sh
501
nsupdate.sh
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Update a nameserver entry at inwx with the current WAN IP (DynDNS)
|
||||
|
||||
@ -24,228 +24,301 @@
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# check required tools
|
||||
command -v curl &> /dev/null || { echo >&2 "I require curl but it's not installed. Note: all needed items are listed in the README.md file."; exit 1; }
|
||||
command -v awk &> /dev/null || { echo >&2 "I require awk but it's not installed. Note: all needed items are listed in the README.md file."; exit 1; }
|
||||
command -v drill &> /dev/null || command -v nslookup &> /dev/null || { echo >&2 "I need drill or nslookup installed. Note: all needed items are listed in the README.md file."; exit 1; }
|
||||
command -v xmllint &> /dev/null || { echo >&2 "I recommend xmllint but it's not installed. Note: all needed items are listed in the README.md file."; NO_XMLLINT="true";}
|
||||
# Print and log messages when verbose mode is on
|
||||
# Usage: chat [0|1|2|3] MESSAGE
|
||||
## 0 = regular output
|
||||
## 1 = error messages
|
||||
## 2 = verbose messages
|
||||
## 3 = debug messages
|
||||
|
||||
LOG=$0.log
|
||||
SILENT=NO
|
||||
chat () {
|
||||
messagetype=$1
|
||||
message=$2
|
||||
log=$nsupdate_log_dir/$nsupdate_log_file
|
||||
log_date=$(date "+$log_date_format")
|
||||
|
||||
if [ $messagetype = 0 ]; then
|
||||
echo "[$log_date] [INFO] $message" | tee -a $log ;
|
||||
fi
|
||||
#
|
||||
if [ $messagetype = 1 ]; then
|
||||
echo "[$log_date] [ERROR] $message" | tee -a $log ; exit 1;
|
||||
fi
|
||||
|
||||
if [ $messagetype = 2 ] && [ "$VERBOSE" = true ]; then
|
||||
echo "[$log_date] [INFO] $message" | tee -a $log
|
||||
fi
|
||||
|
||||
if [ $messagetype = 3 ] && [ "$DEBUG" = true ]; then
|
||||
echo "[$log_date] [DEBUG] $message" | tee -a $log
|
||||
fi
|
||||
}
|
||||
|
||||
# Load config file, set default variables and get wan IP
|
||||
# Usage: init
|
||||
init () {
|
||||
|
||||
nsupdate_conf_file="nsupdate.conf"
|
||||
basedir="${BASEDIR:-/usr/local/etc}"
|
||||
nsupdate_conf_dir="${NSUPDATE_CONF_DIR:-$basedir/nsupdate}"
|
||||
|
||||
## Try to load nsupdate.conf
|
||||
[ -f "./$nsupdate_conf_file" ] && . ./$nsupdate_conf_file
|
||||
[ -f "$nsupdate_conf_dir/$nsupdate_conf_file" ] && . $nsupdate_conf_dir/$nsupdate_conf_file
|
||||
|
||||
VERBOSE="${VERBOSE:-false}"
|
||||
DEBUG="${DEBUG:-false}"
|
||||
|
||||
if [ "$DEBUG" = true ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
nsupdate_confd_dir="${NSUPDATE_CONFD_DIR:-$nsupdate_conf_dir/conf.d}"
|
||||
log_date_format="${LOG_DATE_FORMAT:-%Y-%m-%d %H:%M:%S}"
|
||||
nsupdate_log_dir="${NSUPDATE_LOG_DIR:-/var/log/nsupdate}"
|
||||
nsupdate_log_file="${NSUPDATE_LOG_FILE:-nsupdate.log}"
|
||||
tmp_dir="${NSUPDATE_TMP_DIR:-/tmp}"
|
||||
nsupdate_conf_extension="${NSUPDATE_CONF_EXTENSION:-.conf}"
|
||||
|
||||
nsupdate_record_type="${NSUPDATE_RECORD_TYPE:-A}"
|
||||
nsupdate_record_ttl="${NSUPDATE_RECORD_TTL:-300}"
|
||||
|
||||
inwx_api="https://api.domrobot.com/xmlrpc/"
|
||||
inwx_api_xpath_ip='string(/methodResponse/params/param/value/struct/member[name="resData"]/value/struct/member[name="record"]/value/array/data/value/struct/member[name="content"]/value/string)'
|
||||
inwx_api_xpath_id='string(/methodResponse/params/param/value/struct/member[name="resData"]/value/struct/member[name="record"]/value/array/data/value/struct/member[name="id"]/value/int)'
|
||||
inwx_nameserver="ns.inwx.de"
|
||||
ip_check_site="${NSUPDATE_IP_CHECK_SITE:-https://api64.ipify.org}"
|
||||
|
||||
## Get WAN IP 4
|
||||
wan_ip4="$(curl -s -4 ${ip_check_site})"
|
||||
chat 2 "WAN IP 4: ${wan_ip4}"
|
||||
|
||||
## Get WAN IP 6
|
||||
wan_ip6="$(curl -s -6 ${ip_check_site})"
|
||||
chat 2 "WAN IP 6: ${wan_ip6}"
|
||||
}
|
||||
|
||||
# Get the data for a given domain
|
||||
# Usage: get_inwx_domain_id
|
||||
get_domain_info () {
|
||||
|
||||
## Check if xmllint is installed and use it.
|
||||
if command -v xmllint > /dev/null 2>&1; then
|
||||
|
||||
## File name for temporary file to store the XML from API
|
||||
tmp_file="${main_domain}_${record_type}_$(date +%s).xml" # ${main_domain} in case of wildcards in ${domain}
|
||||
|
||||
## Check if WAN_IP_COMMAND is set and use it for retrieving the IP
|
||||
if [ "$WAN_IP_COMMAND" != "" ]; then
|
||||
#WAN_IP_COMMAND="${IPCOMMAND:-$WAN_IP_COMMAND}" ## for backwards compatibility
|
||||
wan_ip="${WAN_IP_COMMAND}"
|
||||
chat 2 "Using WAN_IP_COMMAND for retrieving WAN IP."
|
||||
else
|
||||
## Otherwise use IP retrieved from web site
|
||||
## Get connection type by record type
|
||||
if [ "${record_type}" = "AAAA" ]; then
|
||||
wan_ip="${wan_ip6}"
|
||||
else
|
||||
wan_ip="${wan_ip4}"
|
||||
fi
|
||||
fi
|
||||
|
||||
chat 3 "Found xmllint. Using curl for retrieving data from INWX API."
|
||||
|
||||
inwx_api_xml_info="<?xml version=\"1.0\"?>
|
||||
<methodCall>
|
||||
<methodName>nameserver.info</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>user</name>
|
||||
<value>
|
||||
<string>${inwx_user}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>lang</name>
|
||||
<value>
|
||||
<string>en</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>pass</name>
|
||||
<value>
|
||||
<string>${inwx_password}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>domain</name>
|
||||
<value>
|
||||
<string>${main_domain}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>name</name>
|
||||
<value>
|
||||
<string>${domain}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>type</name>
|
||||
<value>
|
||||
<string>${record_type}</string>
|
||||
</value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>"
|
||||
|
||||
## Get domain info from INWX API and save it to a temporary file
|
||||
curl --silent --show-error --fail --output ${tmp_dir}/${tmp_file} -X POST ${inwx_api} -H "Content-Type: application/xml" -d "${inwx_api_xml_info}"
|
||||
|
||||
## Extract ID and IP from INWX data
|
||||
inwx_domain_ip="$(xmllint --xpath ${inwx_api_xpath_ip} ${tmp_dir}/${tmp_file})"
|
||||
inwx_domain_id="$(xmllint --xpath ${inwx_api_xpath_id} ${tmp_dir}/${tmp_file})"
|
||||
|
||||
## Remove domain info tmp file
|
||||
rm ${tmp_dir}/${tmp_file}
|
||||
else
|
||||
## Check if nslookup is installed and use it to get the IP
|
||||
if command -v nslookup > /dev/null 2>&1; then
|
||||
chat 3 "Found nslookup. Using it for IP from INWX nameserver."
|
||||
inwx_domain_ip=$(nslookup -sil -type=${record_type} ${domain} - ${inwx_nameserver} | tail -2 | head -1 | cut -d' ' -f2)
|
||||
## Check if drill is installed and use it to get the IP
|
||||
else command -v drill > /dev/null 2>&1;
|
||||
chat 3 "Found drill. Using it for IP from INWX nameserver."
|
||||
inwx_domain_ip=$(drill ${domain} @${inwx_nameserver} ${record_type} | head -7 | tail -1 | cut -f2 -d$'\t' -f5)
|
||||
fi
|
||||
|
||||
## Set domain ID from config file
|
||||
chat 3 "Trying to get domain ID from config file."
|
||||
inwx_domain_id="${INWX_DOMAIN_ID}"
|
||||
fi
|
||||
|
||||
if [ -z "$inwx_domain_ip" ]; then
|
||||
chat 1 "Couldn't get current IP address for ${domain} [${record_type}]. please check the installation instructions."
|
||||
fi
|
||||
|
||||
if [ -z "$inwx_domain_id" ]; then
|
||||
chat 1 "Couldn't find domain ID for ${domain} [${record_type}]. please check the installation instructions."
|
||||
fi
|
||||
}
|
||||
|
||||
# Update a dns record
|
||||
# Usage: update_record
|
||||
update_record () {
|
||||
chat 3 "Using curl to update the DNS record with INWX API."
|
||||
inwx_api_xml_update_record="<?xml version=\"1.0\"?>
|
||||
<methodCall>
|
||||
<methodName>nameserver.updateRecord</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>user</name>
|
||||
<value>
|
||||
<string>${inwx_user}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>lang</name>
|
||||
<value>
|
||||
<string>en</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>pass</name>
|
||||
<value>
|
||||
<string>${inwx_password}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>id</name>
|
||||
<value>
|
||||
<int>${inwx_domain_id}</int>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>content</name>
|
||||
<value>
|
||||
<string>${wan_ip}</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>ttl</name>
|
||||
<value>
|
||||
<int>${record_ttl}</int>
|
||||
</value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>"
|
||||
|
||||
curl --silent --output /dev/null --show-error --fail -X POST "${inwx_api}" -H "Content-Type: application/xml" -d "${inwx_api_xml_update_record}"
|
||||
}
|
||||
|
||||
## Initalize nsupdate
|
||||
init
|
||||
|
||||
# Check if there are any usable config files
|
||||
if ls $(dirname $0)/nsupdate.d/*.config &> /dev/null; then
|
||||
# Loop through configs
|
||||
for f in $(dirname $0)/nsupdate.d/*.config
|
||||
do
|
||||
# Config files could be much cleaner by containing only relevant settings.
|
||||
# If your User and Password is always the same just set it here once and delete it in the config files.
|
||||
#INWX_USER="Username"
|
||||
#INWX_PASS="Password"
|
||||
# Resets previous set variables to catch wrong or not configured settings and set defaults.
|
||||
MAIN_DOMAIN=
|
||||
DOMAIN=
|
||||
INWX_DOMAIN_ID="unset"
|
||||
TTL=300
|
||||
TYPE=A
|
||||
CONNECTION_TYPE=4
|
||||
# For backward compatability the following options remain in this script
|
||||
IPV6="NO"
|
||||
MX="NO"
|
||||
if ls ${nsupdate_confd_dir}/*${nsupdate_conf_extension} > /dev/null 2>&1; then
|
||||
# Loop through config files
|
||||
for f in ${nsupdate_confd_dir}/*${nsupdate_conf_extension}
|
||||
do
|
||||
. ${f}
|
||||
chat 2 "Loading config file ${f}"
|
||||
|
||||
source $f
|
||||
## Get variables from config file
|
||||
inwx_user="${INWX_USER:-$NSUPDATE_INWX_USER}"
|
||||
inwx_password="${INWX_PASSWORD:-$NSUPDATE_INWX_PASSWORD}"
|
||||
main_domain="${MAIN_DOMAIN}"
|
||||
domain="${DOMAIN}"
|
||||
|
||||
if [[ "$SILENT" == "NO" ]]; then
|
||||
echo "Starting nameserver update with config file $f ($LOG)"
|
||||
fi
|
||||
|
||||
if [[ "$TYPE" == "A" ]]; then
|
||||
CONNECTION_TYPE=4
|
||||
fi
|
||||
|
||||
## Set record type to MX
|
||||
if [[ "$MX" == "YES" ]]; then
|
||||
TYPE=MX
|
||||
fi
|
||||
RECORD_TYPE="${TYPE:-$RECORD_TYPE}" ## For backwards compatibility in config files
|
||||
RECORD_TTL="${TTL:-$RECORD_TTL}" ## For backwards compatibility in config files
|
||||
record_type="${RECORD_TYPE:-$nsupdate_record_type}"
|
||||
record_ttl="${RECORD_TTL:-$nsupdate_record_ttl}"
|
||||
|
||||
## Set record type to IPv6
|
||||
if [[ "$IPV6" == "YES" ]]; then
|
||||
TYPE=AAAA
|
||||
fi
|
||||
## Get domain info
|
||||
get_domain_info
|
||||
|
||||
if [[ "$TYPE" == "AAAA" ]]; then
|
||||
CONNECTION_TYPE=6
|
||||
fi
|
||||
## Verbose output
|
||||
chat 2 "DOMAIN: ${domain}"
|
||||
chat 2 "RECORD TYPE: ${record_type}"
|
||||
chat 2 "RECORD TTL: ${record_ttl}"
|
||||
chat 2 "INWX DOMAIN ID: ${inwx_domain_id}"
|
||||
chat 2 "INWX IP: ${inwx_domain_ip}"
|
||||
|
||||
if [[ "$USE_DRILL" == "YES" ]]; then
|
||||
if [[ "$TYPE" == "MX" ]]; then
|
||||
echo looking up MX records with drill currently not supported!
|
||||
exit 1
|
||||
else
|
||||
NSLOOKUP=$(drill $DOMAIN @ns.inwx.de $TYPE | head -7 | tail -1 | awk '{print $5}')
|
||||
fi
|
||||
else
|
||||
if [[ "$TYPE" == "MX" ]]; then
|
||||
PART_NSLOOKUP=$(nslookup -sil -type=$TYPE $DOMAIN - ns.inwx.de | tail -2 | head -1 | cut -d' ' -f5)
|
||||
NSLOOKUP=${PART_NSLOOKUP%"."}
|
||||
else
|
||||
NSLOOKUP=$(nslookup -sil -type=$TYPE $DOMAIN - ns.inwx.de | tail -2 | head -1 | cut -d' ' -f2)
|
||||
fi
|
||||
fi
|
||||
## Check if record needs an update and do it
|
||||
if [ "${inwx_domain_ip}" != "${wan_ip}" ]; then
|
||||
chat 0 "Updating DNS record for ${domain} [${record_type}]. Old IP: ${inwx_domain_ip}. New IP: ${wan_ip}."
|
||||
update_record ${inwx_user} ${inwx_password} ${inwx_domain_id} ${wan_ip} ${record_ttl}
|
||||
else
|
||||
chat 0 "No update required for ${domain} [${record_type}]."
|
||||
fi
|
||||
|
||||
# WAN_IP=`curl -s -$CONNECTION_TYPE ${IP_CHECK_SITE}| grep -Eo '\<[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){3}\>'`
|
||||
if [[ -z ${IPCOMMAND} ]]; then
|
||||
WAN_IP=$(curl -s -$CONNECTION_TYPE ${IP_CHECK_SITE})
|
||||
else
|
||||
WAN_IP=$($IPCOMMAND)
|
||||
fi
|
||||
|
||||
# This is relevant for getting the specific domain record id.
|
||||
API_XML_INFO="<?xml version=\"1.0\"?>
|
||||
<methodCall>
|
||||
<methodName>nameserver.info</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>user</name>
|
||||
<value>
|
||||
<string>$INWX_USER</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>lang</name>
|
||||
<value>
|
||||
<string>en</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>pass</name>
|
||||
<value>
|
||||
<string>$INWX_PASS</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>domain</name>
|
||||
<value>
|
||||
<string>$MAIN_DOMAIN</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>name</name>
|
||||
<value>
|
||||
<string>$DOMAIN</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>type</name>
|
||||
<value>
|
||||
<string>$TYPE</string>
|
||||
</value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>"
|
||||
|
||||
# The full xpath is
|
||||
# XPATH='string(/methodResponse/params/param/value/struct/member[name="resData"]/value/struct/member[name="record"]/value/array/data/value/struct/member[name="id"]/value/int)'
|
||||
# A short version of the xpath
|
||||
XPATH='string(//member[name="id"]/value/int/text())'
|
||||
if [[ "$NO_XMLLINT" != "true" ]]; then
|
||||
if [[ "$NSLOOKUP" != "$WAN_IP" ]]; then
|
||||
if [[ "$INWX_DOMAIN_ID" == "unset" ]]; then
|
||||
INWX_DOMAIN_ID=$(curl -s -X POST https://api.domrobot.com/xmlrpc/ \
|
||||
-H "Content-Type: application/xml" \
|
||||
-d "$API_XML_INFO" \
|
||||
| xmllint --xpath $XPATH -)
|
||||
if [[ "$SILENT" == "NO" ]]; then
|
||||
echo $(printf "%s - The %s-Type Record-ID of %s is: %s" "$(date)" "$TYPE" "$DOMAIN" "$INWX_DOMAIN_ID")>>$LOG
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
API_XML_UPDATE_RECORD="<?xml version=\"1.0\"?>
|
||||
<methodCall>
|
||||
<methodName>nameserver.updateRecord</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>user</name>
|
||||
<value>
|
||||
<string>$INWX_USER</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>lang</name>
|
||||
<value>
|
||||
<string>en</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>pass</name>
|
||||
<value>
|
||||
<string>$INWX_PASS</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>id</name>
|
||||
<value>
|
||||
<int>$INWX_DOMAIN_ID</int>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>content</name>
|
||||
<value>
|
||||
<string>$WAN_IP</string>
|
||||
</value>
|
||||
</member>
|
||||
<member>
|
||||
<name>ttl</name>
|
||||
<value>
|
||||
<int>$TTL</int>
|
||||
</value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>"
|
||||
|
||||
if [[ "$NSLOOKUP" != "$WAN_IP" ]]; then
|
||||
curl -s -X POST https://api.domrobot.com/xmlrpc/ \
|
||||
-H "Content-Type: application/xml" \
|
||||
-d "$API_XML_UPDATE_RECORD"
|
||||
|
||||
if [[ "$SILENT" == "NO" ]]; then
|
||||
echo "$(date) - $DOMAIN updated. Old IP: "$NSLOOKUP "New IP: "$WAN_IP >> $LOG
|
||||
fi
|
||||
else
|
||||
if [[ "$SILENT" == "NO" ]]; then
|
||||
echo "$(date) - No update needed for $DOMAIN. Current IP: "$NSLOOKUP >> $LOG
|
||||
fi
|
||||
fi
|
||||
|
||||
unset TYPE
|
||||
unset MAIN_DOMAIN
|
||||
unset DOMAIN
|
||||
unset IPV6
|
||||
unset MX
|
||||
unset WAN_IP
|
||||
unset TTL
|
||||
unset NSLOOKUP
|
||||
unset INWX_PASS
|
||||
unset INWX_USER
|
||||
unset INWX_DOMAIN_ID
|
||||
unset API_XML_UPDATE_RECORD
|
||||
unset API_XML_INFO
|
||||
done
|
||||
## Clean up variables for a fresh start
|
||||
unset INWX_USER
|
||||
unset INWX_PASSWORD
|
||||
unset MAIN_DOMAIN
|
||||
unset DOMAIN
|
||||
unset RECORD_TYPE
|
||||
unset RECORD_TTL
|
||||
unset WAN_IP_COMMAND
|
||||
unset tmp_file
|
||||
unset inwx_domain_id
|
||||
unset inwx_domain_ip
|
||||
unset wan_ip
|
||||
done
|
||||
else
|
||||
echo "There does not seem to be any config file available in $(dirname $0)/nsupdate.d/."
|
||||
exit 1
|
||||
fi
|
||||
chat 1 "Couldn't find any usable config files. Check installation instructions."
|
||||
fi
|
30
nsupdate/conf.d/sub.example.com_AAAA.conf.dist
Normal file
30
nsupdate/conf.d/sub.example.com_AAAA.conf.dist
Normal file
@ -0,0 +1,30 @@
|
||||
## Example DNS record config file
|
||||
|
||||
# nsupdate.sh is processing all .conf files in a loop.
|
||||
# If you want to update an IPv4 and an IPv6 record you need two config files.
|
||||
|
||||
# The domain that you want to update AND its main/zone domain
|
||||
# The MAIN_DOMAIN is needed for the API-Request to get the record ID
|
||||
MAIN_DOMAIN="example.com"
|
||||
DOMAIN="sub.example.com"
|
||||
|
||||
# The following options must only be set if they differ from the global config in nsupdate.conf
|
||||
|
||||
# Login credentials for the INWX API
|
||||
# These can be left undefined if you specified them globally in the nsupdate.conf
|
||||
#INWX_USER="YOUR_INWX_USERNAME"
|
||||
#INWX_PASSWORD="YOUR_INWX_PASSWORD"
|
||||
|
||||
# Set the record type to either A, AAAA
|
||||
# If undefined, A is used globally
|
||||
RECORD_TYPE="AAAA"
|
||||
|
||||
# TTL: Time to Live
|
||||
# default TTL setting by INWX is 3600 (1 hour)
|
||||
# minimum TTL allowed by INWX is 300 (5 minutes) for regular nameserver record updates
|
||||
# If unspecified, nsupdate uses a TTL of 300
|
||||
#RECORD_TTL="300"
|
||||
|
||||
# Use a shell command to retrieve the WAN IP (eg. by SSHing to the router and get the IP from the WAN interface)
|
||||
# Otherwise the IP retrieved by website will be used
|
||||
#WAN_IP_COMMAND=$(ssh user@10.0.3.1 ifconfig pppoe1 | grep 'inet ' | cut -d' ' -f2)
|
74
nsupdate/nsupdate.conf.dist
Normal file
74
nsupdate/nsupdate.conf.dist
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
# nsupdate.conf
|
||||
#
|
||||
# This file holds the global configuration for nsupdate.
|
||||
# It will be found in the directory of the nsupdate script or /usr/local/etc/nsupdate.
|
||||
# All options have sensible defaults and can be left undefined, except of your INWX credentials.
|
||||
|
||||
## Backwards compatibilty
|
||||
## If you've used nsupdate before, uncomment the following lines to use your old configurations
|
||||
#NSUPDATE_CONFD_DIR="./nsupdate.d"
|
||||
#NSUPDATE_LOG_DIR="."
|
||||
#NSUPDATE_LOG_FILE="nsupdate.sh.log"
|
||||
#NSUPDATE_CONF_EXTENSION=".config"
|
||||
#NSUPDATE_TMP_DIR="."
|
||||
|
||||
# NSUPDATE_INWX_USER
|
||||
# INWX API user that's globally used; can be overwritten in DNS record configuration
|
||||
#NSUPDATE_INWX_USER="YOUR_INWX_USER_NAME"
|
||||
|
||||
# NSUPDATE_INWX_PASSWORD
|
||||
# INWX API password that's globally used; can be overwritten in DNS record configuration
|
||||
#NSUPDATE_INWX_PASSWORD="YOUR_INWX_USER_PASSWORD"
|
||||
|
||||
# NSUPDATE_RECORD_TYPE
|
||||
# DNS record type that's used when nothing is defined; A or AAAA; default: A
|
||||
#NSUPDATE_RECORD_TYPE="A"
|
||||
|
||||
# NSUPDATE_RECORD_TTL
|
||||
# DNS record TTL that's used when nothing is defined; minimum: 300; default: 300
|
||||
#NSUPDATE_RECORD_TTL="300"
|
||||
|
||||
# VERBOSE
|
||||
# Print more output; true or false; default: false
|
||||
#VERBOSE="false"
|
||||
|
||||
# DEBUG
|
||||
# Print debugging messages; true or false; default: false
|
||||
#DEBUG="false"
|
||||
|
||||
# BASEDIR
|
||||
# Base path for configuration files on the system; default: /usr/local/etc
|
||||
#BASEDIR="/usr/local/etc"
|
||||
|
||||
# NSUPDATE_CONF_DIR
|
||||
# Directory path of the nsupdate configuration files in base path for configuration files on the system; default: nsupdate
|
||||
#NSUPDATE_CONF_DIR="$BASEDIR/nsupdate"
|
||||
|
||||
# NSUPDATE_CONFD_DIR
|
||||
# Directory name for the DNS config files; dfault: $NSUPDATE_CONF_DIR/conf.d
|
||||
#NSUPDATE_CONFD_DIR="$NSUPDATE_CONF_DIR/conf.d"
|
||||
|
||||
# LOG_DATE_FORMAT
|
||||
# Date format for log files; default: %Y-%m-%d %H:%M:%S
|
||||
#LOG_DATE_FORMAT="%Y-%m-%d %H:%M:%S"
|
||||
|
||||
# NSUPDATE_LOG_DIR
|
||||
# Directory path for the log file; default: /var/log
|
||||
#NSUPDATE_LOG_DIR="/var/log/nsupdate"
|
||||
|
||||
# NSUPDATE_LOG_FILE
|
||||
# Name of the log file; default: nsupdate.log
|
||||
#NSUPDATE_LOG_FILE="nsupdate.log"
|
||||
|
||||
# NSUPDATE_TMP_DIR
|
||||
# Directory path for temporary files; default: /tmp
|
||||
#NSUPDATE_TMP_DIR="/tmp"
|
||||
|
||||
# NSUPDATE_CONF_EXTENSION
|
||||
# File name extension for configuration files; default: .conf
|
||||
#NSUPDATE_CONF_EXTENSION=".conf"
|
||||
|
||||
# NSUPDATE_IP_CHECK_SITE
|
||||
# Website to retrieve the wan IP; should be accissible by IPv4 and IPv6; default: https://api64.ipify.org
|
||||
#NSUPDATE_IP_CHECK_SITE="https://api64.ipify.org"
|
Loading…
x
Reference in New Issue
Block a user