ovpn-key 0.7.1 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da769c59267c3c1bc605a2da314d55b0599e56de6e48dc25ef17ea56ed1af960
4
- data.tar.gz: eb106210d91f8e5ba367d20d94e72e74f27e1a53a8abd3cf58cf61fc7580f0fb
3
+ metadata.gz: 13681f4cf8c6abc0badce3feceacf4ce489daab4ff9ea7b177bdca7c3fe983ed
4
+ data.tar.gz: 621ad232db5032b90b1b631f7765dc15aca7b8131465bb2658408c13a7c1d8b0
5
5
  SHA512:
6
- metadata.gz: 44b34a49e1730f3c9bff11022fa63e8cf1426c85a6f737c84b68cafa50be8c4e05110202d40dc1e1bfbfda36d29df02003b6ebd07c489fa21a76dcd8afea8d94
7
- data.tar.gz: c4370cde04518bc151c64f2fb329718d68eed360080987807ed201103d55f999a84b0fcfd4d96634bc1124e96f419956b2c497046ab9bf957e55590e2882724c
6
+ metadata.gz: cc2d031bd9f8a595fa1efd862c2e5e371643928d34c7d7398db179466b655e48d412dd5494cfc6d705e614114846acbcce717b1117026df685bac5a4eb6e65b7
7
+ data.tar.gz: d31fd3d8936ab9bbd94daed1db9f2334925e073dfb9319d6d96aabfa1db566bd2f340144dd0190ee27ee2652d64ef70d59e6c0a6a1c63af6392dfdba0191073e
data/README.md CHANGED
@@ -12,9 +12,12 @@ It supports encrypting `.key` files with a passphrase (there is an option to dis
12
12
 
13
13
  It can be used with a non-self signed CA, just place your `ca.key` and `ca.crt` in the keys directory and skip the `--ca` step.
14
14
 
15
- It can be used to manage a non-OpenVPN CA, in that case `--zip` step will be useless, but all others will work.
15
+ It can be used to manage a non-OpenVPN CA, in that case `--zip` and `--static` steps will be useless, but all others will work.
16
16
 
17
- For now it should be considered experimental and rather undocumented.
17
+ OpenVPN static keys are supported partially, as they should be used for `tls-auth`/`tls-crypt` only.
18
+ Please note that they are not encrypted regardless of `--nopass` option.
19
+
20
+ For now this utility should be considered experimental and rather undocumented.
18
21
  If you're brave, [let me know](https://github.com/chillum/ovpn-key/issues), where the problems are.
19
22
 
20
23
  ### Installation
@@ -26,12 +29,14 @@ If you're brave, [let me know](https://github.com/chillum/ovpn-key/issues), wher
26
29
 
27
30
  1. `ovpn-key --init`
28
31
  2. edit `ovpn-key.yml` and `openssl.ini`
29
- 3. `ovpn-key --ca --dh --server --nopass`
30
- 4. `ovpn-key --client somebody`
31
- 5. `ovpn-key --revoke somebody`
32
- 6. add a file with `.ovpn` extension to the directory
32
+ 3. `ovpn-key --ca --dh`
33
+ 4. `ovpn-key --server --nopass`
34
+ 5. `ovpn-key --client somebody [--nopass]`
35
+ 6. `ovpn-key --revoke somebody`
36
+ 7. `ovpn-key --static` (generates `ta.key`)
37
+ 8. add a file with `.ovpn` extension to the directory
33
38
  it should contain every setting except for `cert` and `key`
34
- 7. `ovpn-key --zip somebody-else`
39
+ 9. `ovpn-key --zip somebody-else [--nopass]`
35
40
 
36
41
  ### Configuration
37
42
 
data/bin/ovpn-key CHANGED
@@ -1,76 +1,82 @@
1
1
  #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'optparse'
3
5
  require 'fileutils'
4
6
  require 'yaml'
5
7
  require 'zip'
6
- require_relative '../lib/version.rb'
7
- require_relative '../lib/functions.rb'
8
+ require_relative '../lib/version'
9
+ require_relative '../lib/functions'
8
10
 
9
11
  SSL_CONF = 'openssl.ini'
10
12
  APP_CONF = 'ovpn-key.yml'
11
13
 
12
14
  options = {}
13
15
  OptionParser.new do |opts|
14
- opts.banner = "Usage: #{File.basename $0} <options> [--nopass]"
15
- opts.on("--init [directory]", "Init a CA directory (defaults to current)") do |v|
16
- options[:init] = v ? v : "."
16
+ opts.banner = "Usage: #{File.basename $PROGRAM_NAME} <options> [--nopass]"
17
+ opts.on('--init [directory]', 'Init a CA directory (defaults to current)') do |v|
18
+ options[:init] = v || '.'
17
19
  end
18
- opts.on("--ca", "Generate a CA (ca.crt)") do |v|
20
+ opts.on('--ca', 'Generate a CA (ca.crt)') do |v|
19
21
  check_crt('ca')
20
22
  options[:generate_ca] = v
21
23
  end
22
- opts.on("--dh", "Generate a DH keyfile (dh.pem)") do |v|
23
- # it's safe to rewrite this file
24
+ opts.on('--dh', 'Generate a DH keyfile (dh.pem)') do |v|
25
+ # it's safe to overwrite this file
24
26
  options[:generate_dh] = v
25
27
  end
26
- opts.on("--server [name]", "Generate a server key (defaults to 'server')") do |v|
27
- options[:generate_server] = v ? v : "server"
28
+ opts.on('--static', 'Generate OpenVPN static key (ta.key)') do |v|
29
+ options[:generate_static] = v
30
+ check_crt('ta')
31
+ end
32
+ opts.on('--server [name]', "Generate a server key (defaults to 'server')") do |v|
33
+ options[:generate_server] = v || 'server'
28
34
  check_crt(options[:generate_server])
29
35
  end
30
- opts.on("--client [name]", "Generate a client key and sign it") do |v|
36
+ opts.on('--client [name]', 'Generate a client key and sign it') do |v|
31
37
  check_client(v)
32
38
  options[:generate_client] = v
33
39
  end
34
- opts.on("--zip [name]", "Ditto plus pack it to ZIP with OpenVPN config") do |v|
40
+ opts.on('--zip [name]', 'Ditto plus pack it to ZIP with OpenVPN config') do |v|
35
41
  check_client(v)
36
42
  options[:generate_zip] = v
37
43
  end
38
- opts.on("--revoke [name]", "Revoke a certificate (using crl.pem) and delete it") do |v|
39
- abort "Please specify what certificate to revoke" unless v
44
+ opts.on('--revoke [name]', 'Revoke a certificate (using crl.pem) and delete it') do |v|
45
+ abort 'Please specify what certificate to revoke' unless v
40
46
  options[:revoke] = v
41
47
  end
42
- opts.on("--nopass", "Don't protect .key files with a password") do |v|
48
+ opts.on('--nopass', "Don't protect .key files with a password") do |v|
43
49
  options[:no_password] = v
44
50
  end
45
51
  end.parse!
46
- if ARGV.length > 0
47
- abort "Error: invalid args: #{ARGV.join ' '}\nSee `#{File.basename $0} -h` for help"
52
+ if ARGV.length.positive?
53
+ abort "Error: invalid args: #{ARGV.join ' '}\nSee `#{File.basename $PROGRAM_NAME} -h` for help"
48
54
  end
49
- unless options[:init] || options[:generate_ca] || options[:generate_dh] || options[:generate_server] \
50
- || options[:generate_client] || options[:generate_zip] || options[:revoke]
51
- abort "See `#{File.basename $0} -h` for usage"
55
+ unless options[:init] || options[:generate_ca] || options[:generate_dh] || options[:generate_static] \
56
+ || options[:generate_server] || options[:generate_client] || options[:generate_zip] || options[:revoke]
57
+ abort "See `#{File.basename $PROGRAM_NAME} -h` for usage"
52
58
  end
53
- if options[:generate_client] and options[:generate_zip]
59
+ if options[:generate_client] && options[:generate_zip]
54
60
  # I assume that user likely wants one of them and is confused with usage
55
- abort "There can be only one: --client or --zip"
61
+ abort 'There can be only one: --client or --zip'
56
62
  end
57
- File.umask 0077
63
+ umask = File.umask 0o077
58
64
 
59
65
  if options[:init]
60
66
  unless options[:init] == '.'
61
67
  create_dir options[:init]
62
68
  Dir.chdir options[:init]
63
69
  end
64
- ['certs', 'meta'].each {|dir| create_dir dir}
70
+ %w[certs meta].each {|dir| create_dir dir}
65
71
  ['meta/index.txt', 'meta/index.txt.attr', 'meta/serial', SSL_CONF, APP_CONF].each {|file|
66
72
  unless File.exist? file
67
73
  FileUtils.copy_file(File.expand_path("defaults/#{file}", "#{__dir__}/.."), "./#{file}")
68
74
  puts "Created file: #{file}"
69
75
  end
70
76
  }
71
- elsif !File.exist? 'ovpn-key.yml'
77
+ elsif !File.exist? APP_CONF
72
78
  begin
73
- rc = YAML.load_file(File.expand_path '~/.ovpn-key.yml')
79
+ rc = YAML.load_file(File.expand_path("~/.#{APP_CONF}"))
74
80
  rescue Errno::ENOENT
75
81
  # no configuration file in home directory is not an error
76
82
  end
@@ -80,23 +86,28 @@ end
80
86
  begin
81
87
  settings = YAML.load_file(APP_CONF)
82
88
  rescue Errno::ENOENT
83
- abort "Run `#{File.basename $0} --init` before generating certificates"
89
+ abort "Run `#{File.basename $PROGRAM_NAME} --init` before generating certificates"
84
90
  end
85
91
  ZIP_DIR = settings['zip_dir'] || '~'
92
+ OPENVPN = settings['openvpn'] || 'openvpn'
86
93
  OPENSSL = settings['openssl'] || 'openssl'
87
- KEY_SIZE = settings['key_size'] || 2048
88
94
  ENCRYPT = settings['encrypt'] || 'aes128'
95
+ KEY_SIZE = settings['key_size'] || 2048
96
+ CA_DAYS = settings['ca_days'] || 3650
89
97
  CN_CA = settings['ca_name'] || 'Certification Authority'
90
98
  REQ = settings['details']
91
99
 
92
100
  if options[:generate_ca]
93
- gen_key('ca', 'ca', options[:no_password])
101
+ gen_key('ca', options[:no_password])
94
102
  sign_key('ca', 'ca', CN_CA)
95
103
  gen_crl
96
104
  end
97
105
  if options[:generate_dh]
98
106
  exe "#{OPENSSL} dhparam -out dh.pem #{KEY_SIZE}"
99
107
  end
108
+ if options[:generate_static]
109
+ exe "#{OPENVPN} --genkey --secret ta.key"
110
+ end
100
111
  if options[:generate_server]
101
112
  gen_and_sign('server', options[:generate_server], options[:no_password])
102
113
  end
@@ -109,27 +120,29 @@ if options[:generate_zip]
109
120
  when 1
110
121
  ovpn_file = ovpn_files.first
111
122
  when 0
112
- abort "No .ovpn file in current directory, please add one"
123
+ abort 'No .ovpn file in current directory, please add one'
113
124
  else
114
- abort "More than one .ovpn files in current directory, aborting"
125
+ abort 'More than one .ovpn files in current directory, aborting'
115
126
  end
116
127
 
117
128
  gen_and_sign('client', options[:generate_zip], options[:no_password])
118
129
 
119
130
  zip_file = File.join(File.expand_path(ZIP_DIR), "#{File.basename ovpn_file, '.ovpn'}.tblk.zip")
120
131
  File.delete(zip_file) if File.exist?(zip_file)
132
+ File.umask umask
121
133
  Zip::File.open(zip_file, Zip::File::CREATE) do |zip|
122
134
  zip.get_output_stream(ovpn_file) {|f|
123
135
  File.open(ovpn_file).each {|line| f.write line}
124
136
  f.write "cert #{options[:generate_zip]}.crt\nkey #{options[:generate_zip]}.key\n"
125
137
  }
126
- [ 'ca.crt', "#{options[:generate_zip]}.crt", "#{options[:generate_zip]}.key"].each {|i|
138
+ ['ca.crt', "#{options[:generate_zip]}.crt", "#{options[:generate_zip]}.key"].each {|i|
127
139
  zip.add(i, i)
128
140
  }
141
+ zip.add('ta.key', 'ta.key') if File.exist? 'ta.key'
129
142
  end
130
143
  end
131
144
  if options[:revoke]
132
145
  exe "#{OPENSSL} ca -revoke '#{options[:revoke]}.crt' -config #{SSL_CONF}"
133
146
  gen_crl
134
- ['crt', 'key'].each {|ext| File.delete "#{options[:revoke]}.#{ext}"}
147
+ %w[crt key].each {|ext| File.delete "#{options[:revoke]}.#{ext}"}
135
148
  end
data/defaults/meta/serial CHANGED
@@ -1 +1 @@
1
- 01
1
+ 00
data/defaults/openssl.ini CHANGED
@@ -1,7 +1,6 @@
1
1
  [req]
2
2
  default_md = sha256
3
3
  distinguished_name = dn.ovpn
4
- days = 3650
5
4
 
6
5
  [dn.ovpn]
7
6
  CN = Certificate name (required)
@@ -1,6 +1,8 @@
1
1
  zip_dir: '~'
2
+ openvpn: openvpn
2
3
  openssl: openssl
3
- key_size: 2048
4
4
  encrypt: aes128
5
+ key_size: 2048
6
+ ca_days: 3650
5
7
  ca_name: Certification Authority
6
8
  details: /C=US/ST=CA/L=San Francisco/O=Dva Debila/OU=OpenVPN
data/lib/functions.rb CHANGED
@@ -1,34 +1,36 @@
1
- def check_crt filename
2
- ['key', 'crt'].each {|ext|
1
+ # frozen_string_literal: true
2
+
3
+ def check_crt(filename)
4
+ %w[key crt].each {|ext|
3
5
  abort "#{filename}.#{ext} already exists, exiting" if File.exist? "#{filename}.#{ext}"
4
6
  }
5
7
  end
6
8
 
7
- def check_client name
8
- abort "Error: client should have an alphanumeric name" unless name
9
+ def check_client(name)
10
+ abort 'Error: client should have an alphanumeric name' unless name
9
11
  check_crt(name)
10
12
  end
11
13
 
12
- def exe cmd
14
+ def exe(cmd)
13
15
  system(cmd) or abort "error executing: #{cmd}"
14
16
  end
15
17
 
16
- def gen_and_sign type, certname, no_password
17
- gen_key(type, certname, no_password)
18
+ def gen_and_sign(type, certname, no_password)
19
+ gen_key(certname, no_password)
18
20
  sign_key(type, certname, certname)
19
21
  end
20
22
 
21
- def gen_key type, certname, no_password
23
+ def gen_key(certname, no_password)
22
24
  if no_password
23
- exe "#{OPENSSL} genrsa -out '#{certname}.key' #{KEY_SIZE} -config #{SSL_CONF} -extensions ext.#{type}"
25
+ exe "#{OPENSSL} genrsa -out '#{certname}.key' #{KEY_SIZE}"
24
26
  else
25
- exe "#{OPENSSL} genrsa -#{ENCRYPT} -out '#{certname}.key' #{KEY_SIZE} -config #{SSL_CONF} -extensions ext.#{type}"
27
+ exe "#{OPENSSL} genrsa -#{ENCRYPT} -out '#{certname}.key' #{KEY_SIZE}"
26
28
  end
27
29
  end
28
30
 
29
- def sign_key type, certname, cn
31
+ def sign_key(type, certname, cn)
30
32
  if certname == 'ca'
31
- exe "#{OPENSSL} req -new -x509 -key '#{certname}.key' -out '#{certname}.crt' -config #{SSL_CONF} -subj '/CN=#{cn}#{REQ}' -extensions ext.#{type}"
33
+ exe "#{OPENSSL} req -new -x509 -key '#{certname}.key' -out '#{certname}.crt' -config #{SSL_CONF} -subj '/CN=#{cn}#{REQ}' -extensions ext.#{type} -days #{CA_DAYS}"
32
34
  else
33
35
  exe "#{OPENSSL} req -new -key '#{certname}.key' -out '#{certname}.csr' -config #{SSL_CONF} -subj '/CN=#{cn}#{REQ}' -extensions ext.#{type}"
34
36
  exe "#{OPENSSL} ca -in '#{certname}.csr' -out '#{certname}.crt' -config #{SSL_CONF} -extensions ext.#{type} -batch"
@@ -40,9 +42,9 @@ def gen_crl
40
42
  exe "#{OPENSSL} ca -gencrl -out crl.pem -config #{SSL_CONF}"
41
43
  end
42
44
 
43
- def create_dir name
44
- unless Dir.exist? name
45
- Dir.mkdir name
46
- puts "Created directory: #{name}"
47
- end
45
+ def create_dir(name)
46
+ return if Dir.exist? name
47
+
48
+ Dir.mkdir name
49
+ puts "Created directory: #{name}"
48
50
  end
data/lib/version.rb CHANGED
@@ -1 +1,3 @@
1
- ::Version = '0.7.1'
1
+ # frozen_string_literal: true
2
+
3
+ ::VERSION = '0.7.7'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ovpn-key
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasily Korytov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-09 00:00:00.000000000 Z
11
+ date: 2021-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -16,16 +16,17 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.2'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.2'
27
- description: ''
28
- email: vasily.korytov@icloud.com
26
+ version: '2.0'
27
+ description: Generates and revokes certificates, also packs them to ZIP files with
28
+ OpenVPN configuration
29
+ email: v.korytov@outlook.com
29
30
  executables:
30
31
  - ovpn-key
31
32
  extensions: []
@@ -45,7 +46,7 @@ homepage: https://github.com/chillum/ovpn-key
45
46
  licenses:
46
47
  - Apache-2.0
47
48
  metadata: {}
48
- post_install_message:
49
+ post_install_message:
49
50
  rdoc_options: []
50
51
  require_paths:
51
52
  - lib
@@ -53,16 +54,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
54
  requirements:
54
55
  - - ">="
55
56
  - !ruby/object:Gem::Version
56
- version: '2.0'
57
+ version: '2.4'
57
58
  required_rubygems_version: !ruby/object:Gem::Requirement
58
59
  requirements:
59
60
  - - ">="
60
61
  - !ruby/object:Gem::Version
61
62
  version: '0'
62
63
  requirements: []
63
- rubyforge_project:
64
- rubygems_version: 2.7.6
65
- signing_key:
64
+ rubygems_version: 3.2.3
65
+ signing_key:
66
66
  specification_version: 4
67
67
  summary: Key management utility for OpenVPN
68
68
  test_files: []