s3-secure 0.5.1 → 0.6.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 (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