Skip to content

Instantly share code, notes, and snippets.

@kainam00
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save kainam00/351ed61fad0a891810c0 to your computer and use it in GitHub Desktop.

Select an option

Save kainam00/351ed61fad0a891810c0 to your computer and use it in GitHub Desktop.

Revisions

  1. kainam00 revised this gist Aug 6, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion secure-s3-bucket.rb
    Original file line number Diff line number Diff line change
    @@ -110,6 +110,7 @@ def secure_object(client, bucket, key, dryrun)
    numobjects = numobjects+1
    secure_object(client, ARGV[0], object.key, dryrun)
    end
    puts "Working... Checked #{numobjects} objects. Fixed #{@numfixed}"
    end

    puts "Checked #{numobjects} objects. Fixed #{@numfixed}"
    puts "Done. Checked #{numobjects} objects. Fixed #{@numfixed}"
  2. kainam00 revised this gist Aug 6, 2015. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions secure-s3-bucket.rb
    Original file line number Diff line number Diff line change
    @@ -61,6 +61,7 @@ def secure_object(client, bucket, key, dryrun)
    bucket: bucket,
    key: key
    })
    @numfixed = @numfixed+1
    return true
    elsif changed == true && dryrun == true
    puts "*dryrun* is set, not applying new grants to #{key}!"
    @@ -73,7 +74,7 @@ def secure_object(client, bucket, key, dryrun)
    # Load config file
    config = YAML.load(File.read(ARGV[1]))

    # Create AWS client. Slightly different depending on whether we're using roles or not
    # Create AWS client. Slightly different depending on whether we're using roles or not
    if config["access_key_id"].nil?
    # Don't pass credentials, we're using roles given to this box
    client = Aws::S3::Client.new(
    @@ -91,6 +92,7 @@ def secure_object(client, bucket, key, dryrun)
    done = false
    marker = ""
    numobjects = 0
    @numfixed = 0

    while done == false
    resp = client.list_objects( {
    @@ -110,4 +112,4 @@ def secure_object(client, bucket, key, dryrun)
    end
    end

    puts "Checked #{numobjects} objects"
    puts "Checked #{numobjects} objects. Fixed #{@numfixed}"
  3. kainam00 created this gist Aug 6, 2015.
    113 changes: 113 additions & 0 deletions secure-s3-bucket.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,113 @@
    #!/usr/bin/env ruby
    require 'aws-sdk'
    require 'yaml'

    # Check args
    if ARGV[0].nil? || ARGV[1].nil?
    puts "Usage: securey-s3-bucket.rb bucket_name path-to-config-file.yml dryrun(optional)"
    puts " Where the config file is a YAML formatted file with the following data:"
    puts " access_key_id: xxx"
    puts " secret_access_key: yyy"
    puts " region: us-east-1"
    exit 1
    end

    if ARGV[2]
    dryrun = true
    end

    #### Utility functions ####
    def secure_object(client, bucket, key, dryrun)
    resp = client.get_object_acl({
    bucket: bucket,
    key: key,
    })
    changed = false
    newgrants = Array.new()
    # Go through all the grants, creating a new grants array without the "Everyone" grant
    resp.grants.each do | grant |
    # Check to see if there is an "Everyone" grant in the grants array
    if grant.grantee.uri == "http://acs.amazonaws.com/groups/global/AllUsers"
    puts "#{key} has 'Everyone' permissions. Fixing."
    # Mark as insecure so we can fix below
    changed = true
    else
    # If not, copy the grant to the new grants array to be applied to the object if needed

    # Set the "type" field to CanonicalUserId or Group manually, since it comes from amazon as "nil" for some reason
    # Damn you Amazon!
    if grant.grantee.uri.nil?
    grant.grantee.type = "CanonicalUser"
    else
    grant.grantee.type = "Group"
    end

    # Copy
    newgrants << grant
    end
    end

    # Apply changes if needed
    if changed == true && dryrun != true
    puts "Applying new grants to #{key}"
    resp2 = client.put_object_acl ({
    access_control_policy: {
    grants: newgrants,
    owner: {
    display_name: resp.owner.display_name,
    id: resp.owner.id
    },
    },
    bucket: bucket,
    key: key
    })
    return true
    elsif changed == true && dryrun == true
    puts "*dryrun* is set, not applying new grants to #{key}!"
    return true
    else
    return true
    end
    end

    # Load config file
    config = YAML.load(File.read(ARGV[1]))

    # Create AWS client. Slightly different depending on whether we're using roles or not
    if config["access_key_id"].nil?
    # Don't pass credentials, we're using roles given to this box
    client = Aws::S3::Client.new(
    region: config["region"],
    )
    else
    client = Aws::S3::Client.new(
    # Pass credentials
    region: config["region"],
    credentials: Aws::Credentials.new(config["access_key_id"], config["secret_access_key"]),
    )
    end

    # Loop through all of the objects in the bucket
    done = false
    marker = ""
    numobjects = 0

    while done == false
    resp = client.list_objects( {
    bucket: ARGV[0],
    max_keys: 1000,
    marker: marker
    })
    if resp.is_truncated == false
    done = true
    else
    marker = resp.contents[resp.contents.count - 1].key
    end

    resp.contents.each do | object |
    numobjects = numobjects+1
    secure_object(client, ARGV[0], object.key, dryrun)
    end
    end

    puts "Checked #{numobjects} objects"