Skip to content

Instantly share code, notes, and snippets.

@andersonvom
Last active November 4, 2015 17:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andersonvom/6a5966cdc3691b0dca63 to your computer and use it in GitHub Desktop.
Save andersonvom/6a5966cdc3691b0dca63 to your computer and use it in GitHub Desktop.
Connect to two OpenVPNs in sequence where the first one uses token auth
creds.yml
*.ovpn
*.crt

Connect to two OpenVPNs sequentially

  1. The first VPN must be the one that uses token auth.
  2. Fill out creds.yml with your correct information; you can use the creds.yml.example file as instructions and starting point.
  3. Change its permissions to 0600: chmod 0600 creds.yml
  4. Add your .ovpn and certificate files to this directory.
  5. Run ruby connect.rb

You'll be prompted for your SUDO password (depending on your environment) and your OATH token. The script will connect to both VPNs sequentially and, at the end, will display information on how to view logs and disconnect.

#!/usr/bin/env ruby
require 'logger'
require 'tempfile'
require 'timeout'
require 'yaml'
OPENVPN_BIN = '/usr/local/sbin/openvpn'
SYSTEM_LOG = '/var/log/system.log'
LOG_PATTERN = /Initialization Sequence Completed/
WAIT_TIMEOUT = 120
LOG = Logger.new(STDOUT)
def wait_for_log_pattern(file, pattern, timeout)
LOG.info "Waiting for connection to complete..."
f = File.open(file, "r")
f.seek(0, IO::SEEK_END)
Timeout::timeout(timeout) {
while true do
select([f])
line = f.gets
if line
LOG.debug line.chomp
break if line =~ pattern
end
end
}
end
def connect(vpn)
creds_file = Tempfile.new 'creds'
creds_file.chmod(0600)
begin
vpn_name = vpn[:vpn_name]
creds_file.puts vpn[:user]
creds_file.puts vpn[:pwd]
creds_file.flush
LOG.info "Connecting to #{vpn_name}..."
`sudo #{OPENVPN_BIN} --config #{vpn[:config_file]} --auth-user-pass #{creds_file.path} --daemon #{vpn_name}`
ensure
creds_file.close
creds_file.unlink
end
wait_for_log_pattern(SYSTEM_LOG, LOG_PATTERN, WAIT_TIMEOUT)
end
def openvpn_pids
`ps -A | grep openvpn | awk '{print $1}'`.gsub("\n", " ")
end
def get_auth_token
print "Enter your OATH token: "
`stty -echo`
oath_token = STDIN.gets.chomp
`stty echo`
puts
oath_token
end
def disconnect
`sudo killall openvpn`
end
def main
disconnect
# cache sudo password
puts "If prompted, enter your SUDO password..."
`sudo ls`
oath_token = get_auth_token
# load creds and add oath token to pin
vpns = YAML::load(open("creds.yml"))
vpns[0][:pwd] += oath_token
begin
vpns.each do |vpn|
connect(vpn)
end
rescue Timeout::Error
disconnect
end
grep_pattern = vpns.map { |vpn| "-e #{vpn[:vpn_name]}" }.join " "
LOG.info "To view logs: tail -f #{SYSTEM_LOG} | grep " + grep_pattern
LOG.info "To disconnect: sudo kill #{openvpn_pids}"
end
if __FILE__ == $0
log_level = ARGV.first == '--debug' ? Logger::DEBUG : Logger::INFO
LOG.level = log_level
main
end
# make sure this file has 0600 permissions
---
- :vpn_name: "anything_you_want_1"
:user: "employee_id"
:pwd: "oath_pin"
:config_file: "ovpn_config_file_1"
- :vpn_name: "anything_you_want_2"
:user: "email_address"
:pwd: "password"
:config_file: "ovpn_config_file_2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment