migrate git repo to repo-format 0

This commit is contained in:
stefan.tollkuehn committed 2026-06-13 02:01:45 +02:00
1 parent d3f3e45196
commit 7994df3ed9
5 files changed
+339 -1

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2026 stefan.tollkuehn Copyright (c) 2023 Falk Lubiniecki
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including associated documentation files (the "Software"), to deal in the Software without restriction, including
+107
View File
@@ -1,2 +1,109 @@
# opnsense-action-netcup-ddns # opnsense-action-netcup-ddns
Dynamic DNS for opnsense for the netcup api as cronjob action.
This repository contains the cron job action for opnsense and a shell script to use the ddns api of netcup. With this you can update multiple dns records on different domains via opnsense cron jobs.
This is a fork of https://github.com/lubbyhst/opnsense-action-netcup-ddns
The fork is able to update IPv4 as well as IPv6 records and set custom hostname via commandline parameter
## Installation
Clone this repo on your opnsense installation
```bash
git clone https://github.com/lubbyhst/opnsense-action-netcup-ddns.git
cd opnsense-action-netcup-ddns
```
Run install script
```bash
chmod +x ./install.sh && ./install.sh
```
Obtain DNS record id
If your DNS Type A record does not exists. Create it via the CCP Gui. After that you can optain the id via this script. You need to modify the parameters for your account. After executing the script you find you dns record and use the id of your record in the cron job.
```bash
DOMAIN_NAME="test.com"
NC_Apikey="apikey"
NC_Apipw="apipw"
NC_CID="customer_id"
NC_ENDPOINT='https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON'
echo "Try logging in"
tmp=$(curl -X POST \
$NC_ENDPOINT \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"login",
"param":{
"apikey": "'$NC_Apikey'",
"apipassword": "'$NC_Apipw'",
"customernumber": "'$NC_CID'"
}
}')
sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
curl -X POST \
$NC_ENDPOINT \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"infoDnsRecords",
"param":{
"apikey": "'$NC_Apikey'",
"apisessionid": "'$sid'",
"customernumber": "'$NC_CID'",
"clientrequestid": "",
"domainname": "'$DOMAIN_NAME'"
}
}'
```
for better readability pipe this into `jq`
### Example output
```json
{
"serverrequestid": "dgZmd0p4j=YFhdsdo",
"clientrequestid": "",
"action": "infoDnsRecords",
"status": "success",
"statuscode": 2000,
"shortmessage": "DNS records found",
"longmessage": "DNS Records for this zone were found.",
"responsedata": {
"dnsrecords": [
{
"id": "54356783",
"hostname": "testserver",
"type": "A",
"priority": "0",
"destination": "82.66.268.178",
"deleterecord": false,
"state": "yes"
}
]
}
}
```
## Configure cron job
1. Open opnsense webui
2. go to System -> Settings -> Cron
3. Click on [+] to add a new cron task
4. Define the cron interval eg. * * * * * for every minute
5. Select the command "Netcup DDNS update"
6. Set the parameters in the following order [DOMAIN_NAME DNS_RECORD_ID NC_ApiKey NC_Apipw NC_CID]
7. Define a description
8. Click save
9. Click Confirm to activate the cron task
After a successfull run, you should see the correct external ip in your ccp dns view.
+6
View File
@@ -0,0 +1,6 @@
[start]
command: update_netcup_ddns.sh
parameters: %s %s %s %s %s %s %s
type:script
message: Netcup Dynamic DNS Update
description: Netcup DDNS update
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
IS_OPNSENSE=$(cat /etc/shells | grep opnsense-shell)
if [ ! -z $IS_OPNSENSE ]; then
echo "copy action conf"
cp ./actions_netcup_ddns.conf /usr/local/opnsense/service/conf/actions.d/actions_netcup_ddns.conf
echo "reload action config"
service configd restart
echo "copy update script to bin folder"
cp ./update_netcup_ddns.sh /usr/local/bin/update_netcup_ddns.sh
echo "make script executable"
chmod +x /usr/local/bin/update_netcup_ddns.sh
echo "install done"
else
echo "Could not detect OPNsense environment! Exiting doing nothing!"
exit 1
fi
+205
View File
@@ -0,0 +1,205 @@
#!/usr/bin/env bash
# This script will update given netcup domain dns record with the actual ip of the calling service
# Parameters:
# IPVERSION: 4 or 6
# DOMAIN_NAME: the zone name eg. test.com
# DNS_RECORD_ID: the id of the dns record that should be updated
# HOSTNAMERECORD: the hostname in domain
# NC_Apikey: Api Key from your netcup account
# NC_Apipw: Api password from your netcup account
# NC_CID: Customer ID from your netcup account
IPVERSION=$1
DOMAIN_NAME=$2
DNS_RECORD_ID=$3
HOSTNAMERECORD=$4
NC_Apikey=$5
NC_Apipw=$6
NC_CID=$7
NC_ENDPOINT='https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON'
CACHE_PATH="/var/cache/update_netcup_ddns"
usage() {
#
# Displays usage of script
#
# returns usage
#
echo
echo "./update_netcup_ddns.sh <IPVERSION> <DOMAIN_NAME> <DNS_RECORD_ID> <HOSTNAMERECORD> <NC_Apikey> <NC_Apipw> <NC_CID>"
echo
}
query_ip_address() {
#
# Queries the IP address in use
#
# returns IP address or exits with log message
#
local IPVERSION=$1
local CACHE_PATH=$2
case $IPVERSION in
4)
QUERY_ADDRESS=$(curl -s -4 -q v4.ident.me | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])')
STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt"
;;
6)
QUERY_ADDRESS=$(curl -s -6 -q v6.ident.me | grep -oE '^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$')
STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt"
;;
*)
usage
exit 1
;;
esac
if [ ! -d $CACHE_PATH ]; then mkdir -p $CACHE_PATH; fi
if [ ! -f $STATEFILE ]; then touch $STATEFILE; fi
if [ ! -z $QUERY_ADDRESS ]; then
echo $QUERY_ADDRESS
else
logger -t $(basename $0) -p user.err "Unable to query IP address"
exit 255;
fi
}
get_auth_token() {
#
# Get auth token
#
# returns auth_token
#
echo $(curl -s -X POST \
$NC_ENDPOINT \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"login",
"param":{
"apikey": "'$NC_Apikey'",
"apipassword": "'$NC_Apipw'",
"customernumber": "'$NC_CID'"
}
}')
}
determine_record_type() {
#
# Determine dns record type
#
# returns dns record type (currently support A and AAAA)
#
local IPVERSION=$1
if [ $IPVERSION -eq 4 ]; then
RECORDTYPE="A"
elif [ $IPVERSION -eq 6 ]; then
RECORDTYPE="AAAA"
else
logger -t $(basename $0) -p user.err "Could not determine IP version. Exiting"
exit 1
fi
echo $RECORDTYPE
}
get_ip_from_state() {
#
# Get IP address currently set in DNS
#
# returns address set in DNS
#
# local IPVERSION=$1
# local CACHE_PATH=$2
#
# STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt"
# LAST_ADDRESS=$(<$STATEFILE)
#
# echo $LAST_ADDRESS
sid=$(get_auth_token | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
curl -s -X POST \
$NC_ENDPOINT \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"infoDnsRecords",
"param":{
"apikey": "'$NC_Apikey'",
"apisessionid": "'$sid'",
"customernumber": "'$NC_CID'",
"clientrequestid": "",
"domainname": "'$DOMAIN_NAME'"
}
}' | jq -r '.responsedata.dnsrecords[] | select(.id == "'$DNS_RECORD_ID'") | .destination'
}
update_dns_record() {
#
# Update DNS record
#
# returns the IP address updated in DNS
#
update=$(curl -s -X POST \
$NC_ENDPOINT \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"updateDnsRecords",
"param":{
"apikey": "'$NC_Apikey'",
"apisessionid": "'$sessionid'",
"customernumber": "'$NC_CID'",
"clientrequestid": "",
"domainname": "'$DOMAIN_NAME'",
"dnsrecordset": {
"dnsrecords": [
{
"id": "'$DNS_RECORD_ID'",
"hostname": "'$HOSTNAMERECORD'",
"type": "'$(determine_record_type $IPVERSION)'",
"destination": "'$QUERIED_ADDRESS'"
}
]
}
}
}')
echo $update | jq -r '.responsedata.dnsrecords[] | select(.id == "'$DNS_RECORD_ID'") | .destination'
}
QUERIED_ADDRESS=$(query_ip_address $IPVERSION "$CACHE_PATH")
LAST_ADDRESS=$(get_ip_from_state)
# If IP address hasn't changed, exit, otherwise save the new IP
if [ "$QUERIED_ADDRESS" == "$LAST_ADDRESS" ]; then
logger -t $(basename $0) -p user.notice "No update necessary for $HOSTNAMERECORD.$DOMAIN_NAME ($(determine_record_type $IPVERSION))!"
exit 0
fi
echo $QUERIED_ADDRESS > "$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt"
sessionid=$(get_auth_token | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
if [ "$sessionid" = "" ]; then
logger -t $(basename $0) -p user.err "SessionID was empty. Login failed."
exit 1
fi
logger -t $(basename $0) -p user.notice "Successfully logged in"
logger -t $(basename $0) -p user.notice "Try registering new IP for FQDN $HOSTNAMERECORD.$DOMAIN_NAME ($QUERIED_ADDRESS - $(determine_record_type $IPVERSION))"
update=$(update_dns_record)
if [ "$update" == "$QUERIED_ADDRESS" ]; then
logger -t $(basename $0) -p user.notice "Finished updating domain $DOMAIN_NAME"
else
logger -t $(basename $0) -p user.err "Could not update $HOSTNAMERECORD.$DOMAIN_NAME ($QUERIED_ADDRESS - $(determine_record_type $IPVERSION))"
fi