AlertPowerMT        syncLMS-Multi-MikroTik-PPPoE        syncLMS-Multi-MikroTik-SimpleQueues        syncLMS-Multi-MikroTik-Nat       

inne

 

jak wdrożyć ustawę hazardową 2017 w sieci ISP (Mikrotik, Bind, Dnsmasq, PowerDNS)

   26-04-2017 18:00:00      19-05-2024 00:00:00       Odwiedziny: 12139

Aktualizacja [2024-03-01]
- skrypt z przeznaczeniem dla PowerDNS od Marka z amelek.net

Aktualizacja [2022-02-18]
- naprawienie problemu w skrypcie dla BIND`a z domenami, które mają w nazwie '_' [podkreślenie]

Aktualizacja [2018-11-01]
- wyeliminowanie problemu z DNS-em powodowanym przez występowanie w domenach znaków specyficznych dla krajów - IDN

Aktualizacja [2017-07-04]
- w strefie było zbyt długie TTL (7 dni) zmieniono na 2 godziny w hazardBind

Aktualizacja [2017-06-29]
- błędna kolejność IP oraz Domeny w hazardDNSMasq,
- brak nowej linii w $zoneNew po IP MF w hazardBind

Aktualizacja [2017-06-28]
- dodano Lp (hazardMikrotik, hazardBind oraz hazardDNSMasq),
- dodano generowanie kodu inne dla Mikrotik RouterOS v5 oraz v6 (hazardMikrotik)


Dz.U. 2017 poz. 88 (Ustawa z dnia 15 grudnia 2016 r. o zmianie ustawy o grach hazardowych oraz niektórych innych ustaw)
Z dniem 1 lipca 2017r. przedsiębiorca telekomunikacyjny świadczący usługi dostępu do sieci Internet jest obowiązany do:
  • nieodpłatnego uniemożliwienia dostępu do stron internetowych wykorzystujących nazwy domen internetowych wpisanych do Rejestru poprzez ich usunięcie z systemów teleinformatycznych przedsiębiorców telekomunikacyjnych, służących do zamiany nazw domen internetowych na adresy IP, nie później niż w ciągu 48 godzin od dokonania wpisu do Rejestru;
  • nieodpłatnego przekierowania połączeń odwołujących się do nazw domen internetowych wpisanych do Rejestru do strony internetowej prowadzonej przez ministra właściwego do spraw finansów publicznych, zawierającej komunikat, skierowany do odbiorców usługi dostępu do Internetu obejmujący w szczególności informacje o lokalizacji Rejestru, wpisaniu szukanej nazwy domeny internetowej do tego Rejestru, listę podmiotów legalnie oferujących gry hazardowe na terytorium Rzeczypospolitej Polskiej, a także powiadomienie o grożącej odpowiedzialności karno-skarbowej uczestnika gier urządzanych wbrew przepisom ustawy;
  • nieodpłatnego umożliwienia dostępu do stron internetowych wykorzystujących nazwy domen wykreślonych z Rejestru, nie później niż w ciągu 48 godzin od wykreślenia nazwy domeny internetowej z Rejestru.

źródło isap.sejm.gov.pl


Polecam obejrzeć relacje z iNET Meeting 2017, rozmowa chyba z prawnikiem:
https://www.facebook.com/inetgroup/videos/1407249126009025/


Rejestr Domen Służących do Oferowania Gier Hazardowych Niezgodnie z Ustawą: https://hazard.mf.gov.pl
Adres na który należy kierować połączenia: 145.237.235.240

Skrypty pisane są pod Debiana 8, ale nie znaczy to że nie będą działać na innych systemach.
Do uruchomiena jest wymagany perl oraz moduły perlowe: XML::Simple, LWP::UserAgent, IO::Socket::SSL, POSIX, Net::IDN::Encode.
Instalacja Debian: apt-get install libxml-simple-perl libnet-idn-encode-perl
Wykorzystując skrypt dla Mikrotika dodatkowo jest potrzebny serwer WWW, poprzez który Mikrotik pobierze plik z liniami kodu.

Konfiguracja dla RouterOS by Mikrotik:
Stwórz pliki:
touch /opt/hazardMikrotik.pl
touch /etc/cron.d/hazardMikrotik
touch /var/www/mikrotik5.rsc
touch /var/www/mikrotik6.rsc
touch /var/www/date.txt
Do pliku /opt/hazardMikrotik.pl dodaj (ew. zmień pod siebie "USTAWIENIA"):
#!/usr/bin/perl
use XML::Simple;
use LWP::UserAgent;
use IO::Socket::SSL;
use POSIX qw(strftime);
use Net::IDN::Encode ':all';

## www.kazuko.pl
## hazardMikrotik v0.4 [2018-11-30]


## START ## USTAWIENIA

my $urlHazardXML = "https://hazard.mf.gov.pl/api/Register";    # baza stron hazardowych
my $addressIP = "145.237.235.240";                             # adres IP na który mają być kierowane zapytania 
my $pathFile5 = "/var/www/mikrotik5.rsc";                      # ścieżka do pliku z transkodem dla mikrotika v5.xx
my $pathFile6 = "/var/www/mikrotik6.rsc";                      # ścieżka do pliku z transkodem dla mikrotika v6.xx
my $pathFileDate = "/var/www/date.txt";                        # ścieżka do pliku, w którym jest data ostatniej aktualizacji
my $runCommend = "";                                           # komenda która będzie uruchamiana, jeśli zostanie coś zmodyfikowane w bazie stron

## KONIEC ## USTAWIENIA



my $ua = LWP::UserAgent->new;
$ua->default_header('Accept-Language' => "pl");
$ua->ssl_opts(%{{'verify_hostname' => 0, 'SSL_verify_mode' => SSL_VERIFY_NONE}});

my $response = $ua->get($urlHazardXML);

   if($response->is_success) {
	my $xml = new XML::Simple;
	$data = $xml->XMLin($response->content);

	my $dataNew5  = "/ip dns static remove [find comment~\"# hazard\"]\n";
	   $dataNew5 .= "/ip dns static\n";
	my $dataNew6  = "/ip dns static remove [find comment~\"# hazard\"]\n";
	   $dataNew6 .= "/ip dns static\n";
	my %isAdd;
	   foreach my $domain (@{$data->{'PozycjaRejestru'}}) {
		my $domena = domain_to_ascii($domain->{'AdresDomeny'});

		   if(!$isAdd{$domena}) { 
			   if($domain->{'DataWykreslenia'}) {
				$dataNew5 .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\n";
				$dataNew5 .= "add name=\"$domena\" address=\"$addressIP\" disabled=yes comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\";\n\n";

				$dataNew6 .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\n";
				$dataNew6 .= ":do { add name=\"$domena\" address=\"$addressIP\" disabled=yes comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\"; } on-error={ set [find name=\"$domena\"] address=\"$addressIP\" disabled=yes comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\"; }\n\n";
			   } else {
				$dataNew5 .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."\n";
				$dataNew5 .= "add name=\"$domena\" address=\"$addressIP\" disabled=no comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."\";\n\n";

				$dataNew6 .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."\n";
				$dataNew6 .= ":do { add name=\"$domena\" address=\"$addressIP\" disabled=no comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."\"; } on-error={ set [find name=\"$domena\"] address=\"$addressIP\" disabled=no comment=\"# hazard # Lp: ".$domain->{'Lp'}." # dodano: ".$domain->{'DataWpisu'}."\"; }\n\n";
			   }
			$isAdd{$domena} = $domena;
		   }
	   }
	$dataNew5 =~ s/^\s+//;
	$dataNew5 =~ s/\s+$//;
	$dataNew6 =~ s/^\s+//;
	$dataNew6 =~ s/\s+$//;


	my $dataOld5 = "";
	   if(-e $pathFile5) {
		open(UCHWYT, $pathFile5);
		  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $dataOld5 .= $row; } }
		close (UCHWYT);
		$dataOld5 =~ s/^\s+//;
		$dataOld5 =~ s/\s+$//;
	   }

	my $dataOld6 = "";
	   if(-e $pathFile6) {
		open(UCHWYT, $pathFile6);
		  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $dataOld6 .= $row; } }
		close (UCHWYT);
		$dataOld6 =~ s/^\s+//;
		$dataOld6 =~ s/\s+$//;
	   }

	   if($dataOld5 ne $dataNew5 or $dataOld6 ne $dataNew6) {
		my $date = strftime('%d-%m-%Y %H:%M:%S',localtime(time));
		open(UCHWYT, '>', $pathFile5) or die "Nie można otworzyć $pathFile5: $!"; 
		print UCHWYT "## Ostatnia aktualizacja: $date\n\n".$dataNew5;
		close UCHWYT;
		#system("chown root:root $pathFile5 1> /dev/null 2> /dev/null");

		my $date = strftime('%d-%m-%Y %H:%M:%S',localtime(time));
		open(UCHWYT, '>', $pathFile6) or die "Nie można otworzyć $pathFile6: $!"; 
		print UCHWYT "## Ostatnia aktualizacja: $date\n\n".$dataNew6;
		close UCHWYT;
		#system("chown root:root $pathFile6 1> /dev/null 2> /dev/null");

		   if($pathFileDate) {
			open(UCHWYT, '>', $pathFileDate) or die "Nie można otworzyć $pathFileDate: $!"; 
			print UCHWYT $date;
			close UCHWYT;
			#system("chown root:root $pathFileDate 1> /dev/null 2> /dev/null");
		   }

		   if($runCommend) { system($runCommend); }
	   }

   } else {
	print STDERR "Error: ".$response->status_line."\n";
   }
Do pliku /etc/cron.d/hazardMikrotik dodaj:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 */2 * * *   root    perl /opt/hazardMikrotik.pl
Aby sprawdzić poprawność działania, wklej poniższą line w terminalu:
perl /opt/hazardMikrotik.pl
Wklej poniższe linie kodu w terminalu Mikrotik`a:
http://hazard.domena.pl - zmień na swoją
## Włącz cache DNS na mikrotiku:
/ip dns set allow-remote-requests=yes


