Home Assistant (HA) has a fantastic extension ecosystem that uses the Home Assistant Community Store (HACS). Most of the repositories are held on Github that have specific files copied down to your HA instance. Attempting to install a new front-end card (button-card) I kept getting a timeout issue, this seemed odd, so I SSH’d into the VM that has the container, and then exec’d into the container with:
docker exec -it <container name> bash
to install the module manually. Using wget I saw that it was attempting to connect via IPv6, and failing. I knew that my network was working with IPv6 routing as most other services function over IPv6. And that is where I came across this discussion: IPv6 support for cloning Git repositories · community · Discussion #10539 (github.com)
It appeared that my solution was going to be that I needed to disable IPv6, or at the very least prevent the container from resolving an IPv6 address for Github and associated domains. I could not disable IPv6 across the network as that would impact Thread, and other network enabled systems. I needed to prevent my local DNS from resolving the specific domains, and only returning the IPv4 entries.
My router is running OpnSense, and it has the DNS service of Unbound DNS. Initially I attempted to use the GUI to block the IPv6, but it was not granular enough. I came across this forum: Netflix and HE.net tunnel fixed using Unbound python module | Netgate Forum that lead me to this Github Gist: Unbound python-script to route websites over IPv4. (github.com)
def init(id, cfg):
return True
def deinit(id):
return True
def inform_super(id, qstate, superqstate, qdata):
return True
domains = [
".github.com.",
".github.io",
".githubusercontent.com"
]
def operate(id, event, qstate, qdata):
if event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS:
if qstate.qinfo.qtype != RR_TYPE_AAAA:
qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
for domain in domains:
if qstate.qinfo.qname_str == domain or qstate.qinfo.qname_str.endswith("." + domain):
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA)
if not msg.set_return_msg(qstate):
qstate.ext_state[id] = MODULE_ERROR
return True
# We don't need validation, result is valid
qstate.return_msg.rep.security = 2
qstate.return_rcode = RCODE_NOERROR
qstate.ext_state[id] = MODULE_FINISHED
log_info("no-aaaa: blocking AAAA request for %s" % qstate.qinfo.qname_str)
return True
qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
if event == MODULE_EVENT_MODDONE:
qstate.ext_state[id] = MODULE_FINISHED
return True
qstate.ext_state[id] = MODULE_ERROR
return True
log_info("pythonmod: script loaded")
PythonAnd then adding the following line to the /var/unbound/unbound.conf
python-script: /var/unbound/no-aaaa.py
Then restarting the Unbound DNS service in the OpnSense UI, restarting the VM, and attempting again allowed me to install the HACS component that I wanted. At some point in the future I will unwind this to see if it has been rectified, but for the moment it is working.