riseup_vpn 0.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 061471e29bcb71a8ad7d20c0757f445ed026913613deb3a289bde237aa40022e
4
- data.tar.gz: 7a780713819d589fdf07e4abd684c6b341e61e5d0ffdf6ccc331693f35cc5301
3
+ metadata.gz: 5749722468abc5f22914e79b50843c565be88d489d8fba1ef5cb9d26f30bdb52
4
+ data.tar.gz: 76f3542e75019a9dea6d319664a1bb1b5fe0f8c28b2e75939cc02e44418aeadd
5
5
  SHA512:
6
- metadata.gz: ae6548f93e8f3734c6578a0f593b979384735e34d07e84d6ffc6bf71ec741440086e0a480b2e19c7939072ee0876a33bf53b33224c3283e15ca7d913c98bd8d1
7
- data.tar.gz: 6e5c748da5d135578357540b95d0ea97fb8e92287408443dac4acd655da6a8cd8ecd7dcb8bec4cc0944ad419a9eb4770c76447590da7d2927fb8efcab1a62652
6
+ metadata.gz: f70b3352d7e5be2ba70e765dc346b8948e1819fe5b60195963651fe9ff8627f5171eee642dfd0a28ca83cc0c620b9451f4bf72c6d020da47c8a4eabf02e1254d
7
+ data.tar.gz: a2adafe678f656818a760dd453b2e599d7ecfc47c086b424fc88a57fa1bcfb47443398d29cc718af2bde226688e47b3afd9f4b8eb2b6bd686a43c478b2a7ed0f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.0.0] - 2025-04-21
4
+
5
+ ### New features
6
+
7
+ - upgrade TLS to 1.3, if supported by client
8
+
9
+ ### Breaking changes
10
+
11
+ - Namespace changes: `RiseupVpn` -> `RiseupVPN`, `RiseupVpn::Api` -> `RiseupVPN::API` and `Generator` -> `Manager`
12
+ - `#write_files` no longer takes an dir path arg
13
+ - All errors subclass `RiseupVPN::Error`
14
+
3
15
  ## [0.1.0] - 2025-04-19
4
16
 
5
17
  - Initial release
data/README.md CHANGED
@@ -3,12 +3,12 @@
3
3
 
4
4
  # RiseupVPN
5
5
 
