s3-secure 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +3 -2
  4. data/lib/s3_secure/access_logs/base.rb +2 -2
  5. data/lib/s3_secure/access_logs/disable.rb +1 -1
  6. data/lib/s3_secure/access_logs/enable.rb +1 -1
  7. data/lib/s3_secure/access_logs/list.rb +1 -1
  8. data/lib/s3_secure/access_logs/show.rb +1 -1
  9. data/lib/s3_secure/aws_services/s3.rb +7 -0
  10. data/lib/s3_secure/aws_services.rb +6 -0
  11. data/lib/s3_secure/{access_logs.rb → cli/access_logs.rb} +6 -6
  12. data/lib/s3_secure/{abstract_base.rb → cli/base.rb} +2 -2
  13. data/lib/s3_secure/{batch.rb → cli/batch.rb} +1 -1
  14. data/lib/s3_secure/{encryption.rb → cli/encryption.rb} +6 -6
  15. data/lib/s3_secure/cli/help.rb +11 -0
  16. data/lib/s3_secure/{lifecycle.rb → cli/lifecycle.rb} +6 -6
  17. data/lib/s3_secure/{policy.rb → cli/policy.rb} +6 -6
  18. data/lib/s3_secure/cli/public_access.rb +32 -0
  19. data/lib/s3_secure/{remediate_all.rb → cli/remediate_all.rb} +2 -2
  20. data/lib/s3_secure/{say.rb → cli/say.rb} +1 -1
  21. data/lib/s3_secure/{summary.rb → cli/summary.rb} +3 -3
  22. data/lib/s3_secure/{versioning.rb → cli/versioning.rb} +6 -6
  23. data/lib/s3_secure/cli.rb +5 -1
  24. data/lib/s3_secure/encryption/base.rb +2 -2
  25. data/lib/s3_secure/encryption/disable.rb +1 -1
  26. data/lib/s3_secure/encryption/enable.rb +1 -1
  27. data/lib/s3_secure/encryption/list.rb +1 -1
  28. data/lib/s3_secure/encryption/show.rb +2 -1
  29. data/lib/s3_secure/lifecycle/add.rb +1 -1
  30. data/lib/s3_secure/lifecycle/base.rb +2 -2
  31. data/lib/s3_secure/lifecycle/builder.rb +1 -1
  32. data/lib/s3_secure/lifecycle/list.rb +1 -1
  33. data/lib/s3_secure/lifecycle/remove.rb +1 -1
  34. data/lib/s3_secure/lifecycle/show.rb +1 -1
  35. data/lib/s3_secure/policy/base.rb +2 -2
  36. data/lib/s3_secure/policy/checker.rb +1 -1
  37. data/lib/s3_secure/policy/document/base.rb +1 -1
  38. data/lib/s3_secure/policy/document/force_ssl_only_access.rb +1 -1
  39. data/lib/s3_secure/policy/document/force_ssl_only_access_remove.rb +1 -1
  40. data/lib/s3_secure/policy/document.rb +1 -1
  41. data/lib/s3_secure/policy/enforce.rb +1 -1
  42. data/lib/s3_secure/policy/list.rb +1 -1
  43. data/lib/s3_secure/policy/show.rb +1 -1
  44. data/lib/s3_secure/policy/unforce.rb +1 -1
  45. data/lib/s3_secure/public_access/base.rb +10 -0
  46. data/lib/s3_secure/public_access/block.rb +18 -0
  47. data/lib/s3_secure/public_access/list.rb +24 -0
  48. data/lib/s3_secure/public_access/show.rb +27 -0
  49. data/lib/s3_secure/public_access/unblock.rb +12 -0
  50. data/lib/s3_secure/summary/item.rb +1 -1
  51. data/lib/s3_secure/summary/items.rb +6 -7
  52. data/lib/s3_secure/version.rb +1 -1
  53. data/lib/s3_secure/versioning/base.rb +2 -2
  54. data/lib/s3_secure/versioning/disable.rb +1 -1
  55. data/lib/s3_secure/versioning/enable.rb +1 -1
  56. data/lib/s3_secure/versioning/list.rb +1 -1
  57. data/lib/s3_secure/versioning/show.rb +1 -1
  58. data/lib/s3_secure.rb +1 -0
  59. data/s3-secure.gemspec +2 -1
  60. metadata +35 -15
  61. data/lib/s3_secure/help.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fe4cf360f3085cd6d3a6432163e48446163b3fb4c873594198009a9eca48352
