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