ovpn-key 0.7.1 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -7
- data/bin/ovpn-key +46 -33
- data/defaults/meta/serial +1 -1
- data/defaults/openssl.ini +0 -1
- data/defaults/ovpn-key.yml +3 -1
- data/lib/functions.rb +19 -17
- data/lib/version.rb +3 -1
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13681f4cf8c6abc0badce3feceacf4ce489daab4ff9ea7b177bdca7c3fe983ed
|
4
|
+
data.tar.gz: 621ad232db5032b90b1b631f7765dc15aca7b8131465bb2658408c13a7c1d8b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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`
|
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
|
-
|
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
|
30
|
-
4. `ovpn-key --
|
31
|
-
5. `ovpn-key --
|
32
|
-
6.
|
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
|
-
|
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
|
7
|
-
require_relative '../lib/functions
|
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 $
|
15
|
-
opts.on(
|
16
|
-
options[:init] = 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(
|
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(
|
23
|
-
# it's safe to
|
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(
|
27
|
-
options[:
|
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(
|
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(
|
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(
|
39
|
-
abort
|
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(
|
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
|
47
|
-
abort "Error: invalid args: #{ARGV.join ' '}\nSee `#{File.basename $
|
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[:
|
50
|
-
|| options[:generate_client] || options[:generate_zip] || options[:revoke]
|
51
|
-
abort "See `#{File.basename $
|
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]
|
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
|
61
|
+
abort 'There can be only one: --client or --zip'
|
56
62
|
end
|
57
|
-
File.umask
|
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
|
-
[
|
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?
|
77
|
+
elsif !File.exist? APP_CONF
|
72
78
|
begin
|
73
|
-
rc = YAML.load_file(File.expand_path
|
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 $
|
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',
|
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
|
123
|
+
abort 'No .ovpn file in current directory, please add one'
|
113
124
|
else
|
114
|
-
abort
|
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
|
-
[
|
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
|
-
[
|
147
|
+
%w[crt key].each {|ext| File.delete "#{options[:revoke]}.#{ext}"}
|
135
148
|
end
|
data/defaults/meta/serial
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
00
|
data/defaults/openssl.ini
CHANGED
data/defaults/ovpn-key.yml
CHANGED
data/lib/functions.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
|
-
|
2
|
-
|
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
|
8
|
-
abort
|
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
|
14
|
+
def exe(cmd)
|
13
15
|
system(cmd) or abort "error executing: #{cmd}"
|
14
16
|
end
|
15
17
|
|
16
|
-
def gen_and_sign
|
17
|
-
gen_key(
|
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
|
23
|
+
def gen_key(certname, no_password)
|
22
24
|
if no_password
|
23
|
-
exe "#{OPENSSL} genrsa -out '#{certname}.key' #{KEY_SIZE}
|
25
|
+
exe "#{OPENSSL} genrsa -out '#{certname}.key' #{KEY_SIZE}"
|
24
26
|
else
|
25
|
-
exe "#{OPENSSL} genrsa -#{ENCRYPT} -out '#{certname}.key' #{KEY_SIZE}
|
27
|
+
exe "#{OPENSSL} genrsa -#{ENCRYPT} -out '#{certname}.key' #{KEY_SIZE}"
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
def sign_key
|
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
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
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.
|
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:
|
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: '
|
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: '
|
27
|
-
description:
|
28
|
-
|
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.
|
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
|
-
|
64
|
-
|
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: []
|