Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: missing field multiple_railguns_allowed #57

Closed
diogotcorreia opened this issue May 28, 2024 · 6 comments · Fixed by #60
Closed

bug: missing field multiple_railguns_allowed #57

diogotcorreia opened this issue May 28, 2024 · 6 comments · Fixed by #60

Comments

@diogotcorreia
Copy link
Contributor

May 28 21:05:05 bro systemd[1]: Started CloudFlare Dynamic DNS Client.
░░ Subject: A start job for unit cfdyndns.service has finished successfully
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit cfdyndns.service has finished successfully.
░░
░░ The job identifier is 1078646.
May 28 21:05:06 bro cfdyndns-start[212683]:  INFO  cfdyndns::ip > XXX.XXX.XXX.XXX
May 28 21:05:07 bro cfdyndns-start[212683]: Error: error decoding response body: missing field `multiple_railguns_allowed` at line 1 column 578
May 28 21:05:07 bro systemd[1]: cfdyndns.service: Main process exited, code=exited, status=1/FAILURE

Seems like a change in Cloudflare's API?

Config: https://github.com/diogotcorreia/dotfiles/blob/bf6f0ee0fbf956d0983308f7270d7b7698e8d57d/hosts/bro/default.nix#L76-L80
Keep in mind that I'm using a patch from #56 as well.

cc @nrdxp

@ToyVo
Copy link

ToyVo commented May 31, 2024

After encountering this issue, I've ended up switching to a systemd service and I figured I would share, I've made it so that I do not need to manually find the zone and record ids like other example code I found does. Note the customized parts of the domains, the interface (enp2s0), and the api token, which has edit dns permissions on all zones and read permissions on zones.

systemd.services.cfdyndns = {
  serviceConfig.Type = "oneshot";
  after = [ "network.target" ];
  path = with pkgs; [curl iproute2 gawk dig jq];
  script = ''
    declare -a DOMAINS=(
      "*.diekvoss.net"
      "mc.toyvo.dev"
    )
    TOKEN=${builtins.readFile  ./cfapitoken}

    function put_record() {
      curl -sS -X PUT \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $TOKEN" \
        -d "{\"type\":\"A\",\"name\":\"$3\",\"content\":\"$4\",\"ttl\":1,\"proxied\":false}" \
        "https://api.cloudflare.com/client/v4/zones/$1/dns_records/$2"
    }

    function get_ip() {
      curl -sS \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer $TOKEN" \
         https://api.cloudflare.com/client/v4/zones/$1/dns_records/$2 | jq -r '.result.content'
    }

    function get_zone() {
      curl -sS \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer $TOKEN" \
         https://api.cloudflare.com/client/v4/zones?name=$1 | jq -r '.result.[].id'
    }

    function get_record() {
      curl -sS \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer $TOKEN" \
         https://api.cloudflare.com/client/v4/zones/$1/dns_records?name=$2 | jq -r '.result.[].id'
    }

    NEW_IP=$(ip addr show dev enp2s0 | awk '/inet / {print $2}' | cut -d '/' -f1)
    echo "The IP Address of this machine is $NEW_IP"
    for DOMAIN in "''${DOMAINS[@]}"
    do
        CURRENT_IP=$(dig +short $DOMAIN)
        echo "DNS for $DOMAIN is currently set to $CURRENT_IP"
        if [ "$CURRENT_IP" != "$NEW_IP" ]; then
          echo "DNS for $DOMAIN Doesn't point to $NEW_IP, checking for confirmation..."
          BASE_DOMAIN=$(awk -F'.' '{gsub(/^\*\./, ""); print $(NF-1) "." $NF}' <<< "$DOMAIN")
          echo "Base for $DOMAIN is $BASE_DOMAIN"
          ZONE=$(get_zone "$BASE_DOMAIN")
          echo "Zone ID for $BASE_DOMAIN is $ZONE"
          RECORD=$(get_record "$ZONE" "$DOMAIN")
          echo "Record ID for $DOMAIN is $RECORD"
          CONFIRM_IP=$(get_ip "$ZONE" "$RECORD")
          echo "DNS for $DOMAIN is confirmed set to $CONFIRM_IP"
          if [ "$CONFIRM_IP" != "$NEW_IP" ]; then
            echo "Updating DNS record for $DOMAIN to $NEW_IP"
            put_record "$ZONE" "$RECORD" "$DOMAIN" "$NEW_IP"
          else
            echo "DNS record for $DOMAIN is already set to $NEW_IP, skipping update. Assuming TTL."
          fi
        else
          echo "DNS record for $DOMAIN is $NEW_IP, skipping update."
        fi
    done
  '';
  startAt = "*:0/5";
};

Note I did not design this to handle 2tld like .co.uk etc

@diogotcorreia
Copy link
Contributor Author

This is related to cloudflare/cloudflare-rs#236
Doesn't seem fixable until the upstream crate is fixed :/

@nrdxp
Copy link
Owner

nrdxp commented Jun 7, 2024

It sounds as simple as removing a field. I'll take a look upstream later it should be quite a simple crate patch that we can apply quickly 🤞

@diogotcorreia
Copy link
Contributor Author

I ended up doing the same as @ToyVo and created a bash script as a replacement to cfdyndns (and it does less requests since it's not restricted by cloudflare crate's terrible design).
Mine should support all kinds of TLDs and domains, and it gets the public IP through DNS (using Cloudflare's 1.1.1.1), meaning the machine can be behind NAT.
It also uses systemd credentials instead of putting the token in the world-readable nix store (like the module of this project in nixpkgs).

If anyone wants to copy it:
diogotcorreia/dotfiles@7d58611

I appreciate all the work @nrdxp has done for this project, but it seems cloudflare's crate is giving some headaches at the moment 😅
Hope it works again at some point 🤞

@Wyn-Price
Copy link
Contributor

Wyn-Price commented Jun 14, 2024

I've made a PR to fix this (#60), and a PR on the upstream cloudflare-rs (cloudflare/cloudflare-rs#240), although considering they haven't yet merged cloudflare/cloudflare-rs#232 yet I don't have high hopes that mine will be merged anytime soon. I'm happy to update the nixpkgs when this gets merged, unless anybody else wants to.

For now, you can override the source to point to my repo, as shown in https://nixos.wiki/wiki/Overlays#Overriding_a_version

@ToyVo
Copy link

ToyVo commented Jun 16, 2024

It also uses systemd credentials instead of putting the token in the world-readable nix store

Haha yeah I really need to put in the work for sops

@nrdxp nrdxp closed this as completed in #60 Jun 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants