@@ -570,75 +570,84 @@ def manage_dns(mode, dns_server=False):
570
570
571
571
if mode == "leak_protection" :
572
572
logger .debug ("Leak Protection initiated" )
573
- # Restore original resolv.conf if it exists
574
- if os .path .isfile (backupfile ):
575
- logger .debug ("resolv.conf.backup exists" )
576
- manage_dns ("restore" )
577
- # Check for custom DNS Server
578
- if not int (get_config_value ("USER" , "dns_leak_protection" )):
579
- if get_config_value ("USER" , "custom_dns" ) == "None" :
580
- logger .debug ("DNS Leak Protection is disabled" )
581
- return
582
- else :
583
- dns_server = get_config_value ("USER" , "custom_dns" )
584
- logger .debug ("Using custom DNS" )
573
+ if shutil .which ("resolvectl" ) and os .path .islink ("/etc/resolv.conf" ):
574
+ logger .debug ("Running resolvectl command for leak_protection" )
575
+ cmd_args = ["resolvectl" , "dns" , "proton0" , dns_server ]
576
+ pipes = subprocess .Popen (cmd_args , stderr = subprocess .PIPE )
577
+ _ , std_err = pipes .communicate ()
578
+ if pipes .returncode != 0 :
579
+ raise Exception (f"{ ' ' .join (cmd_args )} failed with code { pipes .returncode } -> { std_err .strip ()} " )
585
580
else :
586
- logger .debug ("DNS Leak Protection is enabled" )
587
- # Make sure DNS Server has been provided
588
- if not dns_server :
589
- raise Exception ("No DNS Server has been provided." )
590
-
591
- shutil .copy2 (resolvconf_path , backupfile )
592
- logger .debug ("{0} (resolv.conf) backed up" .format (resolvconf_path ))
593
-
594
- # Remove previous nameservers
595
- dns_regex = re .compile (r"^nameserver .*$" )
596
-
597
- with open (backupfile , 'r' ) as backup_handle :
598
- with open (resolvconf_path , 'w' ) as resolvconf_handle :
599
- for line in backup_handle :
600
- if not dns_regex .search (line ):
601
- resolvconf_handle .write (line )
602
-
603
- logger .debug ("Removed existing DNS Servers" )
604
-
605
- # Add ProtonVPN managed DNS Server to resolv.conf
606
- dns_server = dns_server .split ()
607
- with open (resolvconf_path , "a" ) as f :
608
- f .write ("# ProtonVPN DNS Servers. Managed by ProtonVPN-CLI.\n " )
609
- for dns in dns_server [:3 ]:
610
- f .write ("nameserver {0}\n " .format (dns ))
611
- logger .debug ("Added ProtonVPN or custom DNS" )
612
-
613
- # Write the hash of the edited file in the configuration
614
- #
615
- # This is so it doesn't restore an old DNS configuration
616
- # if the configuration changes during a VPN session
617
- # (e.g. by switching networks)
618
-
619
- with open (resolvconf_path , "rb" ) as f :
620
- filehash = zlib .crc32 (f .read ())
621
- set_config_value ("metadata" , "resolvconf_hash" , filehash )
581
+ # Restore original resolv.conf if it exists
582
+ if os .path .isfile (backupfile ):
583
+ logger .debug ("resolv.conf.backup exists" )
584
+ manage_dns ("restore" )
585
+ # Check for custom DNS Server
586
+ if not int (get_config_value ("USER" , "dns_leak_protection" )):
587
+ if get_config_value ("USER" , "custom_dns" ) == "None" :
588
+ logger .debug ("DNS Leak Protection is disabled" )
589
+ return
590
+ else :
591
+ dns_server = get_config_value ("USER" , "custom_dns" )
592
+ logger .debug ("Using custom DNS" )
593
+ else :
594
+ logger .debug ("DNS Leak Protection is enabled" )
595
+ # Make sure DNS Server has been provided
596
+ if not dns_server :
597
+ raise Exception ("No DNS Server has been provided." )
598
+
599
+ shutil .copy2 (resolvconf_path , backupfile )
600
+ logger .debug ("{0} (resolv.conf) backed up" .format (resolvconf_path ))
601
+
602
+ # Remove previous nameservers
603
+ dns_regex = re .compile (r"^nameserver .*$" )
604
+
605
+ with open (backupfile , 'r' ) as backup_handle :
606
+ with open (resolvconf_path , 'w' ) as resolvconf_handle :
607
+ for line in backup_handle :
608
+ if not dns_regex .search (line ):
609
+ resolvconf_handle .write (line )
610
+
611
+ logger .debug ("Removed existing DNS Servers" )
612
+
613
+ # Add ProtonVPN managed DNS Server to resolv.conf
614
+ dns_server = dns_server .split ()
615
+ with open (resolvconf_path , "a" ) as f :
616
+ f .write ("# ProtonVPN DNS Servers. Managed by ProtonVPN-CLI.\n " )
617
+ for dns in dns_server [:3 ]:
618
+ f .write ("nameserver {0}\n " .format (dns ))
619
+ logger .debug ("Added ProtonVPN or custom DNS" )
620
+
621
+ # Write the hash of the edited file in the configuration
622
+ #
623
+ # This is so it doesn't restore an old DNS configuration
624
+ # if the configuration changes during a VPN session
625
+ # (e.g. by switching networks)
626
+
627
+ with open (resolvconf_path , "rb" ) as f :
628
+ filehash = zlib .crc32 (f .read ())
629
+ set_config_value ("metadata" , "resolvconf_hash" , filehash )
622
630
623
631
elif mode == "restore" :
624
632
logger .debug ("Restoring DNS" )
625
- if os .path .isfile (backupfile ):
633
+ if not (shutil .which ("resolvectl" ) and os .path .islink ("/etc/resolv.conf" )):
634
+ if os .path .isfile (backupfile ):
626
635
627
- # Check if the file changed since connection
628
- oldhash = get_config_value ("metadata" , "resolvconf_hash" )
629
- with open (resolvconf_path , "rb" ) as f :
630
- filehash = zlib .crc32 (f .read ())
636
+ # Check if the file changed since connection
637
+ oldhash = get_config_value ("metadata" , "resolvconf_hash" )
638
+ with open (resolvconf_path , "rb" ) as f :
639
+ filehash = zlib .crc32 (f .read ())
631
640
632
- if filehash == int (oldhash ):
633
- shutil .copy2 (backupfile , resolvconf_path )
634
- logger .debug ("resolv.conf restored from backup" )
635
- else :
636
- logger .debug ("resolv.conf changed. Not restoring." )
641
+ if filehash == int (oldhash ):
642
+ shutil .copy2 (backupfile , resolvconf_path )
643
+ logger .debug ("resolv.conf restored from backup" )
644
+ else :
645
+ logger .debug ("resolv.conf changed. Not restoring." )
637
646
638
- os .remove (backupfile )
639
- logger .debug ("resolv.conf.backup removed" )
640
- else :
641
- logger .debug ("No Backupfile found" )
647
+ os .remove (backupfile )
648
+ logger .debug ("resolv.conf.backup removed" )
649
+ else :
650
+ logger .debug ("No Backupfile found" )
642
651
else :
643
652
raise Exception ("Invalid argument provided. "
644
653
"Mode must be 'restore' or 'leak_protection'" )
0 commit comments