@@ -570,75 +570,84 @@ def manage_dns(mode, dns_server=False):
570570
571571 if mode == "leak_protection" :
572572 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 ()} " )
585580 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 )
622630
623631 elif mode == "restore" :
624632 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 ):
626635
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 ())
631640
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." )
637646
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" )
642651 else :
643652 raise Exception ("Invalid argument provided. "
644653 "Mode must be 'restore' or 'leak_protection'" )
0 commit comments