## Zablokuj możliwość korzystania z cache DNS dla hostów nie będących w Twojej sieci 
## Jeśli nie będzie blokady, Mikrotik może zostać wykorzystany do ataków DDoS
## Zmień na własny: INTERFEJS_WANOWY
/ip firewall filter 
 add action=drop chain=input dst-port=53 protocol=udp in-interface=INTERFEJS_WANOWY


## Skrypt aktualizujący wpisy w cache DNS`ie dla Mikrotika RouterOS v5.xx
/system script
add name=ustawa-hazardowa policy=read,write,policy,test source=":global hazardUpdateOld\r\
    \n/tool fetch url=\"http://hazard.domena.pl/date.txt\" mode=http dst-path=\"/hazardUpdate.txt\"\r\
    \n:delay 2\r\
    \n:local hazardUpdateNew [/file get hazardUpdate.txt contents];\r\
    \n/file remove hazardUpdate.txt\r\
    \n\r\
    \n   :if (\"\$hazardUpdateNew\" != \"\$hazardUpdateOld\" and \"\$hazardUpdateNew\" != \"\") do={\r\
    \r\
    \n\t/tool fetch url=\"http://hazard.domena.pl/mikrotik5.rsc\" mode=http dst-path=\"/hazardUpdate.rs\
    c\"\r\
    \n\t/import hazardUpdate.rsc\r\
    \n\t:delay 2\r\
    \n\t/file remove hazardUpdate.rsc\r\
    \n\t:set hazardUpdateOld \$hazardUpdateNew\r\
    \n   }\r\
    \n"