6
- A tool to create .ovpn ([OpenVPN](https://openvpn.net)) client config files for use with [RiseupVPN](https://riseup.net/vpn). Such files can be imported using, for example, the Debian [openvpn NetworkManager plugin](https://packages.debian.org/search?keywords=network-manager-openvpn). You will then be able to route your network connection through any of Riseup's 20+ VPN gateways! Screenshot below shows Linux Mint's Network Manager panel applet with an active VPN connection to RiseupVPN's Seattle gateway.
7
-
8
- This project was inspired by [this](https://sizeof.cat/project/riseupvpn-to-openvpn) very excellent web tool.
6
+ A tool to create .ovpn ([OpenVPN](https://openvpn.net)) client config files for use with [RiseupVPN](https://riseup.net/vpn). Such files can be imported using, for example, the Debian [openvpn NetworkManager plugin](https://packages.debian.org/search?keywords=network-manager-openvpn). You will then be able to route your network connection through any of Riseup's 20+ VPN gateways! The screenshot below shows Linux Mint's Network Manager panel applet with an active VPN connection to RiseupVPN's Seattle gateway.
9
7
 
10
8
  ![image info](assets/vpns.png)
11
9
 
10
+ This project was inspired by [this](https://sizeof.cat/project/riseupvpn-to-openvpn) very excellent web tool.
11
+
12
12
  ## Installation
13
13
 
14
14
  Install the gem and add to the application's Gemfile by executing:
@@ -28,27 +28,29 @@ gem install riseup_vpn
28
28
  ```ruby
29
29
  require 'riseup_vpn'
30
30
 
31
- generator = RiseupVpn::Generator.new
32
- # => instance_of RiseupVpn::Generator
31
+ manager = RiseupVPN::Manager.new # takes an optional positional arg for the dir path. Default is '~/.config/riseup_vpn'
32
+ # => instance_of RiseupVPN::Manager
33
33
 
34
- generator.ovpns
34
+ manager.ovpns
35
35
  # => {"vpn01-sea.riseup.net" => "client\ntls-client\ndev tun\nproto udp\nremote 204.13.164.252 1194 ...
36
36
 
37
- generator.ovpns.size
37
+ manager.ovpns.size
38
38
  # => 21
39
39
 
40
- RiseupVpn::Generator::OPTS # returns a list of valid options which maybe passed at initialization.
41
- # => {proto: ["udp", "tcp"]} # e.g. RiseupVpn::Generator.new(proto: 'tcp') default is 'udp'
40
+ RiseupVPN::Manager::OPTS # returns a list of valid options which maybe passed as an optional hash at initialization.
41
+ # => {proto: ["udp", "tcp"]} defaults are the first values e.g. 'udp' for :proto
42
+ # For example; RiseupVPN::Manager.new('/some/path', proto: 'tcp')
42
43
 
43
- generator.write_files '~/.config/riseup_vpn' # dir must exist
44
+ manager.write_files # (over)writes the VPN client config files to the dir path
44
45
  ```
45
- The last command creates the following files in the chosen directory:
46
+ The last command creates (or overwrites) the following files:
46
47
  - an .ovpn file for each VPN gateway
47
48
  - the Certificate Authority cert file (ca.crt)
48
49
  - the client private key file (client.key)
49
50
  - the client cert file (client.crt)
50
51
 
51
- Note: OpenVPN requires that cert & key files shared across .ovpn client config files are present in the same directory.
52
+ Note: The last 2 expire after 30 days and therefore need to be updated regularly
53
+ Also note: OpenVPN requires that cert & key files shared across .ovpn client config files are present in the same directory.
52
54
 
53
55
  ## \_why?
54
56
 
@@ -2,11 +2,9 @@
2
2
 
3
3
  require 'openssl'
4
4
 
5
- module RiseupVpn
5
+ module RiseupVPN
6
6
  # parses ca.cert, client cert/key & gateways data from riseup.net API
7
- module Api
8
- class ApiError < StandardError; end
9
-
7
+ module API
10
8
  PROVIDER = 'https://riseup.net/provider.json' # entry point for API
11
9
  API_URI = 'https://api.black.riseup.net' # 443
12
10
  API_VERSION = '3'
@@ -35,15 +33,15 @@ module RiseupVpn
35
33
  def get(url)
36
34
  URI(url).read
37
35
  rescue NoMethodError, URI::Error
38
- raise ApiError, "Bad URI: '#{url}'"
36
+ raise APIError, "Bad URI: '#{url}'"
39
37
  rescue OpenURI::HTTPError
40
- raise ApiError, "Failed to get url: '#{url}'"
38
+ raise APIError, "Failed to get url: '#{url}'"
41
39
  end
42
40
 
43
41
  def get_json(url)
44
42
  JSON.parse get(url)
45
43
  rescue JSON::ParserError
46
- raise ApiError, "Failed to parse JSON at: '#{url}'"
44
+ raise APIError, "Failed to parse JSON at: '#{url}'"
47
45
  end
48
46
  end
49
47
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RiseupVPN
4
+ class Error < StandardError; end
5
+
6
+ class APIError < Error; end
7
+ end
@@ -1,57 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'openssl'
4
3
  require 'yaml'
5
4
 
6
5
  require_relative 'api'
6
+ require_relative 'utils'
7
7
 
8
- module RiseupVpn
9
- # create a .ovpn config file for a gateway
8
+ module RiseupVPN
9
+ # queries API and builds ovpn config files, CA cert and client key & cert
10
10
  class Generator
11
+ include Utils
12
+
11
13
  TEMPLATE = YAML.load_file File.join(__dir__, 'template_ovpn.yml')
12
14
  OPTS = { proto: %w[udp tcp] }.freeze # default is 1st value
13
- LINE_METHODS = %i[remote verify-x509-name].freeze
15
+ LINE_METHODS = %i[remote tls-version-min verify-x509-name].freeze
14
16
 
15
- attr_reader :ovpns
17
+ attr_reader :ovpns, :ca_crt, :client_key, :client_crt
16
18
 
17
19
  def initialize(opts = {})
18
20
  @opts = validate_options opts.transform_keys!(&:to_sym)
19
- @server_config = server_config
20
21
  @template = template
22
+ @server_config = server_config
21
23
  @ovpns = generate_ovpns # hash { gateway_name => string }
22
- end
23
-
24
- def write_files(dir)
25
- dir = File.expand_path dir.to_s
26
- write_ovpn_files dir
27
- write_ca_file dir
28
- write_client_key_and_crt_files dir
29
- rescue Errno::ENOENT, Errno::EACCES
30
- raise ArgumentError, "Dir #{dir} doesn't exist or isn't writable"
24
+ @ca_crt = API.ca_crt
25
+ @client_key, @client_crt = API.client_key_and_crt
31
26
  end
32
27
 
33
28
  private
34
29
 
35
- def write_ovpn_files(dir)
36
- ovpns.each { |k, v| File.write(File.join(dir, "#{k}.ovpn"), v) }
37
- end
38
-
39
- def write_ca_file(dir)
40
- File.write File.join(dir, 'ca.crt'), Api.ca_crt.to_s.chomp
41
- end
42
-
43
- def write_client_key_and_crt_files(dir)
44
- client_key, client_crt = Api.client_key_and_crt
45
- File.write File.join(dir, 'client.key'), client_key.to_s.chomp
46
- File.write File.join(dir, 'client.crt'), client_crt.to_s.chomp
47
- end
48
-
49
30
  def gateways
50
- Api.eip['gateways']
31
+ API.eip['gateways']
51
32
  end
52
33
 
53
34
  def server_config
54
- Api.eip['openvpn_configuration'].transform_keys(&:to_sym)
35
+ API.eip['openvpn_configuration'].transform_keys(&:to_sym)
55
36
  end
56
37
 
57
38
  def validate_options(opts)
@@ -69,17 +50,16 @@ module RiseupVpn
69
50
  end
70
51
 
71
52
  def template
72
- return TEMPLATE.except(*%i[up down]) if RiseupVpn.os == 'darwin'
73
- return TEMPLATE if RiseupVpn.os == 'linux'
53
+ return TEMPLATE.except(*%i[up down]) if Utils.os == 'darwin'
74
54
 
75
- raise RiseupVpnError, "Unsupported OS: '#{RiseupVpn.os}'"
55
+ TEMPLATE # assumed Linux, see Utils::SUPPORTED_PLATFORMS
76
56
  end
77
57
 
78
58
  def generate_line(key, val, gateway)
79
59
  return "#{key} #{val}" if val # hard coded key/value in template file
80
60
  return "#{key} #{@opts[key]}" if @opts[key]
81
- return server_config_line(key) if @server_config[key]
82
61
  return send(regularize_method_name(key), gateway) if LINE_METHODS.include? key
62
+ return server_config_line(key) if @server_config[key]
83
63
 
84
64
  key # hard coded key only in template file
85
65
  end
@@ -98,6 +78,10 @@ module RiseupVpn
98
78
  "remote #{gateway['ip_address']} #{@opts[:proto] == 'udp' ? 1194 : 80}" # TODO: check port 80 in json
99
79
  end
100
80
 
81
+ def tls_version_min(_gateway)
82
+ "tls-version-min #{Utils.tls_version}"
83
+ end
84
+
101
85
  def verify_x509_name(gateway)
102
86
  "verify-x509-name #{name(gateway)} name"
103
87
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generator'
4
+
5
+ module RiseupVPN
6
+ # manages config files
7
+ class Manager
8
+ DEFAULT_DIR = '~/.config/riseup_vpn'
9
+ OPTS = Generator::OPTS
10
+
11
+ def initialize(dir = DEFAULT_DIR, opts = {})
12
+ @dir = File.expand_path dir.to_s
13
+ @generator = Generator.new(opts)
14
+ end
15
+
16
+ def ovpns
17
+ @generator.ovpns
18
+ end
19
+
20
+ def write_files
21
+ write_ovpn_files
22
+ write_ca_crt
23
+ write_client_key
24
+ write_client_crt
25
+ rescue Errno::ENOENT, Errno::EACCES
26
+ raise ArgumentError, "Dir #{@dir} doesn't exist or isn't writable"
27
+ end
28
+
29
+ private
30
+
31
+ def write_ovpn_files
32
+ @generator.ovpns.each { |k, v| File.write(File.join(@dir, "#{k}.ovpn"), v) }
33
+ end
34
+
35
+ def write_ca_crt
36
+ File.write File.join(@dir, 'ca.crt'), @generator.ca_crt.to_s.chomp
37
+ end
38
+
39
+ def write_client_key
40
+ File.write File.join(@dir, 'client.key'), @generator.client_key.to_s.chomp
41
+ end
42
+
43
+ def write_client_crt
44
+ File.write File.join(@dir, 'client.crt'), @generator.client_crt.to_s.chomp
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module RiseupVPN
6
+ # utilties for internal use
7
+ module Utils
8
+ SUPPORTED_PLATFORMS = %w[darwin linux].freeze
9
+
10
+ def self.os
11
+ os = Gem::Platform.local.os
12
+ return os if SUPPORTED_PLATFORMS.include? os
13
+
14
+ raise Error, "Unsupported OS: '#{os}'"
15
+ end
16
+
17
+ def self.tls_version
18
+ "1.#{OpenSSL::VERSION.to_i}".to_f
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RiseupVpn
4
- VERSION = '0.1.0'
3
+ module RiseupVPN
4
+ VERSION = '1.0.0'
5
5
  end
data/lib/riseup_vpn.rb CHANGED
@@ -3,11 +3,12 @@
3
3
  require 'json'
4
4
  require 'open-uri'
5
5
 
6
- # namespace
7
- module RiseupVpn
8
- class RiseupVpnError < StandardError; end
6
+ require_relative 'riseup_vpn/api'
7
+ require_relative 'riseup_vpn/errors'
8
+ require_relative 'riseup_vpn/generator'
9
+ require_relative 'riseup_vpn/manager'
10
+ require_relative 'riseup_vpn/version'
9
11
 
10
- def self.os
11
- @os ||= Gem::Platform.local.os
12
- end
12
+ # namespace
13
+ module RiseupVPN
13
14
  end
data/sig/riseup_vpn.rbs CHANGED
@@ -1,4 +1,4 @@
1
- module RiseupVpn
1
+ module RiseupVPN
2
2
  VERSION: String
3
3
  # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riseup_vpn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MatzFan
@@ -23,8 +23,11 @@ files:
23
23
  - assets/vpns.png
24
24
  - lib/riseup_vpn.rb
25
25
  - lib/riseup_vpn/api.rb
26
+ - lib/riseup_vpn/errors.rb
26
27
  - lib/riseup_vpn/generator.rb
28
+ - lib/riseup_vpn/manager.rb
27
29
  - lib/riseup_vpn/template_ovpn.yml
30
+ - lib/riseup_vpn/utils.rb
28
31
  - lib/riseup_vpn/version.rb
29
32
  - sig/riseup_vpn.rbs
30
33
  - tmp/.placeholder
@@ -50,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
53
  - !ruby/object:Gem::Version
51
54
  version: '0'
52
55
  requirements: []
53
- rubygems_version: 3.6.7
56
+ rubygems_version: 3.7.0.dev
54
57
  specification_version: 4
55
58
  summary: RiseupVPN configuration
56
59
  test_files: []