openvpn-status-web 1.0.0 → 3.0.0
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/README.md +18 -10
- data/{bin → exe}/openvpn-status-web +2 -0
- data/lib/openvpn-status-web.rb +47 -26
- data/lib/openvpn-status-web/int_patch.rb +8 -7
- data/lib/openvpn-status-web/parser/modern_stateless.rb +7 -8
- data/lib/openvpn-status-web/parser/v1.rb +2 -1
- data/lib/openvpn-status-web/parser/v2.rb +2 -1
- data/lib/openvpn-status-web/parser/v3.rb +2 -1
- data/lib/openvpn-status-web/status.rb +1 -0
- data/lib/openvpn-status-web/version.rb +2 -1
- metadata +125 -73
- data/.gitignore +0 -3
- data/.travis.yml +0 -8
- data/Gemfile +0 -3
- data/Rakefile +0 -6
- data/examples/status.v1 +0 -14
- data/examples/status.v2 +0 -12
- data/examples/status.v3 +0 -12
- data/init.d/debian-6-openvpn-status-web +0 -40
- data/openvpn-status-web.gemspec +0 -32
- data/spec/parser/modern_stateless_spec.rb +0 -55
- data/spec/parser/v1_spec.rb +0 -50
- data/spec/spec_helper.rb +0 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4bc46be9230486ffade1bc6234b86386fe6db50a060345a3dd87089272741e0c
|
4
|
+
data.tar.gz: cdedbe66c9eeff9332c561b77c3be0ed10262e01b9feff23889b98a02a4cd77a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1702733dfbe5dca5fbd0803a3cfb80822152e65d9b59b196af560d311d596aa7fb59472a3c52dcf6a1ed1ae4a02de9742cd4ad7ba8eea298fe6205321dd43da5
|
7
|
+
data.tar.gz: ac21793e1ebc175f3d8372fbcbf229593fe2b2dcc3d5bf863cf8ce761c94deeae4472ddf1805e8482fdfee17a4c50c58c4aebdc8146f4f46025eb6d6558c23b5
|
data/README.md
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
# openvpn-status-web
|
2
2
|
|
3
|
-
[](https://travis-ci.org/cmur2/openvpn-status-web) [](https://depfu.com/github/cmur2/openvpn-status-web?project_id=6194)
|
4
4
|
|
5
5
|
## Description
|
6
6
|
|
7
|
-
Small (another word for naive in this case, it's simple and serves my needs) [Rack](http://rack.github.com/) application providing the information
|
7
|
+
Small (another word for naive in this case, it's simple and serves my needs) [Rack](http://rack.github.com/) application providing the information an [OpenVPN](http://openvpn.net/index.php/open-source.html) server collects in it's status file especially including a list of currently connected clients (common name, remote address, traffic, ...).
|
8
8
|
|
9
9
|
It lacks:
|
10
10
|
|
11
|
-
* tracking multiple status at the same time
|
12
|
-
* newer status file versions than v1
|
13
11
|
* caching (parses file on each request, page does auto-refresh every minute as OpenVPN updates the status file these often by default)
|
14
12
|
* management interface support
|
15
13
|
* *possibly more...*
|
@@ -31,9 +29,15 @@ user: "nobody"
|
|
31
29
|
group: "nogroup"
|
32
30
|
# logfile is optional, logs to STDOUT else
|
33
31
|
logfile: "openvpn-status-web.log"
|
34
|
-
# display name for humans and
|
35
|
-
|
36
|
-
|
32
|
+
# hash with each VPNs display name for humans as key and further config as value
|
33
|
+
vpns:
|
34
|
+
My Small VPN:
|
35
|
+
# the status file path and status file format version are required
|
36
|
+
version: 1
|
37
|
+
status_file: "/var/log/openvpn-status.log"
|
38
|
+
My Other VPN:
|
39
|
+
version: 3
|
40
|
+
status_file: "/var/log/other-openvpn-status.log"
|
37
41
|
```
|
38
42
|
|
39
43
|
Your OpenVPN configuration should contain something like this:
|
@@ -45,16 +49,20 @@ status-version 1
|
|
45
49
|
# ...snip...
|
46
50
|
```
|
47
51
|
|
52
|
+
For more information about OpenVPN status file and version, see their [man page](https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage). openvpn-status-web is able to parse all versions from 1 to 3.
|
53
|
+
|
48
54
|
## Advanced topics
|
49
55
|
|
50
56
|
### Authentication
|
51
57
|
|
52
58
|
If the information exposed is important to you serve it via the VPN or use a webserver as a proxy to handle SSL and/or HTTP authentication.
|
53
59
|
|
54
|
-
###
|
60
|
+
### Startup
|
61
|
+
|
62
|
+
There is a [Dockerfile](docs/Dockerfile) that can be used to build a Docker image for running openvpn-status-web.
|
55
63
|
|
56
|
-
The [Debian 6 init
|
64
|
+
The [Debian 6 init script](docs/debian-init-openvpn-status-web) assumes that openvpn-status-web is installed into the system ruby (no RVM support) and the config.yaml is at `/opt/openvpn-status-web/config.yaml`. Modify to your needs.
|
57
65
|
|
58
66
|
## License
|
59
67
|
|
60
|
-
openvpn-
|
68
|
+
openvpn-status-web is licensed under the Apache License, Version 2.0. See LICENSE for more information.
|
data/lib/openvpn-status-web.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'date'
|
4
5
|
require 'etc'
|
@@ -8,7 +9,7 @@ require 'yaml'
|
|
8
9
|
require 'rack'
|
9
10
|
require 'erb'
|
10
11
|
require 'metriks'
|
11
|
-
require 'better_errors'
|
12
|
+
require 'better_errors' if ENV['RACK_ENV'] == 'development'
|
12
13
|
|
13
14
|
require 'openvpn-status-web/status'
|
14
15
|
require 'openvpn-status-web/parser/v1'
|
@@ -18,17 +19,25 @@ require 'openvpn-status-web/int_patch'
|
|
18
19
|
require 'openvpn-status-web/version'
|
19
20
|
|
20
21
|
module OpenVPNStatusWeb
|
22
|
+
# @return [Logger]
|
21
23
|
def self.logger
|
22
24
|
@logger
|
23
25
|
end
|
24
26
|
|
27
|
+
# @param logger [Logger]
|
28
|
+
# @return [Logger]
|
25
29
|
def self.logger=(logger)
|
26
30
|
@logger = logger
|
27
31
|
end
|
28
32
|
|
29
33
|
class LogFormatter
|
30
|
-
|
31
|
-
|
34
|
+
# @param lvl [Object]
|
35
|
+
# @param _time [DateTime]
|
36
|
+
# @param _progname [String]
|
37
|
+
# @param msg [Object]
|
38
|
+
# @return [String]
|
39
|
+
def call(lvl, _time, _progname, msg)
|
40
|
+
format("[%s] %-5s %s\n", Time.now.strftime('%Y-%m-%d %H:%M:%S'), lvl, msg.to_s)
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
@@ -40,29 +49,29 @@ module OpenVPNStatusWeb
|
|
40
49
|
end
|
41
50
|
|
42
51
|
def call(env)
|
43
|
-
return [405, {
|
44
|
-
return [404, {
|
52
|
+
return [405, {'Content-Type' => 'text/plain'}, ['Method Not Allowed']] if env['REQUEST_METHOD'] != 'GET'
|
53
|
+
return [404, {'Content-Type' => 'text/plain'}, ['Not Found']] if env['PATH_INFO'] != '/'
|
45
54
|
|
46
55
|
# variables for template
|
47
56
|
vpns = @vpns
|
48
57
|
stati = {}
|
49
|
-
@vpns.each do |name,config|
|
58
|
+
@vpns.each do |name, config|
|
50
59
|
stati[name] = parse_status_log(config)
|
51
60
|
end
|
52
61
|
# eval
|
53
62
|
html = @main_tmpl.result(binding)
|
54
63
|
|
55
|
-
[200, {
|
64
|
+
[200, {'Content-Type' => 'text/html'}, [html]]
|
56
65
|
end
|
57
66
|
|
58
67
|
def read_template(file)
|
59
|
-
text = File.
|
60
|
-
|
68
|
+
text = File.read(file, mode: 'rb')
|
69
|
+
|
61
70
|
ERB.new(text)
|
62
71
|
end
|
63
|
-
|
72
|
+
|
64
73
|
def parse_status_log(vpn)
|
65
|
-
text = File.
|
74
|
+
text = File.read(vpn['status_file'], mode: 'rb')
|
66
75
|
|
67
76
|
case vpn['version']
|
68
77
|
when 1
|
@@ -76,23 +85,24 @@ module OpenVPNStatusWeb
|
|
76
85
|
end
|
77
86
|
end
|
78
87
|
|
88
|
+
# @return [void]
|
79
89
|
def self.run!
|
80
90
|
if ARGV.length != 1
|
81
|
-
puts
|
91
|
+
puts 'Usage: openvpn-status-web config_file'
|
82
92
|
exit 1
|
83
93
|
end
|
84
94
|
|
85
95
|
config_file = ARGV[0]
|
86
96
|
|
87
|
-
if
|
88
|
-
puts
|
97
|
+
if !File.file?(config_file)
|
98
|
+
puts 'Config file not found!'
|
89
99
|
exit 1
|
90
100
|
end
|
91
|
-
|
101
|
+
|
92
102
|
puts "openvpn-status-web version #{OpenVPNStatusWeb::VERSION}"
|
93
103
|
puts "Using config file #{config_file}"
|
94
104
|
|
95
|
-
config = YAML
|
105
|
+
config = YAML.safe_load(File.read(config_file, mode: 'r'))
|
96
106
|
|
97
107
|
if config['logfile']
|
98
108
|
OpenVPNStatusWeb.logger = Logger.new(config['logfile'])
|
@@ -100,28 +110,39 @@ module OpenVPNStatusWeb
|
|
100
110
|
OpenVPNStatusWeb.logger = Logger.new(STDOUT)
|
101
111
|
end
|
102
112
|
|
103
|
-
OpenVPNStatusWeb.logger.progname =
|
113
|
+
OpenVPNStatusWeb.logger.progname = 'openvpn-status-web'
|
104
114
|
OpenVPNStatusWeb.logger.formatter = LogFormatter.new
|
105
115
|
|
106
|
-
OpenVPNStatusWeb.logger.info
|
116
|
+
OpenVPNStatusWeb.logger.info 'Starting...'
|
107
117
|
|
108
|
-
# drop
|
109
|
-
|
110
|
-
|
118
|
+
# drop priviliges as soon as possible
|
119
|
+
# NOTE: first change group than user
|
120
|
+
if config['group']
|
121
|
+
group = Etc.getgrnam(config['group'])
|
122
|
+
Process::Sys.setgid(group.gid) if group
|
123
|
+
end
|
124
|
+
if config['user']
|
125
|
+
user = Etc.getpwnam(config['user'])
|
126
|
+
Process::Sys.setuid(user.uid) if user
|
127
|
+
end
|
111
128
|
|
112
129
|
# configure rack
|
113
130
|
app = Daemon.new(config['vpns'])
|
114
|
-
if ENV['RACK_ENV'] ==
|
131
|
+
if ENV['RACK_ENV'] == 'development'
|
115
132
|
app = BetterErrors::Middleware.new(app)
|
116
|
-
BetterErrors.application_root = File.expand_path(
|
133
|
+
BetterErrors.application_root = File.expand_path(__dir__)
|
117
134
|
end
|
118
135
|
|
119
136
|
Signal.trap('INT') do
|
120
|
-
OpenVPNStatusWeb.logger.info
|
137
|
+
OpenVPNStatusWeb.logger.info 'Quitting...'
|
138
|
+
Rack::Handler::WEBrick.shutdown
|
139
|
+
end
|
140
|
+
Signal.trap('TERM') do
|
141
|
+
OpenVPNStatusWeb.logger.info 'Quitting...'
|
121
142
|
Rack::Handler::WEBrick.shutdown
|
122
143
|
end
|
123
|
-
|
124
|
-
Rack::Handler::WEBrick.run app, :
|
144
|
+
|
145
|
+
Rack::Handler::WEBrick.run app, Host: config['host'], Port: config['port']
|
125
146
|
end
|
126
147
|
end
|
127
148
|
end
|
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
class Integer
|
3
4
|
def as_bytes
|
4
|
-
return
|
5
|
-
|
6
|
-
label = [
|
5
|
+
return '1 Byte' if self == 1
|
6
|
+
|
7
|
+
label = %w[Bytes KiB MiB GiB TiB]
|
7
8
|
i = 0
|
8
|
-
num =
|
9
|
-
while num >= 1024
|
10
|
-
num
|
9
|
+
num = to_f
|
10
|
+
while num >= 1024
|
11
|
+
num /= 1024
|
11
12
|
i += 1
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
"#{format('%.2f', num)} #{label[i]}"
|
15
16
|
end
|
16
17
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module OpenVPNStatusWeb
|
3
4
|
module Parser
|
@@ -10,29 +11,27 @@ module OpenVPNStatusWeb
|
|
10
11
|
|
11
12
|
text.lines.each do |line|
|
12
13
|
parts = line.strip.split(sep)
|
13
|
-
status.client_list << parse_client(parts[1..5]) if parts[0] ==
|
14
|
-
status.routing_table << parse_route(parts[1..4]) if parts[0] ==
|
15
|
-
status.global_stats << parse_global(parts[1..2]) if parts[0] ==
|
14
|
+
status.client_list << parse_client(parts[1..5]) if parts[0] == 'CLIENT_LIST'
|
15
|
+
status.routing_table << parse_route(parts[1..4]) if parts[0] == 'ROUTING_TABLE'
|
16
|
+
status.global_stats << parse_global(parts[1..2]) if parts[0] == 'GLOBAL_STATS'
|
16
17
|
end
|
17
18
|
|
18
19
|
status
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
def self.parse_client(client)
|
22
|
+
private_class_method def self.parse_client(client)
|
24
23
|
client[2] = client[2].to_i
|
25
24
|
client[3] = client[3].to_i
|
26
25
|
client[4] = DateTime.strptime(client[4], '%a %b %d %k:%M:%S %Y')
|
27
26
|
client
|
28
27
|
end
|
29
28
|
|
30
|
-
def self.parse_route(route)
|
29
|
+
private_class_method def self.parse_route(route)
|
31
30
|
route[3] = DateTime.strptime(route[3], '%a %b %d %k:%M:%S %Y')
|
32
31
|
route
|
33
32
|
end
|
34
33
|
|
35
|
-
def self.parse_global(global)
|
34
|
+
private_class_method def self.parse_global(global)
|
36
35
|
global[1] = global[1].to_i
|
37
36
|
global
|
38
37
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module OpenVPNStatusWeb
|
3
4
|
module Parser
|
@@ -13,7 +14,7 @@ module OpenVPNStatusWeb
|
|
13
14
|
(current_section = :rt; next) if line == "ROUTING TABLE\n"
|
14
15
|
(current_section = :gs; next) if line == "GLOBAL STATS\n"
|
15
16
|
(current_section = :end; next) if line == "END\n"
|
16
|
-
|
17
|
+
|
17
18
|
case current_section
|
18
19
|
when :cl
|
19
20
|
client_list << line.strip.split(',')
|
metadata
CHANGED
@@ -1,122 +1,181 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openvpn-status-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 3.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Christian Nicolai
|
9
8
|
autorequire:
|
10
|
-
bindir:
|
9
|
+
bindir: exe
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2020-07-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
17
|
-
none: false
|
14
|
+
name: metriks
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: metriks
|
27
|
-
requirement: &70153409956540 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
23
|
requirements:
|
30
|
-
- -
|
24
|
+
- - ">="
|
31
25
|
- !ruby/object:Gem::Version
|
32
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
33
34
|
type: :runtime
|
34
35
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
36
41
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
39
|
-
none: false
|
42
|
+
name: better_errors
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
40
44
|
requirements:
|
41
|
-
- -
|
45
|
+
- - ">="
|
42
46
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
47
|
+
version: '0'
|
44
48
|
type: :development
|
45
49
|
prerelease: false
|
46
|
-
version_requirements:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
47
55
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement:
|
50
|
-
none: false
|
56
|
+
name: binding_of_caller
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - ">="
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '0'
|
55
62
|
type: :development
|
56
63
|
prerelease: false
|
57
|
-
version_requirements:
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
60
|
-
requirement:
|
61
|
-
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
79
|
requirements:
|
63
|
-
- -
|
80
|
+
- - ">="
|
64
81
|
- !ruby/object:Gem::Version
|
65
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler-audit
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.7.0
|
66
90
|
type: :development
|
67
91
|
prerelease: false
|
68
|
-
version_requirements:
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.7.0
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: rack-test
|
71
|
-
requirement:
|
72
|
-
none: false
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
73
100
|
requirements:
|
74
|
-
- -
|
101
|
+
- - ">="
|
75
102
|
- !ruby/object:Gem::Version
|
76
103
|
version: '0'
|
77
104
|
type: :development
|
78
105
|
prerelease: false
|
79
|
-
version_requirements:
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
80
111
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement:
|
83
|
-
none: false
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
84
114
|
requirements:
|
85
|
-
- -
|
115
|
+
- - ">="
|
86
116
|
- !ruby/object:Gem::Version
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
91
125
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
93
|
-
requirement:
|
94
|
-
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.88.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.88.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: solargraph
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
95
156
|
requirements:
|
96
|
-
- -
|
157
|
+
- - ">="
|
97
158
|
- !ruby/object:Gem::Version
|
98
159
|
version: '0'
|
99
160
|
type: :development
|
100
161
|
prerelease: false
|
101
|
-
version_requirements:
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
102
167
|
description: Small Rack (Ruby) application serving OpenVPN status file.
|
103
|
-
email:
|
168
|
+
email:
|
104
169
|
executables:
|
105
170
|
- openvpn-status-web
|
106
171
|
extensions: []
|
107
|
-
extra_rdoc_files:
|
172
|
+
extra_rdoc_files:
|
173
|
+
- README.md
|
174
|
+
- LICENSE
|
108
175
|
files:
|
109
|
-
- .gitignore
|
110
|
-
- .travis.yml
|
111
|
-
- Gemfile
|
112
176
|
- LICENSE
|
113
177
|
- README.md
|
114
|
-
-
|
115
|
-
- bin/openvpn-status-web
|
116
|
-
- examples/status.v1
|
117
|
-
- examples/status.v2
|
118
|
-
- examples/status.v3
|
119
|
-
- init.d/debian-6-openvpn-status-web
|
178
|
+
- exe/openvpn-status-web
|
120
179
|
- lib/openvpn-status-web.rb
|
121
180
|
- lib/openvpn-status-web/int_patch.rb
|
122
181
|
- lib/openvpn-status-web/main.html.erb
|
@@ -126,36 +185,29 @@ files:
|
|
126
185
|
- lib/openvpn-status-web/parser/v3.rb
|
127
186
|
- lib/openvpn-status-web/status.rb
|
128
187
|
- lib/openvpn-status-web/version.rb
|
129
|
-
- openvpn-status-web.gemspec
|
130
|
-
- spec/parser/modern_stateless_spec.rb
|
131
|
-
- spec/parser/v1_spec.rb
|
132
|
-
- spec/spec_helper.rb
|
133
188
|
homepage: https://github.com/cmur2/openvpn-status-web
|
134
189
|
licenses:
|
135
|
-
- Apache
|
190
|
+
- Apache-2.0
|
191
|
+
metadata:
|
192
|
+
bug_tracker_uri: https://github.com/cmur2/openvpn-status-web/issues
|
193
|
+
source_code_uri: https://github.com/cmur2/openvpn-status-web
|
136
194
|
post_install_message:
|
137
195
|
rdoc_options: []
|
138
196
|
require_paths:
|
139
197
|
- lib
|
140
198
|
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
-
none: false
|
142
199
|
requirements:
|
143
|
-
- -
|
200
|
+
- - ">="
|
144
201
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
202
|
+
version: '2.5'
|
146
203
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
204
|
requirements:
|
149
|
-
- -
|
205
|
+
- - ">="
|
150
206
|
- !ruby/object:Gem::Version
|
151
207
|
version: '0'
|
152
208
|
requirements: []
|
153
|
-
|
154
|
-
rubygems_version: 1.8.6
|
209
|
+
rubygems_version: 3.0.8
|
155
210
|
signing_key:
|
156
|
-
specification_version:
|
211
|
+
specification_version: 4
|
157
212
|
summary: openvpn-status-web
|
158
|
-
test_files:
|
159
|
-
- spec/parser/modern_stateless_spec.rb
|
160
|
-
- spec/parser/v1_spec.rb
|
161
|
-
- spec/spec_helper.rb
|
213
|
+
test_files: []
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
data/examples/status.v1
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
OpenVPN CLIENT LIST
|
2
|
-
Updated,Sun Jan 1 23:42:00 2012
|
3
|
-
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
|
4
|
-
foo,1.2.3.4:1234,11811160064,4194304,Sun Jan 1 23:42:00 2012
|
5
|
-
bar,1.2.3.5:1235,512,2048,Sun Jan 1 23:42:00 2012
|
6
|
-
ROUTING TABLE
|
7
|
-
Virtual Address,Common Name,Real Address,Last Ref
|
8
|
-
192.168.0.0/24,foo,1.2.3.4:1234,Sun Jan 1 23:42:00 2012
|
9
|
-
192.168.66.2,bar,1.2.3.5:1235,Sun Jan 1 23:42:00 2012
|
10
|
-
192.168.66.3,foo,1.2.3.4:1234,Sun Jan 1 23:42:00 2012
|
11
|
-
2001:db8:0:0::1000,bar,1.2.3.5:1235,Sun Jan 1 23:42:00 2012
|
12
|
-
GLOBAL STATS
|
13
|
-
Max bcast/mcast queue length,42
|
14
|
-
END
|
data/examples/status.v2
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
TITLE,OpenVPN 2.1_rc15 mipsel-unknown-linux-gnu [SSL] [LZO1] [EPOLL] built on Mar 27 2009
|
2
|
-
TIME,Sun Jan 1 23:42:00 2012,1238702330
|
3
|
-
HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)
|
4
|
-
CLIENT_LIST,foo,1.2.3.4:1234,11811160064,4194304,Sun Jan 1 23:42:00 2012,1238702330
|
5
|
-
CLIENT_LIST,bar,1.2.3.5:1235,512,2048,Sun Jan 1 23:42:00 2012,1238702330
|
6
|
-
HEADER,ROUTING_TABLE,Virtual Address,Common Name,Real Address,Last Ref,Last Ref (time_t)
|
7
|
-
ROUTING_TABLE,192.168.0.0/24,foo,1.2.3.4:1234,Sun Jan 1 23:42:00 2012,1238702330
|
8
|
-
ROUTING_TABLE,192.168.66.2,bar,1.2.3.5:1235,Sun Jan 1 23:42:00 2012,1238702330
|
9
|
-
ROUTING_TABLE,192.168.66.3,foo,1.2.3.4:1234,Sun Jan 1 23:42:00 2012,1238702330
|
10
|
-
ROUTING_TABLE,2001:db8:0:0::1000,bar,1.2.3.5:1235,Sun Jan 1 23:42:00 2012,1238702330
|
11
|
-
GLOBAL_STATS,Max bcast/mcast queue length,42
|
12
|
-
END
|
data/examples/status.v3
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
TITLE OpenVPN 2.1_rc15 mipsel-unknown-linux-gnu [SSL] [LZO1] [EPOLL] built on Mar 27 2009
|
2
|
-
TIME Sun Jan 1 23:42:00 2012 1238702330
|
3
|
-
HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes Received Bytes Sent Connected Since Connected Since (time_t)
|
4
|
-
CLIENT_LIST foo 1.2.3.4:1234 11811160064 4194304 Sun Jan 1 23:42:00 2012 1238702330
|
5
|
-
CLIENT_LIST bar 1.2.3.5:1235 512 2048 Sun Jan 1 23:42:00 2012 1238702330
|
6
|
-
HEADER ROUTING_TABLE Virtual Address Common Name Real Address Last Ref Last Ref (time_t)
|
7
|
-
ROUTING_TABLE 192.168.0.0/24 foo 1.2.3.4:1234 Sun Jan 1 23:42:00 2012 1238702330
|
8
|
-
ROUTING_TABLE 192.168.66.2 bar 1.2.3.5:1235 Sun Jan 1 23:42:00 2012 1238702330
|
9
|
-
ROUTING_TABLE 192.168.66.3 foo 1.2.3.4:1234 Sun Jan 1 23:42:00 2012 1238702330
|
10
|
-
ROUTING_TABLE 2001:db8:0:0::1000 bar 1.2.3.5:1235 Sun Jan 1 23:42:00 2012 1238702330
|
11
|
-
GLOBAL_STATS Max bcast/mcast queue length 42
|
12
|
-
END
|
@@ -1,40 +0,0 @@
|
|
1
|
-
#! /bin/sh
|
2
|
-
### BEGIN INIT INFO
|
3
|
-
# Provides: openvpn-status-web
|
4
|
-
# Required-Start: $remote_fs $syslog
|
5
|
-
# Required-Stop: $remote_fs $syslog
|
6
|
-
# Default-Start: 2 3 4 5
|
7
|
-
# Default-Stop: 0 1 6
|
8
|
-
# Short-Description: Handle openvpn-status-web gem
|
9
|
-
### END INIT INFO
|
10
|
-
|
11
|
-
# using the system ruby's gem binaries directory
|
12
|
-
DAEMON="/var/lib/gems/1.8/bin/openvpn-status-web"
|
13
|
-
|
14
|
-
CONFIG_FILE="/opt/openvpn-status-web/config.yaml"
|
15
|
-
|
16
|
-
DAEMON_OPTS="$CONFIG_FILE"
|
17
|
-
|
18
|
-
test -x $DAEMON || exit 0
|
19
|
-
|
20
|
-
. /lib/lsb/init-functions
|
21
|
-
|
22
|
-
case "$1" in
|
23
|
-
start)
|
24
|
-
log_daemon_msg "Starting openvpn-web-status" "openvpn-web-status"
|
25
|
-
start-stop-daemon --start --quiet --oknodo --make-pidfile --pidfile "/var/run/openvpn-web-status.pid" --background --exec $DAEMON -- $DAEMON_OPTS
|
26
|
-
;;
|
27
|
-
stop)
|
28
|
-
log_daemon_msg "Stopping openvpn-web-status" "openvpn-web-status"
|
29
|
-
start-stop-daemon --stop --quiet --oknodo --pidfile "/var/run/openvpn-web-status.pid"
|
30
|
-
;;
|
31
|
-
restart|force-reload)
|
32
|
-
log_daemon_msg "Restarting openvpn-web-status" "openvpn-web-status"
|
33
|
-
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile "/var/run/openvpn-web-status.pid"
|
34
|
-
start-stop-daemon --start --quiet --oknodo --make-pidfile --pidfile "/var/run/openvpn-web-status.pid" --background --exec $DAEMON -- $DAEMON_OPTS
|
35
|
-
;;
|
36
|
-
*)
|
37
|
-
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
|
38
|
-
exit 1
|
39
|
-
;;
|
40
|
-
esac
|
data/openvpn-status-web.gemspec
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
|
4
|
-
require 'openvpn-status-web/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = 'openvpn-status-web'
|
8
|
-
s.version = OpenVPNStatusWeb::VERSION
|
9
|
-
s.summary = 'openvpn-status-web'
|
10
|
-
s.description = 'Small Rack (Ruby) application serving OpenVPN status file.'
|
11
|
-
s.author = 'Christian Nicolai'
|
12
|
-
s.email = 'chrnicolai@gmail.com'
|
13
|
-
s.license = 'Apache License Version 2.0'
|
14
|
-
s.homepage = 'https://github.com/cmur2/openvpn-status-web'
|
15
|
-
|
16
|
-
s.files = `git ls-files`.split($/)
|
17
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
-
|
19
|
-
s.require_paths = ['lib']
|
20
|
-
|
21
|
-
s.executables = ['openvpn-status-web']
|
22
|
-
|
23
|
-
s.add_runtime_dependency 'rack'
|
24
|
-
s.add_runtime_dependency 'metriks'
|
25
|
-
|
26
|
-
s.add_development_dependency 'bundler', '~> 1.3'
|
27
|
-
s.add_development_dependency 'rake'
|
28
|
-
s.add_development_dependency 'rspec'
|
29
|
-
s.add_development_dependency 'rack-test'
|
30
|
-
s.add_development_dependency 'better_errors'
|
31
|
-
s.add_development_dependency 'binding_of_caller'
|
32
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe OpenVPNStatusWeb::Parser::ModernStateless do
|
4
|
-
{
|
5
|
-
2 => status_v2,
|
6
|
-
3 => status_v3
|
7
|
-
}.each do |version, status|
|
8
|
-
context "for status-version #{version}" do
|
9
|
-
context 'for client list' do
|
10
|
-
it 'parses common names' do
|
11
|
-
status.client_list.map { |client| client[0] }.should be == ["foo", "bar"]
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'parses real addresses' do
|
15
|
-
status.client_list.map { |client| client[1] }.should be == ["1.2.3.4:1234", "1.2.3.5:1235"]
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'parses received bytes' do
|
19
|
-
status.client_list.map { |client| client[2] }.should be == [11811160064, 512]
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'parses sent bytes' do
|
23
|
-
status.client_list.map { |client| client[3] }.should be == [4194304, 2048]
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'parses connected since date' do
|
27
|
-
status.client_list.map { |client| client[4] }.should be == [DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0)]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'for routing table' do
|
32
|
-
it 'parses virtual addresses' do
|
33
|
-
status.routing_table.map { |route| route[0] }.should be == ["192.168.0.0/24", "192.168.66.2", "192.168.66.3", "2001:db8:0:0::1000"]
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'parses common names' do
|
37
|
-
status.routing_table.map { |route| route[1] }.should be == ["foo", "bar", "foo", "bar"]
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'parses real addresses' do
|
41
|
-
status.routing_table.map { |route| route[2] }.should be == ["1.2.3.4:1234", "1.2.3.5:1235", "1.2.3.4:1234", "1.2.3.5:1235"]
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'parses last ref date' do
|
45
|
-
status.routing_table.map { |route| route[3] }.should be == [DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0)]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'parses global stats' do
|
50
|
-
status.global_stats.size.should be == 1
|
51
|
-
status.global_stats.first.should be == ["Max bcast/mcast queue length", 42]
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
data/spec/parser/v1_spec.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe OpenVPNStatusWeb::Parser::V1 do
|
4
|
-
def status; status_v1; end
|
5
|
-
|
6
|
-
context 'for client list' do
|
7
|
-
it 'parses common names' do
|
8
|
-
status.client_list.map { |client| client[0] }.should be == ["foo", "bar"]
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'parses real addresses' do
|
12
|
-
status.client_list.map { |client| client[1] }.should be == ["1.2.3.4:1234", "1.2.3.5:1235"]
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'parses received bytes' do
|
16
|
-
status.client_list.map { |client| client[2] }.should be == [11811160064, 512]
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'parses sent bytes' do
|
20
|
-
status.client_list.map { |client| client[3] }.should be == [4194304, 2048]
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'parses connected since date' do
|
24
|
-
status.client_list.map { |client| client[4] }.should be == [DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0)]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'for routing table' do
|
29
|
-
it 'parses virtual addresses' do
|
30
|
-
status.routing_table.map { |route| route[0] }.should be == ["192.168.0.0/24", "192.168.66.2", "192.168.66.3", "2001:db8:0:0::1000"]
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'parses common names' do
|
34
|
-
status.routing_table.map { |route| route[1] }.should be == ["foo", "bar", "foo", "bar"]
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'parses real addresses' do
|
38
|
-
status.routing_table.map { |route| route[2] }.should be == ["1.2.3.4:1234", "1.2.3.5:1235", "1.2.3.4:1234", "1.2.3.5:1235"]
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'parses last ref date' do
|
42
|
-
status.routing_table.map { |route| route[3] }.should be == [DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0), DateTime.new(2012,1,1,23,42,0)]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'parses global stats' do
|
47
|
-
status.global_stats.size.should be == 1
|
48
|
-
status.global_stats.first.should be == ["Max bcast/mcast queue length", 42]
|
49
|
-
end
|
50
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rubygems'
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'rack/test'
|
5
|
-
|
6
|
-
require 'openvpn-status-web'
|
7
|
-
|
8
|
-
def status_v1
|
9
|
-
text = File.open('examples/status.v1', 'rb') do |f| f.read end
|
10
|
-
OpenVPNStatusWeb::Parser::V1.new.parse_status_log text
|
11
|
-
end
|
12
|
-
|
13
|
-
def status_v2
|
14
|
-
text = File.open('examples/status.v2', 'rb') do |f| f.read end
|
15
|
-
OpenVPNStatusWeb::Parser::V2.new.parse_status_log text
|
16
|
-
end
|
17
|
-
|
18
|
-
def status_v3
|
19
|
-
text = File.open('examples/status.v3', 'rb') do |f| f.read end
|
20
|
-
OpenVPNStatusWeb::Parser::V3.new.parse_status_log text
|
21
|
-
end
|