tunnelmtu 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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +11 -0
  3. data/README.md +3 -0
  4. data/bin/tunnelmtu +261 -0
  5. metadata +68 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cbb39e99dfbd5897b0eaecebc385f68594d586ad9489c7927904879d9bcc614f
4
+ data.tar.gz: 9105d16c4f10f2afa09ef5eb8dcae4b38c0b539dcc1bf4fda1120aaf2ed1f862
5
+ SHA512:
6
+ metadata.gz: 01dfc6e9f4b84676d21c2fc71db58068f608895c3de631141b45bfdb7e6b1bd5ca8774e23400da2f84e43368f74ee214057120f0af1ac5ab7aab4a1c9fdc4672
7
+ data.tar.gz: cba995f38a8eef1a03c04bbc025fe3d2f963ff98e8667b31397a5840dafec681be2ea49d7d022d1d217b77fcb9085ff0f465cb766c7b476125ecbb177ffc82e4
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
7
+
8
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
9
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
10
+
11
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # tunnelmtu
2
+
3
+ Interactive script that calculates the optimal MTU for tunnel protocols.
data/bin/tunnelmtu ADDED
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ # sharable_constant_value: literal
4
+
5
+ require 'cli/ui'
6
+
7
+ def ask_openssl_digest
8
+ digests = [
9
+ { name: 'SHA3-512', size: 64 },
10
+ { name: 'SHA512-256', size: 32 },
11
+ { name: 'SHA224', size: 28 },
12
+ { name: 'SHA3-224', size: 28 },
13
+ { name: 'SHA1', size: 20 },
14
+ { name: 'SHA3-384', size: 48 },
15
+ { name: 'RIPEMD160', size: 20 },
16
+ { name: 'SHA512', size: 64 },
17
+ { name: 'SHA512-224', size: 28 },
18
+ { name: 'SHA384', size: 48 },
19
+ { name: 'SM3', size: 32 },
20
+ { name: 'SHA3-256', size: 32 },
21
+ { name: 'MD5', size: 16 },
22
+ { name: 'BLAKE2s256', size: 32 },
23
+ { name: 'SHA256', size: 32 },
24
+ { name: 'BLAKE2b512', size: 64 },
25
+ { name: 'MD5-SHA1', size: 36 },
26
+ { name: 'SHA2-256/192', bits: 192 },
27
+ { name: 'KECCAK-224', size: 28 },
28
+ { name: 'KECCAK-256', size: 32 },
29
+ { name: 'KECCAK-384', size: 48 },
30
+ { name: 'KECCAK-512', size: 64 },
31
+ { name: 'KECCAK-KMAC-128', size: 32 },
32
+ { name: 'KECCAK-KMAC-256', size: 64 }
33
+ ]
34
+ digests_list = digests.map { |v| v[:name] }
35
+
36
+ selected_digest = CLI::UI.ask('Which digest/hash algorithm?', options: digests_list)
37
+
38
+ return digests.find { |d| d[:name] == selected_digest }
39
+ end
40
+
41
+ def ask_openssl_cipher
42
+ ciphers = [
43
+ { name: 'AES', iv_size: 16 },
44
+ { name: 'ARIA', iv_size: 16 },
45
+ { name: 'CAMELLIA', iv_size: 16 },
46
+ { name: 'DES', iv_size: 8 }
47
+ ]
48
+ ciphers_list = ciphers.map { |v| v[:name] }
49
+
50
+ selected_cipher = CLI::UI.ask('Which cipher algorithm?', options: ciphers_list)
51
+
52
+ return ciphers.find { |d| d[:name] == selected_cipher }
53
+ end
54
+
55
+ def get_cbc_mtu(temporary_mtu, in_packet_overhead)
56
+ return temporary_mtu - in_packet_overhead if (temporary_mtu % 16).zero?
57
+
58
+ (temporary_mtu + in_packet_overhead - 1).downto(1) do |i|
59
+ return i - in_packet_overhead - 1 if (i % 16).zero?
60
+ end
61
+ end
62
+
63
+ CLI::UI::StdoutRouter.enable
64
+ CLI::UI.frame_style = :bracket
65
+
66
+ CLI::UI::Frame.open('Tunneling MTU calculator', color: :cyan) do
67
+ outer_mtu = CLI::UI.ask('What is the outer MTU?').to_i
68
+ mtu = outer_mtu
69
+ explanations = []
70
+
71
+ CLI::UI.ask('Which IP protocol is used?') do |handler|
72
+ handler.option 'IPv6 or Dual-Stack (RECOMMENDED)' do
73
+ mtu -= 40
74
+ explanations << { bytes: 40, description: 'IPv6 or Dual-Stack' }
75
+ end
76
+
77
+ handler.option 'IPv4 only' do
78
+ mtu -= 20
79
+ explanations << { bytes: 20, description: 'IPv4' }
80
+ end
81
+ end
82
+
83
+ CLI::UI.ask('Will PPPoE be used for connection?') do |handler|
84
+ handler.option 'Yes' do
85
+ mtu -= 8
86
+ explanations << { bytes: 8, description: 'PPPoE' }
87
+ end
88
+ handler.option 'No' do
89
+ end
90
+ end
91
+
92
+ CLI::UI.ask('Which tunneling protocol would you like to use?') do |handler|
93
+ handler.option 'fastd' do
94
+ mtu -= 8
95
+ explanations << { bytes: 8, description: 'UDP' }
96
+
97
+ CLI::UI.ask('Which tunneling mode is used?') do |handler|
98
+ handler.option 'TUN (layer 3)' do
99
+ explanations << { bytes: 0, description: 'TUN' }
100
+ end
101
+ handler.option 'TAP (layer 2)' do
102
+ mtu -= 14
103
+ explanations << { bytes: 14, description: 'TAP' }
104
+ end
105
+ end
106
+
107
+ CLI::UI.ask('What encryption and authentication method is used?') do |handler|
108
+ handler.option 'null' do
109
+ mtu -= 1
110
+ explanations << { bytes: 1, description: 'null method' }
111
+ end
112
+ handler.option 'null@l2tp' do
113
+ mtu -= 8
114
+ explanations << { bytes: 8, description: 'null@l2tp method' }
115
+ end
116
+ handler.option 'other encryption and authentication method' do
117
+ mtu -= 24
118
+ explanations << { bytes: 24, description: 'encryption and authentication method' }
119
+ end
120
+ end
121
+ end
122
+ handler.option 'WireGuard' do
123
+ mtu -= 40
124
+ explanations << { bytes: 8, description: 'UDP' }
125
+ explanations << { bytes: 32, description: 'WireGuard' }
126
+ end
127
+ handler.option('OpenVPN') do
128
+ CLI::UI.ask('Which transport protocol do you use?') do |handler|
129
+ handler.option 'UDP' do
130
+ mtu -= 8
131
+ explanations << { bytes: 8, description: 'UDP' }
132
+ end
133
+ handler.option 'TCP' do
134
+ mtu -= 60
135
+ explanations << { bytes: 60, description: 'TCP' }
136
+ end
137
+ end
138
+ CLI::UI.ask('What encryption and authentication method is used?') do |handler|
139
+ handler.option 'AEAD ciphers / GCM mode (including CHACHA20-POLY1305)' do
140
+ mtu -= 24
141
+ explanations << { bytes: 24, description: 'OpenVPN' }
142
+ end
143
+ handler.option 'CBC mode' do
144
+ mtu -= 4
145
+ explanations << { bytes: 4, description: 'Opcode, Key-ID and Peer-ID' }
146
+
147
+ hmac = ask_openssl_digest
148
+ mtu -= hmac[:size]
149
+ explanations << { bytes: hmac[:size], description: hmac[:name] }
150
+
151
+ cipher = ask_openssl_cipher
152
+ mtu -= cipher[:iv_size]
153
+ explanations << { bytes: cipher[:iv_size], description: cipher[:name] }
154
+
155
+ CLI::UI.ask('Is a PSK used?') do |handler|
156
+ handler.option 'Yes, a PSK is used.' do
157
+ bmtu = mtu
158
+ mtu = get_cbc_mtu mtu, 8
159
+ explanations << { bytes: bmtu - mtu, description: 'Padding' }
160
+
161
+ explanations << { bytes: 4, description: 'Timestamp' } # subtracted in get_cbc_mtu
162
+ end
163
+ handler.option 'No, PSK is not used.' do
164
+ bmtu = mtu
165
+ mtu = get_cbc_mtu mtu, 4
166
+ explanations << { bytes: bmtu - mtu, description: 'Padding' }
167
+ end
168
+ end
169
+
170
+ explanations << { bytes: 4, description: 'Packet-ID' } # subtracted in get_cbc_mtu
171
+ end
172
+ handler.option 'CFB/OFB mode' do
173
+ mtu -= 4
174
+ explanations << { bytes: 4, description: 'Opcode, Key-ID and Peer-ID' }
175
+
176
+ hmac = ask_openssl_digest
177
+ mtu -= hmac[:size]
178
+ explanations << { bytes: hmac[:size], description: hmac[:name] }
179
+
180
+ cipher = ask_openssl_cipher
181
+ mtu -= cipher[:iv_size]
182
+ explanations << { bytes: cipher[:iv_size], description: cipher[:name] }
183
+ end
184
+ handler.option 'No encryption' do
185
+ mtu -= 4
186
+ explanations << { bytes: 4, description: 'Opcode, Key-ID and Peer-ID' }
187
+
188
+ mtu -= 4
189
+ explanations << { bytes: 4, description: 'Packet-ID' }
190
+
191
+ hmac = ask_openssl_digest
192
+ mtu -= hmac[:size]
193
+ explanations << { bytes: hmac[:size], description: hmac[:name] }
194
+ end
195
+ end
196
+ end
197
+ handler.option('Tinc') do
198
+ CLI::UI.ask('Which Tinc transfer protocol do you use?') do |handler|
199
+ handler.option 'SFTPS (Tinc 1.1)' do
200
+ CLI::UI.ask('Which Tinc protocol version is used?') do |handler|
201
+ handler.option '17.4 or later (IF IN DOUBT, SELECT THIS)' do
202
+ # https://github.com/gsliepen/tinc/commit/8dd1c8a020e3babf5054179b0d30e2aa850d2e2b
203
+ # https://github.com/gsliepen/tinc/blob/940d15c46be812821f134fd7d6333088445b914c/src/net_packet.c#L1293
204
+ mtu -= 12
205
+ explanations << { bytes: 12, description: 'Protocol improvements' }
206
+ end
207
+ handler.option '17.3 or earlier' do
208
+ end
209
+ end
210
+
211
+ mtu -= 21
212
+ explanations << { bytes: 21, description: 'SFTPS' }
213
+ end
214
+ handler.option 'Legacy protocol (Tinc 1.0)' do
215
+ hmac = ask_openssl_digest
216
+ mtu -= hmac[:size]
217
+ explanations << { bytes: hmac[:size], description: hmac[:name] }
218
+
219
+ cipher = ask_openssl_cipher
220
+ mtu -= cipher[:iv_size]
221
+ explanations << { bytes: cipher[:iv_size], description: cipher[:name] }
222
+
223
+ bmtu = mtu
224
+ mtu = get_cbc_mtu mtu, 4
225
+ explanations << { bytes: bmtu - mtu, description: 'Padding' }
226
+
227
+ explanations << { bytes: 4, description: 'Sequence number' } # subtracted in get_cbc_mtu
228
+ end
229
+ end
230
+ end
231
+ # handler.option('GRE') { |selection| selection }
232
+ # handler.option('GRETAP') { |selection| selection }
233
+ end
234
+
235
+ CLI::UI::Frame.open('Overhead Breakdown', color: :blue) do
236
+ puts CLI::UI.fmt '{{bold:Starting Point:}}'
237
+ puts CLI::UI.fmt " Outer MTU: {{cyan:#{outer_mtu}}} Bytes\n"
238
+
239
+ puts CLI::UI.fmt '{{bold:Overhead Components:}}'
240
+ explanations.each do |exp|
241
+ color = if exp[:bytes] > 30
242
+ 'red'
243
+ else
244
+ exp[:bytes] > 15 ? 'yellow' : 'green'
245
+ end
246
+ puts CLI::UI.fmt " {{v}} {{bold:#{exp[:description]}:}} {{#{color}:-#{exp[:bytes]}}} Bytes"
247
+ end
248
+ end
249
+
250
+ CLI::UI::Frame.open('Result', color: :green) do
251
+ puts CLI::UI.fmt "{{bold:Optimal MTU: {{cyan:#{mtu}}} Bytes}}"
252
+ end
253
+
254
+ if mtu < 1280
255
+ CLI::UI::Frame.open('Warning', color: :red) do
256
+ puts CLI::UI.fmt '{{red:{{bold:MTU below 1280 Bytes!}}}}'
257
+ puts 'IPv6 requires a minimum MTU of 1280 Bytes.'
258
+ puts 'Fragmentation will be unavoidable.'
259
+ end
260
+ end
261
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tunnelmtu
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Marek Küthe
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: cli-ui
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.7'
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 2.7.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '2.7'
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 2.7.0
32
+ description: Interactive script that calculates the optimal MTU for tunnel protocols.
33
+ email: m.k@mk16.de
34
+ executables:
35
+ - tunnelmtu
36
+ extensions: []
37
+ extra_rdoc_files:
38
+ - LICENSE
39
+ - README.md
40
+ files:
41
+ - LICENSE
42
+ - README.md
43
+ - bin/tunnelmtu
44
+ homepage: https://codeberg.org/mark22k/tunnelmtu
45
+ licenses:
46
+ - WTFPL
47
+ metadata:
48
+ source_code_uri: https://codeberg.org/mark22k/tunnelmtu
49
+ bug_tracker_uri: https://codeberg.org/mark22k/tunnelmtu/issues
50
+ rubygems_mfa_required: 'true'
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '3.1'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 4.0.4
66
+ specification_version: 4
67
+ summary: Interactive script that calculates the optimal MTU for tunnel protocols.
68
+ test_files: []