Nginx ACME SSL Configuration Issue

Hi everyone,

I’m trying to set up an SSL certificate with ACME for my index.html page using Nginx on NixOS. The page is accessible via the local IP, public IP, and DuckDNS domain. However, I’m running into an error when the ACME service tries to validate the domain.

Here is the error message I receive:

acme: error: 400 :: urn:ietf:params:acme:error:connection :: XXXXXXX: Fetching XXXXXXXXX/.well-known/acme-challenge/XXXXXXXXXXXX: Timeout during connect (likely firewall problem)
Failed to fetch certificates. This may mean your DNS records are set up incorrectly. Selfsigned certs are in place and dependant services will still start.

Additional Information:

  • Nginx Setup: I configured Nginx following the instructions on the NixOS Wiki.

  • Firewall Settings: I have set firewall.enable = false in NixOS, and I have also disabled the firewall on my routers for testing purposes.

  • Port 80 Status: When I check my port 80 using PortChecker, it shows as closed. However, I can still access index.html through port 80 in my browser.

  • Port 22 Status: Only port 22 is open, i think that openSSH on config is in conflict with firewall

              { config, lib, pkgs, ... }:
    
    {
      imports =
        [ # Include the results of the hardware scan.
          ./hardware-configuration.nix
        ];
    
      boot.loader.efi.canTouchEfiVariables = true;
      boot.loader.grub.enable = true;
      boot.loader.grub.device = "nodev";
      boot.loader.grub.efiSupport = true;
      boot.loader.grub.useOSProber = true;
      boot.kernelParams = [ "consoleblank=10" ];
    
       users.users.hoffmano = {
         isNormalUser = true;
         extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
         packages = with pkgs; [];
       };
    
     environment.systemPackages = with pkgs; [
         neovim
         vimPlugins.LazyVim
         curl
         nginx
         zsh
    ];
    
    programs.zsh.enable = true;
    users.defaultUserShell = pkgs.zsh;
    
      services.xserver.xkb.layout = "us";
      services.xserver.xkb.variant = "intl";
      services.openssh.enable = true;
      services.logind.extraConfig = ''
    	HandleLidSwitch = "ignore"
    	HandleLidSwitchExternalPower = "ignore"
    	HandleLidSwitchDocked = "ignore"
    	'';
    
    # services.nginx.package = pkgs.nginxStable.override { openssl = pkgs.libressl; };
    
     security.acme = {
       acceptTerms = true;
       defaults.email = "xxxxxxxxxxxxxxxx";
     };
    
    services.nginx = {
      enable = true;
      virtualHosts."XXXXXXXXXXXXXXX" = {
     # enableACME = true;
     # addSSL = true;
        root = "/var/www/XXXXXXXXXXXXXX";
    };
    };
    
    
      systemd.services.duckdns = {
        description = "DuckDNS update service";
        after = [ "network-online.target" "multi-user.target" ];
        serviceConfig = {
          ExecStart = "/home/hoffmano/scripts/update-duckdns.sh";
        };
      };
    
      systemd.timers.duckdns = {
        description = "Run DuckDNS update script periodically";
        timerConfig = {
          OnBootSec = "5m"; # Start 5 minutes after boot
          OnUnitActiveSec = "1m"; # Run every hour
        };
        wantedBy = [ "timers.target" ];
      };
    
    networking.firewall.enable = true;
    networking.nftables.enable = true;
    networking.firewall.allowedTCPPorts = [ 22 80 443 8080 ];
    networking.firewall.allowedUDPPorts = [ 22 80 443 8080 ];
    
     system.stateVersion = "24.05";
    }
    

	 hoffmano@nixos:~/ > sudo nft list ruleset
	
	# Warning: table ip filter is managed by iptables-nft, do not touch!
	table ip filter {
		chain INPUT {
			type filter hook input priority filter; policy accept;
		}
	
		chain nixos-drop {
			counter packets 0 bytes 0 drop
		}
	
		chain nixos-fw-accept {
			counter packets 1683 bytes 162245 accept
		}
	
		chain nixos-fw-refuse {
			counter packets 26 bytes 728 drop
		}
	
		chain nixos-fw-log-refuse {
			tcp flags syn / fin,syn,rst,ack counter packets 0 bytes 0 log prefix "refused connection: " level info
			pkttype != unicast counter packets 26 bytes 728 jump nixos-fw-refuse
			counter packets 0 bytes 0 jump nixos-fw-refuse
		}
	
		chain nixos-fw {
			iifname "lo" counter packets 0 bytes 0 jump nixos-fw-accept
			ct state related,established counter packets 1679 bytes 162005 jump nixos-fw-accept
			tcp dport 22 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 80 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 443 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 8080 counter packets 4 bytes 240 jump nixos-fw-accept
			udp dport 22 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 80 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 443 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 8080 counter packets 0 bytes 0 jump nixos-fw-accept
			ip protocol icmp icmp type echo-request counter packets 0 bytes 0 jump nixos-fw-accept
			counter packets 26 bytes 728 jump nixos-fw-log-refuse
		}
	}
	# Warning: table ip6 filter is managed by iptables-nft, do not touch!
	table ip6 filter {
		chain INPUT {
			type filter hook input priority filter; policy accept;
		}
	
		chain nixos-drop {
			counter packets 0 bytes 0 drop
		}
	
		chain nixos-fw-accept {
			counter packets 1028 bytes 12174304 accept
		}
	
		chain nixos-fw-refuse {
			counter packets 0 bytes 0 drop
		}
	
		chain nixos-fw-log-refuse {
			tcp flags syn / fin,syn,rst,ack counter packets 0 bytes 0 log prefix "refused connection: " level info
			pkttype != unicast counter packets 0 bytes 0 jump nixos-fw-refuse
			counter packets 0 bytes 0 jump nixos-fw-refuse
		}
	
		chain nixos-fw {
			iifname "lo" counter packets 0 bytes 0 jump nixos-fw-accept
			ct state related,established counter packets 1003 bytes 12172024 jump nixos-fw-accept
			tcp dport 22 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 80 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 443 counter packets 0 bytes 0 jump nixos-fw-accept
			tcp dport 8080 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 22 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 80 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 443 counter packets 0 bytes 0 jump nixos-fw-accept
			udp dport 8080 counter packets 0 bytes 0 jump nixos-fw-accept
			meta l4proto ipv6-icmp icmpv6 type nd-redirect counter packets 0 bytes 0 drop
			meta l4proto ipv6-icmp xt match "icmp6" counter packets 0 bytes 0 drop
			meta l4proto ipv6-icmp counter packets 25 bytes 2280 jump nixos-fw-accept
			ip6 daddr fe80::/64 udp dport 546 counter packets 0 bytes 0 jump nixos-fw-accept
			counter packets 0 bytes 0 jump nixos-fw-log-refuse
		}
	}
	# Warning: table ip mangle is managed by iptables-nft, do not touch!
	table ip mangle {
		chain PREROUTING {
			type filter hook prerouting priority mangle; policy accept;
		}
	
		chain nixos-fw-rpfilter {
			fib saddr . mark . iif oif != 0 counter packets 1709 bytes 162973 return
			udp sport 67 udp dport 68 counter packets 0 bytes 0 return
			meta secpath exists counter packets 0 bytes 0 return
			ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp sport 68 udp dport 67 counter packets 0 bytes 0 return
			counter packets 0 bytes 0 drop
		}
	}
	# Warning: table ip6 mangle is managed by iptables-nft, do not touch!
	table ip6 mangle {
		chain PREROUTING {
			type filter hook prerouting priority mangle; policy accept;
		}
	
		chain nixos-fw-rpfilter {
			fib saddr . mark . iif oif != 0 counter packets 1028 bytes 12174304 return
			meta secpath exists counter packets 0 bytes 0 return
			counter packets 0 bytes 0 drop
		}
	}
	table inet nixos-fw {
		chain rpfilter {
			type filter hook prerouting priority mangle + 10; policy drop;
			meta nfproto ipv4 udp sport . udp dport { 68 . 67, 67 . 68 } accept comment "DHCPv4 client/server"
			meta ipsec exists accept comment "decrypted packets from an IPsec VPN"
			fib saddr . mark . iif oif exists accept
			jump rpfilter-allow
		}
	
		chain rpfilter-allow {
		}
	
		chain input {
			type filter hook input priority filter; policy drop;
			iifname "lo" accept comment "trusted interfaces"
			ct state vmap { invalid : drop, established : accept, related : accept, new : jump input-allow, untracked : jump input-allow }
			tcp flags syn / fin,syn,rst,ack log prefix "refused connection: " level info
		}
	
		chain input-allow {
			tcp dport { 22, 80, 443, 8080 } accept
			udp dport { 22, 80, 443, 8080 } accept
			icmp type echo-request accept comment "allow ping"
			icmpv6 type != { nd-redirect, 139 } accept comment "Accept all ICMPv6 messages except redirects and node information queries (type 139).  See RFC 4890, section 4.4."
			ip6 daddr fe80::/64 udp dport 546 accept comment "DHCPv6 client"
		}
	}

I’m not sure what might be causing the connection timeout. It seems like a firewall issue, but with both NixOS and the router firewalls disabled, I’m not sure what else could be blocking the connection.

Does anyone have any advice on properly configuring Nginx with ACME on NixOS or suggestions for further debugging this issue? Any help would be greatly appreciated!

Thanks!

Feel free to let me know if you want to add anything else!

Sounds like your local DNS is set up to route the domain to your computer, but your router isn’t set up to forward connections to it? You’re likely behind NAT, so duckdns cannot magically establish a connection through your router without additional config there.

Either way, sounds to me like you haven’t got your networking figured out yet. Use your phone’s mobile internet to check so you’re not on the same LAN.

1 Like

You are right, I on mobile does not work properly.
Thank you so much, you help me resolve my problem.
I am behind NAT, I confirm this here.

I fix my problem using Serveo.
Now I have a domain with SSL for free and working with no problem along side my public IP NAT.

Well, frankly, you should configure your router to do port forwarding, since it most likely is not behind NAT.