## Skrypt aktualizujący wpisy w cache DNS`ie dla Mikrotika RouterOS v6.xx
/system script
add name=ustawa-hazardowa policy=read,write,policy,test source=":global hazardUpdateOld\r\
    \n/tool fetch url=\"http://hazard.domena.pl/date.txt\" mode=http dst-path=\"/hazardUpdate.txt\"\r\
    \n:delay 2\r\
    \n:local hazardUpdateNew [/file get hazardUpdate.txt contents];\r\
    \n/file remove hazardUpdate.txt\r\
    \n\r\
    \n   :if (\"\$hazardUpdateNew\" != \"\$hazardUpdateOld\" and \"\$hazardUpdateNew\" != \"\") do={\r\
    \r\
    \n\t/tool fetch url=\"http://hazard.domena.pl/mikrotik6.rsc\" mode=http dst-path=\"/hazardUpdate.rs\
    c\"\r\
    \n\t/import hazardUpdate.rsc\r\
    \n\t:delay 2\r\
    \n\t/file remove hazardUpdate.rsc\r\
    \n\t:set hazardUpdateOld \$hazardUpdateNew\r\
    \n   }\r\
    \n"

## Uruchamianie skryptu aktualizującego wpisy w cache DNS`ie co 12 godzin:
/system scheduler
add interval=12h name=ustawa-hazardowa on-event="/system script run ustawa-hazardowa\r\
    \n" policy=read,write,policy,test start-date=apr/01/2017 start-time=22:10:00
