Created
February 5, 2017 06:53
-
-
Save mgregoro/9f3bc8eec382ab06e0aa9e2bab1ccbff to your computer and use it in GitHub Desktop.
convenience script for starting openvpn and update resolv.conf based on what was PUSHed by the server; handy on the *BSDs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
unless ($> == 0) { | |
die "Must run ovpn.pl as root!\n"; | |
} | |
unless ($ARGV[0]) { | |
die "Usage: ovpn.pl <conf-file-in-cwd>\n"; | |
} | |
my $conf_file = $ARGV[0]; | |
if ($conf_file =~ /\//) { | |
die "[fatal] must run ovpn.pl from the config directory\n"; | |
} | |
if ($conf_file =~ "random(?:-([A-Z]{2}))*") { | |
my (@confs, $country); | |
if ($country = $1) { | |
@confs = glob("ipvanish-$country*.ovpn"); | |
} else { | |
@confs = glob("*.ovpn"); | |
} | |
if (scalar(@confs) == 0) { | |
if ($country) { | |
die "[fatal] couldn't find any configs in country '$country' to choose from\n"; | |
} else { | |
die "[fatal] couldn't find any configs to choose from\n"; | |
} | |
} | |
my $chosen_idx; | |
my $rolls = int(rand(int($#confs / 8))); | |
for (my $i = 0; $i < $rolls; $i++) { | |
$chosen_idx = int(rand($#confs)); | |
} | |
# the last roll is the config | |
$conf_file = $confs[$chosen_idx]; | |
print "[random] randomly chose $conf_file\n"; | |
} | |
my $perl_pid = $$; | |
my $dns_servers = []; | |
$SIG{ALRM} = sub { | |
return unless $$ == $perl_pid; | |
if (scalar(@$dns_servers)) { | |
print "@{[scalar localtime]} automatically generating resolv.conf from vpn PUSHed values\n"; | |
system("mv -f /etc/resolv.conf /tmp/resolv.conf.$$.ovpnorig"); | |
open my $rc, '>', '/etc/resolv.conf' or die "Can't open /etc/resolv.conf for writing: $!\n"; | |
print $rc "# resolv.conf autogenerated by ovpn.pl at @{[scalar localtime ]}\n"; | |
while (my $ns = shift @$dns_servers) { | |
print $rc "nameserver $ns\n"; | |
} | |
} else { | |
warn "@{[scalar localtime]} - warning - dns_servers array was empty\n"; | |
} | |
}; | |
# clean up. | |
$SIG{INT} = $SIG{KILL} = $SIG{TERM} = \&cleanup; | |
# open VPN after signal handlers are installed. | |
open my $fh, '-|', "openvpn --config $conf_file"; | |
while (my $line = <$fh>) { | |
if ($line =~ /PUSH:/) { | |
@dns_servers = (); | |
while ($line =~ /dhcp-option DNS ([\d\.]+)/g) { | |
push(@$dns_servers, $1); | |
} | |
alarm 3; | |
} | |
print "$line"; | |
} | |
# openvpn died, clean up. | |
cleanup(); | |
sub cleanup { | |
return unless $$ == $perl_pid; | |
if (-e "/tmp/resolv.conf.$$.ovpnorig") { | |
print STDOUT "@{[scalar localtime]} - exiting - restoring original resolv.conf\n"; | |
system("mv -f /tmp/resolv.conf.$$.ovpnorig /etc/resolv.conf"); | |
exit; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment