puffy 0.1.0 → 0.2.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 +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/workflows/ci.yml +23 -5
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +50 -0
- data/README.md +22 -13
- data/Rakefile +10 -0
- data/bin/puffy +2 -5
- data/lib/core_ext.rb +16 -4
- data/lib/puffy/cli.rb +1 -1
- data/lib/puffy/formatters/{netfilter.rb → iptables.rb} +7 -7
- data/lib/puffy/formatters/iptables4.rb +23 -0
- data/lib/puffy/formatters/iptables6.rb +23 -0
- data/lib/puffy/parser.tab.rb +406 -360
- data/lib/puffy/puppet.rb +4 -6
- data/lib/puffy/resolver.rb +32 -0
- data/lib/puffy/rule.rb +11 -2
- data/lib/puffy/rule_factory.rb +7 -5
- data/lib/puffy/version.rb +1 -1
- data/lib/puffy.rb +6 -3
- data/puffy.gemspec +2 -0
- metadata +23 -6
- data/lib/puffy/formatters/netfilter4.rb +0 -23
- data/lib/puffy/formatters/netfilter6.rb +0 -23
data/lib/puffy/puppet.rb
CHANGED
@@ -15,8 +15,8 @@ module Puffy
|
|
15
15
|
|
16
16
|
@formatters = [
|
17
17
|
Puffy::Formatters::Pf::Ruleset.new,
|
18
|
-
Puffy::Formatters::
|
19
|
-
Puffy::Formatters::
|
18
|
+
Puffy::Formatters::Iptables4::Ruleset.new,
|
19
|
+
Puffy::Formatters::Iptables6::Ruleset.new,
|
20
20
|
]
|
21
21
|
end
|
22
22
|
|
@@ -29,9 +29,7 @@ module Puffy
|
|
29
29
|
|
30
30
|
next unless fragment_changed?(fragment_name, fragment_content)
|
31
31
|
|
32
|
-
File.
|
33
|
-
f.write(fragment_content)
|
34
|
-
end
|
32
|
+
File.write(fragment_name, fragment_content)
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
@@ -67,7 +65,7 @@ module Puffy
|
|
67
65
|
def fragment_changed?(fragment_name, fragment_content)
|
68
66
|
return true unless File.exist?(fragment_name)
|
69
67
|
|
70
|
-
File.read(fragment_name).split("\n").
|
68
|
+
File.read(fragment_name).split("\n").grep_v(/^#/) != fragment_content.split("\n").grep_v(/^#/)
|
71
69
|
end
|
72
70
|
end
|
73
71
|
end
|
data/lib/puffy/resolver.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'open-uri'
|
3
4
|
require 'resolv'
|
4
5
|
require 'singleton'
|
5
6
|
|
@@ -29,8 +30,39 @@ module Puffy
|
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
33
|
+
# Resolve the SRV record for +service+ and return its target and port.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# Resolver.instance.resolv_srv('_http._tcp.deb.debian.org')
|
37
|
+
# #=> [{ host: 'debian.map.fastlydns.net.', port: 80 }]
|
38
|
+
#
|
39
|
+
# @param service [String] The service to resolve
|
40
|
+
# @return [Array<Hash>]
|
41
|
+
def resolv_srv(service)
|
42
|
+
proto = service.split('.')[1][1..-1].to_sym
|
43
|
+
@dns.getresources(service, Resolv::DNS::Resource::IN::SRV).collect { |r| { host: r.target.to_s, port: r.port, proto_hint: proto } }.sort
|
44
|
+
end
|
45
|
+
|
46
|
+
def resolv_apt_mirror(url)
|
47
|
+
res = []
|
48
|
+
http_url = url.sub(%r{^mirror(\+http)?://}, 'http://')
|
49
|
+
res << parse_url(http_url)
|
50
|
+
|
51
|
+
URI.parse(http_url).open do |document|
|
52
|
+
document.each_line do |line|
|
53
|
+
res << parse_url(line)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
res
|
57
|
+
end
|
58
|
+
|
32
59
|
private
|
33
60
|
|
61
|
+
def parse_url(url)
|
62
|
+
url =~ %r{^([^:]+)://([^/]+)}
|
63
|
+
{ host: Regexp.last_match(2), port: Regexp.last_match(1), proto_hint: :tcp }
|
64
|
+
end
|
65
|
+
|
34
66
|
def resolv_ipaddress(address, address_family)
|
35
67
|
filter_af(address, address_family)
|
36
68
|
end
|
data/lib/puffy/rule.rb
CHANGED
@@ -66,6 +66,8 @@ module Puffy
|
|
66
66
|
|
67
67
|
@af = detect_af unless af
|
68
68
|
|
69
|
+
self.proto ||= from_proto_hint || to_proto_hint
|
70
|
+
|
69
71
|
raise "unsupported action `#{options[:action]}'" unless valid_action?
|
70
72
|
raise 'if from_port or to_port is specified, the protocol must also be given' if port_without_protocol?
|
71
73
|
end
|
@@ -138,16 +140,22 @@ module Puffy
|
|
138
140
|
# Returns the source host of the Puffy::Rule.
|
139
141
|
# @!method from_port
|
140
142
|
# Returns the source port of the Puffy::Rule.
|
143
|
+
# @!method from_proto_hint
|
144
|
+
# Returns the proto hint of the Puffy::Rule.
|
141
145
|
# @!method to_host
|
142
146
|
# Returns the destination host of the Puffy::Rule.
|
143
147
|
# @!method to_port
|
144
148
|
# Returns the destination port of the Puffy::Rule.
|
149
|
+
# @!method to_proto_hint
|
150
|
+
# Returns the proto hint of the Puffy::Rule.
|
145
151
|
# @!method rdr_to_host
|
146
152
|
# Returns the redirect destination host of the Puffy::Rule.
|
147
153
|
# @!method rdr_to_port
|
148
154
|
# Returns the redirect destination port of the Puffy::Rule.
|
155
|
+
# @!method rdr_to_proto_hint
|
156
|
+
# Returns the proto hint of the Puffy::Rule (does not make sense).
|
149
157
|
%i[from to rdr_to].each do |destination|
|
150
|
-
%i[host port].each do |param|
|
158
|
+
%i[host port proto_hint].each do |param|
|
151
159
|
define_method("#{destination}_#{param}") do
|
152
160
|
res = public_send(destination)
|
153
161
|
res && res[param]
|
@@ -197,7 +205,8 @@ module Puffy
|
|
197
205
|
if res.nil? then nil
|
198
206
|
elsif res.ipv4? then :inet
|
199
207
|
elsif res.ipv6? then :inet6
|
200
|
-
else
|
208
|
+
else
|
209
|
+
raise 'Fail'
|
201
210
|
end
|
202
211
|
end.uniq.compact
|
203
212
|
end
|
data/lib/puffy/rule_factory.rb
CHANGED
@@ -34,7 +34,7 @@ module Puffy
|
|
34
34
|
def build(options = {})
|
35
35
|
return [] if options == {}
|
36
36
|
|
37
|
-
options = { action: nil, return: false, dir: nil, af: nil, proto: nil, on: nil, from: { host: nil, port: nil }, to: { host: nil, port: nil }, nat_to: nil, rdr_to: { host: nil, port: nil } }.merge(options)
|
37
|
+
options = { action: nil, return: false, dir: nil, af: nil, proto: nil, on: nil, from: [{ host: nil, port: nil }], to: [{ host: nil, port: nil }], nat_to: nil, rdr_to: [{ host: nil, port: nil }] }.merge(options)
|
38
38
|
|
39
39
|
options = resolv_hostnames_and_ports(options)
|
40
40
|
instanciate_rules(options)
|
@@ -44,8 +44,10 @@ module Puffy
|
|
44
44
|
|
45
45
|
def resolv_hostnames_and_ports(options)
|
46
46
|
%i[from to rdr_to].each do |endpoint|
|
47
|
-
options[endpoint]
|
48
|
-
|
47
|
+
options[endpoint].map do |ep|
|
48
|
+
ep[:host] = host_lookup(ep[:host])
|
49
|
+
ep[:port] = port_lookup(ep[:port])
|
50
|
+
end
|
49
51
|
end
|
50
52
|
options[:nat_to] = host_lookup(options[:nat_to])
|
51
53
|
options
|
@@ -74,8 +76,8 @@ module Puffy
|
|
74
76
|
end
|
75
77
|
end
|
76
78
|
|
77
|
-
def af_match_policy?(
|
78
|
-
@af.nil? ||
|
79
|
+
def af_match_policy?(address_family)
|
80
|
+
@af.nil? || address_family.nil? || address_family == @af
|
79
81
|
end
|
80
82
|
|
81
83
|
def host_lookup(host)
|
data/lib/puffy/version.rb
CHANGED
data/lib/puffy.rb
CHANGED
@@ -4,9 +4,9 @@ require 'core_ext'
|
|
4
4
|
|
5
5
|
require 'puffy/parser.tab'
|
6
6
|
require 'puffy/formatters/base'
|
7
|
-
require 'puffy/formatters/
|
8
|
-
require 'puffy/formatters/
|
9
|
-
require 'puffy/formatters/
|
7
|
+
require 'puffy/formatters/iptables'
|
8
|
+
require 'puffy/formatters/iptables4'
|
9
|
+
require 'puffy/formatters/iptables6'
|
10
10
|
require 'puffy/formatters/pf'
|
11
11
|
require 'puffy/puppet'
|
12
12
|
require 'puffy/resolver'
|
@@ -15,6 +15,7 @@ require 'puffy/rule_factory'
|
|
15
15
|
require 'puffy/version'
|
16
16
|
|
17
17
|
module Puffy
|
18
|
+
# Base class for application errors with a configuration file
|
18
19
|
class PuffyError < RuntimeError
|
19
20
|
def initialize(message, token)
|
20
21
|
super(message)
|
@@ -54,9 +55,11 @@ module Puffy
|
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
58
|
+
# Invalid configuration file
|
57
59
|
class ParseError < PuffyError
|
58
60
|
end
|
59
61
|
|
62
|
+
# Syntax error in configuration file
|
60
63
|
class SyntaxError < PuffyError
|
61
64
|
end
|
62
65
|
end
|
data/puffy.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.metadata['homepage_uri'] = spec.homepage
|
19
19
|
spec.metadata['source_code_uri'] = spec.homepage
|
20
20
|
spec.metadata['changelog_uri'] = spec.homepage
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
21
22
|
|
22
23
|
# Specify which files should be added to the gem when it is released.
|
23
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -36,6 +37,7 @@ Gem::Specification.new do |spec|
|
|
36
37
|
spec.add_development_dependency 'aruba'
|
37
38
|
spec.add_development_dependency 'bundler'
|
38
39
|
spec.add_development_dependency 'cucumber'
|
40
|
+
spec.add_development_dependency 'github_changelog_generator'
|
39
41
|
spec.add_development_dependency 'racc'
|
40
42
|
spec.add_development_dependency 'rake'
|
41
43
|
spec.add_development_dependency 'rspec'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puffy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Romain Tartière
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cri
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: github_changelog_generator
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: racc
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,11 +214,13 @@ executables:
|
|
200
214
|
extensions: []
|
201
215
|
extra_rdoc_files: []
|
202
216
|
files:
|
217
|
+
- ".github/CODEOWNERS"
|
203
218
|
- ".github/workflows/ci.yml"
|
204
219
|
- ".gitignore"
|
205
220
|
- ".rspec"
|
206
221
|
- ".rubocop.yml"
|
207
222
|
- ".simplecov"
|
223
|
+
- CHANGELOG.md
|
208
224
|
- Gemfile
|
209
225
|
- README.md
|
210
226
|
- Rakefile
|
@@ -213,9 +229,9 @@ files:
|
|
213
229
|
- lib/puffy.rb
|
214
230
|
- lib/puffy/cli.rb
|
215
231
|
- lib/puffy/formatters/base.rb
|
216
|
-
- lib/puffy/formatters/
|
217
|
-
- lib/puffy/formatters/
|
218
|
-
- lib/puffy/formatters/
|
232
|
+
- lib/puffy/formatters/iptables.rb
|
233
|
+
- lib/puffy/formatters/iptables4.rb
|
234
|
+
- lib/puffy/formatters/iptables6.rb
|
219
235
|
- lib/puffy/formatters/pf.rb
|
220
236
|
- lib/puffy/parser.tab.rb
|
221
237
|
- lib/puffy/puppet.rb
|
@@ -232,6 +248,7 @@ metadata:
|
|
232
248
|
homepage_uri: https://github.com/opus-codium/puffy
|
233
249
|
source_code_uri: https://github.com/opus-codium/puffy
|
234
250
|
changelog_uri: https://github.com/opus-codium/puffy
|
251
|
+
rubygems_mfa_required: 'true'
|
235
252
|
post_install_message:
|
236
253
|
rdoc_options: []
|
237
254
|
require_paths:
|
@@ -247,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
264
|
- !ruby/object:Gem::Version
|
248
265
|
version: '0'
|
249
266
|
requirements: []
|
250
|
-
rubygems_version: 3.
|
267
|
+
rubygems_version: 3.3.23
|
251
268
|
signing_key:
|
252
269
|
specification_version: 4
|
253
270
|
summary: Network firewall rules made easy!
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Puffy
|
4
|
-
module Formatters
|
5
|
-
module Netfilter4 # :nodoc:
|
6
|
-
# IPv4 Netfilter implementation of a Puffy Ruleset formatter.
|
7
|
-
class Ruleset < Puffy::Formatters::Netfilter::Ruleset # :nodoc:
|
8
|
-
# Return an IPv4 Netfilter String representation of the provided +rules+ Puffy::Rule with the +policy+ policy.
|
9
|
-
def emit_ruleset(rules, policy = :block)
|
10
|
-
super(rules.select(&:ipv4?), policy)
|
11
|
-
end
|
12
|
-
|
13
|
-
def filename_fragment
|
14
|
-
['netfilter', 'rules.v4']
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# IPv4 Netfilter implementation of a Puffy Rulet formatter.
|
19
|
-
class Rule < Puffy::Formatters::Netfilter::Rule # :nodoc:
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Puffy
|
4
|
-
module Formatters
|
5
|
-
module Netfilter6 # :nodoc:
|
6
|
-
# IPv6 Netfilter implementation of a Puffy Ruleset formatter.
|
7
|
-
class Ruleset < Puffy::Formatters::Netfilter::Ruleset # :nodoc:
|
8
|
-
# Return an IPv6 Netfilter String representation of the provided +rules+ Puffy::Rule with the +policy+ policy.
|
9
|
-
def emit_ruleset(rules, policy = :block)
|
10
|
-
super(rules.select(&:ipv6?), policy)
|
11
|
-
end
|
12
|
-
|
13
|
-
def filename_fragment
|
14
|
-
['netfilter', 'rules.v6']
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# IPv6 Netfilter implementation of a Puffy Rule formatter.
|
19
|
-
class Rule < Puffy::Formatters::Netfilter::Rule # :nodoc:
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|