Aby wymusić pobranie wpisów należy usunąć hazardUpdateOld z system > script > environment
/system script environment remove hazardUpdateOld



Konfiguracja dla BIND`a:
Do pliku /etc/bind/named.conf dodaj:
include "/etc/bind/named.conf.hazard-redirect";
Stwórz pliki:
touch /opt/hazardBind.pl
touch /etc/cron.d/hazardBind
touch /etc/bind/named.conf.hazard-redirect
touch /etc/bind/db.hazard-redirect
Do pliku /opt/hazardBind.pl dodaj (ew. zmień pod siebie "USTAWIENIA"):
#!/usr/bin/perl
use XML::Simple;
use LWP::UserAgent;
use IO::Socket::SSL;
use POSIX qw(strftime);
use Net::IDN::Encode ':all';

## www.kazuko.pl
## hazardBind v0.7 [2022-02-18]


## START ## USTAWIENIA

my $urlHazardXML = "https://hazard.mf.gov.pl/api/Register";             # baza stron hazardowych
my $addressIP = "145.237.235.240";                                      # adres IP na który mają być kierowane zapytania 
my $pathFile = "/etc/bind/named.conf.hazard-redirect";                  # ścieżka do pliku, w której będą domeny hazardowe
my $pathFileZone = "/etc/bind/db.hazard-redirect";                      # ścieżka do pliku ze strefą dla domen hazardowych
my $runCommend = "/etc/init.d/bind9 reload 1> /dev/null 2> /dev/null";  # komenda która będzie uruchamiana, jeśli zostanie coś zmodyfikowane w bazie stron

## KONIEC ## USTAWIENIA



my $ua = LWP::UserAgent->new;
$ua->default_header('Accept-Language' => "pl");
$ua->ssl_opts(%{{'verify_hostname' => 0, 'SSL_verify_mode' => SSL_VERIFY_NONE}});

my $response = $ua->get($urlHazardXML);

   if($response->is_success) {
	my $xml = new XML::Simple;
	$data = $xml->XMLin($response->content);

	my $dataNew = "";
	my %isAdd;
	   foreach my $domain (@{$data->{'PozycjaRejestru'}}) {
		my $domena = domain_to_ascii($domain->{'AdresDomeny'});

           if(!$isAdd{$domena}) { 
               if($domain->{'DataWykreslenia'}) {
                $dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\n";
                $dataNew .= "# zone \"$domena\" { type master; file \"$pathFileZone\"; ".($domena =~ /\_/ ? "check-names ignore; " : "")."};\n\n";
               } else {
                $dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."\n";
                $dataNew .= "zone \"$domena\" { type master; file \"$pathFileZone\"; ".($domena =~ /\_/ ? "check-names ignore; " : "")."};\n\n";
               }
            $isAdd{$domena} = $domena;
           }
	   }
	$dataNew =~ s/^\s+//;
	$dataNew =~ s/\s+$//;

	my $dataOld = "";
	   if(-e $pathFile) {
		open(UCHWYT, $pathFile);
		  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $dataOld .= $row; } }
		close (UCHWYT);
		$dataOld =~ s/^\s+//;
		$dataOld =~ s/\s+$//;
	   }

	   if($dataOld ne $dataNew) {
		open(UCHWYT, '>', $pathFile) or die "Nie można otworzyć $pathFile: $!"; 
		print UCHWYT "## Ostatnia aktualizacja: ".strftime('%d-%m-%Y %H:%M:%S',localtime(time))."\n\n".$dataNew;
		close UCHWYT;
		#system("chown root:root $pathFile 1> /dev/null 2> /dev/null");
		   if($runCommend) { system($runCommend); }
	   }

	   if($pathFileZone) {
		my $zoneNew = "\$TTL    7200\n";
		   $zoneNew .= "@       IN      SOA     localhost. root.localhost. (\n";
		   $zoneNew .= "                              1         ; Serial\n";
		   $zoneNew .= "                         604800         ; Refresh\n";
		   $zoneNew .= "                          86400         ; Retry\n";
		   $zoneNew .= "                        2419200         ; Expire\n";
		   $zoneNew .= "                         604800 )       ; Negative Cache TTL\n";
		   $zoneNew .= "@       IN      NS      localhost.\n";
		   $zoneNew .= "@       IN      A       $addressIP\n";

		my $zoneOld = "";
		   if(-e $pathFileZone) {
			open(UCHWYT, $pathFileZone);
			  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $zoneOld .= $row; } }
			close (UCHWYT);
			$zoneOld =~ s/^\s+//;
			$zoneOld =~ s/\s+$//;
		   }

		   if($zoneOld ne $zoneNew) {
			open(UCHWYT, '>', $pathFileZone) or die "Nie można otworzyć $pathFileZone: $!"; 
			print UCHWYT $zoneNew;
			close UCHWYT;
			#system("chown root:root $pathFileZone 1> /dev/null 2> /dev/null");
		   }
	   }

   } else {
	print STDERR "Error: ".$response->status_line."\n";
   }
Do pliku /etc/cron.d/hazardBind dodaj:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 */2 * * *   root    perl /opt/hazardBind.pl
Aby sprawdzić poprawność działania, wklej poniższą line w terminalu:
perl /opt/hazardBind.pl



Konfiguracja dla Dnsmasq`a:
Do pliku /etc/dnsmasq.conf dodaj (lub z edytuj):
addn-hosts=/etc/dnsmasq_hosts_hazard-redirect
Stwórz pliki:
touch /opt/hazardDNSMasq.pl
touch /etc/cron.d/hazardDNSMasq
touch /etc/dnsmasq_hosts_hazard-redirect
Do pliku /opt/hazardDNSMasq.pl dodaj (ew. zmień pod siebie "USTAWIENIA"):
#!/usr/bin/perl
use XML::Simple;
use LWP::UserAgent;
use IO::Socket::SSL;
use POSIX qw(strftime);
use Net::IDN::Encode ':all';

