PiHole Oberfläche nach dem Update auf dem Raspberry Pi 5 nicht mehr erreichbar

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • PiHole Oberfläche nach dem Update auf dem Raspberry Pi 5 nicht mehr erreichbar

      Guten Abend,

      ich habe auf meinem Raspberry Pihole per pihole-up Befehl geupdatet, was auch problemlos funktionierte. Allerdings ist nun die Seite von PiHole nicht mehr erreichbar.

      Die pihole Seite war bisher unter 192.168.10.2:85 problemlos erreichbar

      nun öffnet sich darunter jedoch

      Apache2 Debian Default Page

      woran könnte das denn liegen ?

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von FastEddie ()

    • Lies dir das mal durch.
      Pi-hole v6 arbeitet dank eingebautem Webserver flotter
      Da wurde etwas grundlegend geändert.
      Gruß
      Databox
    • @Databox

      kannst du dir mal mein Kommentar im Spoiler anschauen. Ist das korrekt ?

      Spoiler anzeigen

      # Pi-hole configuration file (v6.0.2)
      # Encoding: UTF-8
      # This file is managed by pihole-FTL
      # Last updated on 2025-02-27 17:02:32 CET

      [dns]
      # Array of upstream DNS servers used by Pi-hole
      # Example: [ "8.8.8.8", "127.0.0.1#5335", "docker-resolver" ]
      #
      # Possible values are:
      # array of IP addresses and/or hostnames, optionally with a port (#...)
      upstreams = [
      "9.9.9.9",
      "149.112.112.112",
      "192.168.10.1"
      ] ### CHANGED, default = []

      # Use this option to control deep CNAME inspection. Disabling it might be beneficial
      # for very low-end devices
      CNAMEdeepInspect = true

      # Should _esni. subdomains be blocked by default? Encrypted Server Name Indication
      # (ESNI) is certainly a good step into the right direction to enhance privacy on the
      # web. It prevents on-path observers, including ISPs, coffee shop owners and
      # firewalls, from intercepting the TLS Server Name Indication (SNI) extension by
      # encrypting it. This prevents the SNI from being used to determine which websites
      # users are visiting.
      # ESNI will obviously cause issues for pixelserv-tls which will be unable to generate
      # matching certificates on-the-fly when it cannot read the SNI. Cloudflare and Firefox
      # are already enabling ESNI. According to the IEFT draft (link above), we can easily
      # restore piselserv-tls's operation by replying NXDOMAIN to _esni. subdomains of
      # blocked domains as this mimics a "not configured for this domain" behavior.
      blockESNI = true

      # Should we overwrite the query source when client information is provided through
      # EDNS0 client subnet (ECS) information? This allows Pi-hole to obtain client IPs even
      # if they are hidden behind the NAT of a router. This feature has been requested and
      # discussed on Discourse where further information how to use it can be found:
      # Support for add-subnet option from dnsmasq (ECS/EDNS0 Client Subnet) - Implemented - Pi-hole Userspace
      EDNS0ECS = true

      # Should FTL hide queries made by localhost?
      ignoreLocalhost = false

      # Should FTL should analyze and show internally generated DNSSEC queries?
      showDNSSEC = true

      # Should FTL analyze *only* A and AAAA queries?
      analyzeOnlyAandAAAA = false

      # Controls whether and how FTL will reply with for address for which a local interface
      # exists. Changing this setting causes FTL to restart.
      #
      # Possible values are:
      # - "NONE"
      # Pi-hole will not respond automatically on PTR requests to local interface
      # addresses. Ensure pi.hole and/or hostname records exist elsewhere.
      # - "HOSTNAME"
      # Serve the machine's hostname. The hostname is queried from the kernel through
      # uname(2)->nodename. If the machine has multiple network interfaces, it can
      # also have multiple nodenames. In this case, it is unspecified and up to the
      # kernel which one will be returned. On Linux, the returned string is what has
      # been set using sethostname(2) which is typically what has been set in
      # /etc/hostname.
      # - "HOSTNAMEFQDN"
      # Serve the machine's hostname (see limitations above) as fully qualified domain
      # by adding the local domain. If no local domain has been defined (config option
      # dns.domain), FTL tries to query the domain name from the kernel using
      # getdomainname(2). If this fails, FTL appends ".no_fqdn_available" to the
      # hostname.
      # - "PI.HOLE"
      # Respond with "pi.hole".
      piholePTR = "PI.HOLE"

      # How should FTL handle queries when the gravity database is not available?
      #
      # Possible values are:
      # - "BLOCK"
      # Block all queries when the database is busy.
      # - "ALLOW"
      # Allow all queries when the database is busy.
      # - "REFUSE"
      # Refuse all queries which arrive while the database is busy.
      # - "DROP"
      # Just drop the queries, i.e., never reply to them at all. Despite "REFUSE"
      # sounding similar to "DROP", it turned out that many clients will just
      # immediately retry, causing up to several thousands of queries per second. This
      # does not happen in "DROP" mode.
      replyWhenBusy = "ALLOW"

      # FTL's internal TTL to be handed out for blocked queries in seconds. This settings
      # allows users to select a value different from the dnsmasq config option local-ttl.
      # This is useful in context of locally used hostnames that are known to stay constant
      # over long times (printers, etc.).
      # Note that large values may render whitelisting ineffective due to client-side
      # caching of blocked queries.
      blockTTL = 2

      # Array of custom DNS records
      # Example: hosts = [ "127.0.0.1 mylocal", "192.168.0.1 therouter" ]
      #
      # Possible values are:
      # Array of custom DNS records each one in HOSTS form: "IP HOSTNAME"
      hosts = []

      # If set, A and AAAA queries for plain names, without dots or domain parts, are never
      # forwarded to upstream nameservers
      domainNeeded = true ### CHANGED, default = false

      # If set, the domain is added to simple names (without a period) in /etc/hosts in the
      # same way as for DHCP-derived names
      expandHosts = true ### CHANGED, default = false

      # The DNS domain used by your Pi-hole to expand hosts and for DHCP.
      #
      # Only if DHCP is enabled below: For DHCP, this has two effects; firstly it causes the
      # DHCP server to return the domain to any hosts which request it, and secondly it sets
      # the domain which it is legal for DHCP-configured hosts to claim. The intention is to
      # constrain hostnames so that an untrusted host on the LAN cannot advertise its name
      # via DHCP as e.g. "google.com" and capture traffic not meant for it. If no domain
      # suffix is specified, then any DHCP hostname with a domain part (ie with a period)
      # will be disallowed and logged. If a domain is specified, then hostnames with a
      # domain part are allowed, provided the domain part matches the suffix. In addition,
      # when a suffix is set then hostnames without a domain part have the suffix added as
      # an optional domain part. For instance, we can set domain=mylab.com and have a
      # machine whose DHCP hostname is "laptop". The IP address for that machine is
      # available both as "laptop" and "laptop.mylab.com".
      #
      # You can disable setting a domain by setting this option to an empty string.
      #
      # Possible values are:
      # <any valid domain>
      domain = "lan"

      # Should all reverse lookups for private IP ranges (i.e., 192.168.x.y, etc) which are
      # not found in /etc/hosts or the DHCP leases file be answered with "no such domain"
      # rather than being forwarded upstream?
      bogusPriv = true

      # Validate DNS replies using DNSSEC?
      dnssec = true ### CHANGED, default = false

      # Interface to use for DNS (see also dnsmasq.listening.mode) and DHCP (if enabled)
      #
      # Possible values are:
      # a valid interface name
      interface = "eth0" ### CHANGED, default = ""

      # Add A, AAAA and PTR records to the DNS. This adds one or more names to the DNS with
      # associated IPv4 (A) and IPv6 (AAAA) records
      #
      # Possible values are:
      # <name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
      hostRecord = ""

      # Pi-hole interface listening modes
      #
      # Possible values are:
      # - "LOCAL"
      # Allow only local requests. This setting accepts DNS queries only from hosts
      # whose address is on a local subnet, i.e., a subnet for which an interface
      # exists on the server. It is intended to be set as a default on installation,
      # to allow unconfigured installations to be useful but also safe from being used
      # for DNS amplification attacks if (accidentally) running public.
      # - "SINGLE"
      # Permit all origins, accept only on the specified interface. Respond only to
      # queries arriving on the specified interface. The loopback (lo) interface is
      # automatically added to the list of interfaces to use when this option is used.
      # Make sure your Pi-hole is properly firewalled!
      # - "BIND"
      # By default, FTL binds the wildcard address. If this is not what you want, you
      # can use this option as it forces FTL to really bind only the interfaces it is
      # listening on. Note that this may result in issues when the interface may go
      # down (cable unplugged, etc.). About the only time when this is useful is when
      # running another nameserver on the same port on the same machine. This may also
      # happen if you run a virtualization API such as libvirt. When this option is
      # used, IP alias interface labels (e.g. enp2s0:0) are checked rather than
      # interface names.
      # - "ALL"
      # Permit all origins, accept on all interfaces. Make sure your Pi-hole is
      # properly firewalled! This truly allows any traffic to be replied to and is a
      # dangerous thing to do as your Pi-hole could become an open resolver. You
      # should always ask yourself if the first option doesn't work for you as well.
      # - "NONE"
      # Do not add any configuration concerning the listening mode to the dnsmasq
      # configuration file. This is useful if you want to manually configure the
      # listening mode in auxiliary configuration files. This option is really meant
      # for advanced users only, support for this option may be limited.
      listeningMode = "LOCAL"

      # Log DNS queries and replies to pihole.log
      queryLogging = true

      # List of CNAME records which indicate that <cname> is really <target>. If the <TTL> is
      # given, it overwrites the value of local-ttl
      #
      # Possible values are:
      # Array of CNAMEs each on in one of the following forms: "<cname>,<target>[,<TTL>]"
      cnameRecords = []

      # Port used by the DNS server
      port = 53

      # Reverse server (former also called "conditional forwarding") feature
      # Array of reverse servers each one in one of the following forms:
      # "<enabled>,<ip-address>[/<prefix-len>],<server>[#<port>][,<domain>]"
      #
      # Individual components:
      #
      # <enabled>: either "true" or "false"
      #
      # <ip-address>[/<prefix-len>]: Address range for the reverse server feature in CIDR
      # notation. If the prefix length is omitted, either 32 (IPv4) or 128 (IPv6) are
      # substituted (exact address match). This is almost certainly not what you want here.
      # Example: "192.168.0.0/24" for the range 192.168.0.1 - 192.168.0.255
      #
      # <server>[#<port>]: Target server to be used for the reverse server feature
      # Example: "192.168.0.1#53"
      #
      # <domain>: Domain used for the reverse server feature (e.g., "fritz.box")
      # Example: "fritz.box"
      #
      # Possible values are:
      # array of reverse servers each one in one of the following forms:
      # "<enabled>,<ip-address>[/<prefix-len>],<server>[#<port>][,<domain>]", e.g.,
      # "true,192.168.0.0/24,192.168.0.1,fritz.box"
      revServers = [
      "true,192.168.10.0/24,192.168.10.1,fritz.box"
      ] ### CHANGED, default = []

      [dns.cache]
      # Cache size of the DNS server. Note that expiring cache entries naturally make room
      # for new insertions over time. Setting this number too high will have an adverse
      # effect as not only more space is needed, but also lookup speed gets degraded in the
      # 10,000+ range. dnsmasq may issue a warning when you go beyond 10,000+ cache entries.
      size = 10000

      # Query cache optimizer: If a DNS name exists in the cache, but its time-to-live has
      # expired only recently, the data will be used anyway (a refreshing from upstream is
      # triggered). This can improve DNS query delays especially over unreliable Internet
      # connections. This feature comes at the expense of possibly sometimes returning
      # out-of-date data and less efficient cache utilization, since old data cannot be
      # flushed when its TTL expires, so the cache becomes mostly least-recently-used. To
      # mitigate issues caused by massively outdated DNS replies, the maximum overaging of
      # cached records is limited. We strongly recommend staying below 86400 (1 day) with
      # this option.
      # Setting the TTL excess time to zero will serve stale cache data regardless how long
      # it has expired. This is not recommended as it may lead to stale data being served
      # for a long time. Setting this option to any negative value will disable this feature
      # altogether.
      optimizer = 3600

      # This setting allows you to specify the TTL used for queries blocked upstream. Once
      # the TTL expires, the query will be forwarded to the upstream server again to check
      # if the block is still valid. Defaults to caching for one day (86400 seconds).
      # Setting this value to zero disables caching of queries blocked upstream.
      upstreamBlockedTTL = 86400

      [dns.blocking]
      # Should FTL block queries?
      active = true

      # How should FTL reply to blocked queries?
      #
      # Possible values are:
      # - "NULL"
      # In NULL mode, which is both the default and recommended mode for Pi-hole
      # FTLDNS, blocked queries will be answered with the "unspecified address"
      # (0.0.0.0 or ::). The "unspecified address" is a reserved IP address specified
      # by RFC 3513 - Internet Protocol Version 6 (IPv6) Addressing Architecture,
      # section 2.5.2.
      # - "IP_NODATA_AAAA"
      # In IP-NODATA-AAAA mode, blocked queries will be answered with the local IPv4
      # addresses of your Pi-hole. Blocked AAAA queries will be answered with
      # NODATA-IPV6 and clients will only try to reach your Pi-hole over its static
      # IPv4 address.
      # - "IP"
      # In IP mode, blocked queries will be answered with the local IP addresses of
      # your Pi-hole.
      # - "NX"
      # In NXDOMAIN mode, blocked queries will be answered with an empty response
      # (i.e., there won't be an answer section) and status NXDOMAIN. A NXDOMAIN
      # response should indicate that there is no such domain to the client making the
      # query.
      # - "NODATA"
      # In NODATA mode, blocked queries will be answered with an empty response (no
      # answer section) and status NODATA. A NODATA response indicates that the domain
      # exists, but there is no record for the requested query type.
      mode = "NULL"

      # Should FTL enrich blocked replies with EDNS0 information?
      #
      # Possible values are:
      # - "NONE"
      # In NONE mode, no additional EDNS information is added to blocked queries
      # - "CODE"
      # In CODE mode, blocked queries will be enriched with EDNS info-code BLOCKED (15)
      # - "TEXT"
      # In TEXT mode, blocked queries will be enriched with EDNS info-code BLOCKED (15)
      # and a text message describing the reason for the block
      edns = "TEXT"

      [dns.specialDomains]
      # Should Pi-hole always replies with NXDOMAIN to A and AAAA queries of
      # use-application-dns.net to disable Firefox automatic DNS-over-HTTP? This is
      # following the recommendation on
      # Configure networks to disable DNS over HTTPS | Firefox Help
      mozillaCanary = true

      # Should Pi-hole always replies with NXDOMAIN to A and AAAA queries of mask.icloud.com
      # and mask-h2.icloud.com to disable Apple's iCloud Private Relay to prevent Apple
      # devices from bypassing Pi-hole? This is following the recommendation on
      # Prepare your network or web server for iCloud Private Relay - iCloud - Apple Developer
      iCloudPrivateRelay = true

      [dns.reply.host]
      # Use a specific IPv4 address for the Pi-hole host? By default, FTL determines the
      # address of the interface a query arrived on and uses this address for replying to A
      # queries with the most suitable address for the requesting client. This setting can
      # be used to use a fixed, rather than the dynamically obtained, address when Pi-hole
      # responds to the following names: [ "pi.hole", "<the device's hostname>",
      # "pi.hole.<local domain>", "<the device's hostname>.<local domain>" ]
      force4 = false

      # Custom IPv4 address for the Pi-hole host
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("") Kommentar: ich denke, das ich hier die IP des Raspberrys eintragen muss
      IPv4 = ""


      # Use a specific IPv6 address for the Pi-hole host? See description for the IPv4
      # variant above for further details.
      force6 = false

      # Custom IPv6 address for the Pi-hole host
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("")
      IPv6 = ""

      [dns.reply.blocking]
      # Use a specific IPv4 address in IP blocking mode? By default, FTL determines the
      # address of the interface a query arrived on and uses this address for replying to A
      # queries with the most suitable address for the requesting client. This setting can
      # be used to use a fixed, rather than the dynamically obtained, address when Pi-hole
      # responds in the following cases: IP blocking mode is used and this query is to be
      # blocked, regular expressions with the ;reply=IP regex extension.
      force4 = false

      # Custom IPv4 address for IP blocking mode
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("")
      IPv4 = ""

      # Use a specific IPv6 address in IP blocking mode? See description for the IPv4 variant
      # above for further details.
      force6 = false

      # Custom IPv6 address for IP blocking mode
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("")
      IPv6 = ""

      [dns.rateLimit]
      # Rate-limited queries are answered with a REFUSED reply and not further processed by
      # FTL.
      # The default settings for FTL's rate-limiting are to permit no more than 1000 queries
      # in 60 seconds. Both numbers can be customized independently. It is important to note
      # that rate-limiting is happening on a per-client basis. Other clients can continue to
      # use FTL while rate-limited clients are short-circuited at the same time.
      # For this setting, both numbers, the maximum number of queries within a given time,
      # and the length of the time interval (seconds) have to be specified. For instance, if
      # you want to set a rate limit of 1 query per hour, the option should look like
      # RATE_LIMIT=1/3600. The time interval is relative to when FTL has finished starting
      # (start of the daemon + possible delay by DELAY_STARTUP) then it will advance in
      # steps of the rate-limiting interval. If a client reaches the maximum number of
      # queries it will be blocked until the end of the current interval. This will be
      # logged to /var/log/pihole/FTL.log, e.g. Rate-limiting 10.0.1.39 for at least 44
      # seconds. If the client continues to send queries while being blocked already and
      # this number of queries during the blocking exceeds the limit the client will
      # continue to be blocked until the end of the next interval (FTL.log will contain
      # lines like Still rate-limiting 10.0.1.39 as it made additional 5007 queries). As
      # soon as the client requests less than the set limit, it will be unblocked (Ending
      # rate-limitation of 10.0.1.39).
      # Rate-limiting may be disabled altogether by setting both values to zero (this
      # results in the same behavior as before FTL v5.7).
      # How many queries are permitted...
      count = 1000

      # ... in the set interval before rate-limiting?
      interval = 60

      [dhcp]
      # Is the embedded DHCP server enabled?
      active = false

      # Start address of the DHCP address pool
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.10"
      start = ""

      # End address of the DHCP address pool
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.250"
      end = ""

      # Address of the gateway to be used (typically the address of your router in a home
      # installation)
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.1"
      router = ""

      # The netmask used by your Pi-hole. For directly connected networks (i.e., networks on
      # which the machine running Pi-hole has an interface) the netmask is optional and may
      # be set to an empty string (""): it will then be determined from the interface
      # configuration itself. For networks which receive DHCP service via a relay agent, we
      # cannot determine the netmask itself, so it should explicitly be specified, otherwise
      # Pi-hole guesses based on the class (A, B or C) of the network address.
      #
      # Possible values are:
      # <any valid netmask> (e.g., "255.255.255.0") or empty string ("") for
      # auto-discovery
      netmask = ""

      # If the lease time is given, then leases will be given for that length of time. If not
      # given, the default lease time is one hour for IPv4 and one day for IPv6.
      #
      # Possible values are:
      # The lease time can be in seconds, or minutes (e.g., "45m") or hours (e.g., "1h")
      # or days (like "2d") or even weeks ("1w"). You may also use "infinite" as string
      # but be aware of the drawbacks
      leaseTime = ""

      # Should Pi-hole make an attempt to also satisfy IPv6 address requests (be aware that
      # IPv6 works a whole lot different than IPv4)
      ipv6 = false

      # Enable DHCPv4 Rapid Commit Option specified in RFC 4039. Should only be enabled if
      # either the server is the only server for the subnet to avoid conflicts
      rapidCommit = false

      # Advertise DNS server multiple times to clients. Some devices will add their own
      # proprietary DNS servers to the list of DNS servers, which can cause issues with
      # Pi-hole. This option will advertise the Pi-hole DNS server multiple times to
      # clients, which should prevent this from happening.
      multiDNS = false

      # Enable logging for DHCP. This will log all relevant DHCP-related activity, including,
      # e.g., all the options sent to DHCP clients and the tags used to determine them (if
      # any). This can be useful for debugging DHCP issues. The generated output is saved to
      # the file specified by files.log.dnsmasq below.
      logging = false

      # Ignore unknown DHCP clients.
      # If this option is set, Pi-hole ignores all clients which are not explicitly
      # configured through dhcp.hosts. This can be useful to prevent unauthorized clients
      # from getting an IP address from the DHCP server.
      # It should be noted that this option is not a security feature, as clients can still
      # assign themselves an IP address and use the network. It is merely a convenience
      # feature to prevent unknown clients from getting a valid IP configuration assigned
      # automatically.
      # Note that you will need to configure new clients manually in dhcp.hosts before they
      # can use the network when this feature is enabled.
      ignoreUnknownClients = false

      # Per host parameters for the DHCP server. This allows a machine with a particular
      # hardware address to be always allocated the same hostname, IP address and lease time
      # or to specify static DHCP leases
      #
      # Possible values are:
      # Array of static leases each on in one of the following forms:
      # "[<hwaddr>][,id:<client_id>|*][,set:<tag>][,tag:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]"
      hosts = []

      [ntp.ipv4]
      # Should FTL act as network time protocol (NTP) server (IPv4)?
      active = true

      # IPv4 address to listen on for NTP requests
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("") for wildcard (0.0.0.0)
      address = ""

      [ntp.ipv6]
      # Should FTL act as network time protocol (NTP) server (IPv6)?
      active = true

      # IPv6 address to listen on for NTP requests
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("") for wildcard (::)
      address = ""

      [ntp.sync]
      # Should FTL try to synchronize the system time with an upstream NTP server?
      active = true

      # NTP upstream server to sync with, e.g., "pool.ntp.org". Note that the NTP server
      # should be located as close as possible to you in order to minimize the time offset
      # possibly introduced by different routing paths.
      #
      # Possible values are:
      # valid NTP upstream server
      server = "pool.ntp.org"

      # Interval in seconds between successive synchronization attempts with the NTP server
      interval = 3600

      # Number of NTP syncs to perform and average before updating the system time
      count = 8

      [ntp.sync.rtc]
      # Should FTL update a real-time clock (RTC) if available?
      set = false

      # Path to the RTC device to update. Leave empty for auto-discovery
      #
      # Possible values are:
      # Path to the RTC device, e.g., "/dev/rtc0"
      device = ""

      # Should the RTC be set to UTC?
      utc = true

      [resolver]
      # Should FTL try to resolve IPv4 addresses to hostnames?
      resolveIPv4 = true

      # Should FTL try to resolve IPv6 addresses to hostnames?
      resolveIPv6 = true

      # Control whether FTL should use the fallback option to try to obtain client names from
      # checking the network table. This behavior can be disabled with this option.
      # Assume an IPv6 client without a host names. However, the network table knows -
      # though the client's MAC address - that this is the same device where we have a host
      # name for another IP address (e.g., a DHCP server managed IPv4 address). In this
      # case, we use the host name associated to the other address as this is the same
      # device.
      networkNames = true

      # With this option, you can change how (and if) hourly PTR requests are made to check
      # for changes in client and upstream server hostnames.
      #
      # Possible values are:
      # - "IPV4_ONLY"
      # Do hourly PTR lookups only for IPv4 addresses. This is the new default since
      # Pi-hole FTL v5.3.2. It should resolve issues with more and more very
      # short-lived PE IPv6 addresses coming up in a lot of networks.
      # - "ALL"
      # Do hourly PTR lookups for all addresses. This was the default until FTL
      # v5.3(.1). It has been replaced as it can create a lot of PTR queries for those
      # with many IPv6 addresses in their networks.
      # - "UNKNOWN"
      # Only resolve unknown hostnames. Already existing hostnames are never refreshed,
      # i.e., there will be no PTR queries made for clients where hostnames are known.
      # This also means that known hostnames will not be updated once known.
      # - "NONE"
      # Don't do any hourly PTR lookups. This means we look host names up exactly once
      # (when we first see a client) and never again. You may miss future changes of
      # host names.
      refreshNames = "IPV4_ONLY"

      [database]
      # Should FTL load information from the database on startup to be aware of the most
      # recent history?
      DBimport = true

      # How long should queries be stored in the database [days]?
      # Setting this value to 0 will disable the database.
      maxDBdays = 91

      # How often do we store queries in FTL's database [seconds]?
      DBinterval = 60

      # Should FTL enable Write-Ahead Log (WAL) mode for the on-disk query database
      # (configured via files.database)?
      # It is recommended to leave this setting enabled for performance reasons. About the
      # only reason to disable WAL mode is if you are experiencing specific issues with it,
      # e.g., when using a database that is accessed from multiple hosts via a network
      # share. When this setting is disabled, FTL will use SQLite3's default journal mode
      # (rollback journal in DELETE mode).
      useWAL = true

      [database.network]
      # Should FTL analyze the local ARP cache? When disabled, client identification and the
      # network table will stop working reliably.
      parseARPcache = true

      # How long should IP addresses be kept in the network_addresses table [days]? IP
      # addresses (and associated host names) older than the specified number of days are
      # removed to avoid dead entries in the network overview table.
      expire = 91

      [webserver]
      # On which domain is the web interface served?
      #
      # Possible values are:
      # <valid domain>
      domain = "pi.hole"

      # Webserver access control list (ACL) allowing for restrictions to be put on the list
      # of IP addresses which have access to the web server. The ACL is a comma separated
      # list of IP subnets, where each subnet is prepended by either a - or a + sign. A plus
      # sign means allow, where a minus sign means deny. If a subnet mask is omitted, such
      # as -1.2.3.4, this means to deny only that single IP address. If this value is not
      # set (empty string), all accesses are allowed. Otherwise, the default setting is to
      # deny all accesses. On each request the full list is traversed, and the last (!)
      # match wins. IPv6 addresses may be specified in CIDR-form [a:b::c]/64.
      #
      # Example 1: acl = "+127.0.0.1,+[::1]"
      # ---> deny all access, except from 127.0.0.1 and ::1,
      # Example 2: acl = "+192.168.0.0/16"
      # ---> deny all accesses, except from the 192.168.0.0/16 subnet,
      # Example 3: acl = "+[::]/0" ---> allow only IPv6 access.
      #
      # Possible values are:
      # <valid ACL>
      acl = ""

      # Ports to be used by the webserver.
      # Comma-separated list of ports to listen on. It is possible to specify an IP address
      # to bind to. In this case, an IP address and a colon must be prepended to the port
      # number. For example, to bind to the loopback interface on port 80 (IPv4) and to all
      # interfaces port 8080 (IPv4), use "127.0.0.1:80,8080". "[::]:80" can be used to
      # listen to IPv6 connections to port 80. IPv6 addresses of network interfaces can be
      # specified as well, e.g. "[::1]:80" for the IPv6 loopback interface. [::]:80 will
      # bind to port 80 IPv6 only.
      # In order to use port 80 for all interfaces, both IPv4 and IPv6, use either the
      # configuration "80,[::]:80" (create one socket for IPv4 and one for IPv6 only), or
      # "+80" (create one socket for both, IPv4 and IPv6). The '+' notation to use IPv4 and
      # IPv6 will only work if no network interface is specified. Depending on your
      # operating system version and IPv6 network environment, some configurations might not
      # work as expected, so you have to test to find the configuration most suitable for
      # your needs. In case "+80" does not work for your environment, you need to use
      # "80,[::]:80".
      # If the port is TLS/SSL, a letter 's' (secure) must be appended, for example,
      # "80,443s" will open port 80 and port 443, and connections on port 443 will be
      # encrypted. For non-encrypted ports, it is allowed to append letter 'r' (as in
      # redirect). Redirected ports will redirect all their traffic to the first configured
      # SSL port. For example, if webserver.port is "80r,443s", then all HTTP traffic coming
      # at port 80 will be redirected to HTTPS port 443.
      # When specifying 'o' (optional) behind a port, inability to use this port is not
      # considered an error. For instance, specifying "80o,8080o" will allow the webserver
      # to listen on either 80, 8080, both or even none of the two ports. This flag may be
      # combined with 'r' and 's' like "80or,443os,8080,4443s" (80 redirecting to SSL if
      # available, 443 encrypted if available, 8080 mandatory and unencrypted, 4443
      # mandatory and encrypted).
      # If this value is not set (empty string), the web server will not be started and,
      # hence, the API will not be available.
      #
      # Possible values are:
      # comma-separated list of <[ip_address:]port>
      port = "8080o,443os,[::]:8080o,[::]:443" ### CHANGED, default = "80o,443os,[::]:80o,[::]:443os"

      # Maximum number of worker threads allowed.
      # The Pi-hole web server handles each incoming connection in a separate thread.
      # Therefore, the value of this option is effectively the number of concurrent HTTP
      # connections that can be handled. Any other connections are queued until they can be
      # processed by a unoccupied thread.
      # The default value of 0 means that the number of threads is automatically determined
      # by the number of online CPU cores minus 1 (e.g., launching up to 8-1 = 7 threads on
      # 8 cores). Any other value specifies the number of threads explicitly. A hard-coded
      # maximum of 64 threads is enforced for this option.
      # The total number of threads you see may be lower than the configured value as
      # threads are only created when needed due to incoming connections.
      threads = 0

      [webserver.session]
      # Session timeout in seconds. If a session is inactive for more than this time, it will
      # be terminated. Sessions are continuously refreshed by the web interface, preventing
      # sessions from timing out while the web interface is open.
      # This option may also be used to make logins persistent for long times, e.g. 86400
      # seconds (24 hours), 604800 seconds (7 days) or 2592000 seconds (30 days). Note that
      # the total number of concurrent sessions is limited so setting this value too high
      # may result in users being rejected and unable to log in if there are already too
      # many sessions active.
      timeout = 1800

      # Should Pi-hole backup and restore sessions from the database? This is useful if you
      # want to keep your sessions after a restart of the web interface.
      restore = true

      [webserver.tls]
      # Path to the TLS (SSL) certificate file. All directories along the path must be
      # readable and accessible by the user running FTL (typically 'pihole'). This option is
      # only required when at least one of webserver.port is TLS. The file must be in PEM
      # format, and it must have both, private key and certificate (the *.pem file created
      # must contain a 'CERTIFICATE' section as well as a 'RSA PRIVATE KEY' section).
      # The *.pem file can be created using
      # cp server.crt server.pem
      # cat server.key >> server.pem
      # if you have these files instead
      #
      # Possible values are:
      # <valid TLS certificate file (*.pem)>
      cert = "/etc/pihole/tls.pem"

      [webserver.paths]
      # Server root on the host
      #
      # Possible values are:
      # <valid path>
      webroot = "/var/www/html"

      # Sub-directory of the root containing the web interface
      #
      # Possible values are:
      # <valid subpath>, both slashes are needed!
      webhome = "/admin/"

      [webserver.interface]
      # Should the web interface use the boxed layout?
      boxed = true

      # Theme used by the Pi-hole web interface
      #
      # Possible values are:
      # - "default-auto"
      # Pi-hole auto
      # - "default-light"
      # Pi-hole day
      # - "default-dark"
      # Pi-hole midnight
      # - "default-darker"
      # Pi-hole deep-midnight
      # - "high-contrast"
      # High-contrast light
      # - "high-contrast-dark"
      # High-contrast dark
      # - "lcars"
      # Star Trek LCARS
      theme = "default-dark" ### CHANGED, default = "default-auto"

      [webserver.api]
      # Number of concurrent sessions allowed for the API. If the number of sessions exceeds
      # this value, no new sessions will be allowed until the number of sessions drops due
      # to session expiration or logout. Note that the number of concurrent sessions is
      # irrelevant if authentication is disabled as no sessions are used in this case.
      max_sessions = 16

      # Should FTL prettify the API output (add extra spaces, newlines and indentation)?
      prettyJSON = false

      # API password hash
      #
      # Possible values are:
      # <valid Pi-hole password hash>
      pwhash = "49b951d42416956882a66b083d93582d291f8c86ddf12c25302c5440bf8636ad" ### CHANGED, default = ""

      # Pi-hole 2FA TOTP secret. When set to something different than "", 2FA authentication
      # will be enforced for the API and the web interface. This setting is write-only, you
      # can not read the secret back.
      #
      # Possible values are:
      # <valid TOTP secret (20 Bytes in Base32 encoding)>
      totp_secret = ""

      # Pi-hole application password.
      # After you turn on two-factor (2FA) verification and set up an Authenticator app, you
      # may run into issues if you use apps or other services that don't support two-step
      # verification. In this case, you can create and use an app password to sign in. An
      # app password is a long, randomly generated password that can be used instead of your
      # regular password + TOTP token when signing in to the API. The app password can be
      # generated through the API and will be shown only once. You can revoke the app
      # password at any time. If you revoke the app password, be sure to generate a new one
      # and update your app with the new password.
      #
      # Possible values are:
      # <valid Pi-hole password hash>
      app_pwhash = ""

      # Should application password API sessions be allowed to modify config settings?
      # Setting this to true allows third-party applications using the application password
      # to modify settings, e.g., the upstream DNS servers, DHCP server settings, or
      # changing passwords. This setting should only be enabled if really needed and only if
      # you trust the applications using the application password.
      app_sudo = false

      # Should FTL create a temporary CLI password? This password is stored in clear in
      # /etc/pihole and can be used by the CLI (pihole ... commands) to authenticate
      # against the API. Note that the password is only valid for the current session and
      # regenerated on each FTL restart. Sessions initiated with this password cannot modify
      # the Pi-hole configuration (change passwords, etc.) for security reasons but can
      # still use the API to query data and manage lists.
      cli_pw = true

      # Array of clients to be excluded from certain API responses (regex):
      # - Query Log (/api/queries)
      # - Top Clients (/api/stats/top_clients)
      # This setting accepts both IP addresses (IPv4 and IPv6) as well as hostnames.
      # Note that backslashes "\" need to be escaped, i.e. "\\" in this setting
      #
      # Example: [ "^192\\.168\\.2\\.56$", "^fe80::341:[0-9a-f]*$", "^localhost$" ]
      #
      # Possible values are:
      # array of regular expressions describing clients
      excludeClients = []

      # Array of domains to be excluded from certain API responses (regex):
      # - Query Log (/api/queries)
      # - Top Clients (/api/stats/top_domains)
      # Note that backslashes "\" need to be escaped, i.e. "\\" in this setting
      #
      # Example: [ "(^|\\.)\\.google\\.de$", "\\.pi-hole\\.net$" ]
      #
      # Possible values are:
      # array of regular expressions describing domains
      excludeDomains = []

      # How much history should be imported from the database and returned by the API
      # [seconds]? (max 24*60*60 = 86400)
      maxHistory = 86400

      # Up to how many clients should be returned in the activity graph endpoint
      # (/api/history/clients)?
      # This setting can be overwritten at run-time using the parameter N. Setting this to 0
      # will always send all clients. Be aware that this may be challenging for the GUI if
      # you have many (think > 1.000 clients) in your network
      maxClients = 10

      # How should the API compute the most active clients? If set to true, the API will
      # return the clients with the most queries globally (within 24 hours). If set to
      # false, the API will return the clients with the most queries per time slot
      # individually.
      client_history_global_max = true

      # Allow destructive API calls (e.g. deleting all queries, powering off the system, ...)
      allow_destructive = true

      [webserver.api.temp]
      # Which upper temperature limit should be used by Pi-hole? Temperatures above this
      # limit will be shown as "hot". The number specified here is in the unit defined below
      limit = 60.000000

      # Which temperature unit should be used for temperatures processed by FTL?
      #
      # Possible values are:
      # - "C"
      # Celsius
      # - "F"
      # Fahrenheit
      # - "K"
      # Kelvin
      unit = "C"

      [files]
      # The file which contains the PID of FTL's main process.
      #
      # Possible values are:
      # <any writable file>
      pid = "/run/pihole-FTL.pid"

      # The location of FTL's long-term database
      #
      # Possible values are:
      # <any FTL database>
      database = "/etc/pihole/pihole-FTL.db"

      # The location of Pi-hole's gravity database
      #
      # Possible values are:
      # <any Pi-hole gravity database>
      gravity = "/etc/pihole/gravity.db"

      # A temporary directory where Pi-hole can store files during gravity updates. This
      # directory must be writable by the user running gravity (typically pihole).
      #
      # Possible values are:
      # <any existing world-writable writable directory>
      gravity_tmp = "/tmp"

      # The database containing MAC -> Vendor information for the network table
      #
      # Possible values are:
      # <any Pi-hole macvendor database>
      macvendor = "/etc/pihole/macvendor.db"

      # The old config file of Pi-hole used before v6.0
      #
      # Possible values are:
      # <any Pi-hole setupVars file>
      setupVars = "/etc/pihole/setupVars.conf"

      # An optional file containing a pcap capture of the network traffic. This file is used
      # for debugging purposes only. If you don't know what this is, you don't need it.
      # Setting this to an empty string disables pcap recording. The file must be writable
      # by the user running FTL (typically pihole). Failure to write to this file will
      # prevent the DNS resolver from starting. The file is appended to if it already
      # exists.
      #
      # Possible values are:
      # <any writable pcap file>
      pcap = ""

      [files.log]
      # The location of FTL's log file
      #
      # Possible values are:
      # <any writable file>
      ftl = "/var/log/pihole/FTL.log"

      # The log file used by the embedded dnsmasq DNS server
      #
      # Possible values are:
      # <any writable file>
      dnsmasq = "/var/log/pihole/pihole.log"

      # The log file used by the webserver
      #
      # Possible values are:
      # <any writable file>
      webserver = "/var/log/pihole/webserver.log"

      [misc]
      # Using privacy levels you can specify which level of detail you want to see in your
      # Pi-hole statistics. Changing this setting will trigger a restart of FTL
      #
      # Possible values are:
      # - 0
      # Don't hide anything, all statistics are available.
      # - 1
      # Hide domains. This setting disables Top Domains and Top Ads
      # - 2
      # Hide domains and clients. This setting disables Top Domains, Top Ads, Top
      # Clients and Clients over time.
      # - 3
      # Anonymize everything. This setting disabled almost any statistics and query
      # analysis. There will be no long-term database logging and no Query Log. You
      # will also loose most regex features.
      privacylevel = 0

      # During startup, in some configurations, network interfaces appear only late during
      # system startup and are not ready when FTL tries to bind to them. Therefore, you may
      # want FTL to wait a given amount of time before trying to start the DNS revolver.
      # This setting takes any integer value between 0 and 300 seconds. To prevent delayed
      # startup while the system is already running and FTL is restarted, the delay only
      # takes place within the first 180 seconds (hard-coded) after booting.
      delay_startup = 0

      # Set niceness of pihole-FTL. Defaults to -10 and can be disabled altogether by setting
      # a value of -999. The nice value is an attribute that can be used to influence the
      # CPU scheduler to favor or disfavor a process in scheduling decisions. The range of
      # the nice value varies across UNIX systems. On modern Linux, the range is -20 (high
      # priority = not very nice to other processes) to +19 (low priority).
      nice = -10

      # Should FTL translate its own stack addresses into code lines during the bug
      # backtrace? This improves the analysis of crashed significantly. It is recommended to
      # leave the option enabled. This option should only be disabled when addr2line is
      # known to not be working correctly on the machine because, in this case, the
      # malfunctioning addr2line can prevent from generating any backtrace at all.
      addr2line = true

      # Should FTL load additional dnsmasq configuration files from /etc/dnsmasq.d/?
      etc_dnsmasq_d = false

      # Additional lines to inject into the generated dnsmasq configuration.
      # Warning: This is an advanced setting and should only be used with care. Incorrectly
      # formatted or duplicated lines as well as lines conflicting with the automatic
      # configuration of Pi-hole can break the embedded dnsmasq and will stop DNS resolution
      # from working.
      # Use this option with extra care.
      #
      # Possible values are:
      # array of valid dnsmasq config line options
      dnsmasq_lines = []

      # Log additional information about queries and replies to pihole.log
      # When this setting is enabled, the log has extra information at the start of each
      # line. This consists of a serial number which ties together the log lines associated
      # with an individual query, and the IP address of the requestor. This setting is only
      # effective if dns.queryLogging is enabled, too. This option is only useful for
      # debugging and is not recommended for normal use.
      extraLogging = false

      # Put configuration into read-only mode. This will prevent any changes to the
      # configuration file via the API or CLI. This setting useful when a configuration is
      # to be forced/modified by some third-party application (like infrastructure-as-code
      # providers) and should not be changed by any means.
      readOnly = false

      [misc.check]
      # Pi-hole is very lightweight on resources. Nevertheless, this does not mean that you
      # should run Pi-hole on a server that is otherwise extremely busy as queuing on the
      # system can lead to unnecessary delays in DNS operation as the system becomes less
      # and less usable as the system load increases because all resources are permanently
      # in use. To account for this, FTL regularly checks the system load. To bring this to
      # your attention, FTL warns about excessive load when the 15 minute system load
      # average exceeds the number of cores.
      # This check can be disabled with this setting.
      load = true

      # FTL stores history in shared memory to allow inter-process communication with forked
      # dedicated TCP workers. If FTL runs out of memory, it cannot continue to work as
      # queries cannot be analyzed any further. Hence, FTL checks if enough shared memory is
      # available on your system and warns you if this is not the case.
      # By default, FTL warns if the shared-memory usage exceeds 90%. You can set any
      # integer limit between 0 to 100 (interpreted as percentages) where 0 means that
      # checking of shared-memory usage is disabled.
      shmem = 90

      # FTL stores its long-term history in a database file on disk. Furthermore, FTL stores
      # log files. By default, FTL warns if usage of the disk holding any crucial file
      # exceeds 90%. You can set any integer limit between 0 to 100 (interpreted as
      # percentages) where 0 means that checking of disk usage is disabled.
      disk = 90

      [debug]
      # Print debugging information about database actions. This prints performed SQL
      # statements as well as some general information such as the time it took to store the
      # queries and how many have been saved to the database.
      database = false

      # Prints a list of the detected interfaces on the startup of pihole-FTL. Also, prints
      # whether these interfaces are IPv4 or IPv6 interfaces.
      networking = false

      # Print information about shared memory locks. Messages will be generated when waiting,
      # obtaining, and releasing a lock.
      locks = false

      # Print extensive query information (domains, types, replies, etc.). This has always
      # been part of the legacy debug mode of pihole-FTL.
      queries = false

      # Print flags of queries received by the DNS hooks. Only effective when DEBUG_QUERIES
      # is enabled as well.
      flags = false

      # Print information about shared memory buffers. Messages are either about creating or
      # enlarging shmem objects or string injections.
      shmem = false

      # Print information about garbage collection (GC): What is to be removed, how many have
      # been removed and how long did GC take.
      gc = false

      # Print information about ARP table processing: How long did parsing take, whether read
      # MAC addresses are valid, and if the macvendor.db file exists.
      arp = false

      # Controls if FTLDNS should print extended details about regex matching into FTL.log.
      regex = false

      # Print extra debugging information concerning API calls. This includes the request,
      # the request parameters, and the internal details about how the algorithms decide
      # which data to present and in what form. This very verbose output should only be used
      # when debugging specific API issues and can be helpful, e.g., when a client cannot
      # connect due to an obscure API error. Furthermore, this setting enables logging of
      # all API requests (auth log) and details about user authentication attempts.
      api = false

      # Print extra debugging information about TLS connections. This includes the TLS
      # version, the cipher suite, the certificate chain and much more. This very verbose
      # output should only be used when debugging specific TLS issues and can be helpful,
      # e.g., when a client cannot connect due to an obscure TLS error as modern browsers do
      # not provide much information about the underlying TLS connection and most often give
      # only very generic error messages without much/any underlying technical information.
      tls = false

      # Print information about overTime memory operations, such as initializing or moving
      # overTime slots.
      overtime = false

      # Print information about status changes for individual queries. This can be useful to
      # identify unexpected unknown queries.
      status = false

      # Print information about capabilities granted to the pihole-FTL process. The current
      # capabilities are printed on receipt of SIGHUP, i.e., the current set of capabilities
      # can be queried without restarting pihole-FTL (by setting DEBUG_CAPS=true and
      # thereafter sending killall -HUP pihole-FTL).
      caps = false

      # Print information about DNSSEC activity
      dnssec = false

      # FTL uses dynamically allocated vectors for various tasks. This config option enables
      # extensive debugging information such as information about allocation, referencing,
      # deletion, and appending.
      vectors = false

      # Extensive information about hostname resolution like which DNS servers are used in
      # the first and second hostname resolving tries (only affecting internally generated
      # PTR queries).
      resolver = false

      # Print debugging information about received EDNS(0) data.
      edns0 = false

      # Log various important client events such as change of interface (e.g., client
      # switching from WiFi to wired or VPN connection), as well as extensive reporting
      # about how clients were assigned to its groups.
      clients = false

      # Log information related to alias-client processing.
      aliasclients = false

      # Log information regarding FTL's embedded event handling queue.
      events = false

      # Log information about script helpers, e.g., due to dhcp-script.
      helper = false

      # Print config parsing details
      config = false

      # Debug monitoring of /etc/pihole filesystem events
      inotify = false

      # Debug monitoring of the webserver (CivetWeb) events
      webserver = false

      # Temporary flag that may print additional information. This debug flag is meant to be
      # used whenever needed for temporary investigations. The logged content may change
      # without further notice at any time.
      extra = false

      # Reserved debug flag
      reserved = false

      # Print information about NTP synchronization
      ntp = false

      # Print information about netlink communication and parsing
      netlink = false

      # Set all debug flags at once. This is a convenience option to enable all debug flags
      # at once. Note that this option is not persistent, setting it to true will enable all
      # *remaining* debug flags but unsetting it will disable *all* debug flags.
      all = false

      # Configuration statistics:
      # 152 total entries out of which 143 entries are default
      # --> 9 entries are modified

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von FastEddie ()

    • Da kann ich dir leider nicht weiterhelfen, da ich Pihole selbst nicht nutze.
      Vielleicht gibt es hier jemand, der dieses Problem schon beseitigt hat.
      Gruß
      Databox
    • Vorher sichern, falls etwas schief läuft. ;)
      Gruß
      Databox
    • Guten Abend @dhwz

      Die Seite des Pi-Hole ist auch unter 192.168.10.2:8080 nicht erreichbar und wenn ich :8080 weglasse lande ich auf der CS-IPC Startseite

      Der Versuch das Webinterface von Pi-Hole unter 192.168.10.2:80/admin/ aufzurufen schlägt fehl:

      Meldung

      403 Forbidden

      hier mal meine lighttpd.conf

      Spoiler anzeigen

      server.modules = (
      "mod_indexfile",
      "mod_access",
      "mod_alias",
      "mod_redirect",
      )

      server.document-root = "/var/www/html"
      server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
      server.errorlog = "/var/log/lighttpd/error.log"
      server.pid-file = "/run/lighttpd.pid"
      server.username = "www-data"
      server.groupname = "www-data"
      server.port = 85

      # features
      #Server_feature-flagsDetails
      server.feature-flags += ("server.h2proto" => "enable")
      server.feature-flags += ("server.h2c" => "enable")
      server.feature-flags += ("server.graceful-shutdown-timeout" => 5)
      #server.feature-flags += ("server.graceful-restart-bg" => "enable")

      # strict parsing and normalization of URL for consistency and security
      # Server_http-parseoptsDetails
      # (might need to explicitly set "url-path-2f-decode" = "disable"
      # if a specific application is encoding URLs inside url-path)
      server.http-parseopts = (
      "header-strict" => "enable",# default
      "host-strict" => "enable",# default
      "host-normalize" => "enable",# default
      "url-normalize-unreserved"=> "enable",# recommended highly
      "url-normalize-required" => "enable",# recommended
      "url-ctrls-reject" => "enable",# recommended
      "url-path-2f-decode" => "enable",# recommended highly (unless breaks app)
      #"url-path-2f-reject" => "enable",
      "url-path-dotseg-remove" => "enable",# recommended highly (unless breaks app)
      #"url-path-dotseg-reject" => "enable",
      #"url-query-20-plus" => "enable",# consistency in query string
      )

      index-file.names = ( "index.php", "index.html" )
      url.access-deny = ( "~", ".inc" )
      static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

      # default listening port for IPv6 falls back to the IPv4 port
      include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
      include_shell "/usr/share/lighttpd/create-mime.conf.pl"
      include "/etc/lighttpd/conf-enabled/*.conf"

      #server.compat-module-load = "disable"
      server.modules += (
      "mod_dirlisting",
      "mod_staticfile",
      )



      ebenfalls hier die pihole.toml Datei:

      Spoiler anzeigen

      # Pi-hole configuration file (v6.0.2)
      # Encoding: UTF-8
      # This file is managed by pihole-FTL
      # Last updated on 2025-02-27 17:02:32 CET

      [dns]
      # Array of upstream DNS servers used by Pi-hole
      # Example: [ "8.8.8.8", "127.0.0.1#5335", "docker-resolver" ]
      #
      # Possible values are:
      # array of IP addresses and/or hostnames, optionally with a port (#...)
      upstreams = [
      "9.9.9.9",
      "149.112.112.112",
      "192.168.10.1"
      ] ### CHANGED, default = []

      # Use this option to control deep CNAME inspection. Disabling it might be beneficial
      # for very low-end devices
      CNAMEdeepInspect = true

      # Should _esni. subdomains be blocked by default? Encrypted Server Name Indication
      # (ESNI) is certainly a good step into the right direction to enhance privacy on the
      # web. It prevents on-path observers, including ISPs, coffee shop owners and
      # firewalls, from intercepting the TLS Server Name Indication (SNI) extension by
      # encrypting it. This prevents the SNI from being used to determine which websites
      # users are visiting.
      # ESNI will obviously cause issues for pixelserv-tls which will be unable to generate
      # matching certificates on-the-fly when it cannot read the SNI. Cloudflare and Firefox
      # are already enabling ESNI. According to the IEFT draft (link above), we can easily
      # restore piselserv-tls's operation by replying NXDOMAIN to _esni. subdomains of
      # blocked domains as this mimics a "not configured for this domain" behavior.
      blockESNI = true

      # Should we overwrite the query source when client information is provided through
      # EDNS0 client subnet (ECS) information? This allows Pi-hole to obtain client IPs even
      # if they are hidden behind the NAT of a router. This feature has been requested and
      # discussed on Discourse where further information how to use it can be found:
      # Support for add-subnet option from dnsmasq (ECS/EDNS0 Client Subnet) - Implemented - Pi-hole Userspace
      EDNS0ECS = true

      # Should FTL hide queries made by localhost?
      ignoreLocalhost = false

      # Should FTL should analyze and show internally generated DNSSEC queries?
      showDNSSEC = true

      # Should FTL analyze *only* A and AAAA queries?
      analyzeOnlyAandAAAA = false

      # Controls whether and how FTL will reply with for address for which a local interface
      # exists. Changing this setting causes FTL to restart.
      #
      # Possible values are:
      # - "NONE"
      # Pi-hole will not respond automatically on PTR requests to local interface
      # addresses. Ensure pi.hole and/or hostname records exist elsewhere.
      # - "HOSTNAME"
      # Serve the machine's hostname. The hostname is queried from the kernel through
      # uname(2)->nodename. If the machine has multiple network interfaces, it can
      # also have multiple nodenames. In this case, it is unspecified and up to the
      # kernel which one will be returned. On Linux, the returned string is what has
      # been set using sethostname(2) which is typically what has been set in
      # /etc/hostname.
      # - "HOSTNAMEFQDN"
      # Serve the machine's hostname (see limitations above) as fully qualified domain
      # by adding the local domain. If no local domain has been defined (config option
      # dns.domain), FTL tries to query the domain name from the kernel using
      # getdomainname(2). If this fails, FTL appends ".no_fqdn_available" to the
      # hostname.
      # - "PI.HOLE"
      # Respond with "pi.hole".
      piholePTR = "PI.HOLE"

      # How should FTL handle queries when the gravity database is not available?
      #
      # Possible values are:
      # - "BLOCK"
      # Block all queries when the database is busy.
      # - "ALLOW"
      # Allow all queries when the database is busy.
      # - "REFUSE"
      # Refuse all queries which arrive while the database is busy.
      # - "DROP"
      # Just drop the queries, i.e., never reply to them at all. Despite "REFUSE"
      # sounding similar to "DROP", it turned out that many clients will just
      # immediately retry, causing up to several thousands of queries per second. This
      # does not happen in "DROP" mode.
      replyWhenBusy = "ALLOW"

      # FTL's internal TTL to be handed out for blocked queries in seconds. This settings
      # allows users to select a value different from the dnsmasq config option local-ttl.
      # This is useful in context of locally used hostnames that are known to stay constant
      # over long times (printers, etc.).
      # Note that large values may render whitelisting ineffective due to client-side
      # caching of blocked queries.
      blockTTL = 2

      # Array of custom DNS records
      # Example: hosts = [ "127.0.0.1 mylocal", "192.168.0.1 therouter" ]
      #
      # Possible values are:
      # Array of custom DNS records each one in HOSTS form: "IP HOSTNAME"
      hosts = []

      # If set, A and AAAA queries for plain names, without dots or domain parts, are never
      # forwarded to upstream nameservers
      domainNeeded = true ### CHANGED, default = false

      # If set, the domain is added to simple names (without a period) in /etc/hosts in the
      # same way as for DHCP-derived names
      expandHosts = true ### CHANGED, default = false

      # The DNS domain used by your Pi-hole to expand hosts and for DHCP.
      #
      # Only if DHCP is enabled below: For DHCP, this has two effects; firstly it causes the
      # DHCP server to return the domain to any hosts which request it, and secondly it sets
      # the domain which it is legal for DHCP-configured hosts to claim. The intention is to
      # constrain hostnames so that an untrusted host on the LAN cannot advertise its name
      # via DHCP as e.g. "google.com" and capture traffic not meant for it. If no domain
      # suffix is specified, then any DHCP hostname with a domain part (ie with a period)
      # will be disallowed and logged. If a domain is specified, then hostnames with a
      # domain part are allowed, provided the domain part matches the suffix. In addition,
      # when a suffix is set then hostnames without a domain part have the suffix added as
      # an optional domain part. For instance, we can set domain=mylab.com and have a
      # machine whose DHCP hostname is "laptop". The IP address for that machine is
      # available both as "laptop" and "laptop.mylab.com".
      #
      # You can disable setting a domain by setting this option to an empty string.
      #
      # Possible values are:
      # <any valid domain>
      domain = "lan"

      # Should all reverse lookups for private IP ranges (i.e., 192.168.x.y, etc) which are
      # not found in /etc/hosts or the DHCP leases file be answered with "no such domain"
      # rather than being forwarded upstream?
      bogusPriv = true

      # Validate DNS replies using DNSSEC?
      dnssec = true ### CHANGED, default = false

      # Interface to use for DNS (see also dnsmasq.listening.mode) and DHCP (if enabled)
      #
      # Possible values are:
      # a valid interface name
      interface = "eth0" ### CHANGED, default = ""

      # Add A, AAAA and PTR records to the DNS. This adds one or more names to the DNS with
      # associated IPv4 (A) and IPv6 (AAAA) records
      #
      # Possible values are:
      # <name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
      hostRecord = ""

      # Pi-hole interface listening modes
      #
      # Possible values are:
      # - "LOCAL"
      # Allow only local requests. This setting accepts DNS queries only from hosts
      # whose address is on a local subnet, i.e., a subnet for which an interface
      # exists on the server. It is intended to be set as a default on installation,
      # to allow unconfigured installations to be useful but also safe from being used
      # for DNS amplification attacks if (accidentally) running public.
      # - "SINGLE"
      # Permit all origins, accept only on the specified interface. Respond only to
      # queries arriving on the specified interface. The loopback (lo) interface is
      # automatically added to the list of interfaces to use when this option is used.
      # Make sure your Pi-hole is properly firewalled!
      # - "BIND"
      # By default, FTL binds the wildcard address. If this is not what you want, you
      # can use this option as it forces FTL to really bind only the interfaces it is
      # listening on. Note that this may result in issues when the interface may go
      # down (cable unplugged, etc.). About the only time when this is useful is when
      # running another nameserver on the same port on the same machine. This may also
      # happen if you run a virtualization API such as libvirt. When this option is
      # used, IP alias interface labels (e.g. enp2s0:0) are checked rather than
      # interface names.
      # - "ALL"
      # Permit all origins, accept on all interfaces. Make sure your Pi-hole is
      # properly firewalled! This truly allows any traffic to be replied to and is a
      # dangerous thing to do as your Pi-hole could become an open resolver. You
      # should always ask yourself if the first option doesn't work for you as well.
      # - "NONE"
      # Do not add any configuration concerning the listening mode to the dnsmasq
      # configuration file. This is useful if you want to manually configure the
      # listening mode in auxiliary configuration files. This option is really meant
      # for advanced users only, support for this option may be limited.
      listeningMode = "LOCAL"

      # Log DNS queries and replies to pihole.log
      queryLogging = true

      # List of CNAME records which indicate that <cname> is really <target>. If the <TTL> is
      # given, it overwrites the value of local-ttl
      #
      # Possible values are:
      # Array of CNAMEs each on in one of the following forms: "<cname>,<target>[,<TTL>]"
      cnameRecords = []

      # Port used by the DNS server
      port = 53

      # Reverse server (former also called "conditional forwarding") feature
      # Array of reverse servers each one in one of the following forms:
      # "<enabled>,<ip-address>[/<prefix-len>],<server>[#<port>][,<domain>]"
      #
      # Individual components:
      #
      # <enabled>: either "true" or "false"
      #
      # <ip-address>[/<prefix-len>]: Address range for the reverse server feature in CIDR
      # notation. If the prefix length is omitted, either 32 (IPv4) or 128 (IPv6) are
      # substituted (exact address match). This is almost certainly not what you want here.
      # Example: "192.168.0.0/24" for the range 192.168.0.1 - 192.168.0.255
      #
      # <server>[#<port>]: Target server to be used for the reverse server feature
      # Example: "192.168.0.1#53"
      #
      # <domain>: Domain used for the reverse server feature (e.g., "fritz.box")
      # Example: "fritz.box"
      #
      # Possible values are:
      # array of reverse servers each one in one of the following forms:
      # "<enabled>,<ip-address>[/<prefix-len>],<server>[#<port>][,<domain>]", e.g.,
      # "true,192.168.0.0/24,192.168.0.1,fritz.box"
      revServers = [
      "true,192.168.10.0/24,192.168.10.1,fritz.box"
      ] ### CHANGED, default = []

      [dns.cache]
      # Cache size of the DNS server. Note that expiring cache entries naturally make room
      # for new insertions over time. Setting this number too high will have an adverse
      # effect as not only more space is needed, but also lookup speed gets degraded in the
      # 10,000+ range. dnsmasq may issue a warning when you go beyond 10,000+ cache entries.
      size = 10000

      # Query cache optimizer: If a DNS name exists in the cache, but its time-to-live has
      # expired only recently, the data will be used anyway (a refreshing from upstream is
      # triggered). This can improve DNS query delays especially over unreliable Internet
      # connections. This feature comes at the expense of possibly sometimes returning
      # out-of-date data and less efficient cache utilization, since old data cannot be
      # flushed when its TTL expires, so the cache becomes mostly least-recently-used. To
      # mitigate issues caused by massively outdated DNS replies, the maximum overaging of
      # cached records is limited. We strongly recommend staying below 86400 (1 day) with
      # this option.
      # Setting the TTL excess time to zero will serve stale cache data regardless how long
      # it has expired. This is not recommended as it may lead to stale data being served
      # for a long time. Setting this option to any negative value will disable this feature
      # altogether.
      optimizer = 3600

      # This setting allows you to specify the TTL used for queries blocked upstream. Once
      # the TTL expires, the query will be forwarded to the upstream server again to check
      # if the block is still valid. Defaults to caching for one day (86400 seconds).
      # Setting this value to zero disables caching of queries blocked upstream.
      upstreamBlockedTTL = 86400

      [dns.blocking]
      # Should FTL block queries?
      active = true

      # How should FTL reply to blocked queries?
      #
      # Possible values are:
      # - "NULL"
      # In NULL mode, which is both the default and recommended mode for Pi-hole
      # FTLDNS, blocked queries will be answered with the "unspecified address"
      # (0.0.0.0 or ::). The "unspecified address" is a reserved IP address specified
      # by RFC 3513 - Internet Protocol Version 6 (IPv6) Addressing Architecture,
      # section 2.5.2.
      # - "IP_NODATA_AAAA"
      # In IP-NODATA-AAAA mode, blocked queries will be answered with the local IPv4
      # addresses of your Pi-hole. Blocked AAAA queries will be answered with
      # NODATA-IPV6 and clients will only try to reach your Pi-hole over its static
      # IPv4 address.
      # - "IP"
      # In IP mode, blocked queries will be answered with the local IP addresses of
      # your Pi-hole.
      # - "NX"
      # In NXDOMAIN mode, blocked queries will be answered with an empty response
      # (i.e., there won't be an answer section) and status NXDOMAIN. A NXDOMAIN
      # response should indicate that there is no such domain to the client making the
      # query.
      # - "NODATA"
      # In NODATA mode, blocked queries will be answered with an empty response (no
      # answer section) and status NODATA. A NODATA response indicates that the domain
      # exists, but there is no record for the requested query type.
      mode = "NULL"

      # Should FTL enrich blocked replies with EDNS0 information?
      #
      # Possible values are:
      # - "NONE"
      # In NONE mode, no additional EDNS information is added to blocked queries
      # - "CODE"
      # In CODE mode, blocked queries will be enriched with EDNS info-code BLOCKED (15)
      # - "TEXT"
      # In TEXT mode, blocked queries will be enriched with EDNS info-code BLOCKED (15)
      # and a text message describing the reason for the block
      edns = "TEXT"

      [dns.specialDomains]
      # Should Pi-hole always replies with NXDOMAIN to A and AAAA queries of
      # use-application-dns.net to disable Firefox automatic DNS-over-HTTP? This is
      # following the recommendation on
      # Configure networks to disable DNS over HTTPS | Firefox Help
      mozillaCanary = true

      # Should Pi-hole always replies with NXDOMAIN to A and AAAA queries of mask.icloud.com
      # and mask-h2.icloud.com to disable Apple's iCloud Private Relay to prevent Apple
      # devices from bypassing Pi-hole? This is following the recommendation on
      # prepare-your-network-for-icloud-private-relay
      iCloudPrivateRelay = true

      [dns.reply.host]
      # Use a specific IPv4 address for the Pi-hole host? By default, FTL determines the
      # address of the interface a query arrived on and uses this address for replying to A
      # queries with the most suitable address for the requesting client. This setting can
      # be used to use a fixed, rather than the dynamically obtained, address when Pi-hole
      # responds to the following names: [ "pi.hole", "<the device's hostname>",
      # "pi.hole.<local domain>", "<the device's hostname>.<local domain>" ]
      force4 = false

      # Custom IPv4 address for the Pi-hole host
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("")
      IPv4 = ""

      # Use a specific IPv6 address for the Pi-hole host? See description for the IPv4
      # variant above for further details.
      force6 = false

      # Custom IPv6 address for the Pi-hole host
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("")
      IPv6 = ""

      [dns.reply.blocking]
      # Use a specific IPv4 address in IP blocking mode? By default, FTL determines the
      # address of the interface a query arrived on and uses this address for replying to A
      # queries with the most suitable address for the requesting client. This setting can
      # be used to use a fixed, rather than the dynamically obtained, address when Pi-hole
      # responds in the following cases: IP blocking mode is used and this query is to be
      # blocked, regular expressions with the ;reply=IP regex extension.
      force4 = false

      # Custom IPv4 address for IP blocking mode
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("")
      IPv4 = ""

      # Use a specific IPv6 address in IP blocking mode? See description for the IPv4 variant
      # above for further details.
      force6 = false

      # Custom IPv6 address for IP blocking mode
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("")
      IPv6 = ""

      [dns.rateLimit]
      # Rate-limited queries are answered with a REFUSED reply and not further processed by
      # FTL.
      # The default settings for FTL's rate-limiting are to permit no more than 1000 queries
      # in 60 seconds. Both numbers can be customized independently. It is important to note
      # that rate-limiting is happening on a per-client basis. Other clients can continue to
      # use FTL while rate-limited clients are short-circuited at the same time.
      # For this setting, both numbers, the maximum number of queries within a given time,
      # and the length of the time interval (seconds) have to be specified. For instance, if
      # you want to set a rate limit of 1 query per hour, the option should look like
      # RATE_LIMIT=1/3600. The time interval is relative to when FTL has finished starting
      # (start of the daemon + possible delay by DELAY_STARTUP) then it will advance in
      # steps of the rate-limiting interval. If a client reaches the maximum number of
      # queries it will be blocked until the end of the current interval. This will be
      # logged to /var/log/pihole/FTL.log, e.g. Rate-limiting 10.0.1.39 for at least 44
      # seconds. If the client continues to send queries while being blocked already and
      # this number of queries during the blocking exceeds the limit the client will
      # continue to be blocked until the end of the next interval (FTL.log will contain
      # lines like Still rate-limiting 10.0.1.39 as it made additional 5007 queries). As
      # soon as the client requests less than the set limit, it will be unblocked (Ending
      # rate-limitation of 10.0.1.39).
      # Rate-limiting may be disabled altogether by setting both values to zero (this
      # results in the same behavior as before FTL v5.7).
      # How many queries are permitted...
      count = 1000

      # ... in the set interval before rate-limiting?
      interval = 60

      [dhcp]
      # Is the embedded DHCP server enabled?
      active = false

      # Start address of the DHCP address pool
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.10"
      start = ""

      # End address of the DHCP address pool
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.250"
      end = ""

      # Address of the gateway to be used (typically the address of your router in a home
      # installation)
      #
      # Possible values are:
      # <valid IPv4 address> or empty string (""), e.g., "192.168.0.1"
      router = ""

      # The netmask used by your Pi-hole. For directly connected networks (i.e., networks on
      # which the machine running Pi-hole has an interface) the netmask is optional and may
      # be set to an empty string (""): it will then be determined from the interface
      # configuration itself. For networks which receive DHCP service via a relay agent, we
      # cannot determine the netmask itself, so it should explicitly be specified, otherwise
      # Pi-hole guesses based on the class (A, B or C) of the network address.
      #
      # Possible values are:
      # <any valid netmask> (e.g., "255.255.255.0") or empty string ("") for
      # auto-discovery
      netmask = ""

      # If the lease time is given, then leases will be given for that length of time. If not
      # given, the default lease time is one hour for IPv4 and one day for IPv6.
      #
      # Possible values are:
      # The lease time can be in seconds, or minutes (e.g., "45m") or hours (e.g., "1h")
      # or days (like "2d") or even weeks ("1w"). You may also use "infinite" as string
      # but be aware of the drawbacks
      leaseTime = ""

      # Should Pi-hole make an attempt to also satisfy IPv6 address requests (be aware that
      # IPv6 works a whole lot different than IPv4)
      ipv6 = false

      # Enable DHCPv4 Rapid Commit Option specified in RFC 4039. Should only be enabled if
      # either the server is the only server for the subnet to avoid conflicts
      rapidCommit = false

      # Advertise DNS server multiple times to clients. Some devices will add their own
      # proprietary DNS servers to the list of DNS servers, which can cause issues with
      # Pi-hole. This option will advertise the Pi-hole DNS server multiple times to
      # clients, which should prevent this from happening.
      multiDNS = false

      # Enable logging for DHCP. This will log all relevant DHCP-related activity, including,
      # e.g., all the options sent to DHCP clients and the tags used to determine them (if
      # any). This can be useful for debugging DHCP issues. The generated output is saved to
      # the file specified by files.log.dnsmasq below.
      logging = false

      # Ignore unknown DHCP clients.
      # If this option is set, Pi-hole ignores all clients which are not explicitly
      # configured through dhcp.hosts. This can be useful to prevent unauthorized clients
      # from getting an IP address from the DHCP server.
      # It should be noted that this option is not a security feature, as clients can still
      # assign themselves an IP address and use the network. It is merely a convenience
      # feature to prevent unknown clients from getting a valid IP configuration assigned
      # automatically.
      # Note that you will need to configure new clients manually in dhcp.hosts before they
      # can use the network when this feature is enabled.
      ignoreUnknownClients = false

      # Per host parameters for the DHCP server. This allows a machine with a particular
      # hardware address to be always allocated the same hostname, IP address and lease time
      # or to specify static DHCP leases
      #
      # Possible values are:
      # Array of static leases each on in one of the following forms:
      # "[<hwaddr>][,id:<client_id>|*][,set:<tag>][,tag:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]"
      hosts = []

      [ntp.ipv4]
      # Should FTL act as network time protocol (NTP) server (IPv4)?
      active = true

      # IPv4 address to listen on for NTP requests
      #
      # Possible values are:
      # <valid IPv4 address> or empty string ("") for wildcard (0.0.0.0)
      address = ""

      [ntp.ipv6]
      # Should FTL act as network time protocol (NTP) server (IPv6)?
      active = true

      # IPv6 address to listen on for NTP requests
      #
      # Possible values are:
      # <valid IPv6 address> or empty string ("") for wildcard (::)
      address = ""

      [ntp.sync]
      # Should FTL try to synchronize the system time with an upstream NTP server?
      active = true

      # NTP upstream server to sync with, e.g., "pool.ntp.org". Note that the NTP server
      # should be located as close as possible to you in order to minimize the time offset
      # possibly introduced by different routing paths.
      #
      # Possible values are:
      # valid NTP upstream server
      server = "pool.ntp.org"

      # Interval in seconds between successive synchronization attempts with the NTP server
      interval = 3600

      # Number of NTP syncs to perform and average before updating the system time
      count = 8

      [ntp.sync.rtc]
      # Should FTL update a real-time clock (RTC) if available?
      set = false

      # Path to the RTC device to update. Leave empty for auto-discovery
      #
      # Possible values are:
      # Path to the RTC device, e.g., "/dev/rtc0"
      device = ""

      # Should the RTC be set to UTC?
      utc = true

      [resolver]
      # Should FTL try to resolve IPv4 addresses to hostnames?
      resolveIPv4 = true

      # Should FTL try to resolve IPv6 addresses to hostnames?
      resolveIPv6 = true

      # Control whether FTL should use the fallback option to try to obtain client names from
      # checking the network table. This behavior can be disabled with this option.
      # Assume an IPv6 client without a host names. However, the network table knows -
      # though the client's MAC address - that this is the same device where we have a host
      # name for another IP address (e.g., a DHCP server managed IPv4 address). In this
      # case, we use the host name associated to the other address as this is the same
      # device.
      networkNames = true

      # With this option, you can change how (and if) hourly PTR requests are made to check
      # for changes in client and upstream server hostnames.
      #
      # Possible values are:
      # - "IPV4_ONLY"
      # Do hourly PTR lookups only for IPv4 addresses. This is the new default since
      # Pi-hole FTL v5.3.2. It should resolve issues with more and more very
      # short-lived PE IPv6 addresses coming up in a lot of networks.
      # - "ALL"
      # Do hourly PTR lookups for all addresses. This was the default until FTL
      # v5.3(.1). It has been replaced as it can create a lot of PTR queries for those
      # with many IPv6 addresses in their networks.
      # - "UNKNOWN"
      # Only resolve unknown hostnames. Already existing hostnames are never refreshed,
      # i.e., there will be no PTR queries made for clients where hostnames are known.
      # This also means that known hostnames will not be updated once known.
      # - "NONE"
      # Don't do any hourly PTR lookups. This means we look host names up exactly once
      # (when we first see a client) and never again. You may miss future changes of
      # host names.
      refreshNames = "IPV4_ONLY"

      [database]
      # Should FTL load information from the database on startup to be aware of the most
      # recent history?
      DBimport = true

      # How long should queries be stored in the database [days]?
      # Setting this value to 0 will disable the database.
      maxDBdays = 91

      # How often do we store queries in FTL's database [seconds]?
      DBinterval = 60

      # Should FTL enable Write-Ahead Log (WAL) mode for the on-disk query database
      # (configured via files.database)?
      # It is recommended to leave this setting enabled for performance reasons. About the
      # only reason to disable WAL mode is if you are experiencing specific issues with it,
      # e.g., when using a database that is accessed from multiple hosts via a network
      # share. When this setting is disabled, FTL will use SQLite3's default journal mode
      # (rollback journal in DELETE mode).
      useWAL = true

      [database.network]
      # Should FTL analyze the local ARP cache? When disabled, client identification and the
      # network table will stop working reliably.
      parseARPcache = true

      # How long should IP addresses be kept in the network_addresses table [days]? IP
      # addresses (and associated host names) older than the specified number of days are
      # removed to avoid dead entries in the network overview table.
      expire = 91

      [webserver]
      # On which domain is the web interface served?
      #
      # Possible values are:
      # <valid domain>
      domain = "pi.hole"

      # Webserver access control list (ACL) allowing for restrictions to be put on the list
      # of IP addresses which have access to the web server. The ACL is a comma separated
      # list of IP subnets, where each subnet is prepended by either a - or a + sign. A plus
      # sign means allow, where a minus sign means deny. If a subnet mask is omitted, such
      # as -1.2.3.4, this means to deny only that single IP address. If this value is not
      # set (empty string), all accesses are allowed. Otherwise, the default setting is to
      # deny all accesses. On each request the full list is traversed, and the last (!)
      # match wins. IPv6 addresses may be specified in CIDR-form [a:b::c]/64.
      #
      # Example 1: acl = "+127.0.0.1,+[::1]"
      # ---> deny all access, except from 127.0.0.1 and ::1,
      # Example 2: acl = "+192.168.0.0/16"
      # ---> deny all accesses, except from the 192.168.0.0/16 subnet,
      # Example 3: acl = "+[::]/0" ---> allow only IPv6 access.
      #
      # Possible values are:
      # <valid ACL>
      acl = ""

      # Ports to be used by the webserver.
      # Comma-separated list of ports to listen on. It is possible to specify an IP address
      # to bind to. In this case, an IP address and a colon must be prepended to the port
      # number. For example, to bind to the loopback interface on port 80 (IPv4) and to all
      # interfaces port 8080 (IPv4), use "127.0.0.1:80,8080". "[::]:80" can be used to
      # listen to IPv6 connections to port 80. IPv6 addresses of network interfaces can be
      # specified as well, e.g. "[::1]:80" for the IPv6 loopback interface. [::]:80 will
      # bind to port 80 IPv6 only.
      # In order to use port 80 for all interfaces, both IPv4 and IPv6, use either the
      # configuration "80,[::]:80" (create one socket for IPv4 and one for IPv6 only), or
      # "+80" (create one socket for both, IPv4 and IPv6). The '+' notation to use IPv4 and
      # IPv6 will only work if no network interface is specified. Depending on your
      # operating system version and IPv6 network environment, some configurations might not
      # work as expected, so you have to test to find the configuration most suitable for
      # your needs. In case "+80" does not work for your environment, you need to use
      # "80,[::]:80".
      # If the port is TLS/SSL, a letter 's' (secure) must be appended, for example,
      # "80,443s" will open port 80 and port 443, and connections on port 443 will be
      # encrypted. For non-encrypted ports, it is allowed to append letter 'r' (as in
      # redirect). Redirected ports will redirect all their traffic to the first configured
      # SSL port. For example, if webserver.port is "80r,443s", then all HTTP traffic coming
      # at port 80 will be redirected to HTTPS port 443.
      # When specifying 'o' (optional) behind a port, inability to use this port is not
      # considered an error. For instance, specifying "80o,8080o" will allow the webserver
      # to listen on either 80, 8080, both or even none of the two ports. This flag may be
      # combined with 'r' and 's' like "80or,443os,8080,4443s" (80 redirecting to SSL if
      # available, 443 encrypted if available, 8080 mandatory and unencrypted, 4443
      # mandatory and encrypted).
      # If this value is not set (empty string), the web server will not be started and,
      # hence, the API will not be available.
      #
      # Possible values are:
      # comma-separated list of <[ip_address:]port>
      port = "8080o,443os,[::]:8080o,[::]:443" ### CHANGED, default = "80o,443os,[::]:80o,[::]:443os"

      # Maximum number of worker threads allowed.
      # The Pi-hole web server handles each incoming connection in a separate thread.
      # Therefore, the value of this option is effectively the number of concurrent HTTP
      # connections that can be handled. Any other connections are queued until they can be
      # processed by a unoccupied thread.
      # The default value of 0 means that the number of threads is automatically determined
      # by the number of online CPU cores minus 1 (e.g., launching up to 8-1 = 7 threads on
      # 8 cores). Any other value specifies the number of threads explicitly. A hard-coded
      # maximum of 64 threads is enforced for this option.
      # The total number of threads you see may be lower than the configured value as
      # threads are only created when needed due to incoming connections.
      threads = 0

      [webserver.session]
      # Session timeout in seconds. If a session is inactive for more than this time, it will
      # be terminated. Sessions are continuously refreshed by the web interface, preventing
      # sessions from timing out while the web interface is open.
      # This option may also be used to make logins persistent for long times, e.g. 86400
      # seconds (24 hours), 604800 seconds (7 days) or 2592000 seconds (30 days). Note that
      # the total number of concurrent sessions is limited so setting this value too high
      # may result in users being rejected and unable to log in if there are already too
      # many sessions active.
      timeout = 1800

      # Should Pi-hole backup and restore sessions from the database? This is useful if you
      # want to keep your sessions after a restart of the web interface.
      restore = true

      [webserver.tls]
      # Path to the TLS (SSL) certificate file. All directories along the path must be
      # readable and accessible by the user running FTL (typically 'pihole'). This option is
      # only required when at least one of webserver.port is TLS. The file must be in PEM
      # format, and it must have both, private key and certificate (the *.pem file created
      # must contain a 'CERTIFICATE' section as well as a 'RSA PRIVATE KEY' section).
      # The *.pem file can be created using
      # cp server.crt server.pem
      # cat server.key >> server.pem
      # if you have these files instead
      #
      # Possible values are:
      # <valid TLS certificate file (*.pem)>
      cert = "/etc/pihole/tls.pem"

      [webserver.paths]
      # Server root on the host
      #
      # Possible values are:
      # <valid path>
      webroot = "/var/www/html"

      # Sub-directory of the root containing the web interface
      #
      # Possible values are:
      # <valid subpath>, both slashes are needed!
      webhome = "/admin/"

      [webserver.interface]
      # Should the web interface use the boxed layout?
      boxed = true

      # Theme used by the Pi-hole web interface
      #
      # Possible values are:
      # - "default-auto"
      # Pi-hole auto
      # - "default-light"
      # Pi-hole day
      # - "default-dark"
      # Pi-hole midnight
      # - "default-darker"
      # Pi-hole deep-midnight
      # - "high-contrast"
      # High-contrast light
      # - "high-contrast-dark"
      # High-contrast dark
      # - "lcars"
      # Star Trek LCARS
      theme = "default-dark" ### CHANGED, default = "default-auto"

      [webserver.api]
      # Number of concurrent sessions allowed for the API. If the number of sessions exceeds
      # this value, no new sessions will be allowed until the number of sessions drops due
      # to session expiration or logout. Note that the number of concurrent sessions is
      # irrelevant if authentication is disabled as no sessions are used in this case.
      max_sessions = 16

      # Should FTL prettify the API output (add extra spaces, newlines and indentation)?
      prettyJSON = false

      # API password hash
      #
      # Possible values are:
      # <valid Pi-hole password hash>
      pwhash = "49b951d42416956882a66b083d93582d291f8c86ddf12c25302c5440bf8636ad" ### CHANGED, default = ""

      # Pi-hole 2FA TOTP secret. When set to something different than "", 2FA authentication
      # will be enforced for the API and the web interface. This setting is write-only, you
      # can not read the secret back.
      #
      # Possible values are:
      # <valid TOTP secret (20 Bytes in Base32 encoding)>
      totp_secret = ""

      # Pi-hole application password.
      # After you turn on two-factor (2FA) verification and set up an Authenticator app, you
      # may run into issues if you use apps or other services that don't support two-step
      # verification. In this case, you can create and use an app password to sign in. An
      # app password is a long, randomly generated password that can be used instead of your
      # regular password + TOTP token when signing in to the API. The app password can be
      # generated through the API and will be shown only once. You can revoke the app
      # password at any time. If you revoke the app password, be sure to generate a new one
      # and update your app with the new password.
      #
      # Possible values are:
      # <valid Pi-hole password hash>
      app_pwhash = ""

      # Should application password API sessions be allowed to modify config settings?
      # Setting this to true allows third-party applications using the application password
      # to modify settings, e.g., the upstream DNS servers, DHCP server settings, or
      # changing passwords. This setting should only be enabled if really needed and only if
      # you trust the applications using the application password.
      app_sudo = false

      # Should FTL create a temporary CLI password? This password is stored in clear in
      # /etc/pihole and can be used by the CLI (pihole ... commands) to authenticate
      # against the API. Note that the password is only valid for the current session and
      # regenerated on each FTL restart. Sessions initiated with this password cannot modify
      # the Pi-hole configuration (change passwords, etc.) for security reasons but can
      # still use the API to query data and manage lists.
      cli_pw = true

      # Array of clients to be excluded from certain API responses (regex):
      # - Query Log (/api/queries)
      # - Top Clients (/api/stats/top_clients)
      # This setting accepts both IP addresses (IPv4 and IPv6) as well as hostnames.
      # Note that backslashes "\" need to be escaped, i.e. "\\" in this setting
      #
      # Example: [ "^192\\.168\\.2\\.56$", "^fe80::341:[0-9a-f]*$", "^localhost$" ]
      #
      # Possible values are:
      # array of regular expressions describing clients
      excludeClients = []

      # Array of domains to be excluded from certain API responses (regex):
      # - Query Log (/api/queries)
      # - Top Clients (/api/stats/top_domains)
      # Note that backslashes "\" need to be escaped, i.e. "\\" in this setting
      #
      # Example: [ "(^|\\.)\\.google\\.de$", "\\.pi-hole\\.net$" ]
      #
      # Possible values are:
      # array of regular expressions describing domains
      excludeDomains = []

      # How much history should be imported from the database and returned by the API
      # [seconds]? (max 24*60*60 = 86400)
      maxHistory = 86400

      # Up to how many clients should be returned in the activity graph endpoint
      # (/api/history/clients)?
      # This setting can be overwritten at run-time using the parameter N. Setting this to 0
      # will always send all clients. Be aware that this may be challenging for the GUI if
      # you have many (think > 1.000 clients) in your network
      maxClients = 10

      # How should the API compute the most active clients? If set to true, the API will
      # return the clients with the most queries globally (within 24 hours). If set to
      # false, the API will return the clients with the most queries per time slot
      # individually.
      client_history_global_max = true

      # Allow destructive API calls (e.g. deleting all queries, powering off the system, ...)
      allow_destructive = true

      [webserver.api.temp]
      # Which upper temperature limit should be used by Pi-hole? Temperatures above this
      # limit will be shown as "hot". The number specified here is in the unit defined below
      limit = 60.000000

      # Which temperature unit should be used for temperatures processed by FTL?
      #
      # Possible values are:
      # - "C"
      # Celsius
      # - "F"
      # Fahrenheit
      # - "K"
      # Kelvin
      unit = "C"

      [files]
      # The file which contains the PID of FTL's main process.
      #
      # Possible values are:
      # <any writable file>
      pid = "/run/pihole-FTL.pid"

      # The location of FTL's long-term database
      #
      # Possible values are:
      # <any FTL database>
      database = "/etc/pihole/pihole-FTL.db"

      # The location of Pi-hole's gravity database
      #
      # Possible values are:
      # <any Pi-hole gravity database>
      gravity = "/etc/pihole/gravity.db"

      # A temporary directory where Pi-hole can store files during gravity updates. This
      # directory must be writable by the user running gravity (typically pihole).
      #
      # Possible values are:
      # <any existing world-writable writable directory>
      gravity_tmp = "/tmp"

      # The database containing MAC -> Vendor information for the network table
      #
      # Possible values are:
      # <any Pi-hole macvendor database>
      macvendor = "/etc/pihole/macvendor.db"

      # The old config file of Pi-hole used before v6.0
      #
      # Possible values are:
      # <any Pi-hole setupVars file>
      setupVars = "/etc/pihole/setupVars.conf"

      # An optional file containing a pcap capture of the network traffic. This file is used
      # for debugging purposes only. If you don't know what this is, you don't need it.
      # Setting this to an empty string disables pcap recording. The file must be writable
      # by the user running FTL (typically pihole). Failure to write to this file will
      # prevent the DNS resolver from starting. The file is appended to if it already
      # exists.
      #
      # Possible values are:
      # <any writable pcap file>
      pcap = ""

      [files.log]
      # The location of FTL's log file
      #
      # Possible values are:
      # <any writable file>
      ftl = "/var/log/pihole/FTL.log"

      # The log file used by the embedded dnsmasq DNS server
      #
      # Possible values are:
      # <any writable file>
      dnsmasq = "/var/log/pihole/pihole.log"

      # The log file used by the webserver
      #
      # Possible values are:
      # <any writable file>
      webserver = "/var/log/pihole/webserver.log"

      [misc]
      # Using privacy levels you can specify which level of detail you want to see in your
      # Pi-hole statistics. Changing this setting will trigger a restart of FTL
      #
      # Possible values are:
      # - 0
      # Don't hide anything, all statistics are available.
      # - 1
      # Hide domains. This setting disables Top Domains and Top Ads
      # - 2
      # Hide domains and clients. This setting disables Top Domains, Top Ads, Top
      # Clients and Clients over time.
      # - 3
      # Anonymize everything. This setting disabled almost any statistics and query
      # analysis. There will be no long-term database logging and no Query Log. You
      # will also loose most regex features.
      privacylevel = 0

      # During startup, in some configurations, network interfaces appear only late during
      # system startup and are not ready when FTL tries to bind to them. Therefore, you may
      # want FTL to wait a given amount of time before trying to start the DNS revolver.
      # This setting takes any integer value between 0 and 300 seconds. To prevent delayed
      # startup while the system is already running and FTL is restarted, the delay only
      # takes place within the first 180 seconds (hard-coded) after booting.
      delay_startup = 0

      # Set niceness of pihole-FTL. Defaults to -10 and can be disabled altogether by setting
      # a value of -999. The nice value is an attribute that can be used to influence the
      # CPU scheduler to favor or disfavor a process in scheduling decisions. The range of
      # the nice value varies across UNIX systems. On modern Linux, the range is -20 (high
      # priority = not very nice to other processes) to +19 (low priority).
      nice = -10

      # Should FTL translate its own stack addresses into code lines during the bug
      # backtrace? This improves the analysis of crashed significantly. It is recommended to
      # leave the option enabled. This option should only be disabled when addr2line is
      # known to not be working correctly on the machine because, in this case, the
      # malfunctioning addr2line can prevent from generating any backtrace at all.
      addr2line = true

      # Should FTL load additional dnsmasq configuration files from /etc/dnsmasq.d/?
      etc_dnsmasq_d = false

      # Additional lines to inject into the generated dnsmasq configuration.
      # Warning: This is an advanced setting and should only be used with care. Incorrectly
      # formatted or duplicated lines as well as lines conflicting with the automatic
      # configuration of Pi-hole can break the embedded dnsmasq and will stop DNS resolution
      # from working.
      # Use this option with extra care.
      #
      # Possible values are:
      # array of valid dnsmasq config line options
      dnsmasq_lines = []

      # Log additional information about queries and replies to pihole.log
      # When this setting is enabled, the log has extra information at the start of each
      # line. This consists of a serial number which ties together the log lines associated
      # with an individual query, and the IP address of the requestor. This setting is only
      # effective if dns.queryLogging is enabled, too. This option is only useful for
      # debugging and is not recommended for normal use.
      extraLogging = false

      # Put configuration into read-only mode. This will prevent any changes to the
      # configuration file via the API or CLI. This setting useful when a configuration is
      # to be forced/modified by some third-party application (like infrastructure-as-code
      # providers) and should not be changed by any means.
      readOnly = false

      [misc.check]
      # Pi-hole is very lightweight on resources. Nevertheless, this does not mean that you
      # should run Pi-hole on a server that is otherwise extremely busy as queuing on the
      # system can lead to unnecessary delays in DNS operation as the system becomes less
      # and less usable as the system load increases because all resources are permanently
      # in use. To account for this, FTL regularly checks the system load. To bring this to
      # your attention, FTL warns about excessive load when the 15 minute system load
      # average exceeds the number of cores.
      # This check can be disabled with this setting.
      load = true

      # FTL stores history in shared memory to allow inter-process communication with forked
      # dedicated TCP workers. If FTL runs out of memory, it cannot continue to work as
      # queries cannot be analyzed any further. Hence, FTL checks if enough shared memory is
      # available on your system and warns you if this is not the case.
      # By default, FTL warns if the shared-memory usage exceeds 90%. You can set any
      # integer limit between 0 to 100 (interpreted as percentages) where 0 means that
      # checking of shared-memory usage is disabled.
      shmem = 90

      # FTL stores its long-term history in a database file on disk. Furthermore, FTL stores
      # log files. By default, FTL warns if usage of the disk holding any crucial file
      # exceeds 90%. You can set any integer limit between 0 to 100 (interpreted as
      # percentages) where 0 means that checking of disk usage is disabled.
      disk = 90

      [debug]
      # Print debugging information about database actions. This prints performed SQL
      # statements as well as some general information such as the time it took to store the
      # queries and how many have been saved to the database.
      database = false

      # Prints a list of the detected interfaces on the startup of pihole-FTL. Also, prints
      # whether these interfaces are IPv4 or IPv6 interfaces.
      networking = false

      # Print information about shared memory locks. Messages will be generated when waiting,
      # obtaining, and releasing a lock.
      locks = false

      # Print extensive query information (domains, types, replies, etc.). This has always
      # been part of the legacy debug mode of pihole-FTL.
      queries = false

      # Print flags of queries received by the DNS hooks. Only effective when DEBUG_QUERIES
      # is enabled as well.
      flags = false

      # Print information about shared memory buffers. Messages are either about creating or
      # enlarging shmem objects or string injections.
      shmem = false

      # Print information about garbage collection (GC): What is to be removed, how many have
      # been removed and how long did GC take.
      gc = false

      # Print information about ARP table processing: How long did parsing take, whether read
      # MAC addresses are valid, and if the macvendor.db file exists.
      arp = false

      # Controls if FTLDNS should print extended details about regex matching into FTL.log.
      regex = false

      # Print extra debugging information concerning API calls. This includes the request,
      # the request parameters, and the internal details about how the algorithms decide
      # which data to present and in what form. This very verbose output should only be used
      # when debugging specific API issues and can be helpful, e.g., when a client cannot
      # connect due to an obscure API error. Furthermore, this setting enables logging of
      # all API requests (auth log) and details about user authentication attempts.
      api = false

      # Print extra debugging information about TLS connections. This includes the TLS
      # version, the cipher suite, the certificate chain and much more. This very verbose
      # output should only be used when debugging specific TLS issues and can be helpful,
      # e.g., when a client cannot connect due to an obscure TLS error as modern browsers do
      # not provide much information about the underlying TLS connection and most often give
      # only very generic error messages without much/any underlying technical information.
      tls = false

      # Print information about overTime memory operations, such as initializing or moving
      # overTime slots.
      overtime = false

      # Print information about status changes for individual queries. This can be useful to
      # identify unexpected unknown queries.
      status = false

      # Print information about capabilities granted to the pihole-FTL process. The current
      # capabilities are printed on receipt of SIGHUP, i.e., the current set of capabilities
      # can be queried without restarting pihole-FTL (by setting DEBUG_CAPS=true and
      # thereafter sending killall -HUP pihole-FTL).
      caps = false

      # Print information about DNSSEC activity
      dnssec = false

      # FTL uses dynamically allocated vectors for various tasks. This config option enables
      # extensive debugging information such as information about allocation, referencing,
      # deletion, and appending.
      vectors = false

      # Extensive information about hostname resolution like which DNS servers are used in
      # the first and second hostname resolving tries (only affecting internally generated
      # PTR queries).
      resolver = false

      # Print debugging information about received EDNS(0) data.
      edns0 = false

      # Log various important client events such as change of interface (e.g., client
      # switching from WiFi to wired or VPN connection), as well as extensive reporting
      # about how clients were assigned to its groups.
      clients = false

      # Log information related to alias-client processing.
      aliasclients = false

      # Log information regarding FTL's embedded event handling queue.
      events = false

      # Log information about script helpers, e.g., due to dhcp-script.
      helper = false

      # Print config parsing details
      config = false

      # Debug monitoring of /etc/pihole filesystem events
      inotify = false

      # Debug monitoring of the webserver (CivetWeb) events
      webserver = false

      # Temporary flag that may print additional information. This debug flag is meant to be
      # used whenever needed for temporary investigations. The logged content may change
      # without further notice at any time.
      extra = false

      # Reserved debug flag
      reserved = false

      # Print information about NTP synchronization
      ntp = false

      # Print information about netlink communication and parsing
      netlink = false

      # Set all debug flags at once. This is a convenience option to enable all debug flags
      # at once. Note that this option is not persistent, setting it to true will enable all
      # *remaining* debug flags but unsetting it will disable *all* debug flags.
      all = false

      # Configuration statistics:
      # 152 total entries out of which 143 entries are default
      # --> 9 entries are modified

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von FastEddie ()

    • Die neue pihole Version verwendet kein lighttpd mehr, pihole hat jetzt einen eigenen Webserver, daher muss ein Port konfiguriert sein der frei ist.

      port = "8080o,443os,[::]:8080o,[::]:443"
      Ein kleines Dankeschön, durch eine Spende, nehme ich gerne an, PayPal oder Amazon-Gutschein an dhwz(at)gmx.net
    • Die Zeile findest ziemlich weit unten in deiner pihole.toml
      Trag dort einfach mal was anderes ein z.B. port = "8080o"
      Dieselbe IP ist erstmal kein Problem.
      Ein kleines Dankeschön, durch eine Spende, nehme ich gerne an, PayPal oder Amazon-Gutschein an dhwz(at)gmx.net

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von dhwz ()

    • dhwz schrieb:

      Die Zeile findest ziemlich weit unten in deiner pihole.toml
      Ich habe heute auch das update durchgeführt und natürlich komme ich auch nicht mehr auf den Webserver aber mein Problem ist, ich finde auf meinem Raspi keine pihole.toml ich hatte auch den Port in der lighttpd.conf verbogen auf 85, da auf der 80 meine Nextcloud läuft.


      kann mir jemand einen Tip geben?
      Screenshot 2025-06-01 192059.jpg
      Andreas

      Ich weiß nicht immer wovon ich rede. Aber ich weiß das es richtig ist. (Muhammad Ali)

      quod erat demonstrandum
    • so Installation ist durchgelaufen
      Spoiler anzeigen

      # Get available interfaces that are UP
      get_available_interfaces() {
      # There may be more than one so it's all stored in a variable
      availableInterfaces=$(ip --oneline link show up | awk '{print $2}' | grep - v "^lo" | cut -d':' -f1 | cut -d'@' -f1)
      }


      # A function for displaying the dialogs the user sees when first running the ins taller
      welcomeDialogs() {
      # Display the welcome dialog using an appropriately sized window via the cal culation conducted earlier in the script
      dialog --no-shadow --clear --keep-tite \
      --backtitle "Welcome" \
      --title "Pi-hole Automated Installer" \
      --msgbox "\\n\\nThis installer will transform your device into a network -wide ad blocker!" \
      "${r}" "${c}" \
      --and-widget --clear \
      --backtitle "Support Pi-hole" \
      --title "Open Source Software" \
      --msgbox "\\n\\nThe Pi-hole is free, but powered by your donations: htt ps://pi-hole.net/donate/" \
      "${r}" "${c}" \
      --and-widget --clear \
      --colors \
      --backtitle "Initiating network interface" \
      --title "Static IP Needed" \
      --no-button "Exit" --yes-button "Continue" \
      --defaultno \
      --yesno "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS t o function properly.\\n\\n\
      \\Zb\\Z1IMPORTANT:\\Zn If you have not already done so, you must ensure that thi s device has a static IP.\\n\\n\
      Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one.\\n\\n\
      Please continue when the static addressing has been configured." \
      "${r}" "${c}" && result=0 || result="$?"


      case "${result}" in
      "${DIALOG_CANCEL}" | "${DIALOG_ESC}")
      printf " %b Installer exited at static IP message.\\n" "${INFO}"
      exit 1
      ;;
      esac
      }


      # A function that lets the user pick an interface to use with Pi-hole
      chooseInterface() {
      # Turn the available interfaces into a string so it can be used with dialog
      local interfacesList
      # Number of available interfaces
      local interfaceCount


      # POSIX compliant way to get the number of elements in an array
      interfaceCount=$(printf "%s\n" "${availableInterfaces}" | wc -l)


      # If there is one interface,
      if [[ "${interfaceCount}" -eq 1 ]]; then
      # Set it as the interface to use since there is no other option
      PIHOLE_INTERFACE="${availableInterfaces}"
      # Otherwise,
      else
      # Set status for the first entry to be selected
      status="ON"


      # While reading through the available interfaces
      for interface in ${availableInterfaces}; do
      # Put all these interfaces into a string
      interfacesList="${interfacesList}${interface} available ${status} "
      # All further interfaces are deselected
      status="OFF"
      done
      # Disable check for double quote here as we are passing a string with sp aces
      PIHOLE_INTERFACE=$(dialog --no-shadow --keep-tite --output-fd 1 \
      --cancel-label "Exit" --ok-label "Select" \
      --radiolist "Choose An Interface (press space to toggle selection)" \
      ${r} ${c} "${interfaceCount}" ${interfacesList})


      result=$?
      case ${result} in
      "${DIALOG_CANCEL}" | "${DIALOG_ESC}")
      # Show an error message and exit
      printf " %b %s\\n" "${CROSS}" "No interface selected, exiting insta ller"
      exit 1
      ;;
      esac


      printf " %b Using interface: %s\\n" "${INFO}" "${PIHOLE_INTERFACE}"
      fi
      }


      # This lets us prefer ULA addresses over GUA
      # This caused problems for some users when their ISP changed their IPv6 addresse s
      # See Prefer ULA over GUA IPv6 · Issue #1473 · pi-hole/pi-hole · GitHub
      testIPv6() {
      # first will contain fda2 (ULA)
      printf -v first "%s" "${1%%:*}"
      # value1 will contain 253 which is the decimal value corresponding to 0xFD
      value1=$(((0x$first) / 256))
      # value2 will contain 162 which is the decimal value corresponding to 0xA2
      value2=$(((0x$first) % 256))
      # the ULA test is testing for fc00::/7 according to RFC 4193
      if (((value1 & 254) == 252)); then
      # echoing result to calling function as return value
      echo "ULA"
      fi
      # the GUA test is testing for 2000::/3 according to RFC 4291
      if (((value1 & 112) == 32)); then
      # echoing result to calling function as return value
      echo "GUA"
      fi
      # the LL test is testing for fe80::/10 according to RFC 4193
      if (((value1) == 254)) && (((value2 & 192) == 128)); then
      # echoing result to calling function as return value
      echo "Link-local"
      fi
      }


      find_IPv6_information() {
      # Detects IPv6 address used for communication to WAN addresses.
      mapfile -t IPV6_ADDRESSES <<<"$(ip -6 address | grep 'scope global' | awk '{ print $2}')"


      # For each address in the array above, determine the type of IPv6 address it is
      for i in "${IPV6_ADDRESSES[@]}"; do
      # Check if it's ULA, GUA, or LL by using the function created earlier
      result=$(testIPv6 "$i")
      # If it's a ULA address, use it and store it as a global variable
      [[ "${result}" == "ULA" ]] && ULA_ADDRESS="${i%/*}"
      # If it's a GUA address, use it and store it as a global variable
      [[ "${result}" == "GUA" ]] && GUA_ADDRESS="${i%/*}"
      # Else if it's a Link-local address, we cannot use it, so just continue
      done


      # Determine which address to be used: Prefer ULA over GUA or don't use any i f none found
      # If the ULA_ADDRESS contains a value,
      if [[ -n "${ULA_ADDRESS}" ]]; then
      # set the IPv6 address to the ULA address
      IPV6_ADDRESS="${ULA_ADDRESS}"
      # Show this info to the user
      printf " %b Found IPv6 ULA address\\n" "${INFO}"
      # Otherwise, if the GUA_ADDRESS has a value,
      elif [[ -n "${GUA_ADDRESS}" ]]; then
      # Let the user know
      printf " %b Found IPv6 GUA address\\n" "${INFO}"
      # And assign it to the global variable
      IPV6_ADDRESS="${GUA_ADDRESS}"
      # If none of those work,
      else
      printf " %b Unable to find IPv6 ULA/GUA address\\n" "${INFO}"
      # So set the variable to be empty
      IPV6_ADDRESS=""
      fi
      }


      # A function to collect IPv4 and IPv6 information of the device
      collect_v4andv6_information() {
      find_IPv4_information
      printf " %b IPv4 address: %s\\n" "${INFO}" "${IPV4_ADDRESS}"
      find_IPv6_information
      printf " %b IPv6 address: %s\\n" "${INFO}" "${IPV6_ADDRESS}"
      if [ "$IPV4_ADDRESS" == "" ] && [ "$IPV6_ADDRESS" != "" ]; then
      confirm_ipv6_only
      fi
      }


      # Check an IP address to see if it is a valid one
      valid_ip() {
      # Local, named variables
      local ip=${1}
      local stat=1


      # Regex matching one IPv4 component, i.e. an integer from 0 to 255.
      # See RFC 1340 - Assigned Numbers
      local ipv4elem="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)"
      # Regex matching an optional port (starting with '#') range of 1-65536
      local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1 -5][0-9]{4}|[1-9][0-9]{0,3}|0))?"
      # Build a full IPv4 regex from the above subexpressions
      local regex="^${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}${portele m}$"


      # Evaluate the regex, and return the result
      [[ $ip =~ ${regex} ]]


      stat=$?
      return "${stat}"
      }


      valid_ip6() {
      local ip=${1}
      local stat=1


      # Regex matching one IPv6 element, i.e. a hex value from 0000 to FFFF
      local ipv6elem="[0-9a-fA-F]{1,4}"
      # Regex matching an IPv6 CIDR, i.e. 1 to 128
      local v6cidr="(\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}"
      # Regex matching an optional port (starting with '#') range of 1-65536
      local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1 -5][0-9]{4}|[1-9][0-9]{0,3}|0))?"
      # Build a full IPv6 regex from the above subexpressions
      local regex="^(((${ipv6elem}))*((:${ipv6elem}))*::((${ipv6elem}))*((:${ipv6e lem}))*|((${ipv6elem}))((:${ipv6elem})){7})${v6cidr}${portelem}$"


      # Evaluate the regex, and return the result
      [[ ${ip} =~ ${regex} ]]


      stat=$?
      return "${stat}"
      }


      # A function to choose the upstream DNS provider(s)
      setDNS() {
      # Local, named variables
      local DNSSettingsCorrect


      # In an array, list the available upstream providers
      DNSChooseOptions=()
      local DNSServerCount=0
      # Save the old Internal Field Separator in a variable,
      OIFS=$IFS
      # and set the new one to newline
      IFS=$'\n'
      # Put the DNS Servers into an array
      for DNSServer in ${DNS_SERVERS}; do
      DNSName="$(cut -d';' -f1 <<<"${DNSServer}")"
      DNSChooseOptions[DNSServerCount]="${DNSName}"
      ((DNSServerCount = DNSServerCount + 1))
      DNSChooseOptions[DNSServerCount]=""
      ((DNSServerCount = DNSServerCount + 1))
      done
      DNSChooseOptions[DNSServerCount]="Custom"
      ((DNSServerCount = DNSServerCount + 1))
      DNSChooseOptions[DNSServerCount]=""
      # Restore the IFS to what it was
      IFS=${OIFS}
      # In a dialog, show the options
      DNSchoices=$(dialog --no-shadow --keep-tite --output-fd 1 \
      --cancel-label "Exit" \
      --menu "Select Upstream DNS Provider. To use your own, select Custom." " ${r}" "${c}" 7 \
      "${DNSChooseOptions[@]}")


      result=$?
      case ${result} in
      "${DIALOG_CANCEL}" | "${DIALOG_ESC}")
      printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_R ED}" "${COL_NC}"
      exit 1
      ;;
      esac


      # Depending on the user's choice, set the GLOBAL variables to the IP of the respective provider
      if [[ "${DNSchoices}" == "Custom" ]]; then
      # Loop until we have a valid DNS setting
      until [[ "${DNSSettingsCorrect}" = True ]]; do
      # Signal value, to be used if the user inputs an invalid IP address
      strInvalid="Invalid"
      if [[ ! "${PIHOLE_DNS_1}" ]]; then
      if [[ ! "${PIHOLE_DNS_2}" ]]; then
      # If the first and second upstream servers do not exist, do not prepopulate an IP address
      prePopulate=""
      else
      # Otherwise, prepopulate the dialogue with the appropriate D NS value(s)
      prePopulate=", ${PIHOLE_DNS_2}"
      fi
      elif [[ "${PIHOLE_DNS_1}" ]] && [[ ! "${PIHOLE_DNS_2}" ]]; then
      prePopulate="${PIHOLE_DNS_1}"
      elif [[ "${PIHOLE_DNS_1}" ]] && [[ "${PIHOLE_DNS_2}" ]]; then
      prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
      fi


      # Prompt the user to enter custom upstream servers
      piholeDNS=$(dialog --no-shadow --keep-tite --output-fd 1 \
      --cancel-label "Exit" \
      --backtitle "Specify Upstream DNS Provider(s)" \
      --inputbox "Enter your desired upstream DNS provider(s), separat ed by a comma.\
      If you want to specify a port other than 53, separate it with a hash.\
      \\n\\nFor example '8.8.8.8, 8.8.4.4' or '127.0.0.1#5335'" \
      "${r}" "${c}" "${prePopulate}")


      result=$?
      case ${result} in
      "${DIALOG_CANCEL}" | "${DIALOG_ESC}")
      printf " %b Cancel was selected, exiting installer%b\\n" "${COL _LIGHT_RED}" "${COL_NC}"
      exit 1
      ;;
      esac


      # Clean user input and replace whitespace with comma.
      piholeDNS=$(sed 's/[, \t]\+/,/g' <<<"${piholeDNS}")


      # Separate the user input into the two DNS values (separated by a co mma)
      printf -v PIHOLE_DNS_1 "%s" "${piholeDNS%%,*}"
      printf -v PIHOLE_DNS_2 "%s" "${piholeDNS##*,}"


      # If the first DNS value is invalid (neither IPv4 nor IPv6) or empty , set PIHOLE_DNS_1="Invalid"
      if ! valid_ip "${PIHOLE_DNS_1}" && ! valid_ip6 "${PIHOLE_DNS_1}" || [[ -z "${PIHOLE_DNS_1}" ]]; then
      PIHOLE_DNS_1=${strInvalid}
      fi
      # If the second DNS value is invalid but not empty, set PIHOLE_DNS_2 ="Invalid"
      if ! valid_ip "${PIHOLE_DNS_2}" && ! valid_ip6 "${PIHOLE_DNS_2}" && [[ -n "${PIHOLE_DNS_2}" ]]; then
      PIHOLE_DNS_2=${strInvalid}
      fi
      # If either of the DNS servers are invalid,
      if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]] || [[ "${PIHOLE_DNS_2} " == "${strInvalid}" ]]; then
      # explain this to the user,
      dialog --no-shadow --keep-tite \
      --title "Invalid IP Address(es)" \
      --backtitle "Invalid IP" \
      --msgbox "\\nOne or both of the entered IP addresses were in valid. Please try again.\
      \\n\\nInvalid IPs: ${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}" \
      "${r}" "${c}"


      # set the variables back to nothing,
      if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]]; then
      PIHOLE_DNS_1=""
      fi
      if [[ "${PIHOLE_DNS_2}" == "${strInvalid}" ]]; then
      PIHOLE_DNS_2=""
      fi
      # and continue the loop.
      DNSSettingsCorrect=False
      else
      dialog --no-shadow --no-collapse --keep-tite \
      --backtitle "Specify Upstream DNS Provider(s)" \
      --title "Upstream DNS Provider(s)" \
      --yesno "Are these settings correct?\\n"$'\t'"DNS Server 1:" $'\t'"${PIHOLE_DNS_1}\\n"$'\t'"DNS Server 2:"$'\t'"${PIHOLE_DNS_2}" \
      "${r}" "${c}" && result=0 || result=$?


      case ${result} in
      "${DIALOG_OK}")
      DNSSettingsCorrect=True
      ;;
      "${DIALOG_CANCEL}")
      DNSSettingsCorrect=False
      ;;
      "${DIALOG_ESC}")
      printf " %b Escape pressed, exiting installer at DNS Settin gs%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
      exit 1
      ;;
      esac
      fi
      done
      else
      # Save the old Internal Field Separator in a variable,
      OIFS=$IFS
      # and set the new one to newline
      IFS=$'\n'
      for DNSServer in ${DNS_SERVERS}; do
      DNSName="$(cut -d';' -f1 <<<"${DNSServer}")"
      if [[ "${DNSchoices}" == "${DNSName}" ]]; then
      PIHOLE_DNS_1="$(cut -d';' -f2 <<<"${DNSServer}")"
      PIHOLE_DNS_2="$(cut -d';' -f3 <<<"${DNSServer}")"
      break
      fi
      done
      # Restore the IFS to what it was
      IFS=${OIFS}
      fi


      # Display final selection
      local DNSIP=${PIHOLE_DNS_1}
      [[ -z ${PIHOLE_DNS_2} ]] || DNSIP+=", ${PIHOLE_DNS_2}"
      printf " %b Using upstream DNS: %s (%s)\\n" "${INFO}" "${DNSchoices}" "${DN SIP}"
      }


      # Allow the user to enable/disable logging
      setLogging() {
      # Ask the user if they want to enable logging
      dialog --no-shadow --keep-tite \
      --backtitle "Pihole Installation" \
      --title "Enable Logging" \
      --yesno "\\n\\nWould you like to enable query logging?" \
      "${r}" "${c}" && result=0 || result=$?


      case ${result} in
      "${DIALOG_OK}")
      # If they chose yes,
      printf " %b Query Logging on.\\n" "${INFO}"
      QUERY_LOGGING=true
      ;;
      "${DIALOG_CANCEL}")
      # If they chose no,
      printf " %b Query Logging off.\\n" "${INFO}"
      QUERY_LOGGING=false
      ;;
      "${DIALOG_ESC}")
      # User pressed <ESC>
      printf " %b Escape pressed, exiting installer at Query Logging choice.% b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
      exit 1
      ;;
      esac
      }


      # Allow the user to set their FTL privacy level
      setPrivacyLevel() {
      # The default selection is level 0
      PRIVACY_LEVEL=$(dialog --no-shadow --keep-tite --output-fd 1 \
      --cancel-label "Exit" \
      --ok-label "Continue" \
      --radiolist "Select a privacy mode for FTL. ftl dns/privacylevels/" \
      "${r}" "${c}" 6 \
      "0" "Show everything" on \
      "1" "Hide domains" off \
      "2" "Hide domains and clients" off \
      "3" "Anonymous mode" off)


      result=$?
      case ${result} in
      "${DIALOG_OK}")
      printf " %b Using privacy level: %s\\n" "${INFO}" "${PRIVACY_LEVEL}"
      ;;
      "${DIALOG_CANCEL}" | "${DIALOG_ESC}")
      printf " %b Cancelled privacy level selection.%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
      exit 1
      ;;
      esac
      }


      # A function to display a list of example blocklists for users to select
      chooseBlocklists() {
      # Back up any existing adlist file, on the off chance that it exists.
      if [[ -f "${adlistFile}" ]]; then
      mv "${adlistFile}" "${adlistFile}.old"
      fi
      # Let user select (or not) blocklists
      dialog --no-shadow --keep-tite \
      --backtitle "Pi-hole Installation" \
      --title "Blocklists" \
      --yesno "\\nPi-hole relies on third party lists in order to block ads.\
      \\n\\nYou can use the suggestion below, and/or add your own after installation.\
      \\n\\nSelect 'Yes' to include:\
      \\n\\nStevenBlack's Unified Hosts List" \
      "${r}" "${c}" && result=0 || result=$?


      case ${result} in
      "${DIALOG_OK}")
      # If they chose yes,
      printf " %b Installing StevenBlack's Unified Hosts List\\n" "${INFO}"
      echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >>"${adlistFile}"
      ;;
      "${DIALOG_CANCEL}")
      # If they chose no,
      printf " %b Not installing StevenBlack's Unified Hosts List\\n" "${INFO }"
      ;;
      "${DIALOG_ESC}")
      # User pressed <ESC>
      printf " %b Escape pressed, exiting installer at blocklist choice.%b\\n " "${COL_LIGHT_RED}" "${COL_NC}"
      exit 1
      ;;
      esac
      # Create an empty adList file with appropriate permissions.
      if [ ! -f "${adlistFile}" ]; then
      install -m 644 /dev/null "${adlistFile}"
      else
      chmod 644 "${adlistFile}"
      fi
      }


      # Used only in unattended setup
      # If there is already the adListFile, we keep it, else we create it using all de fault lists
      installDefaultBlocklists() {
      # In unattended setup, could be useful to use userdefined blocklist.
      # If this file exists, we avoid overriding it.
      if [[ -f "${adlistFile}" ]]; then
      return
      fi
      echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >>"$ {adlistFile}"
      }


      move_old_dnsmasq_ftl_configs() {
      # Create migration directory /etc/pihole/migration_backup_v6
      # and make it owned by pihole:pihole
      mkdir -p "${V6_CONF_MIGRATION_DIR}"
      chown pihole:pihole "${V6_CONF_MIGRATION_DIR}"


      # Move all conf files originally created by Pi-hole into this directory
      # - 01-pihole.conf
      # - 02-pihole-dhcp.conf
      # - 04-pihole-static-dhcp.conf
      # - 05-pihole-custom-cname.conf
      # - 06-rfc6761.conf
      mv /etc/dnsmasq.d/0{1,2,4,5}-pihole*.conf "${V6_CONF_MIGRATION_DIR}/" 2>/dev /null || true
      mv /etc/dnsmasq.d/06-rfc6761.conf "${V6_CONF_MIGRATION_DIR}/" 2>/dev/null || true


      # If the dnsmasq main config file exists
      local dnsmasq_conf="/etc/dnsmasq.conf"
      if [[ -f "${dnsmasq_conf}" ]]; then
      # There should not be anything custom in here for Pi-hole users
      # It is no longer needed, but we'll back it up instead of deleting it ju st in case
      mv "${dnsmasq_conf}" "${dnsmasq_conf}.old"
      fi


      # Create /etc/dnsmasq.d if it doesn't exist
      if [[ ! -d "/etc/dnsmasq.d" ]]; then
      mkdir "/etc/dnsmasq.d"
      fi
      }


      remove_old_pihole_lighttpd_configs() {
      local lighttpdConfig="/etc/lighttpd/lighttpd.conf"
      local condfd="/etc/lighttpd/conf.d/pihole-admin.conf"
      local confavailable="/etc/lighttpd/conf-available/15-pihole-admin.conf"
      local confenabled="/etc/lighttpd/conf-enabled/15-pihole-admin.conf"


      if [[ -f "${lighttpdConfig}" ]]; then
      sed -i '/include "\/etc\/lighttpd\/conf.d\/pihole-admin.conf"/d' "${ligh ttpdConfig}"
      fi


      if [[ -f "${condfd}" ]]; then
      rm "${condfd}"
      fi


      if is_command lighty-disable-mod; then
      lighty-disable-mod pihole-admin >/dev/null || true
      fi


      if [[ -f "${confenabled}" || -L "${confenabled}" ]]; then
      rm "${confenabled}"
      fi


      if [[ -f "${confavailable}" ]]; then
      rm "${confavailable}"
      fi
      }


      # Clean an existing installation to prepare for upgrade/reinstall
      clean_existing() {
      # Local, named variables
      # ${1} Directory to clean
      local clean_directory="${1}"
      # Pop the first argument, and shift all addresses down by one (i.e. ${2} bec omes ${1})
      shift
      # Then, we can access all arguments ($@) without including the directory to clean
      local old_files=("$@")


      # Remove each script in the old_files array
      for script in "${old_files[@]}"; do
      rm -f "${clean_directory}/${script}.sh"
      done
      }


      # Install the scripts from repository to their various locations
      installScripts() {
      # Local, named variables
      local str="Installing scripts from ${PI_HOLE_LOCAL_REPO}"
      printf " %b %s..." "${INFO}" "${str}"


      # Clear out script files from Pi-hole scripts directory.
      clean_existing "${PI_HOLE_INSTALL_DIR}" "${PI_HOLE_FILES[@]}"


      # Install files from local core repository
      if is_repo "${PI_HOLE_LOCAL_REPO}"; then
      # move into the directory
      cd "${PI_HOLE_LOCAL_REPO}"
      # Install the scripts by:
      # -o setting the owner to the user
      # -Dm755 create all leading components of destination except the last, then copy the source to the destination and setting the permissions to 755
      #
      # This first one is the directory
      install -o "${USER}" -Dm755 -d "${PI_HOLE_INSTALL_DIR}"
      # The rest are the scripts Pi-hole needs
      install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" gravity.sh
      install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scrip ts/*.sh
      install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./automated\ ins tall/uninstall.sh
      install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scrip ts/COL_TABLE
      install -o "${USER}" -Dm755 -t "${PI_HOLE_BIN_DIR}" pihole
      install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/ pihole
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"


      else
      # Otherwise, show an error and exit
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      printf "\\t\\t%bError: Local repo %s not found, exiting installer%b\\n" "${COL_LIGHT_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}"
      return 1
      fi
      }


      # Install the configs from PI_HOLE_LOCAL_REPO to their various locations
      installConfigs() {
      printf "\\n %b Installing configs from %s...\\n" "${INFO}" "${PI_HOLE_LOCAL _REPO}"


      # Ensure that permissions are correctly set
      chown -R pihole:pihole /etc/pihole


      # Install empty custom.list file if it does not exist
      if [[ ! -r "${PI_HOLE_CONFIG_DIR}/hosts/custom.list" ]]; then
      if ! install -D -T -o pihole -g pihole -m 660 /dev/null "${PI_HOLE_CONFI G_DIR}/hosts/custom.list" &>/dev/null; then
      printf " %b Error: Unable to initialize configuration file %s/custo m.list\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}/hosts"
      return 1
      fi
      fi


      # Install pihole-FTL systemd or init.d service, based on whether systemd is the init system or not
      if ps -p 1 -o comm= | grep -q systemd; then
      install -T -m 0644 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL. systemd" '/etc/systemd/system/pihole-FTL.service'


      # Remove init.d service if present
      if [[ -e '/etc/init.d/pihole-FTL' ]]; then
      rm '/etc/init.d/pihole-FTL'
      update-rc.d pihole-FTL remove
      fi


      # Load final service
      systemctl daemon-reload
      else
      install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL. service" '/etc/init.d/pihole-FTL'
      fi
      install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-pres tart.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-prestart.sh"
      install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-post stop.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-poststop.sh"
      }


      install_manpage() {
      # Copy Pi-hole man pages and call mandb to update man page database
      # Default location for man files for /usr/local/bin is /usr/local/share/man
      # on lightweight systems may not be present, so check before copying.
      printf " %b Testing man page installation" "${INFO}"
      if ! is_command mandb; then
      # if mandb is not present, no manpage support
      printf "%b %b man not installed\\n" "${OVER}" "${INFO}"
      return
      elif [[ ! -d "/usr/local/share/man" ]]; then
      # appropriate directory for Pi-hole's man page is not present
      printf "%b %b man pages not installed\\n" "${OVER}" "${INFO}"
      return
      fi
      if [[ ! -d "/usr/local/share/man/man8" ]]; then
      # if not present, create man8 directory
      install -d -m 755 /usr/local/share/man/man8
      fi
      if [[ ! -d "/usr/local/share/man/man5" ]]; then
      # if not present, create man5 directory
      install -d -m 755 /usr/local/share/man/man5
      fi
      # Testing complete, copy the files & update the man db
      install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/manpages/pihole.8 /usr/local/shar e/man/man8/pihole.8


      # remove previously installed man pages
      if [[ -f "/usr/local/share/man/man5/pihole-FTL.conf.5" ]]; then
      rm /usr/local/share/man/man5/pihole-FTL.conf.5
      fi
      if [[ -f "/usr/local/share/man/man8/pihole-FTL.8" ]]; then
      rm /usr/local/share/man/man8/pihole-FTL.8
      fi


      if mandb -q &>/dev/null; then
      # Updated successfully
      printf "%b %b man pages installed and database updated\\n" "${OVER}" "$ {TICK}"
      return
      else
      # Something is wrong with the system's man installation, clean up
      # our files, (leave everything how we found it).
      rm /usr/local/share/man/man8/pihole.8
      printf "%b %b man page db not updated, man pages not installed\\n" "${O VER}" "${CROSS}"
      fi
      }


      stop_service() {
      # Stop service passed in as argument.
      # Can softfail, as process may not be installed when this is called
      local str="Stopping ${1} service"
      printf " %b %s..." "${INFO}" "${str}"
      if is_command systemctl; then
      systemctl -q stop "${1}" || true
      else
      service "${1}" stop >/dev/null || true
      fi
      printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
      }


      # Start/Restart service passed in as argument
      restart_service() {
      # Local, named variables
      local str="Restarting ${1} service"
      printf " %b %s..." "${INFO}" "${str}"
      # If systemctl exists,
      if is_command systemctl; then
      # use that to restart the service
      systemctl -q restart "${1}"
      else
      # Otherwise, fall back to the service command
      service "${1}" restart >/dev/null
      fi
      printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
      }


      # Enable service so that it will start with next reboot
      enable_service() {
      # Local, named variables
      local str="Enabling ${1} service to start on reboot"
      printf " %b %s..." "${INFO}" "${str}"
      # If systemctl exists,
      if is_command systemctl; then
      # use that to enable the service
      systemctl -q enable "${1}"
      else
      # Otherwise, use update-rc.d to accomplish this
      update-rc.d "${1}" defaults >/dev/null
      fi
      printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
      }


      # Disable service so that it will not with next reboot
      disable_service() {
      # Local, named variables
      local str="Disabling ${1} service"
      printf " %b %s..." "${INFO}" "${str}"
      # If systemctl exists,
      if is_command systemctl; then
      # use that to disable the service
      systemctl -q disable "${1}"
      else
      # Otherwise, use update-rc.d to accomplish this
      update-rc.d "${1}" disable >/dev/null
      fi
      printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
      }


      check_service_active() {
      # If systemctl exists,
      if is_command systemctl; then
      # use that to check the status of the service
      systemctl -q is-enabled "${1}" 2>/dev/null
      else
      # Otherwise, fall back to service command
      service "${1}" status &>/dev/null
      fi
      }


      # Systemd-resolved's DNSStubListener and ftl can't share port 53.
      disable_resolved_stublistener() {
      printf " %b Testing if systemd-resolved is enabled\\n" "${INFO}"
      # Check if Systemd-resolved's DNSStubListener is enabled and active on port 53
      if check_service_active "systemd-resolved"; then
      # Disable the DNSStubListener to unbind it from port 53
      # Note that this breaks dns functionality on host until FTL is up and ru nning
      printf "%b %b Disabling systemd-resolved DNSStubListener\\n" "${OVER}" "${TICK}"
      mkdir -p /etc/systemd/resolved.conf.d
      cat > /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf << EOF
      [Resolve]
      DNSStubListener=no
      EOF
      systemctl reload-or-restart systemd-resolved
      else
      printf "%b %b Systemd-resolved is not enabled\\n" "${OVER}" "${INFO}"
      fi
      }


      update_package_cache() {
      # Update package cache on apt based OSes. Do this every time since
      # it's quick and packages can be updated at any time.


      # Local, named variables
      local str="Update local cache of available packages"
      printf " %b %s..." "${INFO}" "${str}"
      # Create a command from the package cache variable
      if eval "${UPDATE_PKG_CACHE}" &>/dev/null; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      # Otherwise, show an error and exit


      # In case we used apt-get and apt is also available, we use this as reco mmendation as we have seen it
      # gives more user-friendly (interactive) advice
      if [[ ${PKG_MANAGER} == "apt-get" ]] && is_command apt; then
      UPDATE_PKG_CACHE="apt update"
      fi
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      printf " %b Error: Unable to update package cache. Please try \"%s\"%b\ \n" "${COL_LIGHT_RED}" "sudo ${UPDATE_PKG_CACHE}" "${COL_NC}"
      return 1
      fi
      }


      # Let user know if they have outdated packages on their system and
      # advise them to run a package update at soonest possible.
      notify_package_updates_available() {
      # Local, named variables
      local str="Checking ${PKG_MANAGER} for upgraded packages"
      printf "\\n %b %s..." "${INFO}" "${str}"
      # Store the list of packages in a variable
      updatesToInstall=$(eval "${PKG_COUNT}")


      if [[ "${updatesToInstall}" -eq 0 ]]; then
      printf "%b %b %s... up to date!\\n\\n" "${OVER}" "${TICK}" "${str}"
      else
      printf "%b %b %s... %s updates available\\n" "${OVER}" "${TICK}" "${str }" "${updatesToInstall}"
      printf " %b %bIt is recommended to update your OS after installing the Pi-hole!%b\\n\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}"
      fi
      }


      install_dependent_packages() {
      # Install meta dependency package
      local str="Installing Pi-hole dependency package"
      printf " %b %s..." "${INFO}" "${str}"


      # Install Debian/Ubuntu packages
      if is_command apt-get; then
      if [ -f /tmp/pihole-meta.deb ]; then
      if eval "${PKG_INSTALL}" "/tmp/pihole-meta.deb" &>/dev/null; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      rm /tmp/pihole-meta.deb
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      printf " %b Error: Unable to install Pi-hole dependency package .\\n" "${COL_LIGHT_RED}"
      return 1
      fi
      else
      printf " %b Error: Unable to find Pi-hole dependency package.\\n" " ${COL_LIGHT_RED}"
      return 1
      fi
      # Install Fedora/CentOS packages
      elif is_command rpm; then
      if [ -f /tmp/pihole-meta.rpm ]; then
      if eval "${PKG_INSTALL}" "/tmp/pihole-meta.rpm" &>/dev/null; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      rm /tmp/pihole-meta.rpm
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      printf " %b Error: Unable to install Pi-hole dependency package .\\n" "${COL_LIGHT_RED}"
      return 1
      fi
      else
      printf " %b Error: Unable to find Pi-hole dependency package.\\n" " ${COL_LIGHT_RED}"
      return 1
      fi


      # If neither apt-get or yum/dnf package managers were found
      else
      # we cannot install the dependency package
      printf " %b No supported package manager found\\n" "${CROSS}"
      # so exit the installer
      exit 1
      fi


      printf "\\n"
      return 0
      }


      # Installs a cron file
      installCron() {
      # Install the cron job
      local str="Installing latest Cron script"
      printf "\\n %b %s..." "${INFO}" "${str}"
      # Copy the cron file over from the local repo
      # File must not be world or group writeable and must be owned by root
      install -D -m 644 -T -o root -g root ${PI_HOLE_LOCAL_REPO}/advanced/Template s/pihole.cron /etc/cron.d/pihole
      # Randomize gravity update time
      sed -i "s/59 1 /$((1 + RANDOM % 58)) $((3 + RANDOM % 2))/" /etc/cron.d/pihol e
      # Randomize update checker time
      sed -i "s/59 17/$((1 + RANDOM % 58)) $((12 + RANDOM % 8))/" /etc/cron.d/piho le
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      }


      # Gravity is a very important script as it aggregates all of the domains into a single HOSTS formatted list,
      # which is what Pi-hole needs to begin blocking ads
      runGravity() {
      # Run gravity in the current shell as user pihole
      { sudo -u pihole bash /opt/pihole/gravity.sh --force; }
      }


      # Check if the pihole user exists and create if it does not
      create_pihole_user() {
      local str="Checking for user 'pihole'"
      printf " %b %s..." "${INFO}" "${str}"
      # If the pihole user exists,
      if id -u pihole &>/dev/null; then
      # and if the pihole group exists,
      if getent group pihole >/dev/null 2>&1; then
      # succeed
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      local str="Checking for group 'pihole'"
      printf " %b %s..." "${INFO}" "${str}"
      local str="Creating group 'pihole'"
      # if group can be created
      if groupadd pihole; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      local str="Adding user 'pihole' to group 'pihole'"
      printf " %b %s..." "${INFO}" "${str}"
      # if pihole user can be added to group pihole
      if usermod -g pihole pihole; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi
      fi
      else
      # If the pihole user doesn't exist,
      printf "%b %b %s" "${OVER}" "${CROSS}" "${str}"
      local str="Checking for group 'pihole'"
      printf " %b %s..." "${INFO}" "${str}"
      if getent group pihole >/dev/null 2>&1; then
      # group pihole exists
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      # then create and add her to the pihole group
      local str="Creating user 'pihole'"
      printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
      if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pihole; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi
      else
      # group pihole does not exist
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      local str="Creating group 'pihole'"
      # if group can be created
      if groupadd pihole; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      # create and add pihole user to the pihole group
      local str="Creating user 'pihole'"
      printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
      if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pih ole; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi


      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi
      fi
      fi
      }


      # Install the logrotate script
      installLogrotate() {
      local str="Installing latest logrotate script"
      local target=/etc/pihole/logrotate
      local logfileUpdate=false


      printf "\\n %b %s..." "${INFO}" "${str}"
      if [[ -f ${target} ]]; then


      # Account for changed logfile paths from /var/log -> /var/log/pihole/ ma de in core v5.11.
      if grep -q "/var/log/pihole.log" ${target} || grep -q "/var/log/pihole-F TL.log" ${target}; then
      sed -i 's/\/var\/log\/pihole.log/\/var\/log\/pihole\/pihole.log/g' $ {target}
      sed -i 's/\/var\/log\/pihole-FTL.log/\/var\/log\/pihole\/FTL.log/g' ${target}


      printf "\\n\\t%b Old log file paths updated in existing logrotate fi le. \\n" "${INFO}"
      logfileUpdate=true
      fi


      # Account for added webserver.log in v6.0
      if ! grep -q "/var/log/pihole/webserver.log" ${target}; then
      echo "/var/log/pihole/webserver.log {
      # su #
      weekly
      copytruncate
      rotate 3
      compress
      delaycompress
      notifempty
      nomail
      }" >> ${target}


      printf "\\n\\t%b webserver.log added to logrotate file. \\n" "${INFO }"
      logfileUpdate=true
      fi
      if [[ "${logfileUpdate}" == false ]]; then
      printf "\\n\\t%b Existing logrotate file found. No changes made.\\n" "${INFO}"
      return
      fi
      else
      # Copy the file over from the local repo
      # Logrotate config file must be owned by root and not writable by group or other
      install -o root -g root -D -m 644 -T "${PI_HOLE_LOCAL_REPO}"/advanced/Te mplates/logrotate ${target}
      fi


      # Different operating systems have different user / group
      # settings for logrotate that makes it impossible to create
      # a static logrotate file that will work with e.g.
      # Rasbian and Ubuntu at the same time. Hence, we have to
      # customize the logrotate script here in order to reflect
      # the local properties of the /var/log directory
      logusergroup="$(stat -c '%U %G' /var/log)"
      # If there is a usergroup for log rotation,
      if [[ -n "${logusergroup}" ]]; then
      # replace the line in the logrotate script with that usergroup.
      sed -i "s/# su #/su ${logusergroup}/g;" ${target}
      fi
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      }


      # Install base files and web interface
      installPihole() {
      # Install base files and web interface
      if ! installScripts; then
      printf " %b Failure in dependent script copy function.\\n" "${CROSS}"
      exit 1
      fi


      # Move old dnsmasq files to $V6_CONF_MIGRATION_DIR for later migration via m igrate_dnsmasq_configs()
      move_old_dnsmasq_ftl_configs
      remove_old_pihole_lighttpd_configs


      # Install config files
      if ! installConfigs; then
      printf " %b Failure in dependent config copy function.\\n" "${CROSS}"
      exit 1
      fi


      # Install the cron file
      installCron


      # Install the logrotate file
      installLogrotate || true


      # install a man page entry for pihole
      install_manpage
      }


      # SELinux
      checkSelinux() {
      local DEFAULT_SELINUX
      local CURRENT_SELINUX
      local SELINUX_ENFORCING=0
      # Check for SELinux configuration file and getenforce command
      if [[ -f /etc/selinux/config ]] && is_command getenforce; then
      # Check the default SELinux mode
      DEFAULT_SELINUX=$(awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config)
      case "${DEFAULT_SELINUX,,}" in
      enforcing)
      printf " %b %bDefault SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${ DEFAULT_SELINUX,,}" "${COL_NC}"
      SELINUX_ENFORCING=1
      ;;
      *) # 'permissive' and 'disabled'
      printf " %b %bDefault SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "$ {DEFAULT_SELINUX,,}" "${COL_NC}"
      ;;
      esac
      # Check the current state of SELinux
      CURRENT_SELINUX=$(getenforce)
      case "${CURRENT_SELINUX,,}" in
      enforcing)
      printf " %b %bCurrent SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${ CURRENT_SELINUX,,}" "${COL_NC}"
      SELINUX_ENFORCING=1
      ;;
      *) # 'permissive' and 'disabled'
      printf " %b %bCurrent SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "$ {CURRENT_SELINUX,,}" "${COL_NC}"
      ;;
      esac
      else
      echo -e " ${INFO} ${COL_GREEN}SELinux not detected${COL_NC}"
      fi
      # Exit the installer if any SELinux checks toggled the flag
      if [[ "${SELINUX_ENFORCING}" -eq 1 ]] && [[ -z "${PIHOLE_SELINUX}" ]]; then
      printf " Pi-hole does not provide an SELinux policy as the required cha nges modify the security of your system.\\n"
      printf " Please refer to HowTos/SELinux if SELi nux is required for your deployment.\\n"
      printf " This check can be skipped by setting the environment varia ble %bPIHOLE_SELINUX%b to %btrue%b\\n" "${COL_LIGHT_RED}" "${COL_NC}" "${COL_LIG HT_RED}" "${COL_NC}"
      printf " e.g: export PIHOLE_SELINUX=true\\n"
      printf " By setting this variable to true you acknowledge there may be issues with Pi-hole during or after the install\\n"
      printf "\\n %bSELinux Enforcing detected, exiting installer%b\\n" "${CO L_LIGHT_RED}" "${COL_NC}"
      exit 1
      elif [[ "${SELINUX_ENFORCING}" -eq 1 ]] && [[ -n "${PIHOLE_SELINUX}" ]]; the n
      printf " %b %bSELinux Enforcing detected%b. PIHOLE_SELINUX env variable set - installer will continue\\n" "${INFO}" "${COL_LIGHT_RED}" "${COL_NC}"
      fi
      }


      check_download_exists() {
      # Check if the download exists and we can reach the server
      local status
      status=$(curl --head --silent "https://ftl.pi-hole.net/${1}" | head -n 1)


      # Check the status code
      if grep -q "200" <<<"$status"; then
      return 0
      elif grep -q "404" <<<"$status"; then
      return 1
      fi


      # Other error or no status code at all, e.g., no Internet, server not
      # available/reachable, ...
      return 2
      }


      fully_fetch_repo() {
      # Add upstream branches to shallow clone
      local directory="${1}"


      cd "${directory}" || return 1
      if is_repo "${directory}"; then
      git remote set-branches origin '*' || return 1
      git fetch --quiet || return 1
      else
      return 1
      fi
      return 0
      }


      get_available_branches() {
      # Return available branches
      local directory
      directory="${1}"
      local output


      cd "${directory}" || return 1
      # Get reachable remote branches, but store STDERR as STDOUT variable
      output=$({ git ls-remote --heads --quiet | cut -d'/' -f3- -; } 2>&1)
      # echo status for calling function to capture
      echo "$output"
      return
      }


      fetch_checkout_pull_branch() {
      # Check out specified branch
      local directory
      directory="${1}"
      local branch
      branch="${2}"


      # Set the reference for the requested branch, fetch, check it put and pull i t
      cd "${directory}" || return 1
      git remote set-branches origin "${branch}" || return 1
      git stash --all --quiet &>/dev/null || true
      git clean --quiet --force -d || true
      git fetch --quiet || return 1
      checkout_pull_branch "${directory}" "${branch}" || return 1
      }


      checkout_pull_branch() {
      # Check out specified branch
      local directory
      directory="${1}"
      local branch
      branch="${2}"
      local oldbranch


      cd "${directory}" || return 1


      oldbranch="$(git symbolic-ref HEAD)"


      str="Switching to branch: '${branch}' from '${oldbranch}'"
      printf " %b %s" "${INFO}" "$str"
      git checkout "${branch}" --quiet || return 1
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "$str"
      # Data in the repositories is public anyway so we can make it readable by ev eryone (+r to keep executable permission if already set by git)
      chmod -R a+rX "${directory}"


      git_pull=$(git pull --no-rebase || return 1)


      printf " %b %s\\n" "${INFO}" "${git_pull}"


      return 0
      }


      clone_or_reset_repos() {
      # If the user wants to repair/update,
      if [[ "${repair}" == true ]]; then
      printf " %b Resetting local repos\\n" "${INFO}"
      # Reset the Core repo
      resetRepo ${PI_HOLE_LOCAL_REPO} ||
      {
      printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_ LIGHT_RED}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}"
      exit 1
      }
      # Reset the Web repo
      resetRepo ${webInterfaceDir} ||
      {
      printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_ LIGHT_RED}" "${webInterfaceDir}" "${COL_NC}"
      exit 1
      }
      # Otherwise, a fresh installation is happening
      else
      # so get git files for Core
      getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} ||
      {
      printf " %b Unable to clone %s into %s, unable to continue%b\\n " "${COL_LIGHT_RED}" "${piholeGitUrl}" "${PI_HOLE_LOCAL_REPO}" "${COL_NC}"
      exit 1
      }
      # get the Web git files
      getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} ||
      {
      printf " %b Unable to clone %s into ${webInterfaceDir}, exiting installer%b\\n" "${COL_LIGHT_RED}" "${webInterfaceGitUrl}" "${COL_NC}"
      exit 1
      }
      fi
      }


      # Download FTL binary to random temp directory and install FTL binary
      # Disable directive for SC2120 a value _can_ be passed to this function, but it is passed from an external script that sources this one
      FTLinstall() {
      # Local, named variables
      local str="Downloading and Installing FTL"
      printf " %b %s..." "${INFO}" "${str}"


      # Move into the temp ftl directory
      pushd "$(mktemp -d)" >/dev/null || {
      printf "Unable to make temporary directory for FTL binary download\\n"
      return 1
      }
      local tempdir
      tempdir="$(pwd)"
      local ftlBranch
      local url


      if [[ -f "/etc/pihole/ftlbranch" ]]; then
      ftlBranch=$(</etc/pihole/ftlbranch)
      else
      ftlBranch="master"
      fi


      local binary
      binary="${1}"


      # Determine which version of FTL to download
      if [[ "${ftlBranch}" == "master" ]]; then
      url="https://github.com/pi-hole/ftl/releases/latest/download"
      else
      url="https://ftl.pi-hole.net/${ftlBranch}"
      fi


      if curl -sSL --fail "${url}/${binary}" -o "${binary}"; then
      # If the download worked, get sha1 of the binary we just downloaded for verification.
      curl -sSL --fail "${url}/${binary}.sha1" -o "${binary}.sha1"


      # If we downloaded binary file (as opposed to text),
      if sha1sum --status --quiet -c "${binary}".sha1; then
      printf "transferred... "


      # Before stopping FTL, we download the macvendor database
      curl -sSL "https://ftl.pi-hole.net/macvendor.db" -o "${PI_HOLE_CONFI G_DIR}/macvendor.db" || true


      # Stop pihole-FTL service if available
      stop_service pihole-FTL >/dev/null


      # Install the new version with the correct permissions
      install -T -m 0755 "${binary}" /usr/bin/pihole-FTL


      # Move back into the original directory the user was in
      popd >/dev/null || {
      printf "Unable to return to original directory after FTL binary download.\\n"
      return 1
      }


      # Installed the FTL service
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"


      # Remove temp dir
      remove_dir "${tempdir}"


      return 0
      else
      # Otherwise, the hash download failed, so print and exit.
      popd >/dev/null || {
      printf "Unable to return to original directory after FTL binary download.\\n"
      return 1
      }
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      printf " %b Error: Download of %s/%s failed (checksum error)%b\\n" "${COL_LIGHT_RED}" "${url}" "${binary}" "${COL_NC}"


      # Remove temp dir
      remove_dir "${tempdir}"
      return 1
      fi
      else
      # Otherwise, the download failed, so print and exit.
      popd >/dev/null || {
      printf "Unable to return to original directory after FTL binary down load.\\n"
      return 1
      }
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      # The URL could not be found
      printf " %b Error: URL %s/%s not found%b\\n" "${COL_LIGHT_RED}" "${url} " "${binary}" "${COL_NC}"


      # Remove temp dir
      remove_dir "${tempdir}"
      return 1
      fi
      }


      remove_dir() {
      # Delete dir
      rm -r "${1}" >/dev/null 2>&1 ||
      echo -e " ${CROSS} Unable to remove ${1}"
      }


      get_binary_name() {
      local l_binary
      local machine
      machine=$(uname -m)


      local str="Detecting processor"
      printf " %b %s..." "${INFO}" "${str}"


      # If the machine is aarch64 (armv8)
      if [[ "${machine}" == "aarch64" ]]; then
      # If AArch64 is found (e.g., BCM2711 in Raspberry Pi 4)
      printf "%b %b Detected AArch64 (64 Bit ARM) architecture\\n" "${OVER}" "${TICK}"
      l_binary="pihole-FTL-arm64"
      elif [[ "${machine}" == "arm"* ]]; then
      # ARM 32 bit
      # Get supported processor from other binaries installed on the system
      # We cannot really rely on the output of $(uname -m) above as this may
      # return an incorrect architecture when buildx-compiling with QEMU
      local cpu_arch
      cpu_arch=$(readelf -A "$(command -v sh)" | grep Tag_CPU_arch | awk '{ pr int $2 }')


      # Get the revision from the CPU architecture
      local rev
      rev=$(echo "${cpu_arch}" | grep -o '[0-9]*')
      if [[ "${rev}" -eq 6 ]]; then
      # If ARMv6 is found (e.g., BCM2835 in Raspberry Pi 1 and Zero)
      printf "%b %b Detected ARMv6 architecture\\n" "${OVER}" "${TICK}"
      l_binary="pihole-FTL-armv6"
      elif [[ "${rev}" -ge 7 ]]; then
      # If ARMv7 or higher is found (e.g., BCM2836 in Raspberry PI 2 Mod. B)
      # This path is also used for ARMv8 when the OS is in 32bit mode
      # (e.g., BCM2837 in Raspberry Pi Model 3B, or BCM2711 in Raspberry P i 4)
      printf "%b %b Detected ARMv7 (or newer) architecture (%s)\\n" "${OV ER}" "${TICK}" "${cpu_arch}"
      l_binary="pihole-FTL-armv7"
      else
      # Otherwise, Pi-hole does not support this architecture
      printf "%b %b This processor architecture is not supported by Pi-ho le (%s)\\n" "${OVER}" "${CROSS}" "${cpu_arch}"
      l_binary=""
      fi
      elif [[ "${machine}" == "x86_64" ]]; then
      # This gives the processor of packages dpkg installs (for example, "i386 ")
      local dpkgarch
      dpkgarch=$(dpkg --print-processor 2>/dev/null || dpkg --print-architectu re 2>/dev/null)


      # Special case: This is a 32 bit OS, installed on a 64 bit machine
      # -> change machine processor to download the 32 bit executable
      # We only check this for Debian-based systems as this has been an issue
      # in the past (see Install 32bit FTL on 32bit OS (even if 64bit architecture is detected) by DL6ER · Pull Request #2004 · pi-hole/pi-hole · GitHub)
      if [[ "${dpkgarch}" == "i386" ]]; then
      printf "%b %b Detected 32bit (i686) architecture\\n" "${OVER}" "${T ICK}"
      l_binary="pihole-FTL-386"
      else
      # 64bit OS
      printf "%b %b Detected x86_64 architecture\\n" "${OVER}" "${TICK}"
      l_binary="pihole-FTL-amd64"
      fi
      elif [[ "${machine}" == "riscv64" ]]; then
      printf "%b %b Detected riscv64 architecture\\n" "${OVER}" "${TICK}"
      l_binary="pihole-FTL-riscv64"
      else
      # Something else - we try to use 32bit executable and warn the user
      if [[ ! "${machine}" == "i686" ]]; then
      printf "%b %b %s...\\n" "${OVER}" "${CROSS}" "${str}"
      printf " %b %bNot able to detect architecture (unknown: %s), trying x86 (32bit) executable%b\\n" "${INFO}" "${COL_LIGHT_RED}" "${machine}" "${COL_N C}"
      printf " %b Contact Pi-hole Support if you experience issues (e.g: FTL not running)\\n" "${INFO}"
      else
      printf "%b %b Detected 32bit (i686) architecture\\n" "${OVER}" "${T ICK}"
      fi
      l_binary="pihole-FTL-386"
      fi


      # Returning a string value via echo
      echo ${l_binary}
      }


      FTLcheckUpdate() {
      # In the next section we check to see if FTL is already installed (in case o f pihole -r).
      # If the installed version matches the latest version, then check the instal led sha1sum of the binary vs the remote sha1sum. If they do not match, then down load
      local ftlLoc
      ftlLoc=$(command -v pihole-FTL 2>/dev/null)


      local ftlBranch


      if [[ -f "/etc/pihole/ftlbranch" ]]; then
      ftlBranch=$(</etc/pihole/ftlbranch)
      else
      ftlBranch="master"
      fi


      local binary
      binary="${1}"


      local remoteSha1
      local localSha1


      if [[ ! "${ftlBranch}" == "master" ]]; then
      # This is not the master branch
      local path
      path="${ftlBranch}/${binary}"


      # Check whether or not the binary for this FTL branch actually exists. I f not, then there is no update!
      if ! check_download_exists "$path"; then
      local status
      status=$?
      if [ "${status}" -eq 1 ]; then
      printf " %b Branch \"%s\" is not available.\\n" "${INFO}" "${ft lBranch}"
      printf " %b Use %bpihole checkout ftl [branchname]%b to switch to a valid branch.\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}"
      elif [ "${status}" -eq 2 ]; then
      printf " %b Unable to download from ftl.pi-hole.net. Please che ck your Internet connection and try again later.\\n" "${CROSS}"
      return 3
      else
      printf " %b Unknown error. Please contact Pi-hole Support\\n" " ${CROSS}"
      return 4
      fi
      fi


      if [[ ${ftlLoc} ]]; then
      # We already have a pihole-FTL binary installed, check if it's the
      # same as the remote one
      # Alt branches don't have a tagged version against them, so just
      # confirm the checksum of the local vs remote to decide whether we
      # download or not
      printf " %b FTL binary already installed, verifying integrity...\\n " "${INFO}"
      checkSumFile="https://ftl.pi-hole.net/${ftlBranch}/${binary}.sha1"
      # Continue further down...
      else
      return 0
      fi
      else
      # This is the master branch
      if [[ ${ftlLoc} ]]; then
      # We already have a pihole-FTL binary installed, check if it's the
      # same as the remote one
      local FTLversion
      FTLversion=$(/usr/bin/pihole-FTL tag)


      # Get the latest version from the GitHub API
      local FTLlatesttag
      FTLlatesttag=$(curl -s rele ases/latest | jq -sRr 'fromjson? | .tag_name | values')


      if [ -z "${FTLlatesttag}" ]; then
      # There was an issue while retrieving the latest version
      printf " %b Failed to retrieve latest FTL release metadata\\n" "${CROSS}"
      return 3
      fi


      # Check if the installed version matches the latest version
      if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
      # If the installed version does not match the latest version,
      # then download
      return 0
      else
      # If the installed version matches the latest version, then
      # check the installed sha1sum of the binary vs the remote
      # sha1sum. If they do not match, then download
      printf " %b Latest FTL binary already installed (%s), verifying integrity...\\n" "${INFO}" "${FTLlatesttag}"
      checkSumFile="https://github.com/pi-hole/FTL/releases/download/$ {FTLversion%$'\r'}/${binary}.sha1"
      # Continue further down...
      fi
      else
      # FTL not installed, then download
      return 0
      fi
      fi


      # If we reach this point, we need to check the checksum of the local vs
      # remote to decide whether we download or not
      remoteSha1=$(curl -sSL --fail "${checkSumFile}" | cut -d ' ' -f 1)
      localSha1=$(sha1sum "${ftlLoc}" | cut -d ' ' -f 1)


      # Check we downloaded a valid checksum (no 404 or other error like
      # no DNS resolution)
      if [[ ! "${remoteSha1}" =~ ^[a-f0-9]{40}$ ]]; then
      printf " %b Remote checksum not available, trying to redownload...\\n" "${CROSS}"
      return 0
      elif [[ "${remoteSha1}" != "${localSha1}" ]]; then
      printf " %b Remote binary is different, downloading...\\n" "${CROSS}"
      return 0
      fi


      printf " %b Local binary up-to-date. No need to download!\\n" "${INFO}"
      return 1
      }


      # Detect suitable FTL binary platform
      FTLdetect() {
      printf "\\n %b FTL Checks...\\n\\n" "${INFO}"


      printf " %b" "${2}"


      if FTLcheckUpdate "${1}"; then
      FTLinstall "${1}" || return 1
      fi
      }


      make_temporary_log() {
      # Create a random temporary file for the log
      TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
      # Open handle 3 for templog
      # writing-outputs-to-log-file-a nd-console
      exec 3>"$TEMPLOG"
      # Delete templog, but allow for addressing via file handle
      # This lets us write to the log without having a temporary file on the drive , which
      # is meant to be a security measure so there is not a lingering file on the drive during the install process
      rm "$TEMPLOG"
      }


      copy_to_install_log() {
      # Copy the contents of file descriptor 3 into the install log
      # Since we use color codes such as '\e[1;33m', they should be removed
      sed 's/[[0-9;]\{1,5\}m//g' </proc/$$/fd/3 >"${installLogLoc}"
      chmod 644 "${installLogLoc}"
      chown pihole:pihole "${installLogLoc}"
      }


      disableLighttpd() {
      # Return early when lighttpd is not active
      if ! check_service_active lighttpd; then
      return
      fi


      local response
      # Detect if the terminal is interactive
      if [[ -t 0 ]]; then
      # The terminal is interactive
      dialog --no-shadow --keep-tite \
      --title "Pi-hole v6.0 no longer uses lighttpd" \
      --yesno "\\n\\nPi-hole v6.0 has its own embedded web server so lightt pd is no longer needed *unless* you have custom configurations.\\n\\nIn this cas e, you can opt-out of disabling lighttpd and pihole-FTL will try to bind to an a lternative port such as 8080.\\n\\nDo you want to disable lighttpd (recommended) ?" "${r}" "${c}" && response=0 || response="$?"
      else
      # The terminal is non-interactive, assume yes. Lighttpd will be stopped
      # but keeps being installed and can easily be re-enabled by the user
      response=0
      fi


      # If the user does not want to disable lighttpd, return early
      if [[ "${response}" -ne 0 ]]; then
      return
      fi


      # Lighttpd is not needed anymore, so disable it
      # We keep all the configuration files in place, so the user can re-enable it
      # if needed


      # Check if lighttpd is installed
      if is_command lighttpd; then
      # Stop the lighttpd service
      stop_service lighttpd


      # Disable the lighttpd service
      disable_service lighttpd
      fi
      }


      migrate_dnsmasq_configs() {
      # Previously, Pi-hole created a number of files in /etc/dnsmasq.d
      # During migration, their content is copied into the new single source of
      # truth file /etc/pihole/pihole.toml and the old files are moved away to
      # avoid conflicts with other services on this system


      # Exit early if this is already Pi-hole v6.0
      # We decide this on the non-existence of the file /etc/pihole/setupVars.conf (either moved by previous migration or fresh install)
      if [[ ! -f "/etc/pihole/setupVars.conf" ]]; then
      return 0
      fi


      # Disable lighttpd server during v6 migration
      disableLighttpd


      # move_old_dnsmasq_ftl_configs() moved everything is in place,
      # so we can create the new config file /etc/pihole/pihole.toml
      # This file will be created with the default settings unless the user has
      # changed settings via setupVars.conf or the other dnsmasq files moved befor e
      # During migration, setupVars.conf is moved to /etc/pihole/migration_backup_ v6
      str="Migrating Pi-hole configuration to version 6"
      printf " %b %s..." "${INFO}" "${str}"
      local FTLoutput FTLstatus
      FTLoutput=$(pihole-FTL migrate v6)
      FTLstatus=$?
      if [[ "${FTLstatus}" -eq 0 ]]; then
      printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
      else
      printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
      fi


      # Print the output of the FTL migration prefacing every line with four
      # spaces for alignment
      printf "%b" "${FTLoutput}" | sed 's/^/ /'


      # Print a blank line for separation
      printf "\\n"
      }


      # Check for availability of either the "service" or "systemctl" commands
      check_service_command() {
      # Check for the availability of the "service" command
      if ! is_command service && ! is_command systemctl; then
      # If neither the "service" nor the "systemctl" command is available, inf orm the user
      printf " %b Neither the service nor the systemctl commands are availabl e\\n" "${CROSS}"
      printf " on this machine. This Pi-hole installer cannot continue.\\ n"
      exit 1
      fi
      }


      main() {
      ######## FIRST CHECK ########
      # Must be root to install
      local str="Root user check"
      printf "\\n"


      # If the user's id is zero,
      if [[ "${EUID}" -eq 0 ]]; then
      # they are root and all is good
      printf " %b %s\\n" "${TICK}" "${str}"
      # Show the Pi-hole logo so people know it's genuine since the logo and n ame are trademarked
      show_ascii_berry
      make_temporary_log
      else
      # Otherwise, they do not have enough privileges, so let the user know
      printf " %b %s\\n" "${INFO}" "${str}"
      printf " %b %bScript called with non-root privileges%b\\n" "${INFO}" "$ {COL_LIGHT_RED}" "${COL_NC}"
      printf " The Pi-hole requires elevated privileges to install and ru n\\n"
      printf " Please check the installer for any concerns regarding this requirement\\n"
      printf " Make sure to download this script from a trusted source\\n \\n"
      printf " %b Sudo utility check" "${INFO}"


      # If the sudo command exists, try rerunning as admin
      if is_command sudo; then
      printf "%b %b Sudo utility check\\n" "${OVER}" "${TICK}"


      # when run via curl piping
      if [[ "$0" == "bash" ]]; then
      # Download the install script and run it with admin rights
      exec curl -sSL install.pi-hole.net | sudo bash "$@"
      else
      # when run via calling local bash script
      exec sudo bash "$0" "$@"
      fi


      exit $?
      else
      # Otherwise, tell the user they need to run the script as root, and bail
      printf "%b %b Sudo utility check\\n" "${OVER}" "${CROSS}"
      printf " %b Sudo is needed for the Web Interface to run pihole comm ands\\n\\n" "${INFO}"
      printf " %b %bPlease re-run this installer as root${COL_NC}\\n" "${ INFO}" "${COL_LIGHT_RED}"
      exit 1
      fi
      fi


      # Check if SELinux is Enforcing and exit before doing anything else
      checkSelinux


      # Check for availability of either the "service" or "systemctl" commands
      check_service_command


      # Check for supported package managers so that we may install dependencies
      package_manager_detect


      # Notify user of package availability
      notify_package_updates_available


      # Build dependency package
      build_dependency_package


      # Install Pi-hole dependencies
      install_dependent_packages



      # Check if there is a usable FTL binary available on this architecture - do
      # this early on as FTL is a hard dependency for Pi-hole
      local funcOutput
      funcOutput=$(get_binary_name) #Store output of get_binary_name here
      # Abort early if this processor is not supported (get_binary_name returns em pty string)
      if [[ "${funcOutput}" == "" ]]; then
      printf " %b Upgrade/install aborted\\n" "${CROSS}" "${DISTRO_NAME}"
      exit 1
      fi


      # in case of an update (can be a v5 -> v6 or v6 -> v6 update) or repair
      if [[ -f "${PI_HOLE_V6_CONFIG}" ]] || [[ -f "/etc/pihole/setupVars.conf" ]]; then
      # retain settings
      fresh_install=false
      # if it's running unattended,
      if [[ "${runUnattended}" == true ]]; then
      printf " %b Performing unattended setup, no dialogs will be display ed\\n" "${INFO}"
      # also disable debconf-apt-progress dialogs
      export DEBIAN_FRONTEND="noninteractive"
      fi
      fi


      if [[ "${fresh_install}" == true ]]; then
      # Display welcome dialogs
      welcomeDialogs
      # Create directory for Pi-hole storage (/etc/pihole/)
      install -d -m 755 "${PI_HOLE_CONFIG_DIR}"
      # Determine available interfaces
      get_available_interfaces
      # Find interfaces and let the user choose one
      chooseInterface
      # find IPv4 and IPv6 information of the device
      collect_v4andv6_information
      # Decide what upstream DNS Servers to use
      setDNS
      # Give the user a choice of blocklists to include in their install. Or n ot.
      chooseBlocklists
      # Let the user decide if they want query logging enabled...
      setLogging
      # Let the user decide the FTL privacy level
      setPrivacyLevel
      else
      # Setup adlist file if not exists
      installDefaultBlocklists
      fi
      # Download or reset the appropriate git repos depending on the 'repair' flag
      clone_or_reset_repos


      # Create the pihole user
      create_pihole_user


      # Download and install FTL
      local binary
      binary="pihole-FTL${funcOutput##*pihole-FTL}" #binary name will be the last line of the output of get_binary_name (it always begins with pihole-FTL)
      local theRest
      theRest="${funcOutput%pihole-FTL*}" # Print the rest of get_binary_name's ou tput to display (cut out from first instance of "pihole-FTL")
      if ! FTLdetect "${binary}" "${theRest}"; then
      printf " %b FTL Engine not installed\\n" "${CROSS}"
      exit 1
      fi


      # Install and log everything to a file
      installPihole | tee -a /proc/$$/fd/3


      # /opt/pihole/utils.sh should be installed by installScripts now, so we can use it
      if [ -f "${PI_HOLE_INSTALL_DIR}/utils.sh" ]; then
      # shellcheck source="./advanced/Scripts/utils.sh"
      source "${PI_HOLE_INSTALL_DIR}/utils.sh"
      else
      printf " %b Failure: /opt/pihole/utils.sh does not exist .\\n" "${CROSS }"
      exit 1
      fi


      # Copy the temp log file into final log location for storage
      copy_to_install_log


      # Migrate existing install to v6.0
      migrate_dnsmasq_configs


      # Cleanup old v5 sudoers file if it exists
      sudoers_file="/etc/sudoers.d/pihole"
      if [[ -f "${sudoers_file}" ]]; then
      # only remove the file if it contains the Pi-hole header
      if grep -q "Pi-hole: A black hole for Internet advertisements" "${sudoer s_file}"; then
      rm -f "${sudoers_file}"
      fi
      fi


      # Check for and disable systemd-resolved-DNSStubListener before reloading re solved
      # DNSStubListener needs to remain in place for installer to download needed files,
      # so this change needs to be made after installation is complete,
      # but before starting or resttarting the ftl service
      disable_resolved_stublistener


      if [[ "${fresh_install}" == false ]]; then
      # Check if gravity database needs to be upgraded. If so, do it without r ebuilding
      # gravity altogether. This may be a very long running task needlessly bl ocking
      # the update process.
      # Only do this on updates, not on fresh installs as the database does no t exit yet
      /opt/pihole/gravity.sh --upgrade
      fi


      printf " %b Restarting services...\\n" "${INFO}"
      # Start services


      # Enable FTL
      # Ensure the service is enabled before trying to start it
      # Fixes a problem reported on Ubuntu 18.04 where trying to start
      # the service before enabling causes installer to exit
      enable_service pihole-FTL


      restart_service pihole-FTL


      if [[ "${fresh_install}" == true ]]; then
      # apply settings to pihole.toml
      # needs to be done after FTL service has been started, otherwise pihole. toml does not exist
      # set on fresh installations by setDNS() and setPrivacyLevel() and setLo gging()


      # Upstreams may be needed in order to run gravity.sh
      if [ -n "${PIHOLE_DNS_1}" ]; then
      local string="\"${PIHOLE_DNS_1}\""
      [ -n "${PIHOLE_DNS_2}" ] && string+=", \"${PIHOLE_DNS_2}\""
      setFTLConfigValue "dns.upstreams" "[ $string ]"
      fi


      if [ -n "${QUERY_LOGGING}" ]; then
      setFTLConfigValue "dns.queryLogging" "${QUERY_LOGGING}"
      fi


      if [ -n "${PRIVACY_LEVEL}" ]; then
      setFTLConfigValue "misc.privacylevel" "${PRIVACY_LEVEL}"
      fi


      if [ -n "${PIHOLE_INTERFACE}" ]; then
      setFTLConfigValue "dns.interface" "${PIHOLE_INTERFACE}"
      fi
      fi


      # Download and compile the aggregated block list
      runGravity


      # Update local and remote versions via updatechecker
      /opt/pihole/updatecheck.sh


      if [[ "${fresh_install}" == true ]]; then


      # Get the Web interface port, return only the first port and strip all n on-numeric characters
      WEBPORT=$(getFTLConfigValue webserver.port|cut -d, -f1 | tr -cd '0-9')


      # If this is a fresh install, we will set a random password.
      # Users can change this password after installation if they wish
      pw=$(tr -dc _A-Z-a-z-0-9 </dev/urandom | head -c 8)
      pihole setpassword "${pw}" > /dev/null


      # Explain to the user how to use Pi-hole as their DNS server
      printf "\\n %b You may now configure your devices to use the Pi-hole as their DNS server\\n" "${INFO}"
      [[ -n "${IPV4_ADDRESS%/*}" ]] && printf " %b Pi-hole DNS (IPv4): %s\\n" "${INFO}" "${IPV4_ADDRESS%/*}"
      [[ -n "${IPV6_ADDRESS}" ]] && printf " %b Pi-hole DNS (IPv6): %s\\n" "$ {INFO}" "${IPV6_ADDRESS}"
      printf " %b If you have not done so already, the above IP should be set to static.\\n" "${INFO}"


      printf " %b View the web interface at pi.hole:${WEBPORT}/admin o r http://%s/admin\\n\\n" "${INFO}" "${IPV4_ADDRESS%/*}:${WEBPORT}"
      printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_LIGHT_G REEN}" "${pw}" "${COL_NC}"
      printf " %b This can be changed using 'pihole setpassword'\\n\\n" "${IN FO}"


      # Final dialog message to the user
      dialog --no-shadow --keep-tite \
      --title "Installation Complete!" \
      --msgbox "Configure your devices to use the Pi-hole as their DNS ser ver using:\
      \\n\\nIPv4: ${IPV4_ADDRESS%/*}\
      \\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\
      \\nIf you have not done so already, the above IP should be set to static.\
      \\nView the web interface at admin:${WEBPORT} or http://${IPV4_AD DRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}" "${r }" "${c}"


      INSTALL_TYPE="Installation"
      else
      INSTALL_TYPE="Update"
      fi


      # Display where the log file is
      printf "\\n %b The install log is located at: %s\\n" "${INFO}" "${installLo gLoc}"
      printf " %b %b%s complete! %b\\n" "${TICK}" "${COL_LIGHT_GREEN}" "${INSTALL _TYPE}" "${COL_NC}"


      if [[ "${INSTALL_TYPE}" == "Update" ]]; then
      printf "\\n"
      "${PI_HOLE_BIN_DIR}"/pihole version
      fi
      }


      # allow to source this script without running it
      if [[ "${SKIP_INSTALL}" != true ]]; then
      main "$@"
      fi
      pi@nextcloudpi:~$

      aber auf den Webserver komme ich immer noch nicht und eine pihole.toml habe ich immer noch nicht :love:
      Andreas

      Ich weiß nicht immer wovon ich rede. Aber ich weiß das es richtig ist. (Muhammad Ali)

      quod erat demonstrandum

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Andreas_der_erste ()