ovpn-key 0.4
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 +7 -0
- data/NOTICE +15 -0
- data/README.md +46 -0
- data/bin/ovpn-key +133 -0
- data/defaults/meta/index.txt +0 -0
- data/defaults/meta/index.txt.attr +1 -0
- data/defaults/meta/serial +1 -0
- data/defaults/openssl.ini +49 -0
- data/defaults/ovpn-key.yml +6 -0
- data/lib/functions.rb +38 -0
- data/lib/version.rb +1 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 87d20925cbb4231873b06d213c5cb1b3e47f428d5c349449288b778b0b1fcf38
|
4
|
+
data.tar.gz: fbd4b0f7700bc6c103728b412478a0cbaf7adb5c80cbefa7178ccc00abb9e47b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8e90c6313d933c5298c9c170b7eedeb06fbe5045575aae3dd985c6aad38bb6e7a6b83d2375247d5946bab40aa408c057b18e9d2a1fa474f04fbd60929f8d0db0
|
7
|
+
data.tar.gz: b9d7a14f848837c59c6810985211d9f43c89a7d79b5a4d7bd4305c84f60bf3c3adf119178eb3836c2d9ea56e562235cdf7264201e8e4aaa2b49920df05e59f25
|
data/NOTICE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
ovpn-key: https://github.com/chillum/ovpn-key
|
2
|
+
|
3
|
+
Copyright 2018 Vasily Korytov
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this software except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## ovpn-key: key management for OpenVPN [](http://badge.fury.io/rb/ovpn-key)
|
2
|
+
|
3
|
+
This utility is designed as [easy-rsa](https://github.com/OpenVPN/easy-rsa) replacement suitable for one exact use case.
|
4
|
+
|
5
|
+
It's basically a wrapper around `openssl` to:
|
6
|
+
* create a self-signed CA
|
7
|
+
* create client and server certificates and pack them to ZIP files along with the OpenVPN config
|
8
|
+
* revoke the certificates
|
9
|
+
* create a DH keyfile
|
10
|
+
|
11
|
+
It supports encrypting `.key` files with a passphrase (there is an option to disable that).
|
12
|
+
|
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
|
+
|
15
|
+
For now it should be considered experimental and rather undocumented.
|
16
|
+
If you're brave, [let me know](https://github.com/chillum/ovpn-key/issues), where the problems are.
|
17
|
+
|
18
|
+
### Installation
|
19
|
+
|
20
|
+
1. Get [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
|
21
|
+
2. Run `gem install ovpn-key`
|
22
|
+
|
23
|
+
### Usage
|
24
|
+
|
25
|
+
1. `ovpn-key --init`
|
26
|
+
2. edit `ovpn-key.yml` and `openssl.ini`
|
27
|
+
3. `ovpn-key --ca --dh --server --nopass`
|
28
|
+
4. add a file with `.ovpn` extension to the directory
|
29
|
+
it should contain every setting except for `cert` and `key`
|
30
|
+
5. `ovpn-key --client somebody`
|
31
|
+
6. `ovpn-key --revoke somebody`
|
32
|
+
|
33
|
+
### Configuration
|
34
|
+
|
35
|
+
Most of configuration is done in `open-vpn.key` and `openssl.ini` files in the directory.
|
36
|
+
|
37
|
+
ovpn-key also processes `~/.ovpn-key.yml` file, for now it has only one possible setting:
|
38
|
+
```yaml
|
39
|
+
dir: ~/some/path
|
40
|
+
```
|
41
|
+
|
42
|
+
This setting is used as a default directory if:
|
43
|
+
1. current directory does not have a `ovpn-key.yml`
|
44
|
+
2. `--init` is not specified
|
45
|
+
|
46
|
+
If you specify the default directory, you don't need to travel to it every time you want to launch `ovpn-key`, i.e. you can use it from your home directory or any other, as long as requirements above are met.
|
data/bin/ovpn-key
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'yaml'
|
5
|
+
require 'zip'
|
6
|
+
require_relative '../lib/version.rb'
|
7
|
+
require_relative '../lib/functions.rb'
|
8
|
+
|
9
|
+
SSL_CONF = 'openssl.ini'
|
10
|
+
APP_CONF = 'ovpn-key.yml'
|
11
|
+
|
12
|
+
options = {}
|
13
|
+
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
|
+
if v
|
17
|
+
options[:init] = v
|
18
|
+
else
|
19
|
+
options[:init] = "."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
opts.on("--ca", "Generate a CA (ca.crt)") do |v|
|
23
|
+
check_crt('ca')
|
24
|
+
options[:generate_ca] = v
|
25
|
+
end
|
26
|
+
opts.on("--dh", "Generate a DH keyfile (dh.pem)") do |v|
|
27
|
+
options[:generate_dh] = v
|
28
|
+
end
|
29
|
+
opts.on("--server [name]", "Generate a server key (defaults to 'server')") do |v|
|
30
|
+
if v
|
31
|
+
options[:generate_server] = v
|
32
|
+
else
|
33
|
+
options[:generate_server] = "server"
|
34
|
+
end
|
35
|
+
check_crt(options[:generate_server])
|
36
|
+
end
|
37
|
+
opts.on("--client [name]", "Generate a client key and pack it to ZIP") do |v|
|
38
|
+
abort "Error: client should have an alphanumeric name" unless v
|
39
|
+
check_crt(v)
|
40
|
+
options[:generate_client] = v
|
41
|
+
end
|
42
|
+
opts.on("--revoke [name]", "Revoke a certificate (using crl.pem) and delete it") do |v|
|
43
|
+
abort "Please specify what certificate to revoke" unless v
|
44
|
+
options[:revoke] = v
|
45
|
+
end
|
46
|
+
opts.on("--nopass", "Don't protect .key files with a password") do |v|
|
47
|
+
options[:no_password] = v
|
48
|
+
end
|
49
|
+
end.parse!
|
50
|
+
if ARGV.length > 0
|
51
|
+
abort "Error: invalid args: #{ARGV.join ' '}\nSee `#{File.basename $0} -h` for help"
|
52
|
+
end
|
53
|
+
unless options[:init] || options[:generate_ca] || options[:generate_dh] \
|
54
|
+
|| options[:generate_server] || options[:generate_client] || options[:revoke]
|
55
|
+
abort "See `#{File.basename $0} -h` for usage"
|
56
|
+
end
|
57
|
+
File.umask 0077
|
58
|
+
|
59
|
+
if options[:init]
|
60
|
+
unless options[:init] == '.'
|
61
|
+
create_dir options[:init]
|
62
|
+
Dir.chdir options[:init]
|
63
|
+
end
|
64
|
+
['certs', 'meta'].each {|dir| create_dir dir}
|
65
|
+
['meta/index.txt', 'meta/index.txt.attr', 'meta/serial', SSL_CONF, APP_CONF].each {|file|
|
66
|
+
unless File.exist? file
|
67
|
+
FileUtils.copy_file(File.expand_path("defaults/#{file}", "#{__dir__}/.."), "./#{file}")
|
68
|
+
puts "Created file: #{file}"
|
69
|
+
end
|
70
|
+
}
|
71
|
+
elsif !File.exist? 'ovpn-key.yml'
|
72
|
+
begin
|
73
|
+
rc = YAML.load_file(File.expand_path '~/.ovpn-key.yml')
|
74
|
+
rescue Errno::ENOENT
|
75
|
+
end
|
76
|
+
Dir.chdir File.expand_path(rc['dir']) if rc && rc['dir']
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
settings = YAML.load_file(APP_CONF)
|
81
|
+
rescue Errno::ENOENT
|
82
|
+
abort "Run `#{File.basename $0} --init` before generating certificates"
|
83
|
+
end
|
84
|
+
ZIP_DIR = settings['zip_dir'] || '~'
|
85
|
+
OPENSSL = settings['openssl'] || 'openssl'
|
86
|
+
KEY_SIZE = settings['key_size'] || 2048
|
87
|
+
ENCRYPT = settings['encrypt'] || 'aes128'
|
88
|
+
REQ = settings['req']
|
89
|
+
CN_CA = settings['cn_ca'] || 'Certification Authority'
|
90
|
+
|
91
|
+
if options[:generate_ca]
|
92
|
+
genrsa('ca', 'ca', options[:no_password])
|
93
|
+
req('ca', 'ca', CN_CA)
|
94
|
+
gen_crl
|
95
|
+
end
|
96
|
+
if options[:generate_dh]
|
97
|
+
exe "#{OPENSSL} dhparam -out dh.pem #{KEY_SIZE}"
|
98
|
+
end
|
99
|
+
if options[:generate_server]
|
100
|
+
genrsa('server', options[:generate_server], options[:no_password])
|
101
|
+
req('server', options[:generate_server], options[:generate_server])
|
102
|
+
end
|
103
|
+
if options[:generate_client]
|
104
|
+
ovpn_files = Dir['*.ovpn']
|
105
|
+
case ovpn_files.length
|
106
|
+
when 1
|
107
|
+
ovpn_file = ovpn_files.first
|
108
|
+
when 0
|
109
|
+
abort "No .ovpn file in current directory, please add one"
|
110
|
+
else
|
111
|
+
abort "More than one .ovpn files in current directory, aborting"
|
112
|
+
end
|
113
|
+
|
114
|
+
genrsa('client', options[:generate_client], options[:no_password])
|
115
|
+
req('client', options[:generate_client], options[:generate_client])
|
116
|
+
|
117
|
+
zip_file = File.join(File.expand_path(ZIP_DIR), "#{File.basename ovpn_file, '.ovpn'}.tblk.zip")
|
118
|
+
File.delete(zip_file) if File.exist?(zip_file)
|
119
|
+
Zip::File.open(zip_file, Zip::File::CREATE) do |zip|
|
120
|
+
zip.get_output_stream(ovpn_file) {|f|
|
121
|
+
File.open(ovpn_file).each {|line| f.write line}
|
122
|
+
f.write "cert #{options[:generate_client]}.crt\nkey #{options[:generate_client]}.key\n"
|
123
|
+
}
|
124
|
+
[ 'ca.crt', "#{options[:generate_client]}.crt", "#{options[:generate_client]}.key"].each {|i|
|
125
|
+
zip.add(i, i)
|
126
|
+
}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
if options[:revoke]
|
130
|
+
exe "#{OPENSSL} ca -revoke '#{options[:revoke]}.crt' -config #{SSL_CONF}"
|
131
|
+
gen_crl
|
132
|
+
['crt', 'key'].each {|ext| File.delete "#{options[:revoke]}.#{ext}"}
|
133
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
unique_subject = yes
|
@@ -0,0 +1 @@
|
|
1
|
+
01
|
@@ -0,0 +1,49 @@
|
|
1
|
+
[req]
|
2
|
+
default_md = sha256
|
3
|
+
distinguished_name = dn.ovpn
|
4
|
+
days = 3650
|
5
|
+
|
6
|
+
[dn.ovpn]
|
7
|
+
CN = Certificate name (required)
|
8
|
+
|
9
|
+
[ca]
|
10
|
+
default_ca = ca.ovpn
|
11
|
+
|
12
|
+
[ca.ovpn]
|
13
|
+
default_md = sha256
|
14
|
+
private_key = ca.key
|
15
|
+
certificate = ca.crt
|
16
|
+
database = meta/index.txt
|
17
|
+
serial = meta/serial
|
18
|
+
crl = crl.pem
|
19
|
+
policy = policy.ovpn
|
20
|
+
# create this directory if changing this value
|
21
|
+
new_certs_dir = certs
|
22
|
+
default_days = 3650
|
23
|
+
default_crl_days = 3650
|
24
|
+
subjectKeyIdentifier = hash
|
25
|
+
authorityKeyIdentifier = keyid,issuer:always
|
26
|
+
|
27
|
+
[ext.ca]
|
28
|
+
basicConstraints = CA:true
|
29
|
+
|
30
|
+
[ext.server]
|
31
|
+
basicConstraints = CA:false
|
32
|
+
nsCertType = server
|
33
|
+
extendedKeyUsage = serverAuth
|
34
|
+
keyUsage = digitalSignature, keyEncipherment
|
35
|
+
|
36
|
+
[ext.client]
|
37
|
+
basicConstraints = CA:false
|
38
|
+
extendedKeyUsage = clientAuth
|
39
|
+
keyUsage = digitalSignature
|
40
|
+
|
41
|
+
[policy.ovpn]
|
42
|
+
commonName = supplied
|
43
|
+
countryName = optional
|
44
|
+
stateOrProvinceName = optional
|
45
|
+
localityName = optional
|
46
|
+
organizationName = optional
|
47
|
+
organizationalUnitName = optional
|
48
|
+
name = optional
|
49
|
+
emailAddress = optional
|
data/lib/functions.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
def check_crt filename
|
2
|
+
['key', 'crt'].each {|ext|
|
3
|
+
abort "#{filename}.#{ext} already exists, exiting" if File.exist? "#{filename}.#{ext}"
|
4
|
+
}
|
5
|
+
end
|
6
|
+
|
7
|
+
def exe cmd
|
8
|
+
system(cmd) or abort "error executing: #{cmd}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def genrsa type, certname, no_password
|
12
|
+
if no_password
|
13
|
+
exe "#{OPENSSL} genrsa -out '#{certname}.key' #{KEY_SIZE} -config #{SSL_CONF} -extensions ext.#{type}"
|
14
|
+
else
|
15
|
+
exe "#{OPENSSL} genrsa -#{ENCRYPT} -out '#{certname}.key' #{KEY_SIZE} -config #{SSL_CONF} -extensions ext.#{type}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def req type, certname, cn
|
20
|
+
if certname == 'ca'
|
21
|
+
exe "#{OPENSSL} req -new -x509 -key '#{certname}.key' -out '#{certname}.crt' -config #{SSL_CONF} -subj '/CN=#{cn}#{REQ}' -extensions ext.#{type}"
|
22
|
+
else
|
23
|
+
exe "#{OPENSSL} req -new -key '#{certname}.key' -out '#{certname}.csr' -config #{SSL_CONF} -subj '/CN=#{cn}#{REQ}' -extensions ext.#{type}"
|
24
|
+
exe "#{OPENSSL} ca -in '#{certname}.csr' -out '#{certname}.crt' -config #{SSL_CONF} -extensions ext.#{type} -batch"
|
25
|
+
File.delete "#{certname}.csr"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def gen_crl
|
30
|
+
exe "#{OPENSSL} ca -gencrl -out crl.pem -config #{SSL_CONF}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_dir name
|
34
|
+
unless Dir.exist? name
|
35
|
+
Dir.mkdir name
|
36
|
+
puts "Created directory: #{name}"
|
37
|
+
end
|
38
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
::Version = '0.4'
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ovpn-key
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.4'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vasily Korytov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-08-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubyzip
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
description: ''
|
28
|
+
email: vasily.korytov@icloud.com
|
29
|
+
executables:
|
30
|
+
- ovpn-key
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- NOTICE
|
35
|
+
- README.md
|
36
|
+
- bin/ovpn-key
|
37
|
+
- defaults/meta/index.txt
|
38
|
+
- defaults/meta/index.txt.attr
|
39
|
+
- defaults/meta/serial
|
40
|
+
- defaults/openssl.ini
|
41
|
+
- defaults/ovpn-key.yml
|
42
|
+
- lib/functions.rb
|
43
|
+
- lib/version.rb
|
44
|
+
homepage: https://github.com/chillum/ovpn-key
|
45
|
+
licenses:
|
46
|
+
- Apache-2.0
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.7.6
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: Key management utility for OpenVPN
|
68
|
+
test_files: []
|