public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Bernhard Bitsch <bbitsch@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] RPZ: update code to include WEBGUI and additional languages
Date: Wed, 6 Aug 2025 09:31:27 +0200	[thread overview]
Message-ID: <2007f4fa-4c26-4e72-8d1b-b991584e03c8@ipfire.org> (raw)
In-Reply-To: <ema5a481b0-4e49-4983-9d76-668c8e09a1f7@af5f0be5.com>



Am 05.08.2025 um 18:53 schrieb Jon Murphy:
> 
> Q. * The problem are the sources and the quality of the blacklists. 
> Unless those are available to us and our users the entire technology is 
> becoming worthless. This is exactly what we have with the URL filter.
> 
> A. To me this is similar to many other open source items.  If the head 
> MFiC walks away, then the open source becomes toast.  If the projects is 
> sold or transferred to a paid service, then the open source project is 
> toast.  I don’t like it, but unless IPFire becomes the mix-master of 
> blocklists (collect, filter, publish, etc.) then there is no way around 
> this.
> 
> ==
> 
> Q. * Unbound itself is a whole mess and I hope we will be able to launch 
> our plans to replace it as soon as possible.
> 
> A. This one I cannot answer since I don’t know the issues others have 
> experienced.  I started near the time when IPFire went from dnsmasq to 
> unbound and to me unbound seems A-OK.  But again I don’t know the issues.
> 

What alternative is planned for unbound? Does it support RPZ or 
something alike?
I think it can be agreed, that such a sort of filtering is meaningful.

