reyes 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aee98a9cbc8ed42310ebf0edeac2193d8c919f84
4
- data.tar.gz: 461a416f7ea2a33953792d0bbbe4677c1e895e0f
3
+ metadata.gz: 8e9225619362879c180db3a50563afd569ff3c71
4
+ data.tar.gz: 241984d8db909dc5e34b2444b1906abd88d48f06
5
5
  SHA512:
6
- metadata.gz: dfa634f9ec9e5f317faf5fdd6736c6e9342f88d6f88ba7c25e5b7a9cb38bb5d56b5308dada3db28d351eb0726bed005eb25146486cb14eb55e1548e28ce50d7b
7
- data.tar.gz: 17b0c2e6fa7d23906845ee5edbf4a0e7327f4baff113e679e80b0a7601f26a38777c5179fc443918f158e49b97e779b820f8a1614e27cefe7252fd987fd2b746
6
+ metadata.gz: 7119c776a76ba54cd231c048b4ea06f18ba572538522d292bd1fd3d90f86019cc8bf38cd28c5fa7c196843faa257843ea251e0f204b4df223d98440f3778572d
7
+ data.tar.gz: aa90b05a80ce985576c6ea0ee81df8891bd17dd34a281129a4d543218ea4f839752701e6e7d143586163e13f1ae1fb06fa9488ec4d90bead254d944879f277ac
@@ -0,0 +1,3 @@
1
+ # 1.3.0
2
+
3
+ - Initial public release of Reyes
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2015 Stripe Inc <security@stripe.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
data/README.md CHANGED
@@ -1,12 +1,15 @@
1
1
  Reyes
2
2
  =====
3
3
 
4
+ <a href="https://en.wikipedia.org/wiki/Point_Reyes_Lighthouse">
4
5
  ![Pt. Reyes Lighthouse](http://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Point_Reyes_Lighthouse_%28April_2012%29.jpg/1266px-Point_Reyes_Lighthouse_%28April_2012%29.jpg)
6
+ </a>
5
7
 
6
8
  Reyes populates IPTables firewall rules based on EC2 security group rules.
7
- Named after the Pt. Reyes Lighthouse, which shines light through the fog,
8
- preventing your ships from crashing on the rocks as they make their way to
9
- port.
9
+ It is named after the
10
+ [Pt. Reyes Lighthouse](https://en.wikipedia.org/wiki/Point_Reyes_Lighthouse),
11
+ which shines light through the fog, preventing your ships from crashing on the
12
+ rocks as they make their way to port.
10
13
 
11
14
  Use Case
12
15
  --------
@@ -15,3 +18,101 @@ Reyes is designed to apply security group rules to IPsec VPN traffic that would
15
18
  otherwise be injected past security group protection. This is useful for
16
19
  enforcing firewalls on VPNs between EC2 instances and security groups in other
17
20
  VPCs, even in other regions.
21
+
22
+ Stripe uses Reyes to ensure that we apply security group rules to traffic
23
+ running through our IPsec VPNs between VPCs and between EC2 classic and VPC.
24
+
25
+ Requirements
26
+ ------------
27
+
28
+ Reyes is designed to have as few requirements as possible. It uses Amazon S3 to
29
+ distribute rule updates in JSON, and it signs these updates with a GPG key to
30
+ ensure rule integrity and authenticity.
31
+
32
+ Gem dependencies:
33
+
34
+ - [AWS SDK for Ruby Version 1](
35
+ https://github.com/aws/aws-sdk-ruby/tree/aws-sdk-v1)
36
+ - [Subprocess](https://github.com/stripe/subprocess)
37
+ - [Chalk::Log](https://github.com/stripe/chalk-log)
38
+
39
+ Currently Reyes assumes that your VPC uses a CIDR block in 10.0.0.0/8. It also
40
+ only understands TCP and UDP traffic.
41
+
42
+ Architecture
43
+ ------------
44
+
45
+ To avoid pummeling the EC2 API, Reyes uses a leader and follower model.
46
+
47
+ A reyes leader queries the Amazon EC2 API to list the instances and security
48
+ group rules in all desired regions and VPCs. It then uploads a signed JSON file
49
+ to an S3 bucket. We recommend running multiple hot spare leaders for
50
+ redundancy. (All of them will upload the same data, and the last one will win.)
51
+ The leader should be run periodically, e.g. with a cron job every 5 minutes.
52
+
53
+ A reyes follower downloads the JSON data from S3 and verifies the GPG
54
+ signature. (This GPG key should be managed by your normal configuration
55
+ management process.) It then creates Linux kernel
56
+ [IP sets](http://ipset.netfilter.org/) via `ipset` that replicate the security
57
+ group members, and populates IPTables rules with the security group data. To
58
+ avoid replay attacks, the rule file contains a `not_after` field defaulting to
59
+ 1 hour after generation.
60
+
61
+ Cutover to the new rules is atomic (using `iptables-restore`). To avoid
62
+ accidentally locking you out of your whole infrastructure, Reyes has a few
63
+ safeguards against applying its rules to traffic that did not travel over
64
+ IPsec.
65
+
66
+ **Caveat emptor:** Due to the use of `iptables-restore`, Reyes assumes that
67
+ there are **no other rules** in the IPTables filter table (that includes the
68
+ `INPUT`, `OUTPUT`, and `FORWARD` chains). All other rules in the filter table
69
+ will be silently discarded. Reyes followers should *not* be run on servers that
70
+ rely on having other rules in the filter table. (This may be addressed in a
71
+ future release, but for now there is only support for a flag file to
72
+ temporarily disable Reyes in the event that you need to change the filter table
73
+ by some other process.)
74
+
75
+ Getting Started
76
+ ---------------
77
+
78
+ Questions? Feedback? Please email us! There may be hidden assumptions or
79
+ gotchas specific to Stripe's infrastructure even though we strove to write it
80
+ in a generic way.
81
+
82
+ Reyes can be installed as a stand alone system gem: `gem install reyes`.
83
+
84
+ It uses a YAML configuration file to specify the S3 bucket, GPG signing key,
85
+ and various information about which EC2 regions and VPCs to cover.
86
+
87
+ You'll want to generate a GPG signing key and place it in a keyring in some
88
+ directory referred to by the `keyring_directory` config option. The Reyes
89
+ leaders will need the secret keyring, while the followers should *only* have
90
+ access to the public key. Reyes does not currently support having a passphrase
91
+ on the key.
92
+
93
+ On the EC2 classic side, Reyes assumes that any given EC2 instance will be
94
+ running IPsec directly, so it will ignore any traffic that didn't arrive over
95
+ IPsec. (It ignores traffic that doesn't match `-A INPUT -m policy --pol
96
+ ipsec`.)
97
+
98
+ On the VPC side, Reyes assumes that there will be dedicated VPN instances
99
+ acting as IP routers, so on an EC2 instance it won't be possible to filter by
100
+ policy IPsec. Instead, Reyes will filter all traffic in `10.0.0.0/8`,
101
+ whitelisting the CIDR block of the current VPC so that all VPC-local traffic is
102
+ allowed through (it should be filtered by normal security group rules).
103
+
104
+ To configure security groups properly for Reyes in VPC, allow all traffic from
105
+ foreign VPC (or EC2 classic) CIDR blocks that will be routed by IPsec VPN
106
+ servers. Make sure that this security group is excluded in `config.yaml` by
107
+ `excluded_group_names`, or else Reyes will dutifully mirror the allow rules and
108
+ you will have no firewall whatsoever.
109
+
110
+ It is strongly recommended to use `--log-accept` and `--log-drop` during
111
+ testing. This will add IPTables logging so that you can validate that the
112
+ firewall is taking the expected action on traffic.
113
+
114
+ License
115
+ -------
116
+
117
+ Reyes is distribued under the terms of the MIT license, which can be found in
118
+ this repository in the file called LICENSE.
data/bin/reyes CHANGED
@@ -40,7 +40,7 @@ def command_fetch(region, instance_id, options)
40
40
  r.apply_data!(data, options.fetch(:apply_options))
41
41
 
42
42
  if options[:prune]
43
- r.prune_ipsets
43
+ r.prune_ipsets(options.fetch(:prune_opts, {}))
44
44
  end
45
45
  end
46
46
 
@@ -65,7 +65,7 @@ def command_install(json_file, region, instance_id, options)
65
65
  r.apply_data!(data, options.fetch(:apply_options))
66
66
 
67
67
  if options[:prune]
68
- r.prune_ipsets
68
+ r.prune_ipsets(options.fetch(:prune_opts, {}))
69
69
  end
70
70
  end
71
71
 
@@ -146,6 +146,11 @@ Options:
146
146
  options[:prune] = true
147
147
  end
148
148
 
149
+ opts.on('--prune-future', 'Prune ipsets from future run generations') do
150
+ options[:prune] = true
151
+ options[:prune_opts] = {:future_ok => true}
152
+ end
153
+
149
154
  opts.on('-a', '--archive', 'Store an archived copy of these rules') do
150
155
  options[:archive] = true
151
156
  end
@@ -28,6 +28,6 @@ aws:
28
28
  :max_retries: 4
29
29
 
30
30
  reyes:
31
- pgp:
32
- signing_key: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
31
+ signing_key: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
32
+ keyring_directory: /etc/reyes/keyring/
33
33
  nf_conntrack_max: 262144
@@ -92,7 +92,6 @@ module Reyes
92
92
  set_nf_conntrack_max(Integer(ct_max))
93
93
  end
94
94
 
95
- # XXX(richo) Should we be pruning inside run! ?
96
95
  log.info('Finished RunManager.apply_data!')
97
96
  end
98
97
 
@@ -138,9 +137,15 @@ module Reyes
138
137
  end
139
138
 
140
139
  # Remove old IPSets from previous run generations.
141
- def prune_ipsets
140
+ #
141
+ # @param options [Hash]
142
+ #
143
+ # @option options :future_ok [Boolean] Whether to prune ipsets from future
144
+ # generations, which are normally skipped.
145
+ #
146
+ def prune_ipsets(options={})
142
147
  log.info('Pruning old IPSets')
143
- old_ipsets = []
148
+ prune_ipsets = []
144
149
  current_ipsets = []
145
150
 
146
151
  current_gen = @group_manager.run_generation
@@ -152,13 +157,14 @@ module Reyes
152
157
  end
153
158
 
154
159
  if s[:generation] < current_gen
155
- old_ipsets << set
160
+ prune_ipsets << set
156
161
  elsif s[:generation] == current_gen
157
162
  current_ipsets << set
158
163
  else
159
164
  log.error("IPSet from a future generation detected: #{set.inspect}")
160
- log.error("Cowardly refusing to proceed")
161
- raise Reyes::Error.new("IPSet from future generation detected")
165
+ if options[:future_ok]
166
+ prune_ipsets << set
167
+ end
162
168
  end
163
169
  end
164
170
 
@@ -168,7 +174,7 @@ module Reyes
168
174
  raise Reyes::Error.new("Pruning would remove all IPSets")
169
175
  end
170
176
 
171
- old_ipsets.each do |set|
177
+ prune_ipsets.each do |set|
172
178
  log.info("Pruning IPSet: #{set.name}")
173
179
  set.drop!
174
180
  end
@@ -1,6 +1,6 @@
1
1
  module Reyes
2
2
  # The Reyes version number
3
- VERSION = '1.2.6' unless defined?(self::VERSION)
3
+ VERSION = '1.3.0' unless defined?(self::VERSION)
4
4
 
5
5
  # Number defining the JSON serialization format
6
6
  JSON_FORMAT_VERSION = 2 unless defined?(self::JSON_FORMAT_VERSION)
@@ -0,0 +1,71 @@
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ # This script creates a default drop set of firewall rules that will apply at
5
+ # boot before the first Reyes run. (This ensures fail-closed behavior at boot.)
6
+ # Install this script in /etc/network/if-pre-up.d/ to ensure that it runs
7
+ # before network interfaces are brought up.
8
+
9
+ # You can generate these rules with the help of `reyes --empty`
10
+
11
+ # USAGE: you must select one of the two -A INPUT choices depending on whether
12
+ # this will be running on an instance in EC2 classic or VPC.
13
+
14
+ # INPUT_RULES=''
15
+
16
+ SAMPLE_INPUT_CLASSIC='
17
+ # filter IPsec in EC2 classic
18
+ -A INPUT -m policy --pol ipsec --dir in -j reyes-input
19
+ '
20
+
21
+ SAMPLE_INPUT_VPC='
22
+ # filter 10.0.0.0/8 in VPC, whitelisting the self VPC
23
+ -A INPUT -s 10.0.0.0/8 -j reyes-input
24
+ -A reyes-input -s $LOCAL_VPC_CIDR_BLOCK -j ACCEPT
25
+ '
26
+
27
+ logger -t reyes "Importing default drop firewall rules"
28
+
29
+ # generate these with reyes --empty
30
+
31
+ iptables-restore <<EOM
32
+ # Generated by Reyes, modified by hand
33
+ *filter
34
+ :INPUT ACCEPT
35
+ :FORWARD ACCEPT
36
+ :OUTPUT ACCEPT
37
+
38
+ :reyes-input -
39
+ :reyes-accept -
40
+ :reyes-drop -
41
+ :reyes-log-accept -
42
+ :reyes-log-drop -
43
+
44
+ $INPUT_RULES
45
+
46
+ -A reyes-accept -j reyes-log-accept
47
+ -A reyes-accept -j ACCEPT
48
+ -A reyes-drop -j reyes-log-drop
49
+ -A reyes-drop -j DROP
50
+
51
+ -A reyes-input -p icmp -m icmp --icmp-type 3 -j ACCEPT
52
+ -A reyes-input -p icmp -m icmp --icmp-type 4 -j ACCEPT
53
+ -A reyes-input -p icmp -m icmp --icmp-type 11 -j ACCEPT
54
+ -A reyes-input -p icmp -m icmp --icmp-type 12 -j ACCEPT
55
+ -A reyes-input -p icmp -m icmp --icmp-type 8 -j ACCEPT
56
+ -A reyes-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
57
+ -A reyes-input -m conntrack --ctstate INVALID -j reyes-drop
58
+
59
+ # dynamic rules from security groups
60
+
61
+ # default drop
62
+ -A reyes-input -j reyes-drop
63
+
64
+ # log rules
65
+ -A reyes-log-accept -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[REYES ACCEPT] "
66
+ -A reyes-log-drop -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[REYES BLOCK] "
67
+
68
+ COMMIT
69
+ EOM
70
+
71
+ logger -t reyes "Done importing default drop firewall rules"
@@ -20,11 +20,11 @@ Gem::Specification.new do |gem|
20
20
  gem.email = ["security@stripe.com"]
21
21
  gem.summary = "Reyes manages IPTables rules based on EC2 security groups."
22
22
  gem.description = <<-EOM
23
- Reyes is a gem...
24
-
25
- TO DO
23
+ Reyes populates IPTables firewall rules based on EC2 security group rules.
24
+ It applies security group rules to IPsec VPN traffic that would otherwise
25
+ be injected past security group protection. This is useful for enforcing
26
+ firewalls on VPNs between EC2 instances across VPCs, even across regions.
26
27
  EOM
27
- # TODO ^
28
28
  gem.homepage = "https://github.com/stripe/reyes/"
29
29
 
30
30
  gem.files = list_files
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reyes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.6
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Brody
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-12 00:00:00.000000000 Z
12
+ date: 2015-10-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -96,9 +96,10 @@ dependencies:
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  description: |2
99
- Reyes is a gem...
100
-
101
- TO DO
99
+ Reyes populates IPTables firewall rules based on EC2 security group rules.
100
+ It applies security group rules to IPsec VPN traffic that would otherwise
101
+ be injected past security group protection. This is useful for enforcing
102
+ firewalls on VPNs between EC2 instances across VPCs, even across regions.
102
103
  email:
103
104
  - security@stripe.com
104
105
  executables:
@@ -110,7 +111,9 @@ files:
110
111
  - ".rubocop-disables.yml"
111
112
  - ".rubocop.yml"
112
113
  - ".ruby-version"
114
+ - CHANGES.md
113
115
  - Gemfile
116
+ - LICENSE
114
117
  - README.md
115
118
  - Rakefile
116
119
  - bin/reyes
@@ -133,6 +136,7 @@ files:
133
136
  - lib/reyes/tmp_persistent_file.rb
134
137
  - lib/reyes/utils.rb
135
138
  - lib/reyes/version.rb
139
+ - misc/reyes-default-drop
136
140
  - reyes.gemspec
137
141
  homepage: https://github.com/stripe/reyes/
138
142
  licenses: []