s3tk 0.5.0__tar.gz

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.
s3tk-0.5.0/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017-2025 Andrew Kane
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
s3tk-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,682 @@
1
+ Metadata-Version: 2.4
2
+ Name: s3tk
3
+ Version: 0.5.0
4
+ Summary: A security toolkit for Amazon S3
5
+ Author-email: Andrew Kane <andrew@ankane.org>
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/ankane/s3tk
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE.txt
11
+ Requires-Dist: boto3>=1.9.46
12
+ Requires-Dist: botocore>=1.12.46
13
+ Requires-Dist: clint
14
+ Requires-Dist: click
15
+ Requires-Dist: joblib
16
+ Dynamic: license-file
17
+
18
+ # s3tk
19
+
20
+ A security toolkit for Amazon S3
21
+
22
+ ![Screenshot](https://gist.githubusercontent.com/ankane/13a9230353c78c0d5c35fd9319a23d98/raw/434b9c54bff9d41c398aa3b57f0d0494217ef7fa/console2.gif)
23
+
24
+ :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
25
+
26
+ ## Installation
27
+
28
+ Run:
29
+
30
+ ```sh
31
+ pip install s3tk
32
+ ```
33
+
34
+ You can use the [AWS CLI](https://github.com/aws/aws-cli) or [AWS Vault](https://github.com/99designs/aws-vault) to set up your AWS credentials:
35
+
36
+ ```sh
37
+ pip install awscli
38
+ aws configure
39
+ ```
40
+
41
+ See [IAM policies](#iam-policies) needed for each command.
42
+
43
+ ## Commands
44
+
45
+ ### Scan
46
+
47
+ Scan your buckets for:
48
+
49
+ - ACL open to public
50
+ - policy open to public
51
+ - public access blocked
52
+ - logging enabled
53
+ - versioning enabled
54
+ - default encryption enabled
55
+
56
+ ```sh
57
+ s3tk scan
58
+ ```
59
+
60
+ Only run on specific buckets
61
+
62
+ ```sh
63
+ s3tk scan my-bucket my-bucket-2
64
+ ```
65
+
66
+ Also works with wildcards
67
+
68
+ ```sh
69
+ s3tk scan "my-bucket*"
70
+ ```
71
+
72
+ Confirm correct log bucket(s) and prefix
73
+
74
+ ```
75
+ s3tk scan --log-bucket my-s3-logs --log-bucket other-region-logs --log-prefix "{bucket}/"
76
+ ```
77
+
78
+ Check CloudTrail object-level logging [experimental]
79
+
80
+ ```sh
81
+ s3tk scan --object-level-logging
82
+ ```
83
+
84
+ Skip logging, versioning, or default encryption
85
+
86
+ ```sh
87
+ s3tk scan --skip-logging --skip-versioning --skip-default-encryption
88
+ ```
89
+
90
+ Get email notifications of failures (via SNS)
91
+
92
+ ```sh
93
+ s3tk scan --sns-topic arn:aws:sns:...
94
+ ```
95
+
96
+ ### List Policy
97
+
98
+ List bucket policies
99
+
100
+ ```sh
101
+ s3tk list-policy
102
+ ```
103
+
104
+ Only run on specific buckets
105
+
106
+ ```sh
107
+ s3tk list-policy my-bucket my-bucket-2
108
+ ```
109
+
110
+ Show named statements
111
+
112
+ ```sh
113
+ s3tk list-policy --named
114
+ ```
115
+
116
+ ### Set Policy
117
+
118
+ **Note:** This replaces the previous policy
119
+
120
+ Only private uploads
121
+
122
+ ```sh
123
+ s3tk set-policy my-bucket --no-object-acl
124
+ ```
125
+
126
+ ### Delete Policy
127
+
128
+ Delete policy
129
+
130
+ ```sh
131
+ s3tk delete-policy my-bucket
132
+ ```
133
+
134
+ ### Block Public Access
135
+
136
+ Block public access on specific buckets
137
+
138
+ ```sh
139
+ s3tk block-public-access my-bucket my-bucket-2
140
+ ```
141
+
142
+ Use the `--dry-run` flag to test
143
+
144
+ ### Enable Logging
145
+
146
+ Enable logging on all buckets
147
+
148
+ ```sh
149
+ s3tk enable-logging --log-bucket my-s3-logs
150
+ ```
151
+
152
+ Only on specific buckets
153
+
154
+ ```sh
155
+ s3tk enable-logging my-bucket my-bucket-2 --log-bucket my-s3-logs
156
+ ```
157
+
158
+ Set log prefix (`{bucket}/` by default)
159
+
160
+ ```sh
161
+ s3tk enable-logging --log-bucket my-s3-logs --log-prefix "logs/{bucket}/"
162
+ ```
163
+
164
+ Use the `--dry-run` flag to test
165
+
166
+ A few notes about logging:
167
+
168
+ - buckets with logging already enabled are not updated at all
169
+ - the log bucket must in the same region as the source bucket - run this command multiple times for different regions
170
+ - it can take over an hour for logs to show up
171
+
172
+ ### Enable Versioning
173
+
174
+ Enable versioning on all buckets
175
+
176
+ ```sh
177
+ s3tk enable-versioning
178
+ ```
179
+
180
+ Only on specific buckets
181
+
182
+ ```sh
183
+ s3tk enable-versioning my-bucket my-bucket-2
184
+ ```
185
+
186
+ Use the `--dry-run` flag to test
187
+
188
+ ### Enable Default Encryption
189
+
190
+ Enable [default encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) on all buckets
191
+
192
+ ```sh
193
+ s3tk enable-default-encryption
194
+ ```
195
+
196
+ Only on specific buckets
197
+
198
+ ```sh
199
+ s3tk enable-default-encryption my-bucket my-bucket-2
200
+ ```
201
+
202
+ This does not encrypt existing objects - use the `encrypt` command for this
203
+
204
+ Use the `--dry-run` flag to test
205
+
206
+ ### Scan Object ACL
207
+
208
+ Scan ACL on all objects in a bucket
209
+
210
+ ```sh
211
+ s3tk scan-object-acl my-bucket
212
+ ```
213
+
214
+ Only certain objects
215
+
216
+ ```sh
217
+ s3tk scan-object-acl my-bucket --only "*.pdf"
218
+ ```
219
+
220
+ Except certain objects
221
+
222
+ ```sh
223
+ s3tk scan-object-acl my-bucket --except "*.jpg"
224
+ ```
225
+
226
+ ### Reset Object ACL
227
+
228
+ Reset ACL on all objects in a bucket
229
+
230
+ ```sh
231
+ s3tk reset-object-acl my-bucket
232
+ ```
233
+
234
+ This makes all objects private. See [bucket policies](#bucket-policies) for how to enforce going forward.
235
+
236
+ Use the `--dry-run` flag to test
237
+
238
+ Specify certain objects the same way as [scan-object-acl](#scan-object-acl)
239
+
240
+ ### Encrypt
241
+
242
+ Encrypt all objects in a bucket with [server-side encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html)
243
+
244
+ ```sh
245
+ s3tk encrypt my-bucket
246
+ ```
247
+
248
+ Use [S3-managed keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) by default. For [KMS-managed keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html), use:
249
+
250
+ ```sh
251
+ s3tk encrypt my-bucket --kms-key-id arn:aws:kms:...
252
+ ```
253
+
254
+ For [customer-provided keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html), use:
255
+
256
+ ```sh
257
+ s3tk encrypt my-bucket --customer-key secret-key
258
+ ```
259
+
260
+ Use the `--dry-run` flag to test
261
+
262
+ Specify certain objects the same way as [scan-object-acl](#scan-object-acl)
263
+
264
+ **Note:** Objects will lose any custom ACL
265
+
266
+ ### Delete Unencrypted Versions
267
+
268
+ Delete all unencrypted versions of objects in a bucket
269
+
270
+ ```sh
271
+ s3tk delete-unencrypted-versions my-bucket
272
+ ```
273
+
274
+ For safety, this will not delete any current versions of objects
275
+
276
+ Use the `--dry-run` flag to test
277
+
278
+ Specify certain objects the same way as [scan-object-acl](#scan-object-acl)
279
+
280
+ ### Scan DNS
281
+
282
+ Scan Route 53 for buckets to make sure you own them
283
+
284
+ ```sh
285
+ s3tk scan-dns
286
+ ```
287
+
288
+ Otherwise, you may be susceptible to [subdomain takeover](https://hackerone.com/reports/207576)
289
+
290
+ ## Credentials
291
+
292
+ Credentials can be specified in `~/.aws/credentials` or with environment variables. See [this guide](https://boto3.readthedocs.io/en/latest/guide/configuration.html) for an explanation of environment variables.
293
+
294
+ You can specify a profile to use with:
295
+
296
+ ```sh
297
+ AWS_PROFILE=your-profile s3tk
298
+ ```
299
+
300
+ ## IAM Policies
301
+
302
+ Here are the permissions needed for each command. Only include statements you need.
303
+
304
+ ```json
305
+ {
306
+ "Version": "2012-10-17",
307
+ "Statement": [
308
+ {
309
+ "Sid": "Scan",
310
+ "Effect": "Allow",
311
+ "Action": [
312
+ "s3:ListAllMyBuckets",
313
+ "s3:GetBucketAcl",
314
+ "s3:GetBucketPolicy",
315
+ "s3:GetBucketPublicAccessBlock",
316
+ "s3:GetBucketLogging",
317
+ "s3:GetBucketVersioning",
318
+ "s3:GetEncryptionConfiguration"
319
+ ],
320
+ "Resource": "*"
321
+ },
322
+ {
323
+ "Sid": "ScanObjectLevelLogging",
324
+ "Effect": "Allow",
325
+ "Action": [
326
+ "cloudtrail:ListTrails",
327
+ "cloudtrail:GetTrail",
328
+ "cloudtrail:GetEventSelectors",
329
+ "s3:GetBucketLocation"
330
+ ],
331
+ "Resource": "*"
332
+ },
333
+ {
334
+ "Sid": "ScanDNS",
335
+ "Effect": "Allow",
336
+ "Action": [
337
+ "s3:ListAllMyBuckets",
338
+ "route53:ListHostedZones",
339
+ "route53:ListResourceRecordSets"
340
+ ],
341
+ "Resource": "*"
342
+ },
343
+ {
344
+ "Sid": "ListPolicy",
345
+ "Effect": "Allow",
346
+ "Action": [
347
+ "s3:ListAllMyBuckets",
348
+ "s3:GetBucketPolicy"
349
+ ],
350
+ "Resource": "*"
351
+ },
352
+ {
353
+ "Sid": "SetPolicy",
354
+ "Effect": "Allow",
355
+ "Action": [
356
+ "s3:PutBucketPolicy"
357
+ ],
358
+ "Resource": "*"
359
+ },
360
+ {
361
+ "Sid": "DeletePolicy",
362
+ "Effect": "Allow",
363
+ "Action": [
364
+ "s3:DeleteBucketPolicy"
365
+ ],
366
+ "Resource": "*"
367
+ },
368
+ {
369
+ "Sid": "BlockPublicAccess",
370
+ "Effect": "Allow",
371
+ "Action": [
372
+ "s3:ListAllMyBuckets",
373
+ "s3:PutBucketPublicAccessBlock"
374
+ ],
375
+ "Resource": "*"
376
+ },
377
+ {
378
+ "Sid": "EnableLogging",
379
+ "Effect": "Allow",
380
+ "Action": [
381
+ "s3:ListAllMyBuckets",
382
+ "s3:PutBucketLogging"
383
+ ],
384
+ "Resource": "*"
385
+ },
386
+ {
387
+ "Sid": "EnableVersioning",
388
+ "Effect": "Allow",
389
+ "Action": [
390
+ "s3:ListAllMyBuckets",
391
+ "s3:PutBucketVersioning"
392
+ ],
393
+ "Resource": "*"
394
+ },
395
+ {
396
+ "Sid": "EnableDefaultEncryption",
397
+ "Effect": "Allow",
398
+ "Action": [
399
+ "s3:ListAllMyBuckets",
400
+ "s3:PutEncryptionConfiguration"
401
+ ],
402
+ "Resource": "*"
403
+ },
404
+ {
405
+ "Sid": "ResetObjectAcl",
406
+ "Effect": "Allow",
407
+ "Action": [
408
+ "s3:ListBucket",
409
+ "s3:GetObjectAcl",
410
+ "s3:PutObjectAcl"
411
+ ],
412
+ "Resource": [
413
+ "arn:aws:s3:::my-bucket",
414
+ "arn:aws:s3:::my-bucket/*"
415
+ ]
416
+ },
417
+ {
418
+ "Sid": "Encrypt",
419
+ "Effect": "Allow",
420
+ "Action": [
421
+ "s3:ListBucket",
422
+ "s3:GetObject",
423
+ "s3:PutObject"
424
+ ],
425
+ "Resource": [
426
+ "arn:aws:s3:::my-bucket",
427
+ "arn:aws:s3:::my-bucket/*"
428
+ ]
429
+ },
430
+ {
431
+ "Sid": "DeleteUnencryptedVersions",
432
+ "Effect": "Allow",
433
+ "Action": [
434
+ "s3:ListBucketVersions",
435
+ "s3:GetObjectVersion",
436
+ "s3:DeleteObjectVersion"
437
+ ],
438
+ "Resource": [
439
+ "arn:aws:s3:::my-bucket",
440
+ "arn:aws:s3:::my-bucket/*"
441
+ ]
442
+ }
443
+ ]
444
+ }
445
+ ```
446
+
447
+ ## Access Logs
448
+
449
+ [Amazon Athena](https://aws.amazon.com/athena/) is great for querying S3 logs. Create a table (thanks to [this post](http://aws.mannem.me/?p=1462) for the table structure) with:
450
+
451
+ ```sql
452
+ CREATE EXTERNAL TABLE my_bucket (
453
+ bucket_owner string,
454
+ bucket string,
455
+ time string,
456
+ remote_ip string,
457
+ requester string,
458
+ request_id string,
459
+ operation string,
460
+ key string,
461
+ request_verb string,
462
+ request_url string,
463
+ request_proto string,
464
+ status_code string,
465
+ error_code string,
466
+ bytes_sent string,
467
+ object_size string,
468
+ total_time string,
469
+ turn_around_time string,
470
+ referrer string,
471
+ user_agent string,
472
+ version_id string
473
+ )
474
+ ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
475
+ WITH SERDEPROPERTIES (
476
+ 'serialization.format' = '1',
477
+ 'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \\\"([^ ]*) ([^ ]*) (- |[^ ]*)\\\" (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\\") ([^ ]*)$'
478
+ ) LOCATION 's3://my-s3-logs/my-bucket/';
479
+ ```
480
+
481
+ Change the last line to point to your log bucket (and prefix) and query away
482
+
483
+ ```sql
484
+ SELECT
485
+ date_parse(time, '%d/%b/%Y:%H:%i:%S +0000') AS time,
486
+ request_url,
487
+ remote_ip,
488
+ user_agent
489
+ FROM
490
+ my_bucket
491
+ WHERE
492
+ requester = '-'
493
+ AND status_code LIKE '2%'
494
+ AND request_url LIKE '/some-keys%'
495
+ ORDER BY 1
496
+ ```
497
+
498
+ ## CloudTrail Logs
499
+
500
+ Amazon Athena is also great for querying CloudTrail logs. Create a table (thanks to [this post](https://www.1strategy.com/blog/2017/07/25/auditing-aws-activity-with-cloudtrail-and-athena/) for the table structure) with:
501
+
502
+ ```sql
503
+ CREATE EXTERNAL TABLE cloudtrail_logs (
504
+ eventversion STRING,
505
+ userIdentity STRUCT<
506
+ type:STRING,
507
+ principalid:STRING,
508
+ arn:STRING,
509
+ accountid:STRING,
510
+ invokedby:STRING,
511
+ accesskeyid:STRING,
512
+ userName:String,
513
+ sessioncontext:STRUCT<
514
+ attributes:STRUCT<
515
+ mfaauthenticated:STRING,
516
+ creationdate:STRING>,
517
+ sessionIssuer:STRUCT<
518
+ type:STRING,
519
+ principalId:STRING,
520
+ arn:STRING,
521
+ accountId:STRING,
522
+ userName:STRING>>>,
523
+ eventTime STRING,
524
+ eventSource STRING,
525
+ eventName STRING,
526
+ awsRegion STRING,
527
+ sourceIpAddress STRING,
528
+ userAgent STRING,
529
+ errorCode STRING,
530
+ errorMessage STRING,
531
+ requestId STRING,
532
+ eventId STRING,
533
+ resources ARRAY<STRUCT<
534
+ ARN:STRING,
535
+ accountId:STRING,
536
+ type:STRING>>,
537
+ eventType STRING,
538
+ apiVersion STRING,
539
+ readOnly BOOLEAN,
540
+ recipientAccountId STRING,
541
+ sharedEventID STRING,
542
+ vpcEndpointId STRING,
543
+ requestParameters STRING,
544
+ responseElements STRING,
545
+ additionalEventData STRING,
546
+ serviceEventDetails STRING
547
+ )
548
+ ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
549
+ STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
550
+ OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
551
+ LOCATION 's3://my-cloudtrail-logs/'
552
+ ```
553
+
554
+ Change the last line to point to your CloudTrail log bucket and query away
555
+
556
+ ```sql
557
+ SELECT
558
+ eventTime,
559
+ eventName,
560
+ userIdentity.userName,
561
+ requestParameters
562
+ FROM
563
+ cloudtrail_logs
564
+ WHERE
565
+ eventName LIKE '%Bucket%'
566
+ ORDER BY 1
567
+ ```
568
+
569
+ ## Best Practices
570
+
571
+ Keep things simple and follow the principle of least privilege to reduce the chance of mistakes.
572
+
573
+ - Strictly limit who can perform bucket-related operations
574
+ - Avoid mixing objects with different permissions in the same bucket (use a bucket policy to enforce this)
575
+ - Don’t specify public read permissions on a bucket level (no `GetObject` in bucket policy)
576
+ - Monitor configuration frequently for changes
577
+
578
+ ## Bucket Policies
579
+
580
+ Only private uploads
581
+
582
+ ```json
583
+ {
584
+ "Version": "2012-10-17",
585
+ "Statement": [
586
+ {
587
+ "Effect": "Deny",
588
+ "Principal": "*",
589
+ "Action": "s3:PutObjectAcl",
590
+ "Resource": "arn:aws:s3:::my-bucket/*"
591
+ }
592
+ ]
593
+ }
594
+ ```
595
+
596
+ ## Performance
597
+
598
+ For commands that iterate over bucket objects (`scan-object-acl`, `reset-object-acl`, `encrypt`, and `delete-unencrypted-versions`), run s3tk on an EC2 server for minimum latency.
599
+
600
+ ## Notes
601
+
602
+ The `set-policy`, `block-public-access`, `enable-logging`, `enable-versioning`, and `enable-default-encryption` commands are provided for convenience. We recommend [Terraform](https://www.terraform.io/) for managing your buckets.
603
+
604
+ ```tf
605
+ resource "aws_s3_bucket" "my_bucket" {
606
+ bucket = "my-bucket"
607
+ acl = "private"
608
+
609
+ logging {
610
+ target_bucket = "my-s3-logs"
611
+ target_prefix = "my-bucket/"
612
+ }
613
+
614
+ versioning {
615
+ enabled = true
616
+ }
617
+ }
618
+
619
+ resource "aws_s3_bucket_public_access_block" "my_bucket" {
620
+ bucket = "${aws_s3_bucket.my_bucket.id}"
621
+
622
+ block_public_acls = true
623
+ block_public_policy = true
624
+ ignore_public_acls = true
625
+ restrict_public_buckets = true
626
+ }
627
+ ```
628
+
629
+ ## Upgrading
630
+
631
+ Run:
632
+
633
+ ```sh
634
+ pip install s3tk --upgrade
635
+ ```
636
+
637
+ To use master, run:
638
+
639
+ ```sh
640
+ pip install git+https://github.com/ankane/s3tk.git --upgrade
641
+ ```
642
+
643
+ ## Docker
644
+
645
+ Run:
646
+
647
+ ```sh
648
+ docker run -it ankane/s3tk aws configure
649
+ ```
650
+
651
+ Commit your credentials:
652
+
653
+ ```sh
654
+ docker commit $(docker ps -l -q) my-s3tk
655
+ ```
656
+
657
+ And run:
658
+
659
+ ```sh
660
+ docker run -it my-s3tk s3tk scan
661
+ ```
662
+
663
+ ## History
664
+
665
+ View the [changelog](https://github.com/ankane/s3tk/blob/master/CHANGELOG.md)
666
+
667
+ ## Contributing
668
+
669
+ Everyone is encouraged to help improve this project. Here are a few ways you can help:
670
+
671
+ - [Report bugs](https://github.com/ankane/s3tk/issues)
672
+ - Fix bugs and [submit pull requests](https://github.com/ankane/s3tk/pulls)
673
+ - Write, clarify, or fix documentation
674
+ - Suggest or add new features
675
+
676
+ To get started with development:
677
+
678
+ ```sh
679
+ git clone https://github.com/ankane/s3tk.git
680
+ cd s3tk
681
+ pip install -r requirements.txt
682
+ ```