Bernhard
> ==
> 
> Specifically, what questions are remaining unanswered?
> 
> 
> 
> ------ Original Message ------
>  From "Michael Tremer" <michael.tremer@ipfire.org>
> To "Jon Murphy" <jon.murphy@ipfire.org>
> Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: Development-List" 
> <development@lists.ipfire.org>
> Date 5/23/2025 5:35:58 AM
> Subject Re: [PATCH] RPZ: update code to include WEBGUI and additional 
> languages
> 
>> Hello Jon,
>>
>> You need to be a little bit more precise with what you actually want 
>> to know.
>>
>> I think I have covered this before and can only refer to the previous 
>> emails in this conversation.
>>
>> * RPZ itself is fine as a feature. It is a powerful tool we could 
>> leverage for a lot a of things. It would have the potential to allow 
>> content filtering without the proxy.
>>
>> * The problem are the sources and the quality of the blacklists. 
>> Unless those are available to us and our users the entire technology 
>> is becoming worthless. This is exactly what we have with the URL filter.
>>
>> * Unbound itself is a whole mess and I hope we will be able to launch 
>> our plans to replace it as soon as possible.
>>
>> Best,
>> -Michael
>>
>>>  On 22 May 2025, at 20:45, Jon Murphy <jon.murphy@ipfire.org> wrote:
>>>
>>>
>>>  I understand that "Unbound, RPZ and a blacklist" was unsuitable.  I 
>>> am curious what was suitable.
>>>
>>>
>>>
>>>  ------ Original Message ------
>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: Development- 
>>> List" <development@lists.ipfire.org>
>>>  Date 5/22/2025 10:46:25 AM
>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>> additional languages
>>>
>>>>  Unbound, RPZ and a blacklist that I deemed suitable. It isn’t.
>>>>
>>>>>  On 22 May 2025, at 16:45, Jon Murphy <jon.murphy@ipfire.org> wrote:
>>>>>
>>>>>  Still curious…  What are you using to block adult websites?
>>>>>
>>>>>
>>>>>
>>>>>  ------ Original Message ------
>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: Development- 
>>>>> List" <development@lists.ipfire.org>
>>>>>  Date 5/22/2025 10:43:55 AM
>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>>>> additional languages
>>>>>
>>>>>>  I stated that before. I need to block adult websites.
>>>>>>
>>>>>>>  On 22 May 2025, at 16:42, Jon Murphy <jon.murphy@ipfire.org> wrote:
>>>>>>>
>>>>>>>  Now I am curious! What is your use-case?  Tell me more...
>>>>>>>
>>>>>>>
>>>>>>>  ------ Original Message ------
>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: Development- 
>>>>>>> List" <development@lists.ipfire.org>
>>>>>>>  Date 5/22/2025 10:40:38 AM
>>>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>>>>>> additional languages
>>>>>>>
>>>>>>>>  Hello Jon,
>>>>>>>>
>>>>>>>>  I have not been spending on time on this at all since we talked 
>>>>>>>> last.
>>>>>>>>
>>>>>>>>  I don’t need Unbound to download any files for my use-case either.
>>>>>>>>
>>>>>>>>  -Michael
>>>>>>>>
>>>>>>>>>  On 20 May 2025, at 17:30, Jon Murphy <jon.murphy@ipfire.org> 
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>  Michael,
>>>>>>>>>
>>>>>>>>>  Were you able to debug RPZ and get Unbound to download `.rpz` 
>>>>>>>>> files?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  Jon
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>  ------ Original Message ------
>>>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>>>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: 
>>>>>>>>> Development-List" <development@lists.ipfire.org>
>>>>>>>>>  Date 3/24/2025 9:43:37 AM
>>>>>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>>>>>>>> additional languages
>>>>>>>>>
>>>>>>>>>>  Yes, I don’t need any debugging of this...
>>>>>>>>>>
>>>>>>>>>>>  On 24 Mar 2025, at 14:42, Jon Murphy <jon.murphy@ipfire.org> 
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>  Is there a:
>>>>>>>>>>>
>>>>>>>>>>>  server:
>>>>>>>>>>>     module-config: "respip validator iterator"
>>>>>>>>>>>
>>>>>>>>>>>  In your RPZ set-up?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>  ------ Original Message ------
>>>>>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>>>>>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: 
>>>>>>>>>>> Development-List" <development@lists.ipfire.org>
>>>>>>>>>>>  Date 3/24/2025 9:40:15 AM
>>>>>>>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>>>>>>>>>> additional languages
>>>>>>>>>>>
>>>>>>>>>>>>  Because it is not doing it on my system...
>>>>>>>>>>>>
>>>>>>>>>>>>>  On 24 Mar 2025, at 14:38, Jon Murphy 
>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>  Actually it did.
>>>>>>>>>>>>>
>>>>>>>>>>>>>  Why do you think Unbound did not?
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>  ------ Original Message ------
>>>>>>>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>>>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>>>>>>>>>  Cc "Bernhard Bitsch" <bbitsch@ipfire.org>; "IPFire: 
>>>>>>>>>>>>> Development-List" <development@lists.ipfire.org>
>>>>>>>>>>>>>  Date 3/24/2025 9:36:53 AM
>>>>>>>>>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI and 
>>>>>>>>>>>>> additional languages
>>>>>>>>>>>>>
>>>>>>>>>>>>>>  Unbound did not put those there...
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  On 24 Mar 2025, at 14:33, Jon Murphy 
>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  And where are these stored?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  In `/etc/unbound/zonefiles`:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  [root@ipfire ~] # ls -al /etc/unbound/zonefiles
>>>>>>>>>>>>>>>  total 20664
>>>>>>>>>>>>>>>  drwxr-xr-x 2 nobody nobody     4096 Mar 24 04:40 .
>>>>>>>>>>>>>>>  drwxr-xr-x 4 root   root       4096 Mar 19 16:24 ..
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody  3999087 Mar 23 15:11 
>>>>>>>>>>>>>>> adhocSB.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody     1411 Mar 23 14:23 allow.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody    25355 Mar 24 04:40 
>>>>>>>>>>>>>>> AmazonTrkrHZ.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody     7241 Mar 24 04:40 
>>>>>>>>>>>>>>> AppleTrkrHZ.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody      178 Mar 23 14:23 block.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody    78496 Mar 24 04:40 
>>>>>>>>>>>>>>> DOHblockHZ.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody 16983551 Mar 24 04:40 
>>>>>>>>>>>>>>> MxProPlusHZ.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody     2893 Mar 24 04:40 tldHZ.rpz
>>>>>>>>>>>>>>>  -rw-r--r-- 1 nobody nobody    29419 Mar 24 04:40 
>>>>>>>>>>>>>>> WinTrkrHZ.rpz
>>>>>>>>>>>>>>>  [root@ipfire ~] #
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  ------ Original Message ------
>>>>>>>>>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>>>>>>>>>  To "Bernhard Bitsch" <bbitsch@ipfire.org>
>>>>>>>>>>>>>>>  Cc development@lists.ipfire.org
>>>>>>>>>>>>>>>  Date 3/24/2025 9:25:40 AM
>>>>>>>>>>>>>>>  Subject Re: [PATCH] RPZ: update code to include WEBGUI 
>>>>>>>>>>>>>>> and additional languages
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>  Hello,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>  On 24 Mar 2025, at 13:33, Bernhard Bitsch 
>>>>>>>>>>>>>>>>> <bbitsch@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>     Am 24.03.2025 um 11:17 schrieb Michael Tremer:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  Hello Jon,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  On 24 Mar 2025, at 00:00, Jon Murphy 
>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>   Michael,
>>>>>>>>>>>>>>>>>>>   FYI - I was wrong Unbound RPZ is _not_ watching the 
>>>>>>>>>>>>>>>>>>> serial number, it is watching the "refresh", the 
>>>>>>>>>>>>>>>>>>> number after the serial number.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  Refresh just tells the client how often to check for 
>>>>>>>>>>>>>>>>>> an update.
>>>>>>>>>>>>>>>>>>  If that is actually being set by the list publisher, 
>>>>>>>>>>>>>>>>>> then we have another problem here, because they could 
>>>>>>>>>>>>>>>>>> put some insanely low value there and we would then 
>>>>>>>>>>>>>>>>>> DDoS their infrastructure. I think we should keep it 
>>>>>>>>>>>>>>>>>> like we have it in other places that we control how 
>>>>>>>>>>>>>>>>>> often we want to check or pull for updates.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   You are right. But an extra update process wastes 
>>>>>>>>>>>>>>>>> additional processor time. The update mechanism of 
>>>>>>>>>>>>>>>>> unbound does the check for update ( however it is 
>>>>>>>>>>>>>>>>> realized ) nevertheless.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   Yes, doing more things needs resources. But we are not 
>>>>>>>>>>>>>>>> seriously considering whether an IPFire system has 
>>>>>>>>>>>>>>>> enough resources to perform the download of a text file, 
>>>>>>>>>>>>>>>> or are we?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  I understand that you don’t speak C, but you got the 
>>>>>>>>>>>>>>>>>>> information from somewhere. Documentation maybe? 
>>>>>>>>>>>>>>>>>>> Since that is out of date very often I like to 
>>>>>>>>>>>>>>>>>>> consult the code.
>>>>>>>>>>>>>>>>>>>  From testing. Downloading rpz files using rpz 
>>>>>>>>>>>>>>>>>>> unbound, and watching what happens. If the rpz file 
>>>>>>>>>>>>>>>>>>> is setup for "once per day" refresh, then it only 
>>>>>>>>>>>>>>>>>>> downloads one time.
>>>>>>>>>>>>>>>>>>>     However that won’t solve our problem . . . and 
>>>>>>>>>>>>>>>>>>> having no cache.
>>>>>>>>>>>>>>>>>>>  In `/etc/unbound/tuning.conf` there is `rrset-cache- 
>>>>>>>>>>>>>>>>>>> size: 128m`. Are you referring to a different cache.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>  Naturally unbound is loading the zone into its memory 
>>>>>>>>>>>>>>>>>> which we generally call cache.
>>>>>>>>>>>>>>>>>>  When I say cache I am thinking about persistent data 
>>>>>>>>>>>>>>>>>> storage across multiple restarts of Unbound. If I am 
>>>>>>>>>>>>>>>>>> downloading 100 MiB of RPZ lists (which is presumably 
>>>>>>>>>>>>>>>>>> still on the lower end) and I reboot my firewall, I do 
>>>>>>>>>>>>>>>>>> not want to download the same data again. We can only 
>>>>>>>>>>>>>>>>>> ever download a list *once* unless we are 100% certain 
>>>>>>>>>>>>>>>>>> that it has changed. Then we can download it once again.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   The RPZ lists are stored in files in persistent 
>>>>>>>>>>>>>>>>> storage. Unbound creates the internal cache from these.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   And where are these stored?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  Maybe we need to implement both?
>>>>>>>>>>>>>>>>>>>   Yes. There are very few AXFR list (I think only 
>>>>>>>>>>>>>>>>>>> four were found). And many more HTTPS rpz files.
>>>>>>>>>>>>>>>>>>>     Jon
>>>>>>>>>>>>>>>>>>>    ------ Original Message ------
>>>>>>>>>>>>>>>>>>>  From "Michael Tremer" <michael.tremer@ipfire.org>
>>>>>>>>>>>>>>>>>>>  To "Jon Murphy" <jon.murphy@ipfire.org>
>>>>>>>>>>>>>>>>>>>  Cc "IPFire: Development-List" 
>>>>>>>>>>>>>>>>>>> <development@lists.ipfire.org>
>>>>>>>>>>>>>>>>>>>  Date 3/20/2025 11:26:43 AM
>>>>>>>>>>>>>>>>>>>  Subject Re: [PATCH] RPZ: update code to include 
>>>>>>>>>>>>>>>>>>> WEBGUI and additional languages
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  Hello Jon,
>>>>>>>>>>>>>>>>>>>>  Please don’t forget to Cc the list...
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   On 19 Mar 2025, at 18:27, Jon Murphy 
>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>  Michael,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   Where in the code is this implemented? I cannot 
>>>>>>>>>>>>>>>>>>>>>> find anything like this:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   Keep in mind I am not a "C" person. Maybe in this 
>>>>>>>>>>>>>>>>>>>>> section?:
>>>>>>>>>>>>>>>>>>>>>  https://git.ipfire.org/?p=thirdparty/ 
>>>>>>>>>>>>>>>>>>>>> unbound.git;a=blob;f=services/ 
>>>>>>>>>>>>>>>>>>>>> authzone.c;hb=30b9cb5f813003d0a2b1c2e678652396615b1b7d#l5875
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   This where the AXFR response is being handled when 
>>>>>>>>>>>>>>>>>>>> doing a DNS zone transfer. This code is not being 
>>>>>>>>>>>>>>>>>>>> called when performing a HTTP download.
>>>>>>>>>>>>>>>>>>>>  I understand that you don’t speak C, but you got 
>>>>>>>>>>>>>>>>>>>> the information from somewhere. Documentation maybe? 
>>>>>>>>>>>>>>>>>>>> Since that is out of date very often I like to 
>>>>>>>>>>>>>>>>>>>> consult the code.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   —
>>>>>>>>>>>>>>>>>>>>>  When I was just learning about RPZ I created a 
>>>>>>>>>>>>>>>>>>>>> separate RPZ file for testing. When I changed the 
>>>>>>>>>>>>>>>>>>>>> SOA line with a new serial number, the RPZ file 
>>>>>>>>>>>>>>>>>>>>> download would happen in about 5 minutes.
>>>>>>>>>>>>>>>>>>>>>  https://people.ipfire.org/~jon/sblack-adhoc.rpz
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   It might well be that the file is not being 
>>>>>>>>>>>>>>>>>>>> reloaded if the download matches the content that 
>>>>>>>>>>>>>>>>>>>> unbound already has. That would of course save some 
>>>>>>>>>>>>>>>>>>>> resources.
>>>>>>>>>>>>>>>>>>>>  However that won’t solve our problem with redundant 
>>>>>>>>>>>>>>>>>>>> downloads and having no cache.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   That is how I found out the SOA line is watched 
>>>>>>>>>>>>>>>>>>>>> for a serial number change.
>>>>>>>>>>>>>>>>>>>>>  I’ll reconfirm my findings.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>  The second reason is that we have a lot of 
>>>>>>>>>>>>>>>>>>>>>>>> firewalls out there. Not all of them will enable 
>>>>>>>>>>>>>>>>>>>>>>>> this feature and all of the lists, but even if 
>>>>>>>>>>>>>>>>>>>>>>>> it is a good chunk, we will generate terabytes 
>>>>>>>>>>>>>>>>>>>>>>>> of traffic which put load on the infrastructure 
>>>>>>>>>>>>>>>>>>>>>>>> and will cost money. It simply is not what we 
>>>>>>>>>>>>>>>>>>>>>>>> want to do, regardless of self-hosting those 
>>>>>>>>>>>>>>>>>>>>>>>> lists and pulling them from somewhere else.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   So I understand, are you thinking of hosting RPZ 
>>>>>>>>>>>>>>>>>>>>> AXFR (DNS zone transfer) on IPFire infrastructure?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   No, I don’t think that we can generally do this. 
>>>>>>>>>>>>>>>>>>>> The biggest problem is licensing as we cannot take 
>>>>>>>>>>>>>>>>>>>> anyones content and host it ourselves. We would re- 
>>>>>>>>>>>>>>>>>>>> distribute those lists and that will only work with 
>>>>>>>>>>>>>>>>>>>> permission of the publishers. I assume that would be 
>>>>>>>>>>>>>>>>>>>> too much work to actually get some useful content 
>>>>>>>>>>>>>>>>>>>> out there. We might limit ourselves to only those 
>>>>>>>>>>>>>>>>>>>> lists that are under a very permissive license. 
>>>>>>>>>>>>>>>>>>>> Nobody wants that.
>>>>>>>>>>>>>>>>>>>>  From a technical point of view, DNS over TCP might 
>>>>>>>>>>>>>>>>>>>> not be very nice in terms of forging the transfer 
>>>>>>>>>>>>>>>>>>>> and so we would need TLS as well… It should work, 
>>>>>>>>>>>>>>>>>>>> but even if we would be able to encourage other 
>>>>>>>>>>>>>>>>>>>> people to publish their lists I doubt they would 
>>>>>>>>>>>>>>>>>>>> implement DNS over TLS for authoritative DNS. That 
>>>>>>>>>>>>>>>>>>>> standard is in very early stages as well.
>>>>>>>>>>>>>>>>>>>>  As far as I can see, those vendors who offer a list 
>>>>>>>>>>>>>>>>>>>> as a commercial product are using DNS to distribute 
>>>>>>>>>>>>>>>>>>>> it (e.g. Spamhaus). Those people who have made this 
>>>>>>>>>>>>>>>>>>>> all a hobby are throwing the lists onto GitHub and 
>>>>>>>>>>>>>>>>>>>> let them handle the traffic.
>>>>>>>>>>>>>>>>>>>>  Maybe we need to implement both?
>>>>>>>>>>>>>>>>>>>>  -Michael
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>   Jon
>>>>>>>>>>>>>>>>>>>>>  On 3/19/25 5:35 AM, Michael Tremer wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    Hello Jon,
>>>>>>>>>>>>>>>>>>>>>>  Where in the code is this implemented? I cannot 
>>>>>>>>>>>>>>>>>>>>>> find anything like this:
>>>>>>>>>>>>>>>>>>>>>>  Unbound loads the entire file into memory and 
>>>>>>>>>>>>>>>>>>>>>> then starts parsing it. The only special treatment 
>>>>>>>>>>>>>>>>>>>>>> there is is to check whether the first line is a 
>>>>>>>>>>>>>>>>>>>>>> valid zone entry. It does not even have to be a 
>>>>>>>>>>>>>>>>>>>>>> SOA record.
>>>>>>>>>>>>>>>>>>>>>>  https://git.ipfire.org/?p=thirdparty/ 
>>>>>>>>>>>>>>>>>>>>>> unbound.git;a=blob;f=services/ 
>>>>>>>>>>>>>>>>>>>>>> authzone.c;hb=30b9cb5f813003d0a2b1c2e678652396615b1b7d#l1188
>>>>>>>>>>>>>>>>>>>>>>  I am also concerned that Unbound will not be able 
>>>>>>>>>>>>>>>>>>>>>> to support an upstream proxy for any downloads. 
>>>>>>>>>>>>>>>>>>>>>> The caching situation is also unclear for me, so I 
>>>>>>>>>>>>>>>>>>>>>> believe that we will be looking at writing a 
>>>>>>>>>>>>>>>>>>>>>> custom downloader that implements all these things.
>>>>>>>>>>>>>>>>>>>>>>  -Michael
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>   On 19 Mar 2025, at 02:58, Jon Murphy 
>>>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>  Michael,
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   The emphasis is on the repeated downloads of 
>>>>>>>>>>>>>>>>>>>>>>>> the same list. That is
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>   ​> what cannot happen.
>>>>>>>>>>>>>>>>>>>>>>>  The Unbound RPZ code, as installed within 
>>>>>>>>>>>>>>>>>>>>>>> IPFire, watches for a change
>>>>>>>>>>>>>>>>>>>>>>>  ​in the SOA line of each RPZ file. This is an 
>>>>>>>>>>>>>>>>>>>>>>> example of the first few
>>>>>>>>>>>>>>>>>>>>>>>  ​lines for every RPZ file.
>>>>>>>>>>>>>>>>>>>>>>>  $TTL 300
>>>>>>>>>>>>>>>>>>>>>>>  @ SOA localhost. root.localhost. 1742298960 
>>>>>>>>>>>>>>>>>>>>>>> 43200 3600 86400 300
>>>>>>>>>>>>>>>>>>>>>>>  NS localhost.
>>>>>>>>>>>>>>>>>>>>>>>  ;
>>>>>>>>>>>>>>>>>>>>>>>  ; Title: HaGeZi's Pop-Up Ads DNS Blocklist
>>>>>>>>>>>>>>>>>>>>>>>  ; Description: Blocks annoying and malicious 
>>>>>>>>>>>>>>>>>>>>>>> pop-up ads.
>>>>>>>>>>>>>>>>>>>>>>>  If the SOA serial number changes (e.g. the 
>>>>>>>>>>>>>>>>>>>>>>> 1742298960), then Unbound RPZ
>>>>>>>>>>>>>>>>>>>>>>>  ​code does its thing and downloads. Otherwise 
>>>>>>>>>>>>>>>>>>>>>>> there is no download.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   So there has to be a way to ensure that we 
>>>>>>>>>>>>>>>>>>>>>>>> won’t download a list again
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>   ​> unless it has actually changed.
>>>>>>>>>>>>>>>>>>>>>>>  This should do what you want but I may be 
>>>>>>>>>>>>>>>>>>>>>>> missing your point.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   DNS has a builtin functionality called AXFR. 
>>>>>>>>>>>>>>>>>>>>>>>> It simply does the job
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>   ​> for you. I was just wondering whether that 
>>>>>>>>>>>>>>>>>>>>>>> was not being used.
>>>>>>>>>>>>>>>>>>>>>>>  I need to read about AXFR/IXFR and learn a 
>>>>>>>>>>>>>>>>>>>>>>> little more.
>>>>>>>>>>>>>>>>>>>>>>>  Jon
>>>>>>>>>>>>>>>>>>>>>>>  On 3/17/25 5:35 AM, Michael Tremer wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>    Good Morning Jon,
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>   On 16 Mar 2025, at 17:00, Jon Murphy 
>>>>>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>  Michael,
>>>>>>>>>>>>>>>>>>>>>>>>>  I was reading through you response again an I 
>>>>>>>>>>>>>>>>>>>>>>>>> want to understand this post:
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>   I have also stated that we cannot download 
>>>>>>>>>>>>>>>>>>>>>>>>>> any lists over HTTPS again and again and 
>>>>>>>>>>>>>>>>>>>>>>>>>> again. The implementation that we have here 
>>>>>>>>>>>>>>>>>>>>>>>>>> seems to exactly do that and therefore I think 
>>>>>>>>>>>>>>>>>>>>>>>>>> that my feedback has been dismissed entirely.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>   So if RPZ doesn't use HTTPS, what is it 
>>>>>>>>>>>>>>>>>>>>>>>>> using? I am missing a key point here.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   The emphasis is on the repeated downloads of 
>>>>>>>>>>>>>>>>>>>>>>>> the same list. That is what cannot happen.
>>>>>>>>>>>>>>>>>>>>>>>>  Although it might not affect a lot of people in 
>>>>>>>>>>>>>>>>>>>>>>>> our general user-base, there are some that have 
>>>>>>>>>>>>>>>>>>>>>>>> a metered connection and will pay for data by 
>>>>>>>>>>>>>>>>>>>>>>>> volume. Some of the lists I looked at are just 
>>>>>>>>>>>>>>>>>>>>>>>> under 20 MiB. Therefore we need to keep any 
>>>>>>>>>>>>>>>>>>>>>>>> traffic down to a minimum. The second reason is 
>>>>>>>>>>>>>>>>>>>>>>>> that we have a lot of firewalls out there. Not 
>>>>>>>>>>>>>>>>>>>>>>>> all of them will enable this feature and all of 
>>>>>>>>>>>>>>>>>>>>>>>> the lists, but even if it is a good chunk, we 
>>>>>>>>>>>>>>>>>>>>>>>> will generate terabytes of traffic which put 
>>>>>>>>>>>>>>>>>>>>>>>> load on the infrastructure and will cost money. 
>>>>>>>>>>>>>>>>>>>>>>>> It simply is not what we want to do, regardless 
>>>>>>>>>>>>>>>>>>>>>>>> of self-hosting those lists and pulling them 
>>>>>>>>>>>>>>>>>>>>>>>> from somewhere else.
>>>>>>>>>>>>>>>>>>>>>>>>  So there has to be a way to ensure that we 
>>>>>>>>>>>>>>>>>>>>>>>> won’t download a list again unless it has 
>>>>>>>>>>>>>>>>>>>>>>>> actually changed.
>>>>>>>>>>>>>>>>>>>>>>>>  DNS has a builtin functionality called AXFR. It 
>>>>>>>>>>>>>>>>>>>>>>>> simply does the job for you. I was just 
>>>>>>>>>>>>>>>>>>>>>>>> wondering whether that was not being used.
>>>>>>>>>>>>>>>>>>>>>>>>  HTTPS is an option because that is simply what 
>>>>>>>>>>>>>>>>>>>>>>>> we use elsewhere, but extra functionality will 
>>>>>>>>>>>>>>>>>>>>>>>> have to be built for it.
>>>>>>>>>>>>>>>>>>>>>>>>  -Michael
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>   Jon
>>>>>>>>>>>>>>>>>>>>>>>>>  On 2/13/25 3:34 PM, jon wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>    Michael,
>>>>>>>>>>>>>>>>>>>>>>>>>>  I’ve read through your comments a few times 
>>>>>>>>>>>>>>>>>>>>>>>>>> and I ended up with many more questions.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   What I rather mean is that it has never 
>>>>>>>>>>>>>>>>>>>>>>>>>>> been added as a topic on the agenda and it 
>>>>>>>>>>>>>>>>>>>>>>>>>>> has not been pitched by yourself.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>   To me the efforts to get new code accepted 
>>>>>>>>>>>>>>>>>>>>>>>>>> seem to have changed and it seemed easier in 
>>>>>>>>>>>>>>>>>>>>>>>>>> the past. In the past I made the Core Team 
>>>>>>>>>>>>>>>>>>>>>>>>>> aware via the Dev Mailing List and wrote a 
>>>>>>>>>>>>>>>>>>>>>>>>>> simple two or three paragraphs of "What is 
>>>>>>>>>>>>>>>>>>>>>>>>>> it? / What is the value? / Here is the code"
>>>>>>>>>>>>>>>>>>>>>>>>>>  So in an effort to move forward: How exactly 
>>>>>>>>>>>>>>>>>>>>>>>>>> is something presented to the Core Team?
>>>>>>>>>>>>>>>>>>>>>>>>>>  Is there an example of a recent effort that 
>>>>>>>>>>>>>>>>>>>>>>>>>> was presented that I can see as a sample? 
>>>>>>>>>>>>>>>>>>>>>>>>>> (This type of info can also be added to the Wiki)
>>>>>>>>>>>>>>>>>>>>>>>>>>  I understand you want it this way, but I 
>>>>>>>>>>>>>>>>>>>>>>>>>> don’t know what exactly is needed. Please be 
>>>>>>>>>>>>>>>>>>>>>>>>>> specific.
>>>>>>>>>>>>>>>>>>>>>>>>>>  Jon
>>>>>>>>>>>>>>>>>>>>>>>>>>  PS - I am not ignoring your other comments, I 
>>>>>>>>>>>>>>>>>>>>>>>>>> am just trying to move forward and keep things 
>>>>>>>>>>>>>>>>>>>>>>>>>> simple.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   On Feb 8, 2025, at 1:27 PM, Michael Tremer 
>>>>>>>>>>>>>>>>>>>>>>>>>>> <michael.tremer@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>  Hello Jon,
>>>>>>>>>>>>>>>>>>>>>>>>>>>  Thanks for your reply. And good that you are 
>>>>>>>>>>>>>>>>>>>>>>>>>>> copying everyone into this conversation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   On 8 Feb 2025, at 18:41, jon 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Michael,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   I think I have covered this all at 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> lengths before that this project has been 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> started as a separate effort
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Yes, this has been a separate effort (a 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> very public separate effort). Yes, as you 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> pointed this out early on with the "proof- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> of-concept" and then my request for people 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> to help test RPZ. Nothing was hidden.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  This was done because you (and maybe 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> others) did not have the time and I wanted 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> to help and because I needed assistance with 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> RPZ. I tried my best to do this without 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> bothering you.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   I don’t that it is accurate that nobody 
>>>>>>>>>>>>>>>>>>>>>>>>>>> wanted to help on this. The list was always 
>>>>>>>>>>>>>>>>>>>>>>>>>>> open - although not every email has been 
>>>>>>>>>>>>>>>>>>>>>>>>>>> replied to swiftly it is also your 
>>>>>>>>>>>>>>>>>>>>>>>>>>> responsibility to raise a question again if 
>>>>>>>>>>>>>>>>>>>>>>>>>>> it was missed. People here have open ears.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  It was also stated on this very list on in 
>>>>>>>>>>>>>>>>>>>>>>>>>>> our documentation that working on something 
>>>>>>>>>>>>>>>>>>>>>>>>>>> without involving the core team is a risky 
>>>>>>>>>>>>>>>>>>>>>>>>>>> undertaking. Of course IPFire is free 
>>>>>>>>>>>>>>>>>>>>>>>>>>> software and so everyone is free to fork if 
>>>>>>>>>>>>>>>>>>>>>>>>>>> they wish to do so.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  and as far as I am aware none of the other 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> team members has been involved. This has 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> not been discussed either on this list, on 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> our calls.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   You were aware many steps along the way. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> See your email on July 28, 2024, August 15, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2024, September 30, 2024, December 23, 2024, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> and January 16. My attempts to get the team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> involved were met with "things are busy" and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> sometimes silence. (Yes, I get it, people 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> are busy.)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  You and Adolf, Leo, Erik and Bernhard have 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> been aware since the beginning. You mention 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> you were aware of the "proof-of-concept". If 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> you include those beginning posts, since Sep 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2023.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Yes, I am aware of a proof-of-concept that 
>>>>>>>>>>>>>>>>>>>>>>>>>>> I have been running myself for a long time. I 
>>>>>>>>>>>>>>>>>>>>>>>>>>> am also aware of the efforts that you have 
>>>>>>>>>>>>>>>>>>>>>>>>>>> been taking.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  Yet I don’t think there has ever been any 
>>>>>>>>>>>>>>>>>>>>>>>>>>> joint effort, or am I seeing that wrong?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  This has not been discussed . . . on our 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> calls.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   On the July 28th you stated:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  "We have talked about RPZ many times on the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> monthly call since the URL filter feature is 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> falling more and more out of fashion. I 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> think there is also many posts about this on 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the forum."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Please don’t insult me again by stating 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> "you know what I mean".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  And it has been discussed but not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> documented in the Monthly Meeting notes.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   I am not at all insulting you. I don’t want 
>>>>>>>>>>>>>>>>>>>>>>>>>>> to take this down to a personal level at all. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> This is a public mailing list and people who 
>>>>>>>>>>>>>>>>>>>>>>>>>>> read this don’t need to listen to an argument 
>>>>>>>>>>>>>>>>>>>>>>>>>>> we are having. They are here for the tech 
>>>>>>>>>>>>>>>>>>>>>>>>>>> inside IPFire.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  When I wrote that it has not been discussed 
>>>>>>>>>>>>>>>>>>>>>>>>>>> that does not mean that we have not been 
>>>>>>>>>>>>>>>>>>>>>>>>>>> touching on the topic. We have been talking 
>>>>>>>>>>>>>>>>>>>>>>>>>>> about lots of things on the calls, the 
>>>>>>>>>>>>>>>>>>>>>>>>>>> weather, politics, how our pets are. None of 
>>>>>>>>>>>>>>>>>>>>>>>>>>> that makes it to the logs. What I rather mean 
>>>>>>>>>>>>>>>>>>>>>>>>>>> is that it has never been added as a topic on 
>>>>>>>>>>>>>>>>>>>>>>>>>>> the agenda and it has not been pitched by 
>>>>>>>>>>>>>>>>>>>>>>>>>>> yourself.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Instead there has been a separate 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> conversation on the forum with the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> occasional dip here to the list. But that 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> was not a regular two-way conversation.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Regular conversation on the Dev Mailing 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> list is many times met with silence. I get 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> it, people are busy.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  And regular two-way conversation doesn’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> happen on the list. At least not with me. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I’d be happy to point out the posts that 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> were met with silence.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Again, I get it, people are busy.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   And you think my emails are not being met 
>>>>>>>>>>>>>>>>>>>>>>>>>>> with silence? This has nothing to do with 
>>>>>>>>>>>>>>>>>>>>>>>>>>> this specific topic. This has something to do 
>>>>>>>>>>>>>>>>>>>>>>>>>>> with how occupied people are and how engaged 
>>>>>>>>>>>>>>>>>>>>>>>>>>> they are on certain topics. Not everyone is 
>>>>>>>>>>>>>>>>>>>>>>>>>>> involved in all the things and simply will 
>>>>>>>>>>>>>>>>>>>>>>>>>>> ignore emails simply based on their subject 
>>>>>>>>>>>>>>>>>>>>>>>>>>> line.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   But the "dip here to the list" were my 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> attempts to get a conversation started. As I 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> said, many time met with silence.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  The only place I was not met with silence 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> was on the Community. You have a great group 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> of people in the Community. It is a shame 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> you don’t want to have others help. It would 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> reduce your workload.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   You should stop making statements that are 
>>>>>>>>>>>>>>>>>>>>>>>>>>> not true. Who doesn’t want anyone to help?
>>>>>>>>>>>>>>>>>>>>>>>>>>>  Not having this conversation on a Saturday 
>>>>>>>>>>>>>>>>>>>>>>>>>>> evening would reduce my workload. At least it 
>>>>>>>>>>>>>>>>>>>>>>>>>>> would free up time for something else. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> Helping with the things that are already on 
>>>>>>>>>>>>>>>>>>>>>>>>>>> the go would reduce the workload of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>> entire team. Starting one thing at a time and 
>>>>>>>>>>>>>>>>>>>>>>>>>>> finishing it is a lot better to manage than 
>>>>>>>>>>>>>>>>>>>>>>>>>>> starting a hundred things and not even finish 
>>>>>>>>>>>>>>>>>>>>>>>>>>> one. I can tell you that I already have a 
>>>>>>>>>>>>>>>>>>>>>>>>>>> hundred things on the go.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Therefore, what am I supposed to do with 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> this email?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   To me it is beyond obvious…
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  If it isn’t what you want, then guide me 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> with how to do this the correct way. And be 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> specific. I am trying to help. I am trying 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> to make things better. I am trying to do 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> things the right way.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   To me it isn’t. This is yet another project 
>>>>>>>>>>>>>>>>>>>>>>>>>>> that has been dumped to the list like so many 
>>>>>>>>>>>>>>>>>>>>>>>>>>> before and later on everyone has left to have 
>>>>>>>>>>>>>>>>>>>>>>>>>>> the team deal with the rest.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  It is a huge patch set. You explained what 
>>>>>>>>>>>>>>>>>>>>>>>>>>> the vision is, but that is about it. There is 
>>>>>>>>>>>>>>>>>>>>>>>>>>> no chance this will continue if this 
>>>>>>>>>>>>>>>>>>>>>>>>>>> disagreement isn’t solved first. I didn’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>> even look at the code.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I don’t want to merge code that I don’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> agree with.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   I asked multiple times if you "agreed with 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the concept" and again, met with silence. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Yes I get it, people are busy.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Having support for RPZ? Yes, it was 
>>>>>>>>>>>>>>>>>>>>>>>>>>> definitely on the roadmap. That I agree with.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  So many fundamental things that I have 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been raising have either not been discussed 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> or outright dismissed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   You mentioned this a in the past, but for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> some reason you do not disclose what I 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> dismissed. Why do you continue to make this 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> harder, wouldn’t it not be easier to tell me 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> what I have dismissed?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I have sent multiple emails trying to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> answer your concerns and comments. On July 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 28, Aug 14, Aug 22, Aug 23, Sep 30, etc.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I’ve gone through all of the questions you 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> asked and I cannot find a "dismissed" item.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Maybe I need to be *more clear*. I feel 
>>>>>>>>>>>>>>>>>>>>>>>>>>> humoured by this.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  It is late on a Saturday and I want my 
>>>>>>>>>>>>>>>>>>>>>>>>>>> dinner soon, but certainly I have stated that 
>>>>>>>>>>>>>>>>>>>>>>>>>>> this should never be an add-on considering it 
>>>>>>>>>>>>>>>>>>>>>>>>>>> is supposed to replace URL Filter. We should 
>>>>>>>>>>>>>>>>>>>>>>>>>>> never allow people to add their own sources. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> I have also stated that we cannot download 
>>>>>>>>>>>>>>>>>>>>>>>>>>> any lists over HTTPS again and again and 
>>>>>>>>>>>>>>>>>>>>>>>>>>> again. The implementation that we have here 
>>>>>>>>>>>>>>>>>>>>>>>>>>> seems to exactly do that and therefore I 
>>>>>>>>>>>>>>>>>>>>>>>>>>> think that my feedback has been dismissed 
>>>>>>>>>>>>>>>>>>>>>>>>>>> entirely.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I don’t want to merge code that has no 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> future inside IPFire as there is no 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> constructive conversation with the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maintainers of it.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   The maintainers of Unbound and/or RPZ?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  The maintainers of Hagezi list, the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> threatfox list, the urlhaus list, etc.?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  What else? The maintainers or the RPZ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> scripts? That is me. Let’s talk!
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   You. I don’t care much about the providers 
>>>>>>>>>>>>>>>>>>>>>>>>>>> of the lists.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   See, this is where it gets confusing. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> There are hundreds of open source packages 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> as part of IPFire. Pick the last five years 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> of items added to the IPFire build. You're 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> telling me you have "constructive 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> conversation with the maintainers" of all of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the added packages?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   They publish their software and they don’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>> care whether I am pulling it or not. They 
>>>>>>>>>>>>>>>>>>>>>>>>>>> publish it with the commitment to maintain it 
>>>>>>>>>>>>>>>>>>>>>>>>>>> - sometimes for better and sometimes for worse.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  You care about me pulling your code and I 
>>>>>>>>>>>>>>>>>>>>>>>>>>> don’t know whether you would commit to 
>>>>>>>>>>>>>>>>>>>>>>>>>>> maintain this.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  These two are very different cases.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Pick the IP Blocklists list (i.e., 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3CORESEC, ABUSECH, DSHIELD, SPAMHAUS, etc.) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> or the Suricata lists 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> (i.e.,Emergingthreats.net <http:// 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> emergingthreats.net/>,Abuse.ch <http:// 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> abuse.ch/>, etc.). So you’ve have 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> "constructive conversation with the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> maintainers"?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Yes, occasionally I have phone calls with a 
>>>>>>>>>>>>>>>>>>>>>>>>>>> few of these providers.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Having been trying for a long time to make 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you aware of this, nothing of this should 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> come as a surprise.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Ha! Yes a surprise. In the beginning you 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> seemed interested as IPFire needed a 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> replacement for URL Filter. You asked good 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> questions about the lists picked, asked for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the value to the users, etc. And I answered 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the best I could.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  You even asked: “Why is this realised as an 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on and not part of the core system?” 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> from your Jul 28, 2024 email.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Ah, so, why is the patch creating an add- 
>>>>>>>>>>>>>>>>>>>>>>>>>>> on? Not that I am saying that what I say is 
>>>>>>>>>>>>>>>>>>>>>>>>>>> law, but it has not been challenged either. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> If my input is being ignored, why should I 
>>>>>>>>>>>>>>>>>>>>>>>>>>> put this to the top of my list of priorities? 
>>>>>>>>>>>>>>>>>>>>>>>>>>> I am not disappointed about this, just trying 
>>>>>>>>>>>>>>>>>>>>>>>>>>> to be very good with my time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   And on January 16, 2025 I wrote a message 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> looking for help. And you were kind to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> respond quickly. So in three weeks time, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> since the kind response, something has 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed. You went from supportive to "this".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  So yes, I am surprised.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Well, maybe I should not have replied to 
>>>>>>>>>>>>>>>>>>>>>>>>>>> that email. It was clear that you were on 
>>>>>>>>>>>>>>>>>>>>>>>>>>> some path that was not right, but you were 
>>>>>>>>>>>>>>>>>>>>>>>>>>> not interested before in finding the right 
>>>>>>>>>>>>>>>>>>>>>>>>>>> path from the beginning.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Please consider if that can be changed and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if there is a path forward with this.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Be more specific, what has to change? What 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> exactly did I dismiss?
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>   Dismissal is just my assumption. I don’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>> know what you actually did with my feedback. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> I can only see the end product that does not 
>>>>>>>>>>>>>>>>>>>>>>>>>>> seem contain much of it. Repeatedly I have 
>>>>>>>>>>>>>>>>>>>>>>>>>>> been pointing out that we should think before 
>>>>>>>>>>>>>>>>>>>>>>>>>>> we build. I am sure a lot of hours have now 
>>>>>>>>>>>>>>>>>>>>>>>>>>> gone into some code that simply does not 
>>>>>>>>>>>>>>>>>>>>>>>>>>> satisfy me. And I am not not talking about 
>>>>>>>>>>>>>>>>>>>>>>>>>>> the code itself, what it does is what I don’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>> think is right for us.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  The process is very clear for me that we 
>>>>>>>>>>>>>>>>>>>>>>>>>>> should first of all think whether we want a 
>>>>>>>>>>>>>>>>>>>>>>>>>>> certain feature now. Then there should be a 
>>>>>>>>>>>>>>>>>>>>>>>>>>> clear roadmap for everyone to follow; tasks 
>>>>>>>>>>>>>>>>>>>>>>>>>>> can be split-up as we go and hopefully then 
>>>>>>>>>>>>>>>>>>>>>>>>>>> have something that is maintainable, 
>>>>>>>>>>>>>>>>>>>>>>>>>>> interesting for our users and even would do 
>>>>>>>>>>>>>>>>>>>>>>>>>>> us proud. This is how this should work.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  So, what has to change? I don’t think with 
>>>>>>>>>>>>>>>>>>>>>>>>>>> shouting at each other, throwing patches 
>>>>>>>>>>>>>>>>>>>>>>>>>>> around and making me generally unhappy is a 
>>>>>>>>>>>>>>>>>>>>>>>>>>> good start.
>>>>>>>>>>>>>>>>>>>>>>>>>>>  -Michael
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>   Jon
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   On Feb 6, 2025, at 2:13 PM, Michael 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Tremer <michael.tremer@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Hello Jon,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Well, here we are again with another patch 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding this feature.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I cannot quite see from your email what 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the question is, but if this is a request 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to have this merged into IPFire, I am once 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> again sorry to disappoint you.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I think I have covered this all at lengths 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> before that this project has been started 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as a separate effort and as far as I am 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> aware none of the other team members has 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been involved. This has not been discussed 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> either on this list, on our calls. Instead 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there has been a separate conversation on 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the forum with the occasional dip here to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the list. But that was not a regular two- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> way conversation. Therefore, what am I 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> supposed to do with this email?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I don’t want to merge code that I don’t 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> agree with. So many fundamental things that 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I have been raising have either not been 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> discussed or outright dismissed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  I don’t want to merge code that has no 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> future inside IPFire as there is no 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> constructive conversation with the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maintainers of it.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Having been trying for a long time to make 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you aware of this, nothing of this should 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> come as a surprise.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Please consider if that can be changed and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if there is a path forward with this.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  All the best,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  -Michael
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   On 6 Feb 2025, at 16:35, Jon Murphy 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  What is it?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Response Policy Zone (RPZ) is a mechanism 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to define local policies in a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  standardized way and load those policies 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from external sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Bottom line: RPZ allows admins to easily 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block access to websites via DNS lookup.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  RPZ can block websites via categories. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Examples include: fake websites, annoying
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  pop-up ads, newly registered domains, DoH 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bypass sites, bad "host" services,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  maliscious top level domains (e.g., 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *.zip, *.mov), piracy, gambling, pornography,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  and more. RPZ lists come from various RPZ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> providers and their available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  catagories.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  This RPZ add-on enables the RPZ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> functionality by adding a couple lines in a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  configuration file. This add-on simply 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> adds configuration files and adds
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  scripts (config, metrics and sleep) to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> make RPZ easier for the admin to use.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  The RPZ scripts include additional 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> languages: German, Spanish, French, Turkish,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  and Italian.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  RPZ itself was release in 2010 and has 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been part of the IPFire build since ~2015.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Why is it needed? What is its value?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - The RPZ concept places this filtering 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> into IPFire, our internet access
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  gateway, which is (should be) solely used 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as DNS source of the internal network.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - As most sites use HTTPS it makes it 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> difficult to filter traffic with URL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Filter without also properly configuring 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> conventional (non-transparent)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  mode on the proxy. RPZ is a nice 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> replacement for the URL Filter.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - No need to install and maintain an 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> additional device like PiHole or AdBlock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  browser extensions on multiple user devices.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - This is an additional layer of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> protection for users. Less worry someone will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  click on something that gets them into 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> trouble. And, saying this with emphasis,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  the ability to do it in one place!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - Blocked sites save on unneeded traffic 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and can lessen the threat of malware
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  in advertisements
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - Logging allows the admin to see the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> site blocked and take actions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - RPZ will be used at the home, home- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> office (work from home), schools,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ministerial, and at the office. Device 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> counts are small (2-6) to medium (~80)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  to mediam-large (200+).
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - RPZ can block ads, popups, phishing, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> scammers, spyware, malware, annoying
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  popups, NSFW links, DOH servers, and the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> usual internet trash.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ------------------------------
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Change Log for RPZ add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-1.0.0-18 on 2025-02-05
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - Build for approval & release as IPFire 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.18-18.ipfire on 2025-02-01
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added a mod key to force a 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-config and rpz-make:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added action for unbound 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restart `rpz-config unbound-restart`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-metrics:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - simple reformatting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - rename far right column from "last 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> update" to "last download"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.17-17.ipfire on 2024-12-09
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected validation regex for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wildcards like: `*.domain.com`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.16-16.ipfire on 2024-11-18
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: updated validation regex
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: moved validation to beginning 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of process. Now we validate before
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  creating config files.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: use CSS color variables of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the main ipfire theme
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: empty zonefile remarks were 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> stored as “undef” and caused a warning
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: HTML textarea removes the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first empty line in a custom list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - thank you Leo!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.15-15.ipfire on 2024-11-04
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new language file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for Turkish (thank you Peppe)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected empty allow/block 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> list issue. An empty allow/block list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  will now remove contents of allow/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block.rpz files and remove unneeded
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  allow/block.conf file. (thank you iptom)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.14-14.ipfire on 2024-10-29
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-config:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: correct missing rpz extension. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> `rpz-config list` displayed URL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  incorrectly (thank you Bernhard)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: remove extra `"` in language 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> files (thank you Bernhard)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: slightly dim "apply" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> button when not enabled
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.13-13.ipfire on 2024-10-27
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - skipped
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.12-12.ipfire on 2024-10-21
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new language file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for French (thank you gw-ipfire)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.11-11.ipfire on 2024-10-18
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new language file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for Italian (thank you umberto)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new language file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for Spanish (thank you Roberto)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.10-10.ipfire on 2024-10-15
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-make:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected validation error for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a custom list entry (thank you siosios)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - e.g., `*.cloudflare-dns.com`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  install.sh:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: add chown to correct user 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> created files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  update.sh:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: add chown to correct user 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> created files (thank you siosios)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.9-9.ipfire on 2024-10-08
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new language file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for German (thank you Leo)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: add missing "rpz exitcode 110"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected missing RPZ menu 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> item at menu > IPFire
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.8-8.ipfire on 2024-10-04
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - skipped
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-beta-0.1.7-7.ipfire on 2024-10-03
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  All:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: includes beta version 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> numbers for pakfire package,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  instead of only `rpz-1.0.0-1.ipfire`, for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> each release.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz.cgi:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: added new WebGUI at `rpz.cgi`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - a BIG thank you to Leo Hofmann for all 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of his work creating the webgui!!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected missing RPZ menu 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> item at menu > IPFire
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-make:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: validate entries in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist and blocklist
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: add "no-reload" option for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebGUI
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  rpz-metrics:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - new feature: info can be sorted by 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name, by hit count, by line count, by
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  "enabled" list or all lists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  backups:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: include all files in `/var/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ipfire/dns/rpz` directory in backup
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  update.sh:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: corrected ownership for `/var/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ipfire/dns/rpz` directory during an
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  update
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Build:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - bug fix: `block.rpz.conf` and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> `block.rpz` from build. Files to be created
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  by `rpz-make`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  WebGUI and German language file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Leo-Andres Hofmann 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <hofmann@leo-andres.de>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Spanish language file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Roberto Peña
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Italian language file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Umberto Parma
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  French language file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: gw-ipfire
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Turkish language file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Peppe Tech
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Bernhard Bitsch 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <bbitsch@ipfire.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Contribution-by: Erik Kapfer 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <erik.kapfer@ipfire.org>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Signed-off-by: Jon Murphy 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <jon.murphy@ipfire.org
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ---
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/backup/includes/rpz | 4 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/cfgroot/manualpages | 1 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/menu/EX-rpz.menu | 6 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rootfiles/common/configroot | 1 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rootfiles/common/web-user- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> interface | 1 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rootfiles/packages/rpz | 20 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/00-rpz.conf | 10 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz-config | 130 +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz-functions | 85 ++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz-make | 203 +++++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz-metrics | 170 ++++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz-sleep | 58 ++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.de.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.en.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.es.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.fr.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.it.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  config/rpz/rpz.tr.pl | 30 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  html/cgi-bin/rpz.cgi | 923 ++++++++++++++ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +++++++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfs/rpz | 96 +++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  make.sh | 3 +-
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  src/paks/rpz/install.sh | 36 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  src/paks/rpz/uninstall.sh | 38 +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  src/paks/rpz/update.sh | 52 ++
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  24 files changed, 2016 insertions(+), 1 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> deletion(-)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/backup/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> includes/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/menu/EX-rpz.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rootfiles/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> packages/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/00-rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100755 config/rpz/rpz-metrics
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100755 config/rpz/rpz-sleep
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.de.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.en.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.es.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.fr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.it.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 config/rpz/rpz.tr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 html/cgi-bin/rpz.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 lfs/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 src/paks/rpz/install.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 src/paks/rpz/uninstall.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  create mode 100644 src/paks/rpz/update.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/backup/includes/rpz 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> b/config/backup/includes/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..36513e494
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/backup/includes/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,4 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/var/ipfire/dns/rpz/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/unbound/zonefiles/allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/unbound/zonefiles/block.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/unbound/local.d/*rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/cfgroot/manualpages 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> b/config/cfgroot/manualpages
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 1f7e01efc..d3a48c633 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- a/config/cfgroot/manualpages
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/cfgroot/manualpages
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -70,6 +70,7 @@ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pakfire.cgi=configuration/ipfire/pakfire
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  wlanap.cgi=addons/wireless
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  tor.cgi=addons/tor
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  samba.cgi=addons/samba
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpz.cgi=addons/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  # Logs menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  logs.cgi/summary.dat=configuration/logs/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> summary
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/menu/EX-rpz.menu b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/menu/EX-rpz.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..2f4daf410
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/menu/EX-rpz.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,6 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +$subipfire->{'20.rpz'} = {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'caption' => $Lang::tr{'rpz'},
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'uri' => '/cgi-bin/rpz.cgi',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'title' => "RPZ",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'enabled' => 1,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rootfiles/common/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> configroot b/config/rootfiles/common/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> configroot
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 9839eee45..b30d6aae4 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- a/config/rootfiles/common/configroot
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rootfiles/common/configroot
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -120,6 +120,7 @@ var/ipfire/menu.d/70- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> log.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-apcupsd.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-guardian.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-mympd.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#var/ipfire/menu.d/EX-rpz.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-samba.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-tor.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #var/ipfire/menu.d/EX-transmission.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rootfiles/common/web- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> user-interface b/config/rootfiles/common/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> web-user-interface
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 816241dae..e00464076 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- a/config/rootfiles/common/web-user- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> interface
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rootfiles/common/web-user- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> interface
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -69,6 +69,7 @@ srv/web/ipfire/cgi-bin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proxy.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  srv/web/ipfire/cgi-bin/qos.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  srv/web/ipfire/cgi-bin/remote.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  srv/web/ipfire/cgi-bin/routing.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#srv/web/ipfire/cgi-bin/rpz.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  #srv/web/ipfire/cgi-bin/samba.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  srv/web/ipfire/cgi-bin/services.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  srv/web/ipfire/cgi-bin/shutdown.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rootfiles/packages/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz b/config/rootfiles/packages/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..1c8663049
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rootfiles/packages/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,20 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +etc/unbound/local.d/00-rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +etc/unbound/zonefiles
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +etc/unbound/zonefiles/allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +usr/sbin/rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +usr/sbin/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +usr/sbin/rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +usr/sbin/rpz-metrics
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +usr/sbin/rpz-sleep
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.de.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.en.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.es.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.fr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.it.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/addon-lang/rpz.tr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/backup/addons/includes/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/dns/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/dns/rpz/allowlist
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/dns/rpz/blocklist
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +var/ipfire/menu.d/EX-rpz.menu
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +srv/web/ipfire/cgi-bin/rpz.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/00-rpz.conf b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/00-rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..f005a4f2e
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/00-rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,10 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +server:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + module-config: "respip validator iterator"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpz:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + name: allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + zonefile: /etc/unbound/zonefiles/allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-action-override: passthru
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log: yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log-name: allow
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-signal-nxdomain-ra: yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz-config b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..c72d50f9b
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,130 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024-2025 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +version="2025-01-11 - v44"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Functions ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +source /usr/sbin/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Main ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +tagName="unbound"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzAction="${1}" # input RPZ action
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzName="${2}" # input RPZ name
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzURL="${3}" # input RPZ URL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzOption1="${4}" # input RPZ option #1
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzOption2="${5}" # input RPZ option #2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzConfig="/etc/unbound/local.d/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${rpzName}.rpz.conf" # output zone conf file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzFile="/etc/unbound/zonefiles/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${rpzName}.rpz" # output for RPZ file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzLog="yes" # log default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +ucReload="yes" # reload default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +while [[ $# -gt 0 ]] ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + case "$1" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --no-log ) rpzLog="no" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --no-reload ) ucReload="no" ; 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checkConf="no" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + shift # Shift after checking all the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cases to get next option
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +case "${rpzAction}" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # add new rpz list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + add )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + check_name "${rpzName}" # is this a 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid name?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # does this config already exist? If 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> yes, then exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ -f "${rpzConfig}" ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: duplicate - 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${rpzConfig} already exists. exit"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 104
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # is this a valid URL?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + regex='^https://[-[:alnum:]\+&@#/%? 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> =~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if ! [[ "${rpzURL}" =~ $regex ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: the URL is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid: \"${rpzURL}\". exit."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 105
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # create the zone config file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "rpz:"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " name: ${rpzName}.rpz"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " zonefile: ${rpzFile}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " url: ${rpzURL}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " rpz-action-override: nxdomain"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " rpz-log: ${rpzLog}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " rpz-log-name: ${rpzName}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo " rpz-signal-nxdomain-ra: yes"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } > "${rpzConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # set-up zonefile
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # create an empty rpz file if it does 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> not exist
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ ! -f "${rpzFile}" ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + touch "${rpzFile}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # unbound requires these settings for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + set_permissions "${rpzFile}" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${rpzConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # trash config file & rpz file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + remove )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if ! [[ -f "${rpzConfig}" ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: cannot remove 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${rpzConfig}, does not exist. exit"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 106
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: remove config file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> & rpz file \"${rpzName}\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rm "${rpzConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rm "${rpzFile}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + reload )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + check_unbound_conf "${checkConf}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + list )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + awk -F':' '/^\s*name:/{ gsub(/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [[:blank:]]|\.rpz/, "",$2) ; NAME=$2 } \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /^\s*url:/{ gsub(/[[:blank:]]/, "") ; 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> print NAME"="$2":"$3} ' \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /etc/unbound/local.d/*rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound-restart )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + check_unbound_conf "${checkConf}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound_restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + * )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: missing or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incorrect parameter"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "Usage: $(basename "$0") 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <ACTION> <NAME> <URL> <OPTION> <OPTION>\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "Version: ${version}\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 108
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unbound_control_reload "${ucReload}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz-functions b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..ace1d2690
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,85 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +version="2024-12-10 - v02"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Functions ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +msg_log () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + logger --tag "${tagName}" "$*"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if tty --silent ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "${tagName}:" "$*"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# check for a valid name
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +check_name () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theName="${1}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + regex='^[a-zA-Z0-9_]+$' # no dash or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> plus, alpha numeric only
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + regex1='^(allow|block)$' # allow and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block are reserved NAMEs
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ ! "${theName}" =~ $regex ]] || 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [[ "${theName}" =~ $regex1 ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: the NAME is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid: \"${theName}\". exit."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 101
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +set_permissions () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chown nobody:nobody "$@"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chmod 644 "$@"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +check_unbound_conf () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local thecheckConf="${1:-yes}" # check 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # check the above config files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ "${thecheckConf}" == yes ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: check for errors 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with \"unbound-checkconf\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if ! unbound-checkconf ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> found invalid configuration."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + "error: rpz: In Terminal run the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> command \"unbound-checkconf\" for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> information. exit."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 102
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unbound_control_reload () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theReload="${1:-yes}" # reload 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ "${theReload}" == yes ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # reload due to the changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: run \"unbound- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> control reload\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if ! unbound-control reload ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload. exit."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 109
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unbound_restart () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # restart due to the changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: run \"unbound 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restart\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /usr/local/bin/unboundctrl restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz-make b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..927d55170
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz-make
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,203 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024-2025 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +version="2025-01-11 - v14"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Functions ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +source /usr/sbin/rpz-functions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# create the config file for allow
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +make_allow_config () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theLog="${1:-yes}" # log default ON
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theConfig="/etc/unbound/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> local.d/00-rpz.conf" # output zone conf file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theList="/var/ipfire/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist" # input custom list of domains
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: make config file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \"00-rpz.conf\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "server:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + module-config: \"respip validator 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> iterator\"" > "${theConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # does allow list exist?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ -s "${theList}" ]] && grep -q . 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theList}" ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "rpz:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + name: allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + zonefile: /etc/unbound/zonefiles/allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-action-override: passthru
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log: ${theLog}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log-name: allow
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-signal-nxdomain-ra: yes" >> 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # set-up zonefile - unbound requires 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> these settings for rpz files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + set_permissions "${theConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# create the config file for block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +make_block_config () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theLog="${1:-yes}" # log default ON
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theConfig="/etc/unbound/local.d/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block.rpz.conf" # output zone conf file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theList="/var/ipfire/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blocklist" # input custom list of domains
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: make config file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \"block.rpz.conf\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # does block list exist?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ -s "${theList}" ]] && grep -q . 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theList}" ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "rpz:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + name: block.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + zonefile: /etc/unbound/zonefiles/block.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-action-override: nxdomain
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log: ${theLog}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-log-name: block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rpz-signal-nxdomain-ra: yes" > 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # set-up zonefile - unbound requires 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> these settings for rpz files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + set_permissions "${theConfig}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + else
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # no - trash the config file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rm --verbose /etc/unbound/local.d/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block.rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# create an RPZ file for allow or block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +make_rpz_file () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theName="${1}" # allow or block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theAction='.' # the default is 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nxdomain or block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local actionList
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theList="/var/ipfire/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theName}list" # input custom list of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domains
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theZonefile="/etc/unbound/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> zonefiles/${theName}.rpz" # output file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for RPZ
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # does a list exist?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ -s "${theList}" ]] && grep -q . 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theList}" ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # for allow set to passthru
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + [[ "${theName}" == allow ]] && 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> theAction='rpz-passthru.'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # drop any extra "blanks" and add 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "CNAME <RPZ action>." to each line
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + actionList=$( awk '{$1=$1};1' 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${theList}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + sed "/^[^;].*[[:alnum:]]/ s|$| CNAME 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theAction}|" )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: create zonefile for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \"${theName}list\""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +echo "; Name: ${theName} list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +; Last modified: $(date "+%Y-%m-%d at 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %H.%M.%S %Z")
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +; domains with actions list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +${actionList}" > "${theZonefile}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # set-up zonefile - unbound requires 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> these settings for rpz files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + set_permissions "${theZonefile}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # set-up allow/block list files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + set_permissions "${theList}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + else
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "info: rpz: the ${theList} is 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> empty."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + rm --verbose "${theZonefile}" # trash 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the RPZ file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# check if allow/block list is valid
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +validate_list () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theName="${1}" # allow or block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + local theList="/var/ipfire/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theName}list" # input custom list of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domains
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # remove good:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # - properly formated domain names with 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> or without leading wildcard
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # - properly formated top level domain 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (TLD) names with wildcard
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # - blank lines and comment lines
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # remaining lines are considered "bad"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + bad_lines=$( sed --regexp-extended \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + '/^(\*\.)?([a-zA-Z0-9](([a-zA-Z0-9\-]) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {0,61}[a-zA-Z0-9])?\.)+([a-zA-Z]{2,}|xn-- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$/d ;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /^(\*\.)([a-z]{2,61}|xn--[a-z0-9] 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {1,60})$/d ;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /^$/d ; /^;/d' "${theList}" )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ ! -z "${bad_lines}" ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: invalid line(s) in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theList}."
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "%s\n" "bad line(s): ${bad_lines}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 110
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Main ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +tagName="unbound"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzName="${1}" # input RPZ name
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzLog="yes" # log default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +ucReload="yes" # reload default is yes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +while [[ $# -gt 0 ]] ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + case "$1" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --no-log ) rpzLog="no" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --no-reload ) ucReload="no" ; 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checkConf="no" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + shift # Shift after checking all the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cases to get next option
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +case "${rpzName}" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # make a new allow or block rpz file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + allow )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + validate_list 'allow' # is the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist valid?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_allow_config "${rpzLog}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_rpz_file 'allow'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + allowblock )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + validate_list 'allow' # is the list valid?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_allow_config "${rpzLog}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_rpz_file 'allow'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;&
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + block )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + validate_list 'block' # is the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blocklist valid?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_block_config "${rpzLog}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + make_rpz_file 'block'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + reload )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + check_unbound_conf "${checkConf}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound-restart )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + check_unbound_conf "${checkConf}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound_restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + * )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + msg_log "error: rpz: missing or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incorrect parameter"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "Usage: $(basename "$0") <NAME> 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <OPTION> <OPTION>\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "Version: ${version}\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit 108
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unbound_control_reload "${ucReload}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz-metrics b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz-metrics
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100755
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..4d43e1629
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz-metrics
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,170 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +version="2025-01-20 - v25"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Main ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +weeks="2" # default to two message logs
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sortBy="name" # default "by name"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzActive="enabled" # default "enabled 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> only"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +while [[ $# -gt 0 ]] ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + case "$1" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --by-names | --by-name | name ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sortBy="name" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --by-hits | --by-hit | hits | hit ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sortBy="hit" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --by-lines | --by-line | lines | line ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sortBy="line" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --by-effect ) sortBy="effect" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --enabled-only ) rpzActive="enabled" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --active-all | --all | all ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpzActive="all" ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + [0-9] | [0-9][0-9] ) weeks=$1 ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + shift # Shift after checking all the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cases to get next option
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get the list of message logs for N weeks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +messageLogs=$( find /var/log/messages* - 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> type f | sort --version-sort |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + head -"${weeks}" )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get the list of RPZ names & counts 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from the message log(s)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzNameCount=$( for logf in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${messageLogs} ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + zgrep --text --fixed-strings 'info: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz: applied' "${logf}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + awk '$10 ~ /\[\w*]/ { print $10 }' ;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + done | sort | uniq --count )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# flip results and remove brackets `[` 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and `]`
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzNameCount=$( echo "${rpzNameCount}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + awk '{ print $2, $1 }' |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + sed --regexp-extended 's|^\[(.*)\]|\1|' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# grab only names
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzNames=$( echo "${rpzNameCount}" | awk 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '{ print $1 }' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get list of RPZ files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzFileList=$( find /etc/unbound/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> zonefiles -type f -iname "*.rpz" )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get basename of those files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzBaseNames=$( echo "${rpzFileList}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + sed 's|/etc/unbound/zonefiles/||g ; s| 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \.rpz||g ;' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# add to rpzNames
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzNames="${rpzNames}"$'\n'"${rpzBaseNames}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# drop duplicate names
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +rpzNames=$( echo "${rpzNames}" | sort -- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unique )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get line count for each RPZ
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +lineCount=$( echo "${rpzFileList}" | 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> xargs wc -l )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get comment line count and blank line 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> count for each RPZ
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +commentCount=$( echo "${rpzFileList}" | 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> xargs grep --count -e "^$" -e "^;" )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get modified date each RPZ
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +modDateList=$( echo "${rpzFileList}" | 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> xargs stat -c '%.10y %n' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +ucListAuthZones=$( unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> list_auth_zones )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# get width of RPZ names
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +pWidth=$( echo "${rpzNames}" | awk 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '{ print $1" " }' | wc -L )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +pFormat="%-${pWidth}s %-8s %-8s %8s %12s 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %12s\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# print title line
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +printf "${pFormat}" "name" "hits" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "active" "lines" " hits/line" "last download"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +printf -- "--------------"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +theResults=""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +totalLines=0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +totalHits=0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +while read -r theName
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf -- "--" # pretend progress bar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # is this RPZ list active?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theActive="disabled"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if grep --quiet "^${theName}\.rpz" <<< 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${ucListAuthZones}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theActive="enabled"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + else
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + [[ "${rpzActive}" == enabled ]] && 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> continue
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # get hit count
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theHits="0"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if output=$( grep "^${theName}\s" <<< 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${rpzNameCount}" ) ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theHits=$( echo "${output}" | awk 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '{ print $2 }' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + totalHits=$(( totalHits + theHits ))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # get line count
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theLines="n/a"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + hitsPerLine="0"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if output=$( grep --fixed-strings "/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theName}.rpz" <<< "${lineCount}" ) ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theLines=$( echo "${output}" | awk 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '{ print $1 }' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + totalLines=$(( totalLines + theLines ))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if [[ "${theLines}" -gt 2 ]] ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + hitsPerLine=$(( 100 * theHits / 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> theLines ))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # get modification date
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theModDate="n/a"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if output=$( grep --fixed-strings "/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theName}.rpz" <<< "${modDateList}" ) ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theModDate=$( echo "${output}" | awk 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '{ print $1 }' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # add to results list
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + theResults+="${theName} ${theHits} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theActive} ${theLines} ${hitsPerLine} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${theModDate}"$'\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done <<< "${rpzNames}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +case "${sortBy}" in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # sort by "active" then by "name"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + name) sortArg=(-k3,3r -k1,1) ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # sort by "active" then by "hits" then 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> by "name"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + hit) sortArg=(-k3,3r -k2,2nr -k1,1) ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # sort by "active" then by "lines" then 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> by "name"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + line) sortArg=(-k3,3r -k4,4nr -k1,1) ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # sort by "active" then by "effect" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then by "name"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + effect) sortArg=(-k3,3r -k5,5nr -k1,1) ;;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +esac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +printf -- "--------------\n"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# remove blank lines, sort, print as 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> columns
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +echo "${theResults}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + awk '!/^[[:space:]]*$/' |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + sort "${sortArg[@]}" |
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + awk --assign=width="${pWidth}" \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + '{ printf "%-*s %-8s %-8s %8s %10s %% 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %12s\n", width, $1, $2, $3, $4, $5, $6 }'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +printf "${pFormat}" "" "=======" "" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "========" "" ""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +printf "${pFormat}" "Totals -->" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${totalHits}" "" "${totalLines}" "" ""
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz-sleep b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz-sleep
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100755
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..dd3603599
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz-sleep
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,58 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +version="2024-08-16" # v05
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Functions ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# send message to message log
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +msg_log () {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + logger --tag "${tagName}" "$*"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if tty --silent ; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + echo "${tagName}:" "$*"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +############### Main ###############
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +tagName="unbound"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sleepTime="${1:-5m}" # default to sleep 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for 5m (5 minutes)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +zoneList=$( unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> list_auth_zones | awk '{print $1}' )
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +for zone in ${zoneList} ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "disable ${zone}\t"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound-control rpz_disable "${zone}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +msg_log "info: rpz: disabled all zones 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for ${sleepTime}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sleep "${sleepTime}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +for zone in ${zoneList} ; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + printf "enable ${zone}\t"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unbound-control rpz_enable "${zone}"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +msg_log "info: rpz: enabled all zones"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +exit
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.de.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.de.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..3770c6bb0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.de.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Added for Response Policy Zone (RPZ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Response Policy Zones (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Übernehmen',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'Benutzerdefinierte Allowlist aktivieren:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Zugelassene 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Domains (eine pro Zeile)<br>Beispiel: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Benutzerdefinierte 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Allowlist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'Benutzerdefinierte Blocklist aktivieren:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Gesperrte 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Domains (eine pro Zeile)<br>Beispiel: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'Benutzerdefinierte 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Blocklist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Benutzerdefinierte Listen',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'Der Name enthält 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unzulässige Zeichen',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hat eine fehlerhafte Konfiguration 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ermittelt. Führen Sie das Kommando 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound-checkconf auf der Konsole aus, um 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> weitere Informationen zu erhalten.',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'Die 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> benutzerdefinierte Allow-/Blocklist ist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leer',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'Ein Eintrag mit 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> identischem Namen existiert bereits',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'Die URL ist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ungültig',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => 'Eintrag kann 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicht entfernt werden, der Name existiert 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicht',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'Der Name ist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ungültig - nur "allow" oder "block" möglich',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'Fehlende oder 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> inkorrekte Parameter',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload ist fehlgeschlagen',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'Die 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> benutzerdefinierte Allow-/Blocklist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enthält unzulässige Einträge',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'Die Anmerkung 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enthält unzulässige Zeichen',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'Ungültiger 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Eintrag in der benutzerdefinierten 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Allowlist, Zeile ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'Ungültiger 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Eintrag in der benutzerdefinierten 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Blocklist, Zeile ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'Ausgewählter 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Eintrag existiert nicht: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'Zonendatei-Eintrag 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bearbeiten',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(importiert aus 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'Erlaubte 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Zeichen sind a-z, A-Z, 0-9 und Unterstriche',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Zonendateien',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.en.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.en.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..0720a8940
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.en.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Added for Response Policy Zone (RPZ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Response Policy Zones (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Apply',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => 'Enable custom 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Allowed domains 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (one per line)<br>Example: domain.com, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Custom allowlist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => 'Enable custom 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blocklist:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Blocked domains 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (one per line)<br>Example: domain.com, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'Custom blocklist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Custom lists',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'the NAME is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> found invalid configuration. In the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Terminal run the command unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for more information',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'the allow/block 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> list is empty',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'duplicate - NAME 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> already exists',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'the URL is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => 'cannot remove the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAME does not exist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'the NAME is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid - "allow" or "block" only',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'missing or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incorrect parameter',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload failed',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'custom Allowlist/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Blocklist contains invalid entries',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'the REMARK is not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valid',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'invalid entry in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist, line ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'invalid entry in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blocklist, line ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'Selected entry 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> does not exist: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'Edit zonefiles entry',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(imported from 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'Valid 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> characters are a-z, A-Z, 0-9 and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> underscore.',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Zonefiles',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.es.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.es.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..98628e4aa
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.es.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Added for Response Policy Zone (RPZ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Zonas de política de respuesta 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Aplicar',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => 'Habilitar la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> lista blanca personalizada:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Dominio 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> permitido (uno por línea)<br>Ejemplo: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Lista blanca 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> personalizada',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => 'Habilitar la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> lista negra personalizada:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Dominio 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bloqueado (uno por línea)<br>Ejemplo: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'Lista negra 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> personalizada',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Lista personalizada',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'El NOMBRE no es 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> válido',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ha encontrado una configuración no válida. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Desde Terminal, ejecute el comando 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound-checkconf para mayor información',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'La lista de 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> permitidos/bloqueados está vacía',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'duplicado - 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NOMBRE ya existe',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'la URL no es 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> válida',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => 'no es posible 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> eliminar el NOMBRE que no existe',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'el NOMBRE no es 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> válido - sólo "permitir" o "bloquear"',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'parámetro 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> faltante o incorrecto',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'Error al recargar 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound-control',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'la Lista blanca/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lista negra personalizada contiene 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entradas no válidas',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'el COMENTARIO no 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> es válido',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'entrada no válida 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> en la lista blanca, línea ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'entrada no válida 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> en la lista negra, línea ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'La entrada 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seleccionada no existe: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'Editar la entrada de 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> archivos de zona',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(importado de rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'Los caracteres 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> válidos son a-z, A-Z, 0-9 y guión bajo',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Archivos de zona',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.fr.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.fr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..f35f3c2d0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.fr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Added for Response Policy Zone (RPZ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Response Policy Zones (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Appliquer',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => 'Activer la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> liste d\'autorisations personnalisée:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Domaines 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autorisés (un par ligne)<br>Example: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Liste 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> d\'autorisations personnalisée',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => 'Activer la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> liste de blocage personnalisée:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Domaines bloqués 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (un par ligne)<br>Example: domain.com, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'liste de blocage 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> personnalisé',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Listes personnalisées',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'le NOM n\'est pas 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valide',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> configuration non valide trouvée. Dans le 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> terminal, exécutez la commande unbound- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checkconf pour plus d\'informations',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'la liste 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoriser/bloquer est vide',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'le NOM existe déjà',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'L\'URL n\'est pas 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valide',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => 'impossible de 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> supprimer le NOM n\'existe pas',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'le NOM n\'est pas 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valide - « autoriser » ou « bloquer » 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> seulement',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'paramètre 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> manquant ou incorrect',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rechargement échoué',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'la liste 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> autoriser/bloquer contient des entrées non 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valides',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'la REMARQUE 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> n\'est pas valable',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'entrée non valide 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dans la liste d\'autorisation, ligne ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'entrée non valide 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dans la liste de blocs, ligne ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'L\'entrée 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sélectionnée n\'existe pas: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'Modifier l\'entrée 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fichiers Zone',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(importé de rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'Les caractères 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valides sont a-z, A-Z, 0-9 et soulignement.',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Fichiers Zone',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.it.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.it.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..ee81605c9
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.it.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Added for Response Policy Zone (RPZ) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> add-on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Response Policy Zones (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Applica',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => 'Abilita la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Whitelist personalizzata:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Domini 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> consentiti (uno per riga)<br>Esempio: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Whitelist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> personalizzata',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => 'Abilita la 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Blacklist personalizzata:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Domini bloccati 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (uno per riga)<br>Esempio: domain.com, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'Blacklist 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> personalizzata',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Liste personalizzate',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'il NOME non è 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valido',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ha trovato una configurazione non valida. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dal Terminale esegui il comando unbound- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checkconf per maggiori informazioni',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'l\'elenco 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> consentiti/bloccati è vuoto',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'duplicato - NAME 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> esiste di già',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'l\'URL non è 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valido',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => 'non è possibile 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rimuovere il NOME non esiste',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'il NOME non è 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valido - solo "consenti" o "blocca"',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'parametro 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mancante o non corretto',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'ricaricamento del 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> controllo non associato non riuscito',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'la Whitelist/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Blacklist personalizzata contiene voci non 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> valide',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'l"OSSERVAZIONE 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> non è valida',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'voce non valida 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nella Whitelist, riga ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'voce non valida 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nella Blacklist, riga ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'La voce 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selezionata non esiste: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'Modifica la voce dei 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> file di zona',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(importato da rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'I caratteri 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> validi sono a-z, A-Z, 0-9 e trattino basso',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Zonefiles',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/config/rpz/rpz.tr.pl b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config/rpz/rpz.tr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..00226e192
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/config/rpz/rpz.tr.pl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,30 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# I�in eklendi Ayriyeten Response Policy 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Zone (RPZ)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +%tr = (%tr,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz' => 'Response Policy Zones (RPZ)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz apply' => 'Uygulamak',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow enable' => '�zel 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Etkinlestir allowlist:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow info' => 'Izin verilmis 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domains (satir basina bir)<br>�rnegin: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl allow' => 'Etkinlestir allowlist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block enable' => '�zel 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Etkinlestir blocklist:',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block info' => 'Engellenmis 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domains (satir basina bir)<br>�rnegin: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> domain.com, *.domain.com',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl block' => 'Engellenmis blocklist',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz cl' => 'Engellenmis lists',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 101' => 'NAME ge�erli degil',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 102' => 'unbound-checkconf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ge�ersiz yapilandirma bulundu. Terminalde 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> daha fazla bilgi i�in Unbound-checkConf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> komutunu �alistirin',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 103' => 'allow/block liste 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bos',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 104' => 'kopyalamak - NAME 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> zaten var',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 105' => 'URL ge�erli degil',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 106' => '�ikarilamiyor 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAME yok',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 107' => 'NAME ge�erli 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> degil - "allow" veya "block" yalniz',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 108' => 'Parametre eksik 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> veya yanlis',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 109' => 'unbound-control 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> basarisiz',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 110' => 'Engellenmis 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Allowlist/Blocklist ge�ersiz girisler 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> i�erir',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 201' => 'REMARK ge�erli 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> degil',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 202' => 'Ge�ersiz giris 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allowlist, line ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 203' => 'Ge�ersiz giris 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blocklist, line ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz exitcode 204' => 'Se�ilen giris 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> yok: ',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf editor' => 'yazimlamak zonefiles 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> giris',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf imported' => '(ithal edildi rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config)',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf remark info' => 'Ge�erli 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> karakterler a-z, A-Z, 0-9ve alt�st.',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +'rpz zf' => 'Zonefiles',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/html/cgi-bin/rpz.cgi b/html/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cgi-bin/rpz.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..a821c92ac
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/html/cgi-bin/rpz.cgi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,923 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/usr/bin/perl
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2005-2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +use strict;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +use Scalar::Util qw(looks_like_number);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# debugging
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#use warnings;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#use CGI::Carp 'fatalsToBrowser';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#use Data::Dumper;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +require '/var/ipfire/general-functions.pl';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +require "${General::swroot}/lang.pl";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +require "${General::swroot}/header.pl";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Extra HTML ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $extraHead = <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<style>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /* alternating row background */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + .tbl tr:nth-child(2n+2) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + background-color: var(--color-light-grey);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + .tbl tr:nth-child(2n+3) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + background-color: var(--color-grey);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /* text styles */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + .tbl th:not(:last-child) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + text-align: left;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + div.right {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + text-align: right;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + margin-top: 0.5em;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /* customlist input */
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + textarea.domainlist {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + margin: 0.5em 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + resize: vertical;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + min-height: 10em;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + overflow: auto;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + white-space: pre;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + button[type=submit]:disabled {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + opacity: 0.6;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</style>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- End of extra HTML ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +### Settings ###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Request DNS service reload after 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> configuration change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $RPZ_RELOAD_FLAG = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${General::swroot}/dns/rpz/reload.flag";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Configuration file for all available 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> zonefiles
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Format: index, name (unique), enabled 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (on/off), URL, remark
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $ZONEFILES_CONF = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${General::swroot}/dns/rpz/zonefiles.conf";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Configuration file for custom lists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IDs: 0=allowlist, 1=blocklist, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2=options (allow/block enabled)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $CUSTOMLISTS_CONF = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${General::swroot}/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> customlists.conf";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Export custom lists to rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $RPZ_ALLOWLIST = "${General::swroot}/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dns/rpz/allowlist";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $RPZ_BLOCKLIST = "${General::swroot}/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dns/rpz/blocklist";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +### Preparation ###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Create missing config files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unless(-f $ZONEFILES_CONF) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { &General::system('touch', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "$ZONEFILES_CONF"); }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +unless(-f $CUSTOMLISTS_CONF) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { &General::system('touch', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "$CUSTOMLISTS_CONF"); }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +## Global gui data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $errormessage = "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +## Global configuration data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my %zonefiles = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my %customlists = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&_zonefiles_load();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&_customlists_load();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +## Global CGI form data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my %cgiparams = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::getcgihash(\%cgiparams);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $action = $cgiparams{'ACTION'} // 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +my $action_key = $cgiparams{'KEY'} // 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ''; # entry being edited, empty = none/new
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Process form actions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Zonefiles action: Check whether the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> requested entry exists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +if((substr($action, 0, 3) eq 'ZF_') && 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ($action_key)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unless(defined $zonefiles{$action_key}) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $errormessage = &_rpz_error_tr(204, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $action_key);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +## Perform actions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +if($action eq 'ZF_SAVE') { ## Save new 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> or modified zonefiles entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_zf_save()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE'; # success, return to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> main page
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'ZF_EDIT'; # error occured, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> keep editing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +} elsif($action eq 'ZF_TOGGLE') { ## 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Toggle on/off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_zf_toggle()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +} elsif($action eq 'ZF_REMOVE') { ## 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Remove entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_zf_remove()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +} elsif($action eq 'CL_SAVE') { ## Save 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> custom lists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_cl_save()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +} elsif($action eq 'RPZ_RELOAD') { ## 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Reload dns configuration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_rpz_reload()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +} elsif($action eq 'UNB_RESTART') { ## 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Restart unbound service
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_action_unb_restart()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action = 'NONE';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_http_prg_redirect();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Start GUI ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +## Start http output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::showhttpheaders();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Start HTML
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::openpage($Lang::tr{'rpz'}, 1, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $extraHead);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::openbigbox('100%', 'left', '');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show error messages
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +if($errormessage) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_print_message($errormessage);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Handle zonefile add/edit mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +if($action eq "ZF_EDIT") {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_print_zonefile_editor();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Finalize page and exit cleanly
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closebigbox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closepage();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + exit(0);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show gui elements
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&_print_zonefiles();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&_print_customlists();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&_print_gui_extras();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::closebigbox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +&Header::closepage();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- End of GUI ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Internal configuration file 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> functions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Load all available zonefiles from rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config and the internal configuration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _zonefiles_load {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Clean start
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + %zonefiles = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Source 1: Get the currently enabled 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> zonefiles from rpz-config (expected format 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [name]=[URL])
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my @enabled_files = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::system_output('/usr/sbin/rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> config', 'list');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $row (@enabled_files) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chomp($row);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Use regex instead of split() to skip 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> non-matching lines
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + next unless($row =~ /^(\w+)=(.+)$/);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($name, $url) = ($1, $2);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Unique names are already guaranteed 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> by rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_rpz_validate_zonefile($name, $url, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '', 0) == 0) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Populate global data hash, mark all 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> found entries as enabled
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %entry = ('enabled' => 'on',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'url' => $url,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'remark' => $Lang::tr{'rpz zf imported'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name} = \%entry;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Source 2: Get additional data and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> disabled entries from configuration file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %configured_files = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::readhasharray($ZONEFILES_CONF, \ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %configured_files);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $row (values 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (%configured_files)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($name, $enabled, $url, $remark) = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @$row;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $remark //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + next unless($name);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Check whether this row belongs to an 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entry already imported from rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(defined $zonefiles{$name}) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Existing entry, only merge additional 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name}{'remark'} = $remark;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Skip entry if it is marked as enabled 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> but not found by rpz-config. It was then 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> deleted manually
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($enabled ne 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Populate global data hash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %entry = ('enabled' => 'off',
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'url' => $url // "",
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'remark' => $remark);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name} = \%entry;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Save internal zonefiles configuration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _zonefiles_save_conf {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $index = 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %export = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Loop trough all zonefiles and create 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "hasharray" type export
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $name (keys %zonefiles) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my @entry = ($name,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name}{'enabled'},
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name}{'url'},
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name}{'remark'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $export{$index++} = \@entry;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::writehasharray($ZONEFILES_CONF, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \%export);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Load custom lists from rpz-config and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the internal configuration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _customlists_load {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Clean start
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + %customlists = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Load configuration file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %lists_conf = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::readhasharray($CUSTOMLISTS_CONF, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \%lists_conf);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Get list options, enabled by default 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to start import
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'allow'}{'enabled'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $lists_conf{2}[0] // 'on';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'block'}{'enabled'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $lists_conf{2}[1] // 'on';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Import enabled list from rpz-config, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> otherwise retrieve stored or empty list 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from configuration file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($customlists{'allow'}{'enabled'} eq 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_customlist_import('allow', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $RPZ_ALLOWLIST);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'allow'}{'list'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $lists_conf{0} // [];
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($customlists{'block'}{'enabled'} eq 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_customlist_import('block', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $RPZ_BLOCKLIST);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'block'}{'list'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $lists_conf{1} // [];
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Save internal custom lists configuration
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _customlists_save_conf {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %export = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Match IDs with import function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $export{0} = $customlists{'allow'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'list'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $export{1} = $customlists{'block'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'list'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $export{2} = [$customlists{'allow'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'enabled'}, $customlists{'block'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'enabled'}];
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::writehasharray($CUSTOMLISTS_CONF, \%export);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Import a custom list from plain file, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> returns empty list if file is missing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _customlist_import {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($listname, $filename) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my @list = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # File exists, load and check all lines
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(-f $filename) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + open(my $FH, '<', $filename) or die 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Can't read $filename: $!";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + while(my $line = <$FH>) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chomp($line);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + push(@list, $line);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + close($FH);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Clean up imported data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_rpz_validate_customlist(\@list, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{$listname}{'list'} = \@list;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Export a custom list to plain file or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clear file if list is disabled
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _customlist_export {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($listname, $filename) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless(defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $customlists{$listname});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Write enabled domain list to file, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> otherwise save empty file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + open(my $FH, '>', $filename) or die 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Can't write $filename: $!";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($customlists{$listname}{'enabled'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> eq 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $line 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (@{$customlists{$listname}{'list'}}) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print $FH "$line\n";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print $FH "; Note: This list is 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> currently disabled by $ENV{'SCRIPT_NAME'}\n";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + close($FH);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Internal gui functions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show simple message box
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _print_message {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($message, $title) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $title ||= $Lang::tr{'error messages'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::openbox('100%', 'left', $title);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print "<span>$message</span>";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closebox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show all zone files and related gui 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> elements
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _print_zonefiles {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::openbox('100%', 'left', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $Lang::tr{'rpz zf'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<table class="tbl" width="100%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <th>$Lang::tr{'name'}</th>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <th>URL</th>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <th>$Lang::tr{'remark'}</th>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <th colspan="3">$Lang::tr{'action'}</th>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Sort zonefiles by name and loop 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> trough all entries
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $name (sort keys %zonefiles) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Toggle button label translation
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $toggle_tr = ($zonefiles{$name} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'enabled'} eq 'on') ? $Lang::tr{'click to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> disable'} : $Lang::tr{'click to enable'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td>$name</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td>$zonefiles{$name}{'url'}</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td>$zonefiles{$name}{'remark'}</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td align="center" width="5%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="KEY" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$name">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="ZF_TOGGLE">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="image" src="/images/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$name}{'enabled'}.gif" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> title="$toggle_tr" alt="$toggle_tr">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td align="center" width="5%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="KEY" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$name">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="ZF_EDIT">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="image" src="/images/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> edit.gif" title="$Lang::tr{'edit'}" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alt="$Lang::tr{'edit'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td align="center" width="5%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="KEY" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$name">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="ZF_REMOVE">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="image" src="/images/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> delete.gif" title="$Lang::tr{'remove'}" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alt="$Lang::tr{'remove'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Disable reload button if not needed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $reload_state = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_needs_reload() ? "" : " disabled";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<div class="right">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <input type="hidden" name="KEY" value="">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <button type="submit" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="ZF_EDIT">$Lang::tr{'add'}</button>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <button type="submit" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="RPZ_RELOAD" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> class="commit"$reload_state>$Lang::tr{'rpz 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> apply'}</button>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closebox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show zonefiles entry editor
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _print_zonefile_editor {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Key specified: Edit existing entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(($action_key) && (defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key})) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Load data to be edited, but don't 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> override already present values (allows 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> user to edit after error)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_NAME'} //= $action_key;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_URL'} //= 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key}{'url'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_REMARK'} //= 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key}{'remark'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Fallback to empty form
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_NAME'} //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_URL'} //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ZF_REMARK'} //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::openbox('100%', 'left', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $Lang::tr{'rpz zf editor'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<input type="hidden" name="KEY" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$action_key">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<table width="100%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> width="20%">$Lang::tr{'name'}:&nbsp;<img 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> src="/blob.gif" alt="*"></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td><input type="text" name="ZF_NAME" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$cgiparams{'ZF_NAME'}" size="40" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maxlength="32" title="$Lang::tr{'rpz zf 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remark info'}" pattern="[a-zA-Z0-9_] 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {1,32}" required></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td width="20%">URL:&nbsp;<img src="/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> blob.gif" alt="*"></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td><input type="url" name="ZF_URL" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$cgiparams{'ZF_URL'}" size="40" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maxlength="128" required></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td width="20%">$Lang::tr{'remark'}:</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td><input type="text" name="ZF_REMARK" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="$cgiparams{'ZF_REMARK'}" size="40" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maxlength="32"></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="2"><hr></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td width="55%"><img src="/blob.gif" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alt="*">&nbsp;$Lang::tr{'required field'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td align="right"><button type="submit" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="ZF_SAVE">$Lang::tr{'save'}</ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> button></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<div class="right">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <button type="submit" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="NONE">$Lang::tr{'back'}</button>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</div>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closebox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Show custom allow/block files and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> related gui elements
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _print_customlists {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Load lists from config, unless they 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are currently being edited
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($action ne 'CL_SAVE') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ALLOW_LIST'} = join("\n", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @{$customlists{'allow'}{'list'}});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'BLOCK_LIST'} = join("\n", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @{$customlists{'block'}{'list'}});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ALLOW_ENABLED'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ($customlists{'allow'}{'enabled'} eq 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on') ? 'on' : undef;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'BLOCK_ENABLED'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ($customlists{'block'}{'enabled'} eq 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on') ? 'on' : undef;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Fallback to empty form
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'ALLOW_LIST'} //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cgiparams{'BLOCK_LIST'} //= "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # HTML checkboxes, unchecked = no or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> undef value in POST data
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %checked = ();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $checked{'ALLOW_ENABLED'} = (defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'ALLOW_ENABLED'}) ? " 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checked" : "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $checked{'BLOCK_ENABLED'} = (defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'BLOCK_ENABLED'}) ? " 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> checked" : "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Disable reload button if not needed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $reload_state = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_needs_reload() ? "" : " disabled";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::openbox('100%', 'left', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $Lang::tr{'rpz cl'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<form method="post" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> action="$ENV{'SCRIPT_NAME'}">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<table width="100%">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="2"><b>$Lang::tr{'rpz cl 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow'}</b><br>$Lang::tr{'rpz cl allow 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> info'}</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="2"><b>$Lang::tr{'rpz cl 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block'}</b><br>$Lang::tr{'rpz cl block 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> info'}</td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="2"><textarea 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name="ALLOW_LIST" class="domainlist" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cols="45">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +$cgiparams{'ALLOW_LIST'}</textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="2"><textarea 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name="BLOCK_LIST" class="domainlist" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cols="45">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +$cgiparams{'BLOCK_LIST'}</textarea></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td><label 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for="allow_enabled">$Lang::tr{'rpz cl 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow enable'}</label></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td width="15%"><input type="checkbox" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name="ALLOW_ENABLED" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> id="allow_enabled"$checked{'ALLOW_ENABLED'}></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td><label 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for="block_enabled">$Lang::tr{'rpz cl 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block enable'}</label></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td width="15%"><input type="checkbox" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> name="BLOCK_ENABLED" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> id="block_enabled"$checked{'BLOCK_ENABLED'}></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td colspan="4"><hr></td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <tr>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <td align="right" colspan="4">
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <button type="submit" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="CL_SAVE">$Lang::tr{'save'}</button>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + <button type="submit" name="ACTION" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> value="RPZ_RELOAD" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> class="commit"$reload_state>$Lang::tr{'rpz 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> apply'}</button>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + </td>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</table>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</form>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &Header::closebox();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Output javascript and extra gui elements
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _print_gui_extras {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Apply/Restart button modifier key 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handler
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(&_rpz_needs_reload()) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print <<END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +<script>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Commit modifier key handler
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + (function(jq, document) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + var keyEventsOn = false; // Keyboard 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> events attached
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + var keyModify = false; // Modifier key 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pressed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + var mouseHover = false; // Mouse over 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> commit button
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + var btnModified = false; // Button 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> modified to "Restart"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Document-level key events, enable 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> only while cursor is over button
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + function attachKeyEvents() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(keyEventsOn) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyEventsOn = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq(document).on("keydown.rpz", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function(event) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if((!keyModify) && event.shiftKey) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyModify = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + handleModify();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq(document).on("keyup.rpz", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function(event) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(keyModify && (!event.shiftKey)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyModify = false;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + handleModify();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + function removeKeyEvents() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyModify = false;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(keyEventsOn) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq(document).off("keydown.rpz keyup.rpz");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyEventsOn = false;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Attach mouse hover events to commit 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> buttons
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + function attachMouseEvents() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq("button.commit").on("mouseenter", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function(event) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(!mouseHover) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + mouseHover = true;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + attachKeyEvents();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Handle already pressed key
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + keyModify = !!(event.shiftKey);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + handleModify();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Cursor moved away: Disable key 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> listener to minimize events
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq("button.commit").on("mouseleave", 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(mouseHover) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + mouseHover = false;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + removeKeyEvents();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + handleModify();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // Modify commit button
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + function handleModify() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + let modify = mouseHover && keyModify;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(btnModified != modify) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(modify) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> jq("button.commit").text("$Lang::tr{'restart'}").val("UNB_RESTART");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> jq("button.commit").text("$Lang::tr{'rpz 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> apply'}").val("RPZ_RELOAD");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + btnModified = modify;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + // jQuery DOM ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + jq(function() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + attachMouseEvents();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + });
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + })(jQuery, document);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +</script>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +END
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } # End of modifier key handler
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Internal action processing 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> functions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Toggle zonefile on/off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_zf_toggle {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless(defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $result = 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $enabled = $zonefiles{$action_key} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'enabled'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Perform toggle action
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($enabled eq 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $enabled = 'off';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = &General::system('/usr/sbin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config', 'remove', $action_key, '--no- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + } else {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $enabled = 'on';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = &General::system('/usr/sbin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config', 'add', $action_key, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key}{'url'}, '--no- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Check for errors, request service 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload on success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_check_result($result, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Save changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$action_key}{'enabled'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $enabled;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_zonefiles_save_conf();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Remove zonefile
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_zf_remove {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless(defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Remove from rpz-config if currently 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> active
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($zonefiles{$action_key}{'enabled'} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> eq 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $result = &General::system('/usr/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sbin/rpz-config', 'remove', $action_key, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '--no-reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Check for errors, request service 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload on success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_check_result($result, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Remove from data hash and save changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + delete $zonefiles{$action_key};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_zonefiles_save_conf();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Clear action_key, as the entry is now 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> removed entirely
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $action_key = "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Create or update zonefile entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Returns undef if gui needs to stay in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> editor mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_zf_save {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $result = 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $name = $cgiparams{'ZF_NAME'} // "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $url = $cgiparams{'ZF_URL'} // "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $remark = $cgiparams{'ZF_REMARK'} // 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $enabled = 'on'; # Enable new 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entries by default
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Note on variables:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # name = unique key, will be used to 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> address the entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # action_key = name of the entry being 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> edited, empty for new entry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Only check for unique name if it changed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # (this also checks new entries because 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the action_key is empty in this case)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_validate_zonefile($name, $url, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $remark, (lc($name) ne lc($action_key)));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_check_result($result, 0);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Edit existing entry: Determine what 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> was changed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(($action_key) && (defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key})) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Name und URL remain unchanged, only 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> save remark and finish
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(($name eq $action_key) && ($url eq 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $zonefiles{$action_key}{'url'})) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$action_key}{'remark'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $remark;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_zonefiles_save_conf();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Entry was changed and needs to be 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> recreated, preserve status
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $enabled = $zonefiles{$action_key} 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {'enabled'};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Remove from rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless &_action_zf_remove();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Add new entry to rpz-config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($enabled eq 'on') {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = &General::system('/usr/sbin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config', 'add', $name, $url, '--no- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Check for errors, request service 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload on success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_check_result($result, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Add to global data hash and save changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my %entry = ('enabled' => $enabled,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'url' => $url,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + 'remark' => $remark);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $zonefiles{$name} = \%entry;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_zonefiles_save_conf();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Save custom lists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_cl_save {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless((defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'ALLOW_LIST'}) && (defined 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'BLOCK_LIST'}));
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $result = 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my @allowlist = split(/\R/, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'ALLOW_LIST'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my @blocklist = split(/\R/, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $cgiparams{'BLOCK_LIST'});
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Validate lists
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_validate_customlist(\@allowlist);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($result != 0) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $errormessage = &_rpz_error_tr(202, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $result);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_validate_customlist(\@blocklist);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($result != 0) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $errormessage = &_rpz_error_tr(203, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $result);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Add to global data hash and save changes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'allow'}{'list'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \@allowlist;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'block'}{'list'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \@blocklist;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'allow'}{'enabled'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (defined $cgiparams{'ALLOW_ENABLED'}) ? 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on' : 'off';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $customlists{'block'}{'enabled'} = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (defined $cgiparams{'BLOCK_ENABLED'}) ? 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'on' : 'off';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_customlists_save_conf();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_customlist_export('allow', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $RPZ_ALLOWLIST);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &_customlist_export('block', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $RPZ_BLOCKLIST);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Make new lists, request service 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reload on success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $result = &General::system('/usr/sbin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-make', 'allowblock', '--no-reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return unless 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &_rpz_check_result($result, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Trigger rpz-config reload
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_rpz_reload {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1 unless &_rpz_needs_reload();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Immediately clear flag to prevent 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> multiple reloads
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(-f $RPZ_RELOAD_FLAG) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unlink($RPZ_RELOAD_FLAG) or die "Can't 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remove $RPZ_RELOAD_FLAG: $!";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Perform reload, recreate reload flag 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> on error to enable retry
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $result = &General::system('/usr/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sbin/rpz-config', 'reload');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(not &_rpz_check_result($result, 0)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &General::system('touch', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "$RPZ_RELOAD_FLAG");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Trigger unbound restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _action_unb_restart {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1 unless &_rpz_needs_reload();
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Immediately clear flag to prevent 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> multiple restarts
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(-f $RPZ_RELOAD_FLAG) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unlink($RPZ_RELOAD_FLAG) or die "Can't 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remove $RPZ_RELOAD_FLAG: $!";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Perform restart, unboundctrl always 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> exits zero
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &General::system('/usr/local/bin/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unboundctrl', 'restart');
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Internal rpz-config functions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Translate rpz-config exitcodes and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> messages
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# 100-199: rpz-config, 200-299: webgui
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _rpz_error_tr {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($error, $append) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $append //= '';
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Translate numeric exit codes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(looks_like_number($error)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(defined $Lang::tr{"rpz exitcode 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $error"}) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $error = $Lang::tr{"rpz exitcode $error"};
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return "RPZ $Lang::tr{'error'}: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $error" . &Header::escape($append);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Check result of rpz-config system 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> call, request reload on success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _rpz_check_result {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($result, $request_reload) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $request_reload //= 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # exitcode 0 = success
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($result != 0) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $errormessage = &_rpz_error_tr($result);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Set reload flag
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($request_reload) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + &General::system('touch', 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "$RPZ_RELOAD_FLAG");
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Test whether reload flag is set
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _rpz_needs_reload {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return (-f $RPZ_RELOAD_FLAG);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Validate a zonefile entry, returns 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz-config exitcode on failure. Use 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _rpz_check_result to verify.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# unique = check for unique name
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _rpz_validate_zonefile {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($name, $url, $remark, $unique) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $unique //= 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unless($name =~ /^[a-zA-Z0-9_]{1,32}$/) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 101;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unless($url =~ /^[\w+\.:;\/\\&@#%?=\- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ~|!]{1,128}$/) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 105;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unless($remark =~ /^[\w \-()\.:;*\/\\?! 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &=]{0,32}$/) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 201;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Check against already existing names
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if($unique) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $existing (keys %zonefiles) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if(lc($name) eq lc($existing)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 104;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Validate a custom list, returns number 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of rejected line on failure. Check for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> non-zero results.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# listref = array reference, cleanup = 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remove invalid entries instead of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> returning an error
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _rpz_validate_customlist {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my ($listref, $cleanup) = @_;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $cleanup //= 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + foreach my $index (reverse 0.. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $#{$listref}) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $row = @$listref[$index];
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + next unless($row); # Skip/allow empty 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> lines
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Reject/remove everything besides 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wildcard domains and remarks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + if((not 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &General::validwildcarddomainname($row)) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> && (not $row =~ /^;[\w \-()\.:;*\/\\?! 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &=]*$/)) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + unless($cleanup) {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # +1 for user friendly line number and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to ensure non-zero exitcode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return $index + 1;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Remove current row
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + splice(@$listref, $index, 1);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + return 0;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###--- Internal misc functions ---###
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Send HTTP 303 redirect headers for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> post/request/get pattern
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (Must be sent before calling 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &Header::showhttpheaders())
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +sub _http_prg_redirect {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + my $location = "https:// 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $ENV{'SERVER_NAME'}: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $ENV{'SERVER_PORT'}$ENV{'SCRIPT_NAME'}";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print "Status: 303 See Other\n";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + print "Location: $location\n";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/lfs/rpz b/lfs/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..7ddbc38e5
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/lfs/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,96 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Definitions
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +include Config
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +SUMMARY = response policy zone - RPZ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reputation system for unbound DNS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +VER = 1.0.0
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +THISAPP = rpz-$(VER)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +DIR_APP = $(DIR_SRC)/$(THISAPP)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +TARGET = $(DIR_INFO)/$(THISAPP)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +PROG = rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +PAK_VER = 18
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +DEPS =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +SERVICES =
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Top-level Rules
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +install : $(TARGET)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +check :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +download :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +b2 :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +dist:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + @$(PAK)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Installation Details
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +$(TARGET) :
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + @$(PREBUILD)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + @rm -rf $(DIR_APP)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # RPZ scripts
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + install --verbose --mode=755 \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $(DIR_CONF)/rpz/{rpz-config,rpz- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> metrics,rpz-sleep,rpz-make,rpz-functions} \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --target-directory=/usr/sbin
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # RPZ config files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + mkdir -pv /etc/unbound/local.d
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + install --verbose --mode=644 -- 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> owner=nobody --group=nobody \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + $(DIR_CONF)/rpz/00-rpz.conf \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --target-directory=/etc/unbound/local.d
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chown --verbose --recursive 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nobody:nobody /etc/unbound/local.d
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # RPZ custom list files for allow and 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> block
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + mkdir -pv /var/ipfire/dns/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + touch /var/ipfire/dns/rpz/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> {allowlist,blocklist}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chown --verbose --recursive 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nobody:nobody /var/ipfire/dns/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # RPZ zone files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # create empty RPZ config file to avoid 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> a unbound config error
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + mkdir -pv /etc/unbound/zonefiles
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + touch /etc/unbound/zonefiles/allow.rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + chown --verbose --recursive 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nobody:nobody /etc/unbound/zonefiles
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Install addon-specific language-files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + install --verbose --mode=004 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $(DIR_CONF)/rpz/rpz.*.pl \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + --target-directory=/var/ipfire/addon-lang
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + # Install backup definition
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + cp -vf $(DIR_CONF)/backup/includes/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rpz /var/ipfire/backup/addons/includes/rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + @rm -rf $(DIR_APP)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + @$(POSTBUILD)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/make.sh b/make.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 827ea9e77..a77535b13 100755
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- a/make.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/make.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -390,7 +390,7 @@ prepareenv() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  if [ "${free_space}" -lt 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${required_space}" ]; then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  # Add any consumed space
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  while read -r consumed_space path; do
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  - (( free_space += consumed_space / 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1024 / 1024 ))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + (( free_space += consumed_space / 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1024 / 1024 ))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  done <<< "$(du --summarize --bytes 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${BUILD_DIR}" "${IMAGES_DIR}" 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "${LOG_DIR}" 2>/dev/null)"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  fi
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -2087,6 +2087,7 @@ build_system() {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfsmake2 btrfs-progs
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfsmake2 inotify-tools
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfsmake2 grub-btrfs
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + lfsmake2 rpz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfsmake2 linux
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  lfsmake2 rtl8812au
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/src/paks/rpz/install.sh b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> src/paks/rpz/install.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..ef99bf742
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/src/paks/rpz/install.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,36 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +. /opt/pakfire/lib/functions.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +extract_files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +restore_backup ${NAME}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# fix user created files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +chown --verbose --recursive nobody:nobody \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /var/ipfire/dns/rpz \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /etc/unbound/zonefiles \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /etc/unbound/local.d
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Update Language cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/usr/local/bin/update-lang-cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# restart unbound to load config file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/init.d/unbound restart
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/src/paks/rpz/uninstall.sh b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> src/paks/rpz/uninstall.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..e11427df3
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/src/paks/rpz/uninstall.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,38 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +. /opt/pakfire/lib/functions.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# stop unbound to delete RPZ conf file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/init.d/unbound stop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +make_backup ${NAME}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +remove_files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# delete rpz config files. Otherwise 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound will throw error:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# "[1723428668] unbound-control[17117:0] 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> error: connect: Connection refused for 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 127.0.0.1 port 8953"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/bin/rm --verbose --force /etc/unbound/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> local.d/*.rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Update Language cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/usr/local/bin/update-lang-cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# start unbound to load unbound config file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/init.d/unbound start
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  diff --git a/src/paks/rpz/update.sh b/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> src/paks/rpz/update.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  new file mode 100644
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  index 000000000..9bc340bc6
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --- /dev/null
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +++ b/src/paks/rpz/update.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @@ -0,0 +1,52 @@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#!/bin/bash
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# IPFire.org - A linux based firewall #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Copyright (C) 2024 IPFire Team 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <info@ipfire.org> #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is free software: you can 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> redistribute it and/or modify #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# it under the terms of the GNU General 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Public License as published by #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# the Free Software Foundation, either 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> version 3 of the License, or #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# (at your option) any later version. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# This program is distributed in the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hope that it will be useful, #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# but WITHOUT ANY WARRANTY; without even 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the implied warranty of #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# MERCHANTABILITY or FITNESS FOR A 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PARTICULAR PURPOSE. See the #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# GNU General Public License for more 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> details. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# You should have received a copy of the 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> GNU General Public License #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# along with this program. If not, see 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <http://www.gnu.org/licenses/>. #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# #
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +###############################################################################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +. /opt/pakfire/lib/functions.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# from update.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +extract_backup_includes
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# stop unbound to delete RPZ conf file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/init.d/unbound stop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# from uninstall.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +make_backup ${NAME}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +remove_files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# delete rpz config files. Otherwise 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unbound will throw error:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# "unbound-control[nn:0] error: connect: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Connection refused for 127.0.0.1 port 8953"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/bin/rm --verbose --force /etc/unbound/ 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> local.d/*.rpz.conf
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# from install.sh
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +extract_files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +restore_backup ${NAME}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# fix user created files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +chown --verbose --recursive nobody:nobody \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /var/ipfire/dns/rpz \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /etc/unbound/zonefiles \
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  + /etc/unbound/local.d
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# Update Language cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/usr/local/bin/update-lang-cache
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +# restart unbound to load config files
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  +/etc/init.d/unbound start
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  2.39.5
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Jon
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  --
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  Jon Murphy
>>>>>>>>>>>>>>>>>>>>>>>>>>>>  jon.murphy@ipfire.org
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>   Jon
>>>>>>>>>>>>>>>>>>>>>>>>>>  --
>>>>>>>>>>>>>>>>>>>>>>>>>>  Jon Murphy
>>>>>>>>>>>>>>>>>>>>>>>>>>  jon.murphy@ipfire.org
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>>
>>
>>
> 



  reply	other threads:[~2025-08-06  7:31 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-06 16:35 Jon Murphy
2025-02-06 19:35 ` Bernhard Bitsch
2025-02-06 20:13 ` Michael Tremer
2025-02-08 18:41   ` jon
2025-02-08 19:27     ` Michael Tremer
     [not found]       ` <C28A0D7E-6C16-4F6F-9366-A8498F40631E@ipfire.org>
2025-02-14 12:07         ` Michael Tremer
2025-02-14 12:58           ` Bernhard Bitsch
2025-02-14 13:52             ` Michael Tremer
2025-02-14 14:16               ` Bernhard Bitsch
2025-03-01 10:18           ` Adolf Belka
     [not found]             ` <3BF29525-C9F4-4FD2-834D-FBE791E99E8C@ipfire.org>
2025-03-02 10:51               ` Adolf Belka
2025-03-10 17:47                 ` jon
2025-03-16 17:00         ` Jon Murphy
2025-03-17 10:35           ` Michael Tremer
2025-03-19  2:58             ` Jon Murphy
2025-03-19 10:35               ` Michael Tremer
2025-03-19 18:22                 ` Jon Murphy
     [not found]                 ` <afcb2a99-1281-43e3-bd3d-d915024683f6@ipfire.org>
2025-03-20 16:26                   ` Michael Tremer
2025-03-24  0:00                     ` Re[2]: " Jon Murphy
2025-03-24 10:17                       ` Michael Tremer
2025-03-24 13:33                         ` Bernhard Bitsch
2025-03-24 14:25                           ` Michael Tremer
2025-03-24 14:33                             ` Re[2]: " Jon Murphy
2025-03-24 14:36                               ` Michael Tremer
2025-03-24 14:38                                 ` Re[2]: " Jon Murphy
2025-03-24 14:40                                   ` Michael Tremer
2025-03-24 14:42                                     ` Re[2]: " Jon Murphy
2025-03-24 14:43                                       ` Michael Tremer
2025-05-20 16:30                                         ` Re[2]: " Jon Murphy
2025-05-22 15:40                                           ` Michael Tremer
2025-05-22 15:42                                             ` Re[2]: " Jon Murphy
2025-05-22 15:43                                               ` Michael Tremer
2025-05-22 15:45                                                 ` Re[2]: " Jon Murphy
2025-05-22 15:46                                                   ` Michael Tremer
2025-05-22 19:45                                                     ` Re[2]: " Jon Murphy
2025-05-23 10:35                                                       ` Michael Tremer
2025-08-05 16:53                                                         ` Re[2]: " Jon Murphy
2025-08-06  7:31                                                           ` Bernhard Bitsch [this message]
2025-08-06 12:32                                                           ` Bernhard Bitsch
2025-08-07  8:17                                                             ` Michael Tremer
2025-08-07  9:18                                                               ` Bernhard Bitsch
2025-08-07 13:40                                                                 ` Michael Tremer
2025-08-07 14:55                                                                   ` Bernhard Bitsch
2025-08-07 18:03                                                                     ` Michael Tremer
2025-08-07  8:17                                                           ` Michael Tremer
2025-03-24 14:49                                 ` Bernhard Bitsch
2025-03-24 14:41                             ` Bernhard Bitsch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2007f4fa-4c26-4e72-8d1b-b991584e03c8@ipfire.org \
    --to=bbitsch@ipfire.org \
    --cc=development@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox