stubby 0.0.1 → 0.0.2
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.
- data/LICENSE +21 -0
- data/README.md +172 -111
- data/lib/stubby/cli/application.rb +1 -50
- data/lib/stubby/extensions/default.rb +72 -0
- data/lib/stubby/extensions/dns.rb +47 -30
- data/lib/stubby/extensions/http.rb +63 -26
- data/lib/stubby/extensions/smtp.rb +47 -0
- data/lib/stubby/kernel.rb +36 -0
- data/lib/stubby/master.rb +83 -42
- data/lib/stubby/process.rb +22 -0
- data/lib/stubby/registry.rb +16 -115
- data/lib/stubby/stub.rb +18 -6
- data/lib/stubby.rb +7 -0
- metadata +38 -2
data/LICENSE
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 James Kassemi, @Pay
|
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.
|
data/README.md
CHANGED
@@ -20,17 +20,16 @@ from your project.
|
|
20
20
|
|
21
21
|
Install the stubby gem:
|
22
22
|
|
23
|
-
|
23
|
+
> $ sudo gem install stubby
|
24
24
|
|
25
25
|
## Available Options
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
> stubby status # View current rules
|
27
|
+
> $ sudo stubby -h
|
28
|
+
> Commands:
|
29
|
+
> stubby env NAME # Switch stubby environment
|
30
|
+
> stubby help [COMMAND] # Describe available commands or one specific command
|
31
|
+
> stubby start ENVIRONMENT # Starts stubby HTTP and DNS servers, default env ENVIRONMENT
|
32
|
+
> stubby status # View current rules
|
34
33
|
|
35
34
|
## Getting Started
|
36
35
|
|
@@ -38,72 +37,99 @@ Stubby uses `Stubfile.json` for configuration. This file includes a mapping of
|
|
38
37
|
environments to a number of rules that define server configurations and stub
|
39
38
|
usage for the project.
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
40
|
+
> cd ~/MyProject
|
41
|
+
> cat Stubfile.json
|
42
|
+
> {
|
43
|
+
> "test": {
|
44
|
+
> "dependencies": {
|
45
|
+
> "https://github.com/jkassemi/example-stubby.git": "staging"
|
46
|
+
> },
|
47
|
+
>
|
48
|
+
> "example.com": "localhost:3000"
|
49
|
+
> },
|
50
|
+
>
|
51
|
+
> "staging": {
|
52
|
+
> "dependencies": {
|
53
|
+
> "https://github.com/jkassemi/example-stubby.git": "staging"
|
54
|
+
> },
|
55
|
+
>
|
56
|
+
> "example.com": "dns-cname://aws..."
|
57
|
+
> }
|
58
|
+
> }
|
59
|
+
|
60
|
+
> $ sudo stubby start
|
62
61
|
|
63
62
|
The 'test' and 'staging' modes for this project both include rules for the
|
64
63
|
'example' stub, and then define a single rule of their own. Stubby starts
|
65
64
|
by default in the 'development' environment, so with this `Stubfile.json`,
|
66
65
|
the stubby server is not yet modifying any requests. In a new terminal:
|
67
66
|
|
68
|
-
|
67
|
+
> $ sudo stubby env test
|
69
68
|
|
70
69
|
Switches stubby to test mode. Now the 'example' stub is activated, and
|
71
70
|
additionally any requests to http or https versions of example.com are
|
72
71
|
routed to http://localhost:3000. Let's take a look at the rules applied:
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
73
|
+
> $ sudo bin/stubby status
|
74
|
+
|
75
|
+
> {
|
76
|
+
> "rules":{
|
77
|
+
> "https://github.com/jkassemi/example-stubby.git":{
|
78
|
+
> "dns://admin.example.com/a":"dns-a://172.16.123.1",
|
79
|
+
> "http://admin.example.com":"http-redirect://blank?to=https://admin.example.com&code=302",
|
80
|
+
> "https://admin.example.com":"http-proxy://10.0.1.1",
|
81
|
+
> "dns://admin2.example.com/a":"dns-cname://admin.example.com",
|
82
|
+
> "http://(.*)\\.?example.com":"http-proxy://10.0.1.1",
|
83
|
+
> "dns://(.*)\\.?example.com/a":"dns-a://172.16.123.1",
|
84
|
+
> "https://g?mail.*/.*":"http-proxy://en.wikipedia.org/wiki/RTFM",
|
85
|
+
> "dns://g?mail.*/.*/a":"dns-a://172.16.123.1",
|
86
|
+
> "http://yahoo.com":"http-redirect://duckduckgo.com",
|
87
|
+
> "dns://yahoo.com/a":"dns-a://172.16.123.1",
|
88
|
+
> "https://yahoo.com":"https-redirect://duckduckgo.com",
|
89
|
+
> "dns://.*\\.stubby.dev/a":"dns-a://172.16.123.1",
|
90
|
+
> "http://.*\\.stubby.dev":"file:///var/www/tmp",
|
91
|
+
> "https://.*\\.stubby.dev":"file:///var/www/tmp",
|
92
|
+
> "dns://api.example.com/a":"dns-a://172.16.123.1",
|
93
|
+
> "http://api.example.com":"file://~/.stubby/example/files",
|
94
|
+
> "https://api.example.com":"file://~/.stubby/example/files",
|
95
|
+
> "dns://.*/mx":"dns-mx://172.16.123.1/?priority=10"
|
96
|
+
> },
|
97
|
+
> "_":{
|
98
|
+
> "dependencies":{
|
99
|
+
> "https://github.com/jkassemi/example-stubby.git":"staging"
|
100
|
+
> },
|
101
|
+
> "dns://secured.atpay.com/a":"dns-a://172.16.123.1",
|
102
|
+
> "http://secured.atpay.com":"http-redirect://blank?to=https://secured.atpay.com&code=302",
|
103
|
+
> "https://secured.atpay.com":"http-proxy://localhost:3000",
|
104
|
+
> "dns://api.atpay.com/a":"dns-a://172.16.123.1",
|
105
|
+
> "http://api.atpay.com":"http-redirect://blank?to=https://api.atpay.com&code=302",
|
106
|
+
> "https://api.atpay.com":"http-proxy://localhost:4000",
|
107
|
+
> "dns://.*/mx":"dns-mx://172.16.123.1/?priority=10"
|
108
|
+
> },
|
109
|
+
> "_smtp":{
|
110
|
+
> "dns://outbox.stubby.dev/a":"dns-a://172.16.123.1",
|
111
|
+
> "http://outbox.stubby.dev":"http-proxy://172.16.123.1:9001"
|
112
|
+
> }
|
113
|
+
> },
|
114
|
+
> "environment":"development"
|
115
|
+
> }
|
98
116
|
|
99
117
|
This shows us all activated rules. the "_" indicates that the rules are loaded
|
100
|
-
from the current `Stubfile.json
|
101
|
-
|
118
|
+
from the current `Stubfile.json`, while "example" indicates that the rules are
|
119
|
+
loaded from an installed stub, "example".
|
102
120
|
|
103
121
|
To revert the system back to normal, just CTRL-C from the main stubby process.
|
104
122
|
This will revert any changes made to configure DNS servers for all network
|
105
123
|
interfaces and will shut down the stubby server.
|
106
124
|
|
125
|
+
### Stubs
|
126
|
+
|
127
|
+
- example: https://github.com/jkassemi/example-stubby.git
|
128
|
+
|
129
|
+
To contribute a stub, just add your stub to the list above and issue a pull
|
130
|
+
request.
|
131
|
+
|
132
|
+
|
107
133
|
## Stubbing
|
108
134
|
|
109
135
|
A stub is a folder named with the name of the stub that contains a stubby.json file. The stubby.json file contains a hash with the available
|
@@ -111,91 +137,94 @@ modes. Each mode contains a set of rules that define how to route DNS and how to
|
|
111
137
|
|
112
138
|
Installed stubs are in the ~/.stubby folder:
|
113
139
|
|
114
|
-
|
115
|
-
|
140
|
+
> $ ls ~/.stubby/jkassemi
|
141
|
+
> stubby-example
|
116
142
|
|
117
143
|
The example folder is the `example` stub, and the system.json file contains the agent configurations. You don't need to manually edit it.
|
118
144
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
145
|
+
> $ find ~/.stubby/jkassemi/example
|
146
|
+
> ... jkassemi/example
|
147
|
+
> ... jkassemi/example/files
|
148
|
+
> ... jkassemi/example/hello.html
|
149
|
+
> ... jkassemi/example/stubby.json
|
124
150
|
|
125
151
|
The example/stubby.json file has two modes, staging, and production:
|
126
152
|
|
127
|
-
|
128
|
-
|
153
|
+
> cat ~/.stubby/jkassemi/example-stubby/stubby.json
|
154
|
+
{ "staging": {...}, "production": {...} }
|
129
155
|
|
130
156
|
Each environment contains a number of rules:
|
131
157
|
|
132
|
-
|
133
|
-
|
134
|
-
|
158
|
+
{ "staging": {
|
159
|
+
"[PROTOCOL://]MATCH_REGEXP": "INSTRUCTION"
|
160
|
+
} ... }
|
135
161
|
|
136
162
|
When a request is made, either DNS or HTTP (important), the request is
|
137
|
-
compared against the
|
138
|
-
|
139
|
-
|
140
|
-
|
163
|
+
compared against the PROTOCOL and MATCH_REGEXP (together these are
|
164
|
+
called the TRIGGER). If matched, INSTRUCTION is executed.
|
165
|
+
Excluding a protocol from the trigger causes Stubby to presuppose a few
|
166
|
+
things about your request. It'll handle DNS, HTTP and HTTPS for definitions
|
167
|
+
like this.
|
141
168
|
|
142
|
-
|
169
|
+
"test.example.com": "http://10.0.1.5"
|
143
170
|
|
144
|
-
|
171
|
+
Expands to:
|
172
|
+
|
173
|
+
"dns://test.example.com/a": "dns-a://10.0.1.5",
|
174
|
+
"http://test.example.com": "http-redirect://blank?to=https://test.example.com&code=302",
|
175
|
+
"https://test.example.com": "http-proxy://10.0.1.5
|
176
|
+
|
177
|
+
Don't want to default over to https? You can be more explicit:
|
178
|
+
|
179
|
+
"http://test.example.com": "http://10.0.1.5"
|
180
|
+
|
181
|
+
Which expands to:
|
145
182
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
183
|
+
"dns://test.example.com/a": "dns-a://10.0.1.5",
|
184
|
+
"http://test.example.com": "http-proxy://10.0.1.5"
|
185
|
+
|
186
|
+
> $ dig test.example.com
|
187
|
+
...
|
188
|
+
;; ANSWER SECTION:
|
189
|
+
test.example.com. 0 IN A 172.16.123.1
|
150
190
|
|
151
|
-
172.16.123.1 is the stubby
|
191
|
+
172.16.123.1 is the stubby interface (TODO: configurable). All requests
|
152
192
|
to http://test.example.com are routed to the stubby web server at that
|
153
193
|
address.
|
154
194
|
|
155
|
-
|
156
|
-
|
157
|
-
Issues a request handled by the stubby web server, which proxies the request to 172.16.123.1.
|
195
|
+
> $ curl test.example.com
|
158
196
|
|
159
|
-
|
160
|
-
|
161
|
-
Fork this repository, update the index.json file, and submit a pull request. For
|
162
|
-
this major version, the remote registry will just be the index.json file from
|
163
|
-
this project's github.
|
197
|
+
Issues a request handled by the stubby web server, which proxies the request to 172.16.123.1.
|
164
198
|
|
165
199
|
### DNS Only
|
166
200
|
|
167
201
|
To simply override DNS for test.example.com, you can create an A record on lookup:
|
168
202
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
"test.example.com": "test.example2.com"
|
174
|
-
|
175
|
-
But you can be explicit in the INSTRUCTION:
|
203
|
+
"dns://test.example.com": "dns-a://10.0.1.5"
|
204
|
+
|
205
|
+
For a CNAME:
|
176
206
|
|
177
|
-
|
178
|
-
"test.example.com": "dns-cname://test.example2.com"
|
207
|
+
"dns://test.example.com": "dns-cname://test.example2.com"
|
179
208
|
|
180
209
|
Using the dns-#{name} convention, you can create simple references to
|
181
|
-
any dns record type.
|
182
|
-
|
210
|
+
any dns record type.
|
211
|
+
|
183
212
|
### File Server
|
184
213
|
|
185
214
|
Because stubby can intercept HTTP requests, it includes a base set of functionality that allows you two serve files directly from the stub. Given a rule:
|
186
215
|
|
187
|
-
|
216
|
+
"api.example.com": "file://~/.stubby/example/files"
|
188
217
|
|
189
218
|
DNS will resolve to the stubby server:
|
190
219
|
|
191
|
-
|
192
|
-
|
193
|
-
|
220
|
+
> $ dig api.example.com
|
221
|
+
...
|
222
|
+
api.example.com. 0 IN A 172.16.123.1
|
194
223
|
|
195
224
|
And a web request to api.example.com will serve files from the ~/.stubby/example/files directory:
|
196
225
|
|
197
|
-
|
198
|
-
|
226
|
+
> $ curl http://api.example.com/hello.html
|
227
|
+
> <html><head></head><body>Hello</body></html>
|
199
228
|
|
200
229
|
This is designed to allow you to create API stubs (success responses, for instance).
|
201
230
|
|
@@ -204,16 +233,48 @@ This is designed to allow you to create API stubs (success responses, for instan
|
|
204
233
|
|
205
234
|
Given a rule:
|
206
235
|
|
207
|
-
|
236
|
+
"http://yahoo.com": "http-redirect://blank?to=duckduckgo.com"
|
208
237
|
|
209
238
|
DNS will resolve to the stubby server, and the web request to http://yahoo.com will redirect to http://duckduckgo.com.
|
210
239
|
|
240
|
+
### Capturing Outgoing Email
|
241
|
+
|
242
|
+
Stubby includes an SMTP extension to capture outgoing messages. Specify the
|
243
|
+
domain to capture mail from and forward to smtp://
|
244
|
+
|
245
|
+
"smtp://.*\.example\.com": "about://blank"
|
246
|
+
|
247
|
+
will ensure any message sent by your system directly (this does not include
|
248
|
+
messages sent from yahoo or gmail) will be captured by Stubby. Visit
|
249
|
+
http://outbox.stubby.dev to see the captured messages.
|
250
|
+
|
251
|
+
Mail capture is currently provided by the "MailCatcher" gem.
|
252
|
+
|
211
253
|
### Vision
|
212
254
|
|
213
|
-
*
|
214
|
-
|
215
|
-
|
216
|
-
* proxy traffic on ports and send to log systems:
|
217
|
-
":25": "log-smtp://"
|
218
|
-
":3306": "log-mysql://"
|
255
|
+
* general traffic monitoring proxy traffic on ports and send to log systems:
|
256
|
+
":25": "smtp://"
|
257
|
+
":3306": "mysql://"
|
219
258
|
* web app front-end: show emails sent, mysql queries made, etc.
|
259
|
+
* github installation with no index.json
|
260
|
+
* P2P connections allow access to dev systems running stubby (agent mode?)
|
261
|
+
|
262
|
+
"example.com" => "localhost:3000"
|
263
|
+
"tunnel://example.com": "tunnel://jkassemi@stubby.site"
|
264
|
+
|
265
|
+
=>
|
266
|
+
|
267
|
+
On host system:
|
268
|
+
|
269
|
+
"example.com" => "localhost:3000"
|
270
|
+
|
271
|
+
On guest system:
|
272
|
+
|
273
|
+
"dns://example.com/.*" => @
|
274
|
+
"http://example.com" => "tunnel://jkassemi@stubby.site/?to=http://example.com"
|
275
|
+
"https://example.com" => "tunnel://jkassemi@stubby.site/?to=http://example.com"
|
276
|
+
"smtp://.*" => "tunnel://jkassemi@stubby.site/?to=smtp://$1"
|
277
|
+
|
278
|
+
|
279
|
+
guest opens a connection to stubby.site, requesting last broadcast of NAT address
|
280
|
+
for host. guest attempts udp tunnel with host
|
@@ -63,55 +63,6 @@ module Stubby
|
|
63
63
|
puts HTTPI.post("http://#{STUBBY_MASTER}:9000/environment.json", environment: name).body
|
64
64
|
end
|
65
65
|
|
66
|
-
desc "search", "View all available stubs"
|
67
|
-
long_desc <<-LONGDESC
|
68
|
-
View all available registered stubs. These are stubs that you can use
|
69
|
-
as dependencies in Stubfile.json.
|
70
|
-
|
71
|
-
> $ sudo stubby search
|
72
|
-
> {
|
73
|
-
> "example":[
|
74
|
-
> {
|
75
|
-
> "name":"example",
|
76
|
-
> "version":"v0.0.1",
|
77
|
-
> ...
|
78
|
-
> }
|
79
|
-
> ],
|
80
|
-
> "spreedly":[
|
81
|
-
> {
|
82
|
-
> "name":"spreedly",
|
83
|
-
> "version":"v0.0.1",
|
84
|
-
> ...
|
85
|
-
> }
|
86
|
-
> ]
|
87
|
-
> }
|
88
|
-
|
89
|
-
Wildcard supported for search:
|
90
|
-
|
91
|
-
> $ sudo stubby search ex*
|
92
|
-
> {
|
93
|
-
> "example":[
|
94
|
-
> {
|
95
|
-
> "name":"example",
|
96
|
-
> "version":"v0.0.1",
|
97
|
-
> ...
|
98
|
-
> }
|
99
|
-
> ]
|
100
|
-
> }
|
101
|
-
|
102
|
-
LONGDESC
|
103
|
-
def search(name=nil)
|
104
|
-
if master_running?
|
105
|
-
available = MultiJson.load(HTTPI.get("http://#{STUBBY_MASTER}:9000/stubs/available.json").body)
|
106
|
-
else
|
107
|
-
available = Stubby::Api.registry.index
|
108
|
-
end
|
109
|
-
|
110
|
-
puts MultiJson.dump(available.select { |key, ri|
|
111
|
-
File.fnmatch(name || "*", key)
|
112
|
-
}, pretty: true)
|
113
|
-
end
|
114
|
-
|
115
66
|
desc "status", "View current rules"
|
116
67
|
long_desc <<-LONGDESC
|
117
68
|
> $ sudo bin/stubby status
|
@@ -126,7 +77,7 @@ module Stubby
|
|
126
77
|
> "example":"staging"
|
127
78
|
> },
|
128
79
|
> "(https?://)?example.com":"http://localhost:3000"
|
129
|
-
>
|
80
|
+
> }
|
130
81
|
> },
|
131
82
|
> "environment":"test"
|
132
83
|
> }
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Extensions
|
2
|
+
class Default
|
3
|
+
def initialize
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
def run!(*args)
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop!(*args)
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def expand_rule(trigger, instruction)
|
16
|
+
# Default expansion:
|
17
|
+
# "example.com": "localhost:3000"
|
18
|
+
#
|
19
|
+
# =>
|
20
|
+
# "dns://example.com": "@"
|
21
|
+
# "http://example.com": "http-redirect://blank?to=https://example.com&code=302"
|
22
|
+
# "https://example.com": "http-proxy://localhost:3000"
|
23
|
+
#
|
24
|
+
# "example.com:4000": "localhost:3000"
|
25
|
+
#
|
26
|
+
# =>
|
27
|
+
# ERROR: port in trigger unsupported
|
28
|
+
#
|
29
|
+
# "dns://example.com": "@"
|
30
|
+
# "http://example.com:4000"
|
31
|
+
#
|
32
|
+
# "example.com": "http-redirect://localhost:3000"
|
33
|
+
#
|
34
|
+
# =>
|
35
|
+
# "dns://example.com": "@"
|
36
|
+
# "http://example.com": "http-redirect://?blank?to=http://localhost:3000&code=302"
|
37
|
+
# =====================================
|
38
|
+
#
|
39
|
+
# ".*\\.stubby.dev": "file:///var/www/tmp
|
40
|
+
#
|
41
|
+
# =>
|
42
|
+
#
|
43
|
+
# "dns://.*\\.stubby.dev": "@",
|
44
|
+
# "http://.*\\.stubby.dev": "file:///var/www/tmp",
|
45
|
+
# "https://.*\\.stubby.dev": "file:///var/www/tmp",
|
46
|
+
scheme, remains = instruction.split("://")
|
47
|
+
scheme, remains = remains, scheme if remains.nil?
|
48
|
+
|
49
|
+
if scheme.nil?
|
50
|
+
expand_bare(trigger, instruction)
|
51
|
+
else
|
52
|
+
expand_with_protocol(trigger, instruction)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def expand_bare(trigger, instruction)
|
57
|
+
{
|
58
|
+
"dns://#{trigger}/a" => "dns-a://#{STUBBY_MASTER}",
|
59
|
+
"http://#{trigger}" => "http-redirect://blank?to=https://#{trigger}&code=302",
|
60
|
+
"https://#{trigger}" => "http-proxy://#{instruction}"
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def expand_with_protocol(trigger, instruction)
|
65
|
+
{
|
66
|
+
"dns://#{trigger}/a" => "dns-a://#{STUBBY_MASTER}",
|
67
|
+
"http://#{trigger}" => instruction,
|
68
|
+
"https://#{trigger}" => instruction
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -23,49 +23,46 @@ module Extensions
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def process(name, resource_class, transaction)
|
26
|
-
body = HTTPI.post("http://#{STUBBY_MASTER}:9000/rules/search.json",
|
26
|
+
body = HTTPI.post("http://#{STUBBY_MASTER}:9000/rules/search.json",
|
27
|
+
trigger: "dns://#{name}/#{symbol_from_resource_class(resource_class)}").body
|
27
28
|
|
28
29
|
instruction = MultiJson.load(body)
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
if instruction.nil? or instruction == "@"
|
32
|
+
transaction.passthrough!(UPSTREAM)
|
33
|
+
return
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
+
url = URI.parse(instruction)
|
36
37
|
|
37
|
-
|
38
|
-
url = URI.parse("dns-a://" + instruction)
|
39
|
-
elsif (url.scheme.to_s =~ /^dns-.*/).nil?
|
40
|
-
url.host = STUBBY_MASTER
|
41
|
-
end
|
38
|
+
response_resource_class = resource url.scheme.gsub('dns-', '')
|
42
39
|
|
43
|
-
|
40
|
+
if !IPAddress.valid?(url.host) and response_resource_class == IN::A
|
41
|
+
response_resource_class = IN::CNAME
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
url.host = STUBBY_MASTER
|
47
|
-
end
|
44
|
+
response = url.host
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
if [IN::CNAME, IN::MX].include? response_resource_class
|
47
|
+
response = Resolv::DNS::Name.create(url.host)
|
48
|
+
end
|
52
49
|
|
53
|
-
|
50
|
+
puts "DNS: #{name} => #{response}-#{resource_class.name})"
|
54
51
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
if response_resource_class == IN::MX
|
53
|
+
transaction.respond!(10, response,
|
54
|
+
:resource_class => response_resource_class,
|
55
|
+
:ttl => 0)
|
56
|
+
else
|
57
|
+
transaction.respond!(response,
|
58
|
+
:resource_class => response_resource_class,
|
59
|
+
:ttl => 0)
|
60
|
+
end
|
64
61
|
end
|
65
62
|
|
66
63
|
def run!(session, options)
|
67
64
|
return if options[:dns] == false
|
68
|
-
trap("INT"){ stop!
|
65
|
+
trap("INT"){ stop! }
|
69
66
|
|
70
67
|
@session = session
|
71
68
|
setup_references and run_dns_server
|
@@ -75,12 +72,32 @@ module Extensions
|
|
75
72
|
teardown_references and stop_dns_server
|
76
73
|
end
|
77
74
|
|
75
|
+
def expand_rule(trigger, instruction)
|
76
|
+
i = URI.parse(instruction)
|
77
|
+
t = URI.parse(trigger)
|
78
|
+
|
79
|
+
# If not specifying a record type, match a
|
80
|
+
t.path = "/a" if t.path.empty?
|
81
|
+
|
82
|
+
if i.scheme.nil?
|
83
|
+
{ t.to_s => "dns-a://#{instruction}" }
|
84
|
+
else
|
85
|
+
{ t.to_s => instruction }
|
86
|
+
end
|
87
|
+
end
|
78
88
|
|
79
89
|
private
|
80
90
|
|
81
91
|
def resource(pattern)
|
82
92
|
return IN::A unless pattern.respond_to? :to_sym
|
93
|
+
symbol_to_resource_class[pattern.to_sym] || IN::A
|
94
|
+
end
|
95
|
+
|
96
|
+
def symbol_from_resource_class(klass)
|
97
|
+
symbol_to_resource_class.invert[klass] || :a
|
98
|
+
end
|
83
99
|
|
100
|
+
def symbol_to_resource_class
|
84
101
|
{
|
85
102
|
a: IN::A,
|
86
103
|
aaaa: IN::AAAA,
|
@@ -93,7 +110,7 @@ module Extensions
|
|
93
110
|
soa: IN::SOA,
|
94
111
|
txt: IN::TXT,
|
95
112
|
cname: IN::CNAME
|
96
|
-
}
|
113
|
+
}
|
97
114
|
end
|
98
115
|
|
99
116
|
def run_dns_server
|