@@ -554,75 +554,84 @@ def manage_dns(mode, dns_server=False):
554
554
555
555
if mode == "leak_protection" :
556
556
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 ()} " )
569
564
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 )
606
614
607
615
elif mode == "restore" :
608
616
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 ):
610
619
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 ())
615
624
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." )
621
630
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" )
626
635
else :
627
636
raise Exception ("Invalid argument provided. "
628
637
"Mode must be 'restore' or 'leak_protection'" )
0 commit comments