From ea20b1581d6998ed6aa8d6c9cd6c8fc5d8b3cb9a Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Sat, 26 Mar 2022 14:11:37 +0000
Subject: [PATCH 01/11] enh: ipv6 only global setting
---
share/config_global.toml | 6 ++++++
src/diagnosers/10-ip.py | 5 +++--
src/diagnosers/14-ports.py | 5 +++--
src/diagnosers/21-web.py | 9 +++++----
src/diagnosers/24-mail.py | 5 +++--
src/dns.py | 5 +++--
src/settings.py | 2 ++
7 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/share/config_global.toml b/share/config_global.toml
index 1f3cc1b39..405157c5f 100644
--- a/share/config_global.toml
+++ b/share/config_global.toml
@@ -160,3 +160,9 @@ name = "Other"
[misc.backup.backup_compress_tar_archives]
type = "boolean"
default = false
+
+ [misc.network]
+ name = "Network"
+ [misc.network.network_ipv6_only]
+ type = "boolean"
+ default = false
diff --git a/src/diagnosers/10-ip.py b/src/diagnosers/10-ip.py
index b2bedc802..098bd569c 100644
--- a/src/diagnosers/10-ip.py
+++ b/src/diagnosers/10-ip.py
@@ -28,6 +28,7 @@ from moulinette.utils.filesystem import read_file
from yunohost.diagnosis import Diagnoser
from yunohost.utils.network import get_network_interfaces
+from yunohost.settings import settings_get
logger = log.getActionLogger("yunohost.diagnosis")
@@ -121,7 +122,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv4"},
data={"global": ipv4, "local": get_local_ip("ipv4")},
- status="SUCCESS" if ipv4 else "ERROR",
+ status="SUCCESS" if ipv4 else "WARNING" if settings_get("network_ipv6_only") else "ERROR",
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4",
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv4 else None,
)
@@ -129,7 +130,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv6"},
data={"global": ipv6, "local": get_local_ip("ipv6")},
- status="SUCCESS" if ipv6 else "WARNING",
+ status="SUCCESS" if ipv6 else "ERROR" if settings_get("network_ipv6_only") else "WARNING",
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6",
details=["diagnosis_ip_global", "diagnosis_ip_local"]
if ipv6
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 5671211b5..0ca39a42c 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -21,6 +21,7 @@ from typing import List
from yunohost.diagnosis import Diagnoser
from yunohost.service import _get_services
+from yunohost.settings import settings_get
class MyDiagnoser(Diagnoser):
@@ -46,7 +47,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS":
+ if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -120,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 or ipv6_is_important():
+ if failed == 4 and not settings_get("network_ipv6_only") or ipv6_is_important():
yield dict(
meta={"port": port},
data={
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index 4a69895b2..bdba89f78 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -26,6 +26,7 @@ from moulinette.utils.filesystem import read_file, mkdir, rm
from yunohost.diagnosis import Diagnoser
from yunohost.domain import domain_list
from yunohost.utils.dns import is_special_use_tld
+from yunohost.settings import settings_get
DIAGNOSIS_SERVER = "diagnosis.yunohost.org"
@@ -76,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS":
+ if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -96,7 +97,7 @@ class MyDiagnoser(Diagnoser):
# "curl --head the.global.ip" will simply timeout...
if self.do_hairpinning_test:
global_ipv4 = ipv4.get("data", {}).get("global", None)
- if global_ipv4:
+ if global_ipv4 and not settings_get("network_ipv6_only"):
try:
requests.head("http://" + global_ipv4, timeout=5)
except requests.exceptions.Timeout:
@@ -147,7 +148,7 @@ class MyDiagnoser(Diagnoser):
if all(
results[ipversion][domain]["status"] == "ok" for ipversion in ipversions
):
- if 4 in ipversions:
+ if 4 in ipversions and not settings_get("network_ipv6_only"):
self.do_hairpinning_test = True
yield dict(
meta={"domain": domain},
@@ -185,7 +186,7 @@ class MyDiagnoser(Diagnoser):
)
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
- return AAAA_status in ["OK", "WRONG"]
+ return AAAA_status in ["OK", "WRONG"] or settings_get("network_ipv6_only")
if failed == 4 or ipv6_is_important_for_this_domain():
yield dict(
diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py
index 88d6a8259..536f870b3 100644
--- a/src/diagnosers/24-mail.py
+++ b/src/diagnosers/24-mail.py
@@ -31,6 +31,7 @@ from yunohost.diagnosis import Diagnoser
from yunohost.domain import _get_maindomain, domain_list
from yunohost.settings import settings_get
from yunohost.utils.dns import dig
+from yunohost.settings import settings_get
DEFAULT_DNS_BLACKLIST = "/usr/share/yunohost/dnsbl_list.yml"
@@ -301,13 +302,13 @@ class MyDiagnoser(Diagnoser):
outgoing_ipversions = []
outgoing_ips = []
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS":
+ if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
outgoing_ipversions.append(4)
global_ipv4 = ipv4.get("data", {}).get("global", {})
if global_ipv4:
outgoing_ips.append(global_ipv4)
- if settings_get("email.smtp.smtp_allow_ipv6"):
+ if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("network_ipv6_only"):
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
if ipv6.get("status") == "SUCCESS":
outgoing_ipversions.append(6)
diff --git a/src/dns.py b/src/dns.py
index 1c6b99cf0..cc7ebd7e7 100644
--- a/src/dns.py
+++ b/src/dns.py
@@ -38,6 +38,7 @@ from yunohost.domain import (
from yunohost.utils.dns import dig, is_yunohost_dyndns_domain, is_special_use_tld
from yunohost.utils.error import YunohostValidationError, YunohostError
from yunohost.utils.network import get_public_ip
+from yunohost.settings import settings_get
from yunohost.log import is_unit_operation
from yunohost.hook import hook_callback
@@ -185,7 +186,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
###########################
# Basic ipv4/ipv6 records #
###########################
- if ipv4:
+ if ipv4 and not settings_get("network_ipv6_only"):
basic.append([basename, ttl, "A", ipv4])
if ipv6:
@@ -240,7 +241,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
# Only recommend wildcard and CAA for the top level
if domain == base_domain:
- if ipv4:
+ if ipv4 and not settings_get("network_ipv6_only"):
extra.append([f"*{suffix}", ttl, "A", ipv4])
if ipv6:
diff --git a/src/settings.py b/src/settings.py
index d9ea600a4..f52574785 100644
--- a/src/settings.py
+++ b/src/settings.py
@@ -310,6 +310,7 @@ def regen_ssowatconf(setting_name, old_value, new_value):
@post_change_hook("nginx_compatibility")
@post_change_hook("webadmin_allowlist_enabled")
@post_change_hook("webadmin_allowlist")
+@post_change_hook("network_ipv6_only")
def reconfigure_nginx(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["nginx"])
@@ -341,6 +342,7 @@ def reconfigure_ssh_and_fail2ban(setting_name, old_value, new_value):
@post_change_hook("smtp_relay_user")
@post_change_hook("smtp_relay_password")
@post_change_hook("postfix_compatibility")
+@post_change_hook("network_ipv6_only")
def reconfigure_postfix(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["postfix"])
From 029c3b76863cf0646a2f8e1137a2b9325fbdaf79 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Tue, 11 Oct 2022 18:01:56 +0000
Subject: [PATCH 02/11] Change to select
---
share/config_global.toml | 9 ++++++---
src/diagnosers/10-ip.py | 4 ++--
src/diagnosers/14-ports.py | 4 ++--
src/diagnosers/21-web.py | 8 ++++----
src/diagnosers/24-mail.py | 4 ++--
src/dns.py | 4 ++--
src/settings.py | 4 ++--
7 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/share/config_global.toml b/share/config_global.toml
index 405157c5f..40b71ab19 100644
--- a/share/config_global.toml
+++ b/share/config_global.toml
@@ -163,6 +163,9 @@ name = "Other"
[misc.network]
name = "Network"
- [misc.network.network_ipv6_only]
- type = "boolean"
- default = false
+ [misc.network.dns_exposure]
+ type = "select"
+ choices.both = "Both"
+ choices.ipv4 = "IPv4 Only"
+ choices.ipv6 = "IPv6 Only"
+ default = "both"
diff --git a/src/diagnosers/10-ip.py b/src/diagnosers/10-ip.py
index 098bd569c..7de462334 100644
--- a/src/diagnosers/10-ip.py
+++ b/src/diagnosers/10-ip.py
@@ -122,7 +122,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv4"},
data={"global": ipv4, "local": get_local_ip("ipv4")},
- status="SUCCESS" if ipv4 else "WARNING" if settings_get("network_ipv6_only") else "ERROR",
+ status="SUCCESS" if ipv4 else "ERROR" if settings_get("dns_exposure") == "ipv4" else "WARNING",
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4",
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv4 else None,
)
@@ -130,7 +130,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv6"},
data={"global": ipv6, "local": get_local_ip("ipv6")},
- status="SUCCESS" if ipv6 else "ERROR" if settings_get("network_ipv6_only") else "WARNING",
+ status="SUCCESS" if ipv6 else "ERROR" if settings_get("dns_exposure") == "ipv6" else "WARNING",
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6",
details=["diagnosis_ip_global", "diagnosis_ip_local"]
if ipv6
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 0ca39a42c..2d7eee717 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -47,7 +47,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
+ if ipv4.get("status") == "SUCCESS" or not settings_get("dns_exposure") == "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -121,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 and not settings_get("network_ipv6_only") or ipv6_is_important():
+ if failed == 4 and not settings_get("dns_exposure") == "ipv6" or ipv6_is_important():
yield dict(
meta={"port": port},
data={
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index bdba89f78..eaac0d25f 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -77,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
+ if ipv4.get("status") == "SUCCESS" and not settings_get("dns_exposure") == "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -97,7 +97,7 @@ class MyDiagnoser(Diagnoser):
# "curl --head the.global.ip" will simply timeout...
if self.do_hairpinning_test:
global_ipv4 = ipv4.get("data", {}).get("global", None)
- if global_ipv4 and not settings_get("network_ipv6_only"):
+ if global_ipv4 and settings_get("dns_exposure") != "ipv6":
try:
requests.head("http://" + global_ipv4, timeout=5)
except requests.exceptions.Timeout:
@@ -148,7 +148,7 @@ class MyDiagnoser(Diagnoser):
if all(
results[ipversion][domain]["status"] == "ok" for ipversion in ipversions
):
- if 4 in ipversions and not settings_get("network_ipv6_only"):
+ if 4 in ipversions and settings_get("dns_exposure") != "ipv6":
self.do_hairpinning_test = True
yield dict(
meta={"domain": domain},
@@ -186,7 +186,7 @@ class MyDiagnoser(Diagnoser):
)
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
- return AAAA_status in ["OK", "WRONG"] or settings_get("network_ipv6_only")
+ return AAAA_status in ["OK", "WRONG"] or settings_get("dns_exposure") != "ipv4"
if failed == 4 or ipv6_is_important_for_this_domain():
yield dict(
diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py
index 536f870b3..43273aebf 100644
--- a/src/diagnosers/24-mail.py
+++ b/src/diagnosers/24-mail.py
@@ -302,13 +302,13 @@ class MyDiagnoser(Diagnoser):
outgoing_ipversions = []
outgoing_ips = []
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and not settings_get("network_ipv6_only"):
+ if ipv4.get("status") == "SUCCESS" and settings_get("dns_exposure") != "ipv6":
outgoing_ipversions.append(4)
global_ipv4 = ipv4.get("data", {}).get("global", {})
if global_ipv4:
outgoing_ips.append(global_ipv4)
- if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("network_ipv6_only"):
+ if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("dns_exposure") != "ipv4":
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
if ipv6.get("status") == "SUCCESS":
outgoing_ipversions.append(6)
diff --git a/src/dns.py b/src/dns.py
index cc7ebd7e7..31c91d590 100644
--- a/src/dns.py
+++ b/src/dns.py
@@ -186,7 +186,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
###########################
# Basic ipv4/ipv6 records #
###########################
- if ipv4 and not settings_get("network_ipv6_only"):
+ if ipv4 and not settings_get("dns_exposure") == "ipv6":
basic.append([basename, ttl, "A", ipv4])
if ipv6:
@@ -241,7 +241,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
# Only recommend wildcard and CAA for the top level
if domain == base_domain:
- if ipv4 and not settings_get("network_ipv6_only"):
+ if ipv4 and settings_get("dns_exposure") != "ipv6":
extra.append([f"*{suffix}", ttl, "A", ipv4])
if ipv6:
diff --git a/src/settings.py b/src/settings.py
index f52574785..96f11caeb 100644
--- a/src/settings.py
+++ b/src/settings.py
@@ -310,7 +310,7 @@ def regen_ssowatconf(setting_name, old_value, new_value):
@post_change_hook("nginx_compatibility")
@post_change_hook("webadmin_allowlist_enabled")
@post_change_hook("webadmin_allowlist")
-@post_change_hook("network_ipv6_only")
+@post_change_hook("dns_exposure")
def reconfigure_nginx(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["nginx"])
@@ -342,7 +342,7 @@ def reconfigure_ssh_and_fail2ban(setting_name, old_value, new_value):
@post_change_hook("smtp_relay_user")
@post_change_hook("smtp_relay_password")
@post_change_hook("postfix_compatibility")
-@post_change_hook("network_ipv6_only")
+@post_change_hook("dns_exposure")
def reconfigure_postfix(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["postfix"])
From f4b396219cbf76e3785f0b24dc130b590a2d2464 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Tue, 11 Oct 2022 18:06:57 +0000
Subject: [PATCH 03/11] Clarify conditions
---
src/diagnosers/14-ports.py | 4 ++--
src/diagnosers/21-web.py | 2 +-
src/dns.py | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 2d7eee717..1483dbb96 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -47,7 +47,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" or not settings_get("dns_exposure") == "ipv6":
+ if ipv4.get("status") == "SUCCESS" or settings_get("dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -121,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 and not settings_get("dns_exposure") == "ipv6" or ipv6_is_important():
+ if failed == 4 and settings_get("dns_exposure") != "ipv6" or ipv6_is_important():
yield dict(
meta={"port": port},
data={
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index eaac0d25f..f62d182bc 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -77,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and not settings_get("dns_exposure") == "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get("dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
diff --git a/src/dns.py b/src/dns.py
index 31c91d590..a007f69be 100644
--- a/src/dns.py
+++ b/src/dns.py
@@ -186,7 +186,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
###########################
# Basic ipv4/ipv6 records #
###########################
- if ipv4 and not settings_get("dns_exposure") == "ipv6":
+ if ipv4 and settings_get("dns_exposure") != "ipv6":
basic.append([basename, ttl, "A", ipv4])
if ipv6:
From c4c78f5daa785a9d3356e9365fdc8f6d1900fc92 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 24 Oct 2022 21:55:05 +0000
Subject: [PATCH 04/11] oops
---
src/diagnosers/10-ip.py | 4 ++--
src/diagnosers/14-ports.py | 4 ++--
src/diagnosers/21-web.py | 8 ++++----
src/diagnosers/24-mail.py | 4 ++--
src/dns.py | 4 ++--
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/diagnosers/10-ip.py b/src/diagnosers/10-ip.py
index 7de462334..954b9b4e8 100644
--- a/src/diagnosers/10-ip.py
+++ b/src/diagnosers/10-ip.py
@@ -122,7 +122,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv4"},
data={"global": ipv4, "local": get_local_ip("ipv4")},
- status="SUCCESS" if ipv4 else "ERROR" if settings_get("dns_exposure") == "ipv4" else "WARNING",
+ status="SUCCESS" if ipv4 else "ERROR" if settings_get("misc.network.dns_exposure") == "ipv4" else "WARNING",
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4",
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv4 else None,
)
@@ -130,7 +130,7 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv6"},
data={"global": ipv6, "local": get_local_ip("ipv6")},
- status="SUCCESS" if ipv6 else "ERROR" if settings_get("dns_exposure") == "ipv6" else "WARNING",
+ status="SUCCESS" if ipv6 else "ERROR" if settings_get("misc.network.dns_exposure") == "ipv6" else "WARNING",
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6",
details=["diagnosis_ip_global", "diagnosis_ip_local"]
if ipv6
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 1483dbb96..1e265f78e 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -47,7 +47,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" or settings_get("dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" or settings_get(misc.network.dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -121,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 and settings_get("dns_exposure") != "ipv6" or ipv6_is_important():
+ if failed == 4 and settings_get(misc.network.dns_exposure") != "ipv6" or ipv6_is_important():
yield dict(
meta={"port": port},
data={
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index f62d182bc..2024cf6ce 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -77,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get("dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get(misc.network.dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -97,7 +97,7 @@ class MyDiagnoser(Diagnoser):
# "curl --head the.global.ip" will simply timeout...
if self.do_hairpinning_test:
global_ipv4 = ipv4.get("data", {}).get("global", None)
- if global_ipv4 and settings_get("dns_exposure") != "ipv6":
+ if global_ipv4 and settings_get(misc.network.dns_exposure") != "ipv6":
try:
requests.head("http://" + global_ipv4, timeout=5)
except requests.exceptions.Timeout:
@@ -148,7 +148,7 @@ class MyDiagnoser(Diagnoser):
if all(
results[ipversion][domain]["status"] == "ok" for ipversion in ipversions
):
- if 4 in ipversions and settings_get("dns_exposure") != "ipv6":
+ if 4 in ipversions and settings_get(misc.network.dns_exposure") != "ipv6":
self.do_hairpinning_test = True
yield dict(
meta={"domain": domain},
@@ -186,7 +186,7 @@ class MyDiagnoser(Diagnoser):
)
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
- return AAAA_status in ["OK", "WRONG"] or settings_get("dns_exposure") != "ipv4"
+ return AAAA_status in ["OK", "WRONG"] or settings_get(misc.network.dns_exposure") != "ipv4"
if failed == 4 or ipv6_is_important_for_this_domain():
yield dict(
diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py
index 43273aebf..590b0d9ba 100644
--- a/src/diagnosers/24-mail.py
+++ b/src/diagnosers/24-mail.py
@@ -302,13 +302,13 @@ class MyDiagnoser(Diagnoser):
outgoing_ipversions = []
outgoing_ips = []
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get("dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get(misc.network.dns_exposure") != "ipv6":
outgoing_ipversions.append(4)
global_ipv4 = ipv4.get("data", {}).get("global", {})
if global_ipv4:
outgoing_ips.append(global_ipv4)
- if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("dns_exposure") != "ipv4":
+ if settings_get("email.smtp.smtp_allow_ipv6") or settings_get(misc.network.dns_exposure") != "ipv4":
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
if ipv6.get("status") == "SUCCESS":
outgoing_ipversions.append(6)
diff --git a/src/dns.py b/src/dns.py
index a007f69be..9d81391e5 100644
--- a/src/dns.py
+++ b/src/dns.py
@@ -186,7 +186,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
###########################
# Basic ipv4/ipv6 records #
###########################
- if ipv4 and settings_get("dns_exposure") != "ipv6":
+ if ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
basic.append([basename, ttl, "A", ipv4])
if ipv6:
@@ -241,7 +241,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
# Only recommend wildcard and CAA for the top level
if domain == base_domain:
- if ipv4 and settings_get("dns_exposure") != "ipv6":
+ if ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
extra.append([f"*{suffix}", ttl, "A", ipv4])
if ipv6:
From 28e4b458065d39dc086dae105fa8596b8c3f1b25 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 24 Oct 2022 22:00:30 +0000
Subject: [PATCH 05/11] oops again...
---
src/diagnosers/14-ports.py | 4 ++--
src/diagnosers/21-web.py | 8 ++++----
src/diagnosers/24-mail.py | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 1e265f78e..0cd54efba 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -47,7 +47,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" or settings_get(misc.network.dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" or settings_get("misc.network.dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -121,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 and settings_get(misc.network.dns_exposure") != "ipv6" or ipv6_is_important():
+ if failed == 4 and settings_get("misc.network.dns_exposure") != "ipv6" or ipv6_is_important():
yield dict(
meta={"port": port},
data={
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index 2024cf6ce..74e3ca483 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -77,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get(misc.network.dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") != "ipv6":
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -97,7 +97,7 @@ class MyDiagnoser(Diagnoser):
# "curl --head the.global.ip" will simply timeout...
if self.do_hairpinning_test:
global_ipv4 = ipv4.get("data", {}).get("global", None)
- if global_ipv4 and settings_get(misc.network.dns_exposure") != "ipv6":
+ if global_ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
try:
requests.head("http://" + global_ipv4, timeout=5)
except requests.exceptions.Timeout:
@@ -148,7 +148,7 @@ class MyDiagnoser(Diagnoser):
if all(
results[ipversion][domain]["status"] == "ok" for ipversion in ipversions
):
- if 4 in ipversions and settings_get(misc.network.dns_exposure") != "ipv6":
+ if 4 in ipversions and settings_get("misc.network.dns_exposure") != "ipv6":
self.do_hairpinning_test = True
yield dict(
meta={"domain": domain},
@@ -186,7 +186,7 @@ class MyDiagnoser(Diagnoser):
)
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
- return AAAA_status in ["OK", "WRONG"] or settings_get(misc.network.dns_exposure") != "ipv4"
+ return AAAA_status in ["OK", "WRONG"] or settings_get("misc.network.dns_exposure") != "ipv4"
if failed == 4 or ipv6_is_important_for_this_domain():
yield dict(
diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py
index 590b0d9ba..283f80681 100644
--- a/src/diagnosers/24-mail.py
+++ b/src/diagnosers/24-mail.py
@@ -302,13 +302,13 @@ class MyDiagnoser(Diagnoser):
outgoing_ipversions = []
outgoing_ips = []
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get(misc.network.dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") != "ipv6":
outgoing_ipversions.append(4)
global_ipv4 = ipv4.get("data", {}).get("global", {})
if global_ipv4:
outgoing_ips.append(global_ipv4)
- if settings_get("email.smtp.smtp_allow_ipv6") or settings_get(misc.network.dns_exposure") != "ipv4":
+ if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("misc.network.dns_exposure") != "ipv4":
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
if ipv6.get("status") == "SUCCESS":
outgoing_ipversions.append(6)
From 1a07839b5fa5d390fe76314d2f052d0416d28c13 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 24 Oct 2022 22:20:12 +0000
Subject: [PATCH 06/11] diagnosis
---
locales/en.json | 1 +
src/diagnosers/10-ip.py | 9 ++++++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/locales/en.json b/locales/en.json
index e655acb83..789ec5a4b 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -245,6 +245,7 @@
"diagnosis_ip_no_ipv4": "The server does not have working IPv4.",
"diagnosis_ip_no_ipv6": "The server does not have working IPv6.",
"diagnosis_ip_no_ipv6_tip": "Having a working IPv6 is not mandatory for your server to work, but it is better for the health of the Internet as a whole. IPv6 should usually be automatically configured by the system or your provider if it's available. Otherwise, you might need to configure a few things manually as explained in the documentation here: https://yunohost.org/#/ipv6. If you cannot enable IPv6 or if it seems too technical for you, you can also safely ignore this warning.",
+ "diagnosis_ip_no_ipv6_tip_important": "IPv6 should usually be automatically configured by the system or your provider if it's available. Otherwise, you might need to configure a few things manually as explained in the documentation here: https://yunohost.org/#/ipv6.",
"diagnosis_ip_not_connected_at_all": "The server does not seem to be connected to the Internet at all!?",
"diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but it looks like you're using a custom /etc/resolv.conf
.",
"diagnosis_ip_weird_resolvconf_details": "The file /etc/resolv.conf
should be a symlink to /etc/resolvconf/run/resolv.conf
itself pointing to 127.0.0.1
(dnsmasq). If you want to manually configure DNS resolvers, please edit /etc/resolv.dnsmasq.conf
.",
diff --git a/src/diagnosers/10-ip.py b/src/diagnosers/10-ip.py
index 954b9b4e8..1d28be143 100644
--- a/src/diagnosers/10-ip.py
+++ b/src/diagnosers/10-ip.py
@@ -119,10 +119,13 @@ class MyDiagnoser(Diagnoser):
else:
return local_ip
+ def is_ipvx_important(x):
+ return settings_get("misc.network.dns_exposure") == "both" or "ipv"+str(x)
+
yield dict(
meta={"test": "ipv4"},
data={"global": ipv4, "local": get_local_ip("ipv4")},
- status="SUCCESS" if ipv4 else "ERROR" if settings_get("misc.network.dns_exposure") == "ipv4" else "WARNING",
+ status="SUCCESS" if ipv4 else "ERROR" if is_ipvx_important(4) else "WARNING",
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4",
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv4 else None,
)
@@ -130,11 +133,11 @@ class MyDiagnoser(Diagnoser):
yield dict(
meta={"test": "ipv6"},
data={"global": ipv6, "local": get_local_ip("ipv6")},
- status="SUCCESS" if ipv6 else "ERROR" if settings_get("misc.network.dns_exposure") == "ipv6" else "WARNING",
+ status="SUCCESS" if ipv6 else "ERROR" if is_ipvx_important(6) else "WARNING",
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6",
details=["diagnosis_ip_global", "diagnosis_ip_local"]
if ipv6
- else ["diagnosis_ip_no_ipv6_tip"],
+ else ["diagnosis_ip_no_ipv6_tip_important" if is_ipvx_important(6) else "diagnosis_ip_no_ipv6_tip"],
)
# TODO / FIXME : add some attempt to detect ISP (using whois ?) ?
From e82849492baa6dff14cba2e34ee88d3a4fa9a4e9 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 24 Oct 2022 22:25:09 +0000
Subject: [PATCH 07/11] zblerg
---
src/diagnosers/10-ip.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/diagnosers/10-ip.py b/src/diagnosers/10-ip.py
index 1d28be143..6b35731a0 100644
--- a/src/diagnosers/10-ip.py
+++ b/src/diagnosers/10-ip.py
@@ -120,7 +120,7 @@ class MyDiagnoser(Diagnoser):
return local_ip
def is_ipvx_important(x):
- return settings_get("misc.network.dns_exposure") == "both" or "ipv"+str(x)
+ return settings_get("misc.network.dns_exposure") in ["both", "ipv"+str(x)]
yield dict(
meta={"test": "ipv4"},
From 95f98a9c68aad0d125ede8c3cfb80c2b85c0d266 Mon Sep 17 00:00:00 2001
From: Alexandre Aubin
Date: Thu, 19 Jan 2023 16:45:21 +0100
Subject: [PATCH 08/11] ipexposuresetting: replace confusing negations with
explicit 'in'
---
src/diagnosers/21-web.py | 8 ++++----
src/diagnosers/24-mail.py | 4 ++--
src/dns.py | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/diagnosers/21-web.py b/src/diagnosers/21-web.py
index 74e3ca483..25554fe9d 100644
--- a/src/diagnosers/21-web.py
+++ b/src/diagnosers/21-web.py
@@ -77,7 +77,7 @@ class MyDiagnoser(Diagnoser):
ipversions = []
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
ipversions.append(4)
# To be discussed: we could also make this check dependent on the
@@ -97,7 +97,7 @@ class MyDiagnoser(Diagnoser):
# "curl --head the.global.ip" will simply timeout...
if self.do_hairpinning_test:
global_ipv4 = ipv4.get("data", {}).get("global", None)
- if global_ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
+ if global_ipv4 and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
try:
requests.head("http://" + global_ipv4, timeout=5)
except requests.exceptions.Timeout:
@@ -148,7 +148,7 @@ class MyDiagnoser(Diagnoser):
if all(
results[ipversion][domain]["status"] == "ok" for ipversion in ipversions
):
- if 4 in ipversions and settings_get("misc.network.dns_exposure") != "ipv6":
+ if 4 in ipversions and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
self.do_hairpinning_test = True
yield dict(
meta={"domain": domain},
@@ -186,7 +186,7 @@ class MyDiagnoser(Diagnoser):
)
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
- return AAAA_status in ["OK", "WRONG"] or settings_get("misc.network.dns_exposure") != "ipv4"
+ return AAAA_status in ["OK", "WRONG"] or settings_get("misc.network.dns_exposure") in ["both", "ipv6"]
if failed == 4 or ipv6_is_important_for_this_domain():
yield dict(
diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py
index 283f80681..1ae1da885 100644
--- a/src/diagnosers/24-mail.py
+++ b/src/diagnosers/24-mail.py
@@ -302,13 +302,13 @@ class MyDiagnoser(Diagnoser):
outgoing_ipversions = []
outgoing_ips = []
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
- if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") != "ipv6":
+ if ipv4.get("status") == "SUCCESS" and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
outgoing_ipversions.append(4)
global_ipv4 = ipv4.get("data", {}).get("global", {})
if global_ipv4:
outgoing_ips.append(global_ipv4)
- if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("misc.network.dns_exposure") != "ipv4":
+ if settings_get("email.smtp.smtp_allow_ipv6") or settings_get("misc.network.dns_exposure") in ["both", "ipv6"]:
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
if ipv6.get("status") == "SUCCESS":
outgoing_ipversions.append(6)
diff --git a/src/dns.py b/src/dns.py
index 9d81391e5..d56e8e625 100644
--- a/src/dns.py
+++ b/src/dns.py
@@ -186,7 +186,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
###########################
# Basic ipv4/ipv6 records #
###########################
- if ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
+ if ipv4 and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
basic.append([basename, ttl, "A", ipv4])
if ipv6:
@@ -241,7 +241,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
# Only recommend wildcard and CAA for the top level
if domain == base_domain:
- if ipv4 and settings_get("misc.network.dns_exposure") != "ipv6":
+ if ipv4 and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]:
extra.append([f"*{suffix}", ttl, "A", ipv4])
if ipv6:
From e00d60b0492ddea17e3be384ee30b3dcc96627f5 Mon Sep 17 00:00:00 2001
From: Tagada <36127788+Tagadda@users.noreply.github.com>
Date: Sat, 21 Jan 2023 13:40:04 +0100
Subject: [PATCH 09/11] Apply suggestions from code review
Co-authored-by: Alexandre Aubin
---
src/diagnosers/14-ports.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/diagnosers/14-ports.py b/src/diagnosers/14-ports.py
index 0cd54efba..57fb7cd98 100644
--- a/src/diagnosers/14-ports.py
+++ b/src/diagnosers/14-ports.py
@@ -121,7 +121,7 @@ class MyDiagnoser(Diagnoser):
for record in dnsrecords.get("items", [])
)
- if failed == 4 and settings_get("misc.network.dns_exposure") != "ipv6" or ipv6_is_important():
+ if (failed == 4 and settings_get("misc.network.dns_exposure") in ["both", "ipv4"]) or (failed == 6 and ipv6_is_important()):
yield dict(
meta={"port": port},
data={
From b8f87e372d86b7f80485a60349a9023ad5826d2b Mon Sep 17 00:00:00 2001
From: Alexandre Aubin
Date: Mon, 30 Jan 2023 16:14:49 +0100
Subject: [PATCH 10/11] dns_exposure setting: we don't want to regenconf
nginx/postfix when values change
---
src/settings.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/settings.py b/src/settings.py
index 96f11caeb..d9ea600a4 100644
--- a/src/settings.py
+++ b/src/settings.py
@@ -310,7 +310,6 @@ def regen_ssowatconf(setting_name, old_value, new_value):
@post_change_hook("nginx_compatibility")
@post_change_hook("webadmin_allowlist_enabled")
@post_change_hook("webadmin_allowlist")
-@post_change_hook("dns_exposure")
def reconfigure_nginx(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["nginx"])
@@ -342,7 +341,6 @@ def reconfigure_ssh_and_fail2ban(setting_name, old_value, new_value):
@post_change_hook("smtp_relay_user")
@post_change_hook("smtp_relay_password")
@post_change_hook("postfix_compatibility")
-@post_change_hook("dns_exposure")
def reconfigure_postfix(setting_name, old_value, new_value):
if old_value != new_value:
regen_conf(names=["postfix"])
From 56d3b4762b27eece9dfd37dce7dbbc03a6d1e497 Mon Sep 17 00:00:00 2001
From: Alexandre Aubin
Date: Mon, 30 Jan 2023 16:18:15 +0100
Subject: [PATCH 11/11] dns_exposure setting: add setting description + help
---
locales/en.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/locales/en.json b/locales/en.json
index 789ec5a4b..98abb9812 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -401,6 +401,8 @@
"firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.",
"global_settings_reset_success": "Reset global settings",
"global_settings_setting_passwordless_sudo": "Allow admins to use 'sudo' without re-typing their passwords",
+ "global_settings_setting_dns_exposure": "IP versions to consider for DNS configuration and diagnosis",
+ "global_settings_setting_dns_exposure_help": "NB: This only affects the recommended DNS configuration and diagnosis checks. This does not affect system configurations.",
"global_settings_setting_admin_strength": "Admin password strength requirements",
"global_settings_setting_admin_strength_help": "These requirements are only enforced when initializing or changing the password",
"global_settings_setting_backup_compress_tar_archives": "Compress backups",