## www.kazuko.pl
## hazardDNSMasq v0.5 [2018-11-30]


## START ## USTAWIENIA

my $urlHazardXML = "https://hazard.mf.gov.pl/api/Register";                # baza stron hazardowych
my $addressIP = "145.237.235.240";                                         # adres IP na który mają być kierowane zapytania 
my $pathFile = "/etc/dnsmasq_hosts_hazard-redirect";                       # ścieżka do pliku, w której będą domeny hazardowe
my $runCommend = "/etc/init.d/dnsmasq restart 1> /dev/null 2> /dev/null";  # komenda która będzie uruchamiana, jeśli zostanie coś zmodyfikowane w bazie stron

## KONIEC ## USTAWIENIA



my $ua = LWP::UserAgent->new;
$ua->default_header('Accept-Language' => "pl");
$ua->ssl_opts(%{{'verify_hostname' => 0, 'SSL_verify_mode' => SSL_VERIFY_NONE}});

my $response = $ua->get($urlHazardXML);

   if($response->is_success) {
	my $xml = new XML::Simple;
	$data = $xml->XMLin($response->content);

	my $dataNew = "";
	my %isAdd;
	   foreach my $domain (@{$data->{'PozycjaRejestru'}}) {
		my $domena = domain_to_ascii($domain->{'AdresDomeny'});

		   if(!$isAdd{$domena}) {
			   if($domain->{'DataWykreslenia'}) {
				$dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\n";
				$dataNew .= "# $addressIP $domena\n\n";
			   } else {
				$dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."\n";
				$dataNew .= "$addressIP $domena\n\n";
			   }
			$isAdd{$domena} = $domena;
		   }
	   }
	$dataNew =~ s/^\s+//;
	$dataNew =~ s/\s+$//;

	my $dataOld = "";
	   if(-e $pathFile) {
		open(UCHWYT, $pathFile);
		  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $dataOld .= $row; } }
		close (UCHWYT);
		$dataOld =~ s/^\s+//;
		$dataOld =~ s/\s+$//;
	   }

	   if($dataOld ne $dataNew) {
		open(UCHWYT, '>', $pathFile) or die "Nie można otworzyć $pathFile: $!"; 
		print UCHWYT "## Ostatnia aktualizacja: ".strftime('%d-%m-%Y %H:%M:%S',localtime(time))."\n\n".$dataNew;
		close UCHWYT;
		#system("chown root:root $pathFile 1> /dev/null 2> /dev/null");
		   if($runCommend) { system($runCommend); }
	   }

   } else {
	print STDERR "Error: ".$response->status_line."\n";
   }
