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 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: []