summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/completion/list_ddclient_protocols.sh2
-rwxr-xr-xsrc/conf_mode/conntrack.py7
-rwxr-xr-xsrc/conf_mode/dns_dynamic.py38
-rwxr-xr-xsrc/op_mode/generate_firewall_rule-resequence.py11
-rwxr-xr-xsrc/validators/ddclient-protocol2
-rw-r--r--src/validators/numeric-exclude8
6 files changed, 52 insertions, 16 deletions
diff --git a/src/completion/list_ddclient_protocols.sh b/src/completion/list_ddclient_protocols.sh
index 75fb0cf44..3b4eff4d6 100755
--- a/src/completion/list_ddclient_protocols.sh
+++ b/src/completion/list_ddclient_protocols.sh
@@ -14,4 +14,4 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-echo -n $(ddclient -list-protocols)
+echo -n $(ddclient -list-protocols | grep -vE 'nsupdate|cloudns')
diff --git a/src/conf_mode/conntrack.py b/src/conf_mode/conntrack.py
index 2c5fa335e..4cece6921 100755
--- a/src/conf_mode/conntrack.py
+++ b/src/conf_mode/conntrack.py
@@ -212,7 +212,12 @@ def apply(conntrack):
module_str = ' '.join(rm_modules)
cmd(f'rmmod {module_str}')
- call_dependents()
+ try:
+ call_dependents()
+ except ConfigError:
+ # Ignore config errors on dependent due to being called too early. Example:
+ # ConfigError("ConfigError('Interface ethN requires an IP address!')")
+ pass
# We silently ignore all errors
# See: https://bugzilla.redhat.com/show_bug.cgi?id=1264080
diff --git a/src/conf_mode/dns_dynamic.py b/src/conf_mode/dns_dynamic.py
index 4b1aed742..8a438cf6f 100755
--- a/src/conf_mode/dns_dynamic.py
+++ b/src/conf_mode/dns_dynamic.py
@@ -19,6 +19,7 @@ import os
from sys import exit
from vyos.config import Config
+from vyos.configverify import verify_interface_exists
from vyos.template import render
from vyos.utils.process import call
from vyos import ConfigError
@@ -29,25 +30,32 @@ config_file = r'/run/ddclient/ddclient.conf'
systemd_override = r'/run/systemd/system/ddclient.service.d/override.conf'
# Protocols that require zone
-zone_allowed = ['cloudflare', 'godaddy', 'hetzner', 'gandi', 'nfsn']
+zone_necessary = ['cloudflare', 'godaddy', 'hetzner', 'gandi', 'nfsn']
# Protocols that do not require username
username_unnecessary = ['1984', 'cloudflare', 'cloudns', 'duckdns', 'freemyip', 'hetzner', 'keysystems', 'njalla']
+# Protocols that support TTL
+ttl_supported = ['cloudflare', 'gandi', 'hetzner', 'dnsexit', 'godaddy', 'nfsn']
+
# Protocols that support both IPv4 and IPv6
dualstack_supported = ['cloudflare', 'dyndns2', 'freedns', 'njalla']
+# dyndns2 protocol in ddclient honors dual stack for selective servers
+# because of the way it is implemented in ddclient
+dyndns_dualstack_servers = ['members.dyndns.org', 'dynv6.com']
+
def get_config(config=None):
if config:
conf = config
else:
conf = Config()
- base_level = ['service', 'dns', 'dynamic']
- if not conf.exists(base_level):
+ base = ['service', 'dns', 'dynamic']
+ if not conf.exists(base):
return None
- dyndns = conf.get_config_dict(base_level, key_mangling=('-', '_'),
+ dyndns = conf.get_config_dict(base, key_mangling=('-', '_'),
no_tag_node_value_mangle=True,
get_first_key=True,
with_recursive_defaults=True)
@@ -61,6 +69,10 @@ def verify(dyndns):
return None
for address in dyndns['address']:
+ # If dyndns address is an interface, ensure it exists
+ if address != 'web':
+ verify_interface_exists(address)
+
# RFC2136 - configuration validation
if 'rfc2136' in dyndns['address'][address]:
for config in dyndns['address'][address]['rfc2136'].values():
@@ -78,22 +90,24 @@ def verify(dyndns):
if field not in config:
raise ConfigError(f'"{field.replace("_", "-")}" {error_msg}')
- if config['protocol'] in zone_allowed and 'zone' not in config:
- raise ConfigError(f'"zone" {error_msg}')
+ if config['protocol'] in zone_necessary and 'zone' not in config:
+ raise ConfigError(f'"zone" {error_msg}')
+
+ if config['protocol'] not in zone_necessary and 'zone' in config:
+ raise ConfigError(f'"{config["protocol"]}" does not support "zone"')
- if config['protocol'] not in zone_allowed and 'zone' in config:
- raise ConfigError(f'"{config["protocol"]}" does not support "zone"')
+ if config['protocol'] not in username_unnecessary and 'username' not in config:
+ raise ConfigError(f'"username" {error_msg}')
- if config['protocol'] not in username_unnecessary:
- if 'username' not in config:
- raise ConfigError(f'"username" {error_msg}')
+ if config['protocol'] not in ttl_supported and 'ttl' in config:
+ raise ConfigError(f'"{config["protocol"]}" does not support "ttl"')
if config['ip_version'] == 'both':
if config['protocol'] not in dualstack_supported:
raise ConfigError(f'"{config["protocol"]}" does not support '
f'both IPv4 and IPv6 at the same time')
# dyndns2 protocol in ddclient honors dual stack only for dyn.com (dyndns.org)
- if config['protocol'] == 'dyndns2' and 'server' in config and config['server'] != 'members.dyndns.org':
+ if config['protocol'] == 'dyndns2' and 'server' in config and config['server'] not in dyndns_dualstack_servers:
raise ConfigError(f'"{config["protocol"]}" does not support '
f'both IPv4 and IPv6 at the same time for "{config["server"]}"')
diff --git a/src/op_mode/generate_firewall_rule-resequence.py b/src/op_mode/generate_firewall_rule-resequence.py
index b5b625a80..eb82a1a0a 100755
--- a/src/op_mode/generate_firewall_rule-resequence.py
+++ b/src/op_mode/generate_firewall_rule-resequence.py
@@ -116,9 +116,18 @@ if __name__ == "__main__":
print('Firewall is not configured')
exit(1)
- #config_dict = config.get_config_dict('firewall')
config_dict = config.get_config_dict('firewall')
+ # Remove global-options, group and flowtable as they don't need sequencing
+ if 'global-options' in config_dict['firewall']:
+ del config_dict['firewall']['global-options']
+
+ if 'group' in config_dict['firewall']:
+ del config_dict['firewall']['group']
+
+ if 'flowtable' in config_dict['firewall']:
+ del config_dict['firewall']['flowtable']
+
# Convert rule keys to integers, rule "10" -> rule 10
# This is necessary for sorting the rules
config_dict = convert_rule_keys_to_int(config_dict)
diff --git a/src/validators/ddclient-protocol b/src/validators/ddclient-protocol
index 6f927927b..bc6826120 100755
--- a/src/validators/ddclient-protocol
+++ b/src/validators/ddclient-protocol
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-ddclient -list-protocols | grep -qw $1
+ddclient -list-protocols | grep -vE 'nsupdate|cloudns' | grep -qw $1
if [ $? -gt 0 ]; then
echo "Error: $1 is not a valid protocol, please choose from the supported list of protocols"
diff --git a/src/validators/numeric-exclude b/src/validators/numeric-exclude
new file mode 100644
index 000000000..676a240b6
--- /dev/null
+++ b/src/validators/numeric-exclude
@@ -0,0 +1,8 @@
+#!/bin/sh
+path=$(dirname "$0")
+num="${@: -1}"
+if [ "${num:0:1}" != "!" ]; then
+ ${path}/numeric $@
+else
+ ${path}/numeric ${@:1:$#-1} ${num:1}
+fi