Do pliku /etc/cron.d/hazardDNSMasq dodaj:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 */2 * * *   root    perl /opt/hazardDNSMasq.pl
Aby sprawdzić poprawność działania, wklej poniższą line w terminalu:
perl /opt/hazardDNSMasq.pl



Konfiguracja dla PowerDNS`a by Markek z amelek.net:
Obecnie jako cache DNS dla klientów używam PowerDNS (pdns-recursor 4.8.6-1, Debian 12.5 jako VM pod xcp-ng).
Mam 2 takie serwery, tak samo skonfigurowane, w 2 różnych lokalizacjach dla redundancji.
Skrypt jest zmodyfikowaną wersją dla dnsmasq (ten sam format pliku zgodny z /etc/hosts).
W /etc/powerdns/recursor.conf zmieniamy ustawienia:
allow-from-file=/etc/powerdns/allow-from
etc-hosts-file=/var/cache/pdns/hosts.hazard-redirect
export-etc-hosts=on
local-address=0.0.0.0
socket-mode=0664

W /etc/powerdns/allow-from umieszczamy listę kto może korzystać z DNS, na końcu przykładowe moje prefiksy:
127.0.0.0/8
10.0.0.0/8
192.168.0.0/16
172.16.0.0/12
100.64.0.0/10
::1/128
fe80::/10
91.224.224.0/23
185.38.220.0/22
2a04:7840::/29

Zwykłego użytkownika dodajemy do grupy "pdns" by pozwolić na przeładowanie bez uprawnień root-a (socket-mode 0664 pozwala tej grupie).
Tworzymy katalog /var/cache/pdns z uprawnieniami 0775 zapisywalny dla grupy "pdns" gdzie skrypt będzie zapisywał pliki.
W crontab użytkownika (mój przykładowy "marekm", edycja poleceniem "crontab -e") wpisujemy uruchomienie skryptu:

# m h dom mon dow command
59 */2 * * * /home/marekm/bin/hazard-update.pl
#!/usr/bin/perl
use XML::Simple;
use LWP::UserAgent;
use IO::Socket::SSL;
use POSIX qw(strftime);
use Net::IDN::Encode ':all';

## www.kazuko.pl
## hazardPowerDNS v0.1 [2024-03-01] by Markek z amelek.net

## START ## USTAWIENIA

my $urlHazardXML = "https://hazard.mf.gov.pl/api/Register";                # baza stron hazardowych
my $addressIP = "145.237.235.240";                                         # adres IP na który mają być kierowane zapytania
my $pathFile = "/var/cache/pdns/hosts.hazard-redirect";                       # ścieżka do pliku, w której będą domeny hazardowe
my $pathFileTmp = $pathFile . ".new";
my $pathFileOld = $pathFile . ".old";
my $runCommend = "rec_control reload-zones";  # komenda która będzie uruchamiana, jeśli zostanie coś zmodyfikowane w bazie stron

## KONIEC ## USTAWIENIA

my $ua = LWP::UserAgent->new;
$ua->default_header('Accept-Language' => "pl");
$ua->ssl_opts(%{{'verify_hostname' => 0, 'SSL_verify_mode' => SSL_VERIFY_NONE}});

my $response = $ua->get($urlHazardXML);

   if($response->is_success) {
	my $xml = new XML::Simple;
	$data = $xml->XMLin($response->content);

	my $dataNew = "";
	my %isAdd;
	   foreach my $domain (@{$data->{'PozycjaRejestru'}}) {
		my $domena = domain_to_ascii($domain->{'AdresDomeny'});

		   if(!$isAdd{$domena}) {
			   if($domain->{'DataWykreslenia'}) {
				$dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."   # wykreslono: ".$domain->{'DataWykreslenia'}."\n";
				$dataNew .= "# $addressIP $domena\n\n";
			   } else {
				$dataNew .= "# Lp: ".$domain->{'Lp'}."   # dodano: ".$domain->{'DataWpisu'}."\n";
				$dataNew .= "$addressIP $domena\n\n";
			   }
			$isAdd{$domena} = $domena;
		   }
	   }
	$dataNew =~ s/^\s+//;
	$dataNew =~ s/\s+$//;

	my $dataOld = "";
	   if(-e $pathFile) {
		open(UCHWYT, $pathFile);
		  while (my $row = <UCHWYT>) { if(!($row =~ /^##\sOstatnia\saktualizacja/)) { $dataOld .= $row; } }
		close (UCHWYT);
		$dataOld =~ s/^\s+//;
		$dataOld =~ s/\s+$//;
	   }

	   if($dataOld ne $dataNew) {
		open(UCHWYT, '>', $pathFileTmp) or die "Nie można otworzyć $pathFileTmp: $!";
		print UCHWYT "## Ostatnia aktualizacja: ".strftime('%FT%T',localtime(time))."\n\n".$dataNew;
		close UCHWYT;
		unlink($pathFileOld);
		link($pathFile, $pathFileOld);
		rename($pathFileTmp, $pathFile) or die "rename $pathFileTmp $pathFile: $!";
		if($runCommend) { system($runCommend); }
	   }

   } else {
	print STDERR "Error: ".$response->status_line."\n";
   }


Copyright seszu © 30.10.2010-2024.