ovpn-key 0.4

Sign up to get free protection for your applications and to get access to all the features.
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 [![Gem Version](https://badge.fury.io/rb/ovpn-key.svg)](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
@@ -0,0 +1,6 @@
1
+ zip_dir: '~'
2
+ openssl: openssl
3
+ key_size: 2048
4
+ encrypt: aes128
5
+ req: /C=US/L=San Francisco/O=Dva Debila/OU=OpenVPN
6
+ cn_ca: Certification Authority
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: []