4
- data.tar.gz: 74458fbc45b76b221c51dd75120f75c0122cd32aee9efc1a2516fcba8eaeaebb
3
+ metadata.gz: 739695e06691bf9716545d0874b7a92bca5c739d78ebd7caee2458a45dbf767e
4
+ data.tar.gz: 2b9d47ad43044cd0b70e4063639d08c7963e8c144057ddc4b56556e07f7d7ee1
5
5
  SHA512:
6
- metadata.gz: 3a657388018a9a0aac3b396e6d7480e210871cd2a0f6a7a85cc31a22f9b1caa7ef0e536bfe2dbbf7a921fc1c5f98366c36f388a36330b55cb9ca740fc0ffa56f
7
- data.tar.gz: c52d3846e952af1438bb9f776d66e976a9645b5ec2c8ba8cfec18ae2ce9e24526d69f9c07951b25aaa26cc74c56da25585083c57f9d9775c2f0bd5f78ea89107
6
+ metadata.gz: a68b9daf5ec3b047776a5e3e70ecf7aa680bb5fb685d911ff82d04c0baffd73b13e2d5acc3c899a241c10a2da7825de8b35a8fbe89116c95f515be1ee4b70017
7
+ data.tar.gz: 48346b04e0e720b004aec4b73ecb8da5c191b0f0018eceb9041a0b32fdd71f5a840a005be4df5daed95752af125770ceebc48e06b39b2131adb3c29af0463861
data/CHANGELOG.md CHANGED
@@ -3,6 +3,11 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.6.0] - 2021-12-30
7
+ - [#4](https://github.com/tongueroo/s3-secure/pull/4) refactor move directly related cli classes to subfolder
8
+ - [#5](https://github.com/tongueroo/s3-secure/pull/5) add public access block support
9
+ - fix activesupport require
10
+
6
11
  ## [0.5.1]
7
12
  - #3 add quiet option
8
13
 
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # s3-secure tool
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/s3-secure.png)](http://badge.fury.io/rb/s3-secure)]
3
+ [![Gem Version](https://badge.fury.io/rb/s3-secure.png)](http://badge.fury.io/rb/s3-secure)
4
+
4
5
  [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
5
6
 
6
7
  The s3-secure tool can be used to harden your s3 bucket security posture. The tool is useful if you have a lot of buckets to update. It supports:
@@ -171,4 +172,4 @@ buckets.txt:
171
172
 
172
173
  Install with:
173
174
 
174
- gem install s3-secure
175
+ gem install s3-secure
@@ -1,4 +1,4 @@
1
- class S3Secure::AccessLogs
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::AccessLogs
2
+ class Base < S3Secure::CLI::Base
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::AccessLogs
1
+ module S3Secure::AccessLogs
2
2
  class Disable < Base
3
3
  def run
4
4
  @show = Show.new(bucket: @bucket)
@@ -1,4 +1,4 @@
1
- class S3Secure::AccessLogs
1
+ module S3Secure::AccessLogs
2
2
  class Enable < Base
3
3
  def run
4
4
  @show = Show.new(bucket: @bucket)
@@ -1,4 +1,4 @@
1
- class S3Secure::AccessLogs
1
+ module S3Secure::AccessLogs
2
2
  class List < Base
3
3
  def run
4
4
  presenter = CliFormat::Presenter.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::AccessLogs
1
+ module S3Secure::AccessLogs
2
2
  class Show < Base
3
3
  def run
4
4
  say "Bucket ACL:"
@@ -8,6 +8,13 @@ module S3Secure::AwsServices
8
8
  @@s3_clients[@bucket] ||= new_s3_regional_client
9
9
  end
10
10
 
11
+ def s3_regional_client(bucket)
12
+ temp = @bucket
13
+ @bucket = bucket
14
+ @@s3_clients[bucket] ||= new_s3_regional_client
15
+ @bucket = temp
16
+ end
17
+
11
18
  def new_s3_regional_client
12
19
  options = {}
13
20
  options[:endpoint] = "https://s3.#{region}.amazonaws.com"
@@ -2,6 +2,12 @@ require "aws-sdk-s3"
2
2
 
3
3
  module S3Secure
4
4
  module AwsServices
5
+ extend Memoist
5
6
  include S3
7
+
8
+ def sts
9
+ Aws::STS::Client.new
10
+ end
11
+ memoize :sts
6
12
  end
7
13
  end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class AccessLogs < Command
1
+ class S3Secure::CLI
2
+ class AccessLogs < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
 
5
5
  desc "list", "List bucket access_logs setting"
@@ -7,26 +7,26 @@ module S3Secure
7
7
  option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
8
  option :access_logs, type: :boolean, desc: "Filter for access_logs: all, true, false"
9
9
  def list
10
- List.new(options).run
10
+ S3Secure::AccessLogs::List.new(options).run
11
11
  end
12
12
 
13
13
  desc "show BUCKET", "show bucket access_logs"
14
14
  long_desc Help.text("access_logs/show")
15
15
  def show(bucket)
16
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::AccessLogs::Show.new(options.merge(bucket: bucket)).run
17
17
  end
18
18
 
19
19
  desc "enable BUCKET", "enable bucket access_logs"
20
20
  long_desc Help.text("access_logs/enable")
21
21
  option :target_bucket, desc: "Target s3 bucket"
22
22
  def enable(bucket)
23
- Enable.new(options.merge(bucket: bucket)).run
23
+ S3Secure::AccessLogs::Enable.new(options.merge(bucket: bucket)).run
24
24
  end
25
25
 
26
26
  desc "disable BUCKET", "disable bucket access_logs"
27
27
  long_desc Help.text("access_logs/disable")
28
28
  def disable(bucket)
29
- Disable.new(options.merge(bucket: bucket)).run
29
+ S3Secure::AccessLogs::Disable.new(options.merge(bucket: bucket)).run
30
30
  end
31
31
  end
32
32
  end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class AbstractBase
1
+ class S3Secure::CLI
2
+ class Base
3
3
  extend Memoist
4
4
  include S3Secure::AwsServices
5
5
  include Say
@@ -1,4 +1,4 @@
1
- module S3Secure
1
+ class S3Secure::CLI
2
2
  class Batch
3
3
  extend Memoist
4
4
 
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class Encryption < Command
1
+ class S3Secure::CLI
2
+ class Encryption < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
 
5
5
  desc "list", "List bucket encryptions"
@@ -7,26 +7,26 @@ module S3Secure
7
7
  option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
8
  option :encryption, type: :boolean, desc: "Filter for encryption: all, true, false"
9
9
  def list
10
- List.new(options).run
10
+ S3Secure::Encryption::List.new(options).run
11
11
  end
12
12
 
13
13
  desc "show BUCKET", "show bucket encryption"
14
14
  long_desc Help.text("encryption/show")
15
15
  def show(bucket)
16
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::Encryption::Show.new(options.merge(bucket: bucket)).run
17
17
  end
18
18
 
19
19
  desc "enable BUCKET", "enable bucket encryption"
20
20
  long_desc Help.text("encryption/enable")
21
21
  option :kms_key, desc: "KMS Key Id. If this is set will use sse_algorithm=aws:kms Otherwise will use sse_algorithm=AES256"
22
22
  def enable(bucket)
23
- Enable.new(options.merge(bucket: bucket)).run
23
+ S3Secure::Encryption::Enable.new(options.merge(bucket: bucket)).run
24
24
  end
25
25
 
26
26
  desc "disable BUCKET", "disable bucket encryption"
27
27
  long_desc Help.text("encryption/disable")
28
28
  def disable(bucket)
29
- Disable.new(options.merge(bucket: bucket)).run
29
+ S3Secure::Encryption::Disable.new(options.merge(bucket: bucket)).run
30
30
  end
31
31
  end
32
32
  end
@@ -0,0 +1,11 @@
1
+ class S3Secure::CLI
2
+ class Help
3
+ class << self
4
+ def text(namespaced_command)
5
+ path = namespaced_command.to_s.gsub(':','/')
6
+ path = File.expand_path("../help/#{path}.md", __FILE__)
7
+ IO.read(path) if File.exist?(path)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class Lifecycle < Command
1
+ class S3Secure::CLI
2
+ class Lifecycle < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
 
5
5
  desc "list", "List bucket lifecycles"
@@ -7,13 +7,13 @@ module S3Secure
7
7
  option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
8
  option :lifecycle, desc: "Filter for lifecycle: all, true, false"
9
9
  def list
10
- List.new(options).run
10
+ S3Secure::Lifecycle::List.new(options).run
11
11
  end
12
12
 
13
13
  desc "show BUCKET", "show bucket lifecycle"
14
14
  long_desc Help.text("lifecycle/show")
15
15
  def show(bucket)
16
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::Lifecycle::Show.new(options.merge(bucket: bucket)).run
17
17
  end
18
18
 
19
19
  desc "add BUCKET", "add bucket lifecycle"
@@ -21,13 +21,13 @@ module S3Secure
21
21
  option :additive, type: :boolean, desc: "Force adding another lifecycle rule even if one exists. Note, may fail, need a different prefix filter"
22
22
  option :prefix, desc: "Filter prefix. Used with additive mode."
23
23
  def add(bucket)
24
- Add.new(options.merge(bucket: bucket)).run
24
+ S3Secure::Lifecycle::Add.new(options.merge(bucket: bucket)).run
25
25
  end
26
26
 
27
27
  desc "remove BUCKET", "remove bucket lifecycle"
28
28
  long_desc Help.text("lifecycle/remove")
29
29
  def remove(bucket)
30
- Remove.new(options.merge(bucket: bucket)).run
30
+ S3Secure::Lifecycle::Remove.new(options.merge(bucket: bucket)).run
31
31
  end
32
32
  end
33
33
  end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class Policy < Command
1
+ class S3Secure::CLI
2
+ class Policy < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
 
5
5
  desc "list", "List bucket policies"
@@ -7,25 +7,25 @@ module S3Secure
7
7
  option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
8
  option :policy, type: :boolean, desc: "Filter for policy: all, true, false"
9
9
  def list
10
- List.new(options).run
10
+ S3Secure::Policy::List.new(options).run
11
11
  end
12
12
 
13
13
  desc "show BUCKET", "show bucket policy"
14
14
  long_desc Help.text("policy/show")
15
15
  def show(bucket)
16
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::Policy::Show.new(options.merge(bucket: bucket)).run
17
17
  end
18
18
 
19
19
  desc "enforce_ssl BUCKET", "Add enforce ssl bucket policy"
20
20
  long_desc Help.text("policy/enforce_ssl")
21
21
  def enforce_ssl(bucket)
22
- Enforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
22
+ S3Secure::Policy::Enforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
23
23
  end
24
24
 
25
25
  desc "unforce_ssl BUCKET", "Remove enforce ssl bucket policy"
26
26
  long_desc Help.text("policy/unforce_ssl")
27
27
  def unforce_ssl(bucket)
28
- Unforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
28
+ S3Secure::Policy::Unforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,32 @@
1
+ class S3Secure::CLI
2
+ class PublicAccess < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket public access policy"
6
+ long_desc Help.text("public_access/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :blocked, desc: "Filter for public_access: all, true, false"
9
+ def list
10
+ S3Secure::PublicAccess::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket public_access"
14
+ long_desc Help.text("public_access/show")
15
+ def show(bucket)
16
+ S3Secure::PublicAccess::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "block BUCKET", "block bucket public_access"
20
+ long_desc Help.text("public_access/block")
21
+ option :prefix, desc: "Filter prefix. Used with mode."
22
+ def block(bucket)
23
+ S3Secure::PublicAccess::Block.new(options.merge(bucket: bucket)).run
24
+ end
25
+
26
+ desc "unblock BUCKET", "unblock bucket public_access"
27
+ long_desc Help.text("public_access/unblock")
28
+ def unblock(bucket)
29
+ S3Secure::PublicAccess::Unblock.new(options.merge(bucket: bucket)).run
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class RemediateAll < AbstractBase
1
+ class S3Secure::CLI
2
+ class RemediateAll < Base
3
3
  def run
4
4
  o = @options.merge(bucket: @bucket)
5
5
  Encryption::Enable.new(o).run
@@ -1,4 +1,4 @@
1
- module S3Secure
1
+ class S3Secure::CLI
2
2
  module Say
3
3
  def say(msg)
4
4
  puts msg unless @options[:quiet]
@@ -1,9 +1,9 @@
1
- module S3Secure
2
- class Summary < AbstractBase
1
+ class S3Secure::CLI
2
+ class Summary < Base
3
3
  def run
4
4
  $stderr.puts("Determining bucket security-related settings. Can take a while for lots of buckets...")
5
5
  data = [%w[Bucket SSL? Encrypted?]]
6
- items = Items.new(@options, buckets)
6
+ items = S3Secure::Summary::Items.new(@options, buckets)
7
7
  items.filtered_items.each do |i|
8
8
  data << [i.bucket, i.ssl, i.encrypted]
9
9
  end
@@ -1,5 +1,5 @@
1
- module S3Secure
2
- class Versioning < Command
1
+ class S3Secure::CLI
2
+ class Versioning < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
 
5
5
  desc "list", "List bucket versionings"
@@ -7,25 +7,25 @@ module S3Secure
7
7
  option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
8
  option :versioning, desc: "Filter for versioning: all, true, false"
9
9
  def list
10
- List.new(options).run
10
+ S3Secure::Versioning::List.new(options).run
11
11
  end
12
12
 
13
13
  desc "show BUCKET", "show bucket versioning"
14
14
  long_desc Help.text("versioning/show")
15
15
  def show(bucket)
16
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::Versioning::Show.new(options.merge(bucket: bucket)).run
17
17
  end
18
18
 
19
19
  desc "enable BUCKET", "enable bucket versioning"
20
20
  long_desc Help.text("versioning/enable")
21
21
  def enable(bucket)
22
- Enable.new(options.merge(bucket: bucket)).run
22
+ S3Secure::Versioning::Enable.new(options.merge(bucket: bucket)).run
23
23
  end
24
24
 
25
25
  desc "disable BUCKET", "disable bucket versioning"
26
26
  long_desc Help.text("versioning/disable")
27
27
  def disable(bucket)
28
- Disable.new(options.merge(bucket: bucket)).run
28
+ S3Secure::Versioning::Disable.new(options.merge(bucket: bucket)).run
29
29
  end
30
30
  end
31
31
  end
data/lib/s3_secure/cli.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module S3Secure
2
- class CLI < Command
2
+ class CLI < S3Secure::Command
3
3
  class_option :quiet, type: :boolean
4
4
  class_option :noop, type: :boolean
5
5
 
@@ -23,6 +23,10 @@ module S3Secure
23
23
  long_desc Help.text(:lifecycle)
24
24
  subcommand "lifecycle", Lifecycle
25
25
 
26
+ desc "public_access SUBCOMMAND", "public_access subcommands"
27
+ long_desc Help.text(:public_access)
28
+ subcommand "public_access", PublicAccess
29
+
26
30
  desc "remediate_all BUCKET", "Remediate all. For more fine-grain control use each of the commands directly."
27
31
  long_desc Help.text("remediate_all")
28
32
  def remediate_all(bucket)
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::Encryption
2
+ class Base < S3Secure::CLI::Base
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Disable < Base
3
3
  def run
4
4
  show = Show.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Enable < Base
3
3
  def run
4
4
  show = Show.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class List < Base
3
3
  def run
4
4
  presenter = CliFormat::Presenter.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Show < Base
3
3
  def run
4
4
  if rules
@@ -7,6 +7,7 @@ class S3Secure::Encryption
7
7
  else
8
8
  say "Bucket #{@bucket} is not configured with encryption at the bucket level"
9
9
  end
10
+ rules
10
11
  end
11
12
 
12
13
  def enabled?
@@ -1,4 +1,4 @@
1
- class S3Secure::Lifecycle
1
+ module S3Secure::Lifecycle
2
2
  class Add < Base
3
3
  RULE_ID = Base::RULE_ID
4
4
 
@@ -1,5 +1,5 @@
1
- class S3Secure::Lifecycle
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::Lifecycle
2
+ class Base < S3Secure::CLI::Base
3
3
  RULE_ID = "s3-secure-automated-cleanup"
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Lifecycle
1
+ module S3Secure::Lifecycle
2
2
  class Builder
3
3
  # Note: put_bucket_lifecycle_configuration and put_bucket_lifecycle understand different payloads.
4
4
  # put_bucket_lifecycle is old and shouldnt be used
@@ -1,4 +1,4 @@
1
- class S3Secure::Lifecycle
1
+ module S3Secure::Lifecycle
2
2
  class List < Base
3
3
  def run
4
4
  presenter = CliFormat::Presenter.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Lifecycle
1
+ module S3Secure::Lifecycle
2
2
  class Remove < Base
3
3
  RULE_ID = Base::RULE_ID
4
4
 
@@ -1,4 +1,4 @@
1
- class S3Secure::Lifecycle
1
+ module S3Secure::Lifecycle
2
2
  class Show < Base
3
3
  RULE_ID = Base::RULE_ID
4
4
 
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::Policy
2
+ class Base < S3Secure::CLI::Base
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class Checker
3
3
  def initialize(bucket_policy)
4
4
  @bucket_policy = bucket_policy # existing document policy
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy::Document
1
+ module S3Secure::Policy::Document
2
2
  class Base
3
3
  extend Memoist
4
4
 
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy::Document
1
+ module S3Secure::Policy::Document
2
2
  class ForceSSLOnlyAccess < Base
3
3
  def policy_document
4
4
  if @bucket_policy.blank?
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy::Document
1
+ module S3Secure::Policy::Document
2
2
  class ForceSSLOnlyAccessRemove < Base
3
3
  def initialize(bucket, bucket_policy)
4
4
  # @bucket_policy is existing document policy
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class Document
3
3
  extend Memoist
4
4
 
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class Enforce < Base
3
3
  def initialize(options={})
4
4
  super
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class List < Base
3
3
  def run
4
4
  presenter = CliFormat::Presenter.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class Show < Base
3
3
  def run
4
4
  if policy
@@ -1,4 +1,4 @@
1
- class S3Secure::Policy
1
+ module S3Secure::Policy
2
2
  class Unforce < Base
3
3
  def initialize(options={})
4
4
  super
@@ -0,0 +1,10 @@
1
+ module S3Secure::PublicAccess
2
+ class Base < S3Secure::CLI::Base
3
+ extend Memoist
4
+
5
+ def account_id
6
+ sts.get_caller_identity.account
7
+ end
8
+ memoize :account_id
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ module S3Secure::PublicAccess
2
+ class Block < Base
3
+ def run
4
+ resp = s3.put_public_access_block(
5
+ bucket: @bucket,
6
+ public_access_block_configuration: {
7
+ block_public_acls: true,
8
+ ignore_public_acls: true,
9
+ block_public_policy: true,
10
+ restrict_public_buckets: true,
11
+ },
12
+ )
13
+ $stderr.puts("Public access blocked for bucket: #{@bucket}")
14
+ resp
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,24 @@
1
+ module S3Secure::PublicAccess
2
+ class List < Base
3
+ def run
4
+ presenter = CliFormat::Presenter.new(@options)
5
+ presenter.header = ["Bucket", "Block Public Access?"]
6
+
7
+ buckets.each do |bucket|
8
+ $stderr.puts "Getting bucket public access configuration for bucket #{bucket.color(:green)}"
9
+
10
+ blocked = Show.new(bucket: bucket).blocked?
11
+ row = [bucket, blocked]
12
+ if @options[:blocked].nil?
13
+ presenter.rows << row # always show policy
14
+ elsif @options[:blocked]
15
+ presenter.rows << row if blocked # only show if bucket is blocked
16
+ else
17
+ presenter.rows << row unless blocked # only show if bucket is unblocked
18
+ end
19
+ end
20
+
21
+ presenter.show
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ module S3Secure::PublicAccess
2
+ class Show < Base
3
+ def run
4
+ resp = s3.get_public_access_block(
5
+ bucket: @bucket,
6
+ )
7
+ $stderr.puts(resp.to_h)
8
+ resp
9
+ rescue Aws::S3::Errors::NoSuchPublicAccessBlockConfiguration
10
+ $stderr.puts "No public access block configuration found for bucket: #{@bucket}"
11
+ end
12
+
13
+ def blocked?
14
+ resp = s3.get_public_access_block(
15
+ bucket: @bucket,
16
+ )
17
+ resp.to_h[:public_access_block_configuration] == {
18
+ block_public_acls: true,
19
+ block_public_policy: true,
20
+ ignore_public_acls: true,
21
+ restrict_public_buckets: true,
22
+ }
23
+ rescue Aws::S3::Errors::NoSuchPublicAccessBlockConfiguration
24
+ false
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ module S3Secure::PublicAccess
2
+ class Unblock < Base
3
+ def run
4
+ resp = s3.delete_public_access_block(
5
+ bucket: @bucket,
6
+ )
7
+ $stderr.puts("Removed public access block configuration for bucket: #{@bucket}")
8
+ resp
9
+ end
10
+ end
11
+ end
12
+
@@ -1,4 +1,4 @@
1
- class S3Secure::Summary
1
+ module S3Secure::Summary
2
2
  class Item
3
3
  attr_reader :bucket
4
4
  def initialize(bucket, properties={})
@@ -1,5 +1,5 @@
1
- class S3Secure::Summary
2
- class Items < S3Secure::AbstractBase
1
+ module S3Secure::Summary
2
+ class Items < S3Secure::CLI::Base
3
3
  extend Memoist
4
4
 
5
5
  # override initialize
@@ -44,9 +44,9 @@ class S3Secure::Summary
44
44
 
45
45
  private
46
46
  def ssl?(bucket)
47
- list = S3Secure::Policy::List.new(@options)
47
+ show = S3Secure::Policy::Show.new(@options.merge(bucket: bucket))
48
48
 
49
- bucket_policy = list.get_policy(bucket)
49
+ bucket_policy = show.run
50
50
  document = S3Secure::Policy::Document.new(bucket, bucket_policy)
51
51
  document.has?("ForceSSLOnlyAccess")
52
52
  end
@@ -54,10 +54,9 @@ class S3Secure::Summary
54
54
 
55
55
  def encrypted?(bucket)
56
56
  s3 = s3_regional_client(bucket)
57
- list = S3Secure::Encryption::List.new(@options)
58
- list.set_s3(s3)
57
+ show = S3Secure::Encryption::Show.new(@options.merge(bucket: bucket))
59
58
 
60
- rules = list.get_encryption_rules(bucket)
59
+ rules = show.run
61
60
  !!rules
62
61
  end
63
62
  memoize :encrypted?
@@ -1,3 +1,3 @@
1
1
  module S3Secure
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Versioning
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::Versioning
2
+ class Base < S3Secure::CLI::Base
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Versioning
1
+ module S3Secure::Versioning
2
2
  class Disable < Base
3
3
  def run
4
4
  show = Show.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Versioning
1
+ module S3Secure::Versioning
2
2
  class Enable < Base
3
3
  def run
4
4
  show = Show.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Versioning
1
+ module S3Secure::Versioning
2
2
  class List < Base
3
3
  def run
4
4
  presenter = CliFormat::Presenter.new(@options)
@@ -1,4 +1,4 @@
1
- class S3Secure::Versioning
1
+ module S3Secure::Versioning
2
2
  class Show < Base
3
3
  def run
4
4
  if enabled?
data/lib/s3_secure.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  $:.unshift(File.expand_path("../", __FILE__))
2
+ require "active_support"
2
3
  require "active_support/core_ext/module" # for delegate
3
4
  require "active_support/core_ext/string"
4
5
  require "cli_format"
data/s3-secure.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Tung Nguyen"]
10
10
  spec.email = ["tongueroo@gmail.com"]
11
11
  spec.summary = "S3 Bucket security hardening tool"
12
- spec.homepage = "https://github.com/tongueroo/s3-secure"
12
+ spec.homepage = "https://github.com/boltops-tools/s3-secure"
13
13
  spec.license = "Apache2.0"
14
14
 
15
15
  git_installed = system("type git > /dev/null 2>&1")
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "cli-format"
25
25
  spec.add_dependency "memoist"
26
26
  spec.add_dependency "rainbow"
27
+ spec.add_dependency "rexml"
27
28
  spec.add_dependency "text-table"
28
29
  spec.add_dependency "thor"
29
30
  spec.add_dependency "zeitwerk"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3-secure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-19 00:00:00.000000000 Z
11
+ date: 2021-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rexml
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
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: text-table
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -211,8 +225,6 @@ files:
211
225
  - exe/s3-secure
212
226
  - lib/s3-secure.rb
213
227
  - lib/s3_secure.rb
214
- - lib/s3_secure/abstract_base.rb
215
- - lib/s3_secure/access_logs.rb
216
228
  - lib/s3_secure/access_logs/base.rb
217
229
  - lib/s3_secure/access_logs/disable.rb
218
230
  - lib/s3_secure/access_logs/enable.rb
@@ -221,19 +233,28 @@ files:
221
233
  - lib/s3_secure/autoloader.rb
222
234
  - lib/s3_secure/aws_services.rb
223
235
  - lib/s3_secure/aws_services/s3.rb
224
- - lib/s3_secure/batch.rb
225
236
  - lib/s3_secure/cli.rb
237
+ - lib/s3_secure/cli/access_logs.rb
238
+ - lib/s3_secure/cli/base.rb
239
+ - lib/s3_secure/cli/batch.rb
240
+ - lib/s3_secure/cli/encryption.rb
241
+ - lib/s3_secure/cli/help.rb
242
+ - lib/s3_secure/cli/lifecycle.rb
243
+ - lib/s3_secure/cli/policy.rb
244
+ - lib/s3_secure/cli/public_access.rb
245
+ - lib/s3_secure/cli/remediate_all.rb
246
+ - lib/s3_secure/cli/say.rb
247
+ - lib/s3_secure/cli/summary.rb
248
+ - lib/s3_secure/cli/versioning.rb
226
249
  - lib/s3_secure/command.rb
227
250
  - lib/s3_secure/completer.rb
228
251
  - lib/s3_secure/completer/script.rb
229
252
  - lib/s3_secure/completer/script.sh
230
- - lib/s3_secure/encryption.rb
231
253
  - lib/s3_secure/encryption/base.rb
232
254
  - lib/s3_secure/encryption/disable.rb
233
255
  - lib/s3_secure/encryption/enable.rb
234
256
  - lib/s3_secure/encryption/list.rb
235
257
  - lib/s3_secure/encryption/show.rb
236
- - lib/s3_secure/help.rb
237
258
  - lib/s3_secure/help/batch.md
238
259
  - lib/s3_secure/help/completion.md
239
260
  - lib/s3_secure/help/completion_script.md
@@ -248,14 +269,12 @@ files:
248
269
  - lib/s3_secure/help/policy/list.md
249
270
  - lib/s3_secure/help/policy/unforce_ssl.md
250
271
  - lib/s3_secure/help/summary.md
251
- - lib/s3_secure/lifecycle.rb
252
272
  - lib/s3_secure/lifecycle/add.rb
253
273
  - lib/s3_secure/lifecycle/base.rb
254
274
  - lib/s3_secure/lifecycle/builder.rb
255
275
  - lib/s3_secure/lifecycle/list.rb
256
276
  - lib/s3_secure/lifecycle/remove.rb
257
277
  - lib/s3_secure/lifecycle/show.rb
258
- - lib/s3_secure/policy.rb
259
278
  - lib/s3_secure/policy/base.rb
260
279
  - lib/s3_secure/policy/checker.rb
261
280
  - lib/s3_secure/policy/document.rb
@@ -266,14 +285,15 @@ files:
266
285
  - lib/s3_secure/policy/list.rb
267
286
  - lib/s3_secure/policy/show.rb
268
287
  - lib/s3_secure/policy/unforce.rb
269
- - lib/s3_secure/remediate_all.rb
270
- - lib/s3_secure/say.rb
271
- - lib/s3_secure/summary.rb
288
+ - lib/s3_secure/public_access/base.rb
289
+ - lib/s3_secure/public_access/block.rb
290
+ - lib/s3_secure/public_access/list.rb
291
+ - lib/s3_secure/public_access/show.rb
292
+ - lib/s3_secure/public_access/unblock.rb
272
293
  - lib/s3_secure/summary/item.rb
273
294
  - lib/s3_secure/summary/items.rb
274
295
  - lib/s3_secure/table.rb
275
296
  - lib/s3_secure/version.rb
276
- - lib/s3_secure/versioning.rb
277
297
  - lib/s3_secure/versioning/base.rb
278
298
  - lib/s3_secure/versioning/disable.rb
279
299
  - lib/s3_secure/versioning/enable.rb
@@ -286,7 +306,7 @@ files:
286
306
  - spec/lib/policy/document/force_ssl_remove_spec.rb
287
307
  - spec/lib/policy/document_spec.rb
288
308
  - spec/spec_helper.rb
289
- homepage: https://github.com/tongueroo/s3-secure
309
+ homepage: https://github.com/boltops-tools/s3-secure
290
310
  licenses:
291
311
  - Apache2.0
292
312
  metadata: {}
@@ -305,7 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
305
325
  - !ruby/object:Gem::Version
306
326
  version: '0'
307
327
  requirements: []
308
- rubygems_version: 3.1.2
328
+ rubygems_version: 3.2.32
309
329
  signing_key:
310
330
  specification_version: 4
311
331
  summary: S3 Bucket security hardening tool
@@ -1,9 +0,0 @@
1
- module S3Secure::Help
2
- class << self
3
- def text(namespaced_command)
4
- path = namespaced_command.to_s.gsub(':','/')
5
- path = File.expand_path("../help/#{path}.md", __FILE__)
6
- IO.read(path) if File.exist?(path)
7
- end
8
- end
9
- end