services/Anycast-Wiki.md
... ...
@@ -1,252 +0,0 @@
1
-## Distributed wiki sites
2
-
3
-The idea is to deploy the mirrors across dn42 using [anycast](https://en.wikipedia.org/wiki/Anycast) addressing (BGP), thus providing redundancy, load-balancing and improved access times for the site.
4
-The local webserver is monitored with a simple shell script (below) [working in conjuction](https://wiki.dn42/services/Anycast-Wiki#distributed-wiki-sites_exabgp) with [ExaBGP](https://github.com/Exa-Networks/exabgp), announcing/withdrawing the assigned route if the service is up/down.
5
-
6
-### Network
7
-
8
- - Install wiki anycast address `172.23.0.80/32` on the system
9
- - Setup tunnel(s) to the dn42 network (routing daemon not required)
10
-
11
-### Setup gollum
12
-
13
- - Install [gollum](https://github.com/gollum/gollum)
14
- - Clone the dn42 wiki repo:
15
-
16
- `git clone ssh://[email protected]/dn42/wiki <path>`
17
-
18
- - Setup cron for periodic pull/push jobs for the repo
19
- - Generate a [CSR](/services/Certificate-Authority) and send to `[email protected]`. Wait for a reply containing internal.dn42/wiki.dn42 certificates.
20
- - Start two gollum instances, read-only and editing on `127.0.0.1`:
21
-
22
- Read/write (SSL access only):
23
- ```
24
-gollum --css <path>/custom.css --gollum-path <path> --host 127.0.0.1 --port 4568
25
- ```
26
- Read-only:
27
- ```
28
-gollum --css <path>/custom.css --gollum-path <path> --host 127.0.0.1 --port 4567 --no-edit
29
- ```
30
-
31
-### Nginx proxy
32
-
33
-A custom header `X-SiteID` identifies the site you're connecting to:
34
-
35
- + X-SiteID: `AS number`-`ISO country code`
36
-
37
-
38
-##### Config example
39
-
40
-```
41
-ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
42
-ssl_session_cache shared:SSL:2m;
43
-
44
-ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
45
-
46
-ssl_prefer_server_ciphers on;
47
-
48
-upstream wiki { server 127.0.0.1:4567; }
49
-
50
-server {
51
- server_name internal.dn42 wiki.dn42;
52
-
53
- listen 172.23.0.80:80 default;
54
-
55
- add_header strict-transport-security "max-age=0; includeSubDomains";
56
- add_header X-SiteID '<aut-num>-<cc>';
57
-
58
- location / {
59
- location =/robots.txt { root <path>/wiki.dn42/; }
60
- location =/custom.css { root <path>/wiki.dn42/; }
61
- proxy_pass http://wiki;
62
- }
63
-}
64
-
65
-upstream wikirw { server 127.0.0.1:4568; }
66
-
67
-
68
-server {
69
- server_name internal.dn42 wiki.dn42;
70
-
71
- listen 172.23.0.80:443 ssl default;
72
-
73
- ssl on;
74
- ssl_certificate <path>/ssl.crt;
75
- ssl_certificate_key <path>/ssl.key;
76
-
77
- add_header strict-transport-security "max-age=0; includeSubDomains";
78
- add_header Public-Key-Pins 'pin-sha256="mJ1xUCzfru8Ckq2+M6VkNKGOGgSETImRAHBF24mjalw="; pin-sha256="/gOyi7syRMR+d2jZoB/MzcSD++8ciZkSl/hZAQgzWws="; max-age=0; includeSubDomains';
79
- add_header X-SiteID '<aut-num>-<cc>';
80
-
81
- location / {
82
- location =/robots.txt { root <path>/wiki.dn42/; }
83
- location =/custom.css { root <path>/wiki.dn42/; }
84
- proxy_pass http://wikirw;
85
- }
86
-}
87
-
88
-```
89
-
90
-### [ExaBGP](https://github.com/Exa-Networks/exabgp)
91
-
92
-##### Announcing
93
-
94
-The prefix AS-PATH should show the announcement is originating from your AS. After peering ExaBGP to the nearest speaker(s), check if the prefix is routing properly inside your network. Try not to blackhole the passing traffic (e.g. no static routes to `172.23.0.80/28`). Test the whole thing by shutting down nginx/gollum and watch what happens.
95
-
96
-##### Configuration
97
-
98
-```
99
-# exabgp.conf
100
-
101
-group gollum-watchdog {
102
- neighbor <peer1> {
103
- router-id x.x.x.x;
104
- local-address <source-address>;
105
- local-as <ownas>;
106
- peer-as <peeras>;
107
- }
108
-
109
- ## (example) peer with one of our iBGP speakers:
110
- neighbor <172.22.0.1> {
111
- router-id 172.23.0.80;
112
- local-address 172.22.0.2;
113
- local-as 123456;
114
- peer-as 123456;
115
- }
116
-
117
- ## ...
118
-
119
- process watch-gollum {
120
- run <path>/gollum-watchdog.sh;
121
- }
122
-}
123
-
124
-```
125
-
126
-##### Watchdog script
127
-
128
-Watchdog runs in an infinite loop, sending the appropriate commands to stdout. [ExaBGP](https://github.com/Exa-Networks/exabgp) attaches to the process' stdout and listens for instructions. Watchdog sends either a route announce or widthdraw.
129
-
130
-Run `gollum-watchdog.sh` in a shell first to validate it's working:
131
-
132
-```
133
-#!/bin/bash
134
-
135
-CURL=curl
136
-
137
-## url's to check (all listed must be alive to send announce)
138
-URL=( "http://172.23.0.80" "https://172.23.0.80" )
139
-
140
-## the anycast route (/28 due to prefix size limits)
141
-ROUTE='172.23.0.80/28'
142
-
143
-## the next-hop we'll be advertising to neighbor(s)
144
-NEXTHOP='<source-address>'
145
-
146
-## regex match this keyword against HTTP response from curl
147
-VALIDATE_KEYWORD='gollum'
148
-
149
-INTERVAL=60
150
-
151
-###########################
152
-
153
-RUN_STATE=0
154
-
155
-check_urls() {
156
- for url in "${URL[@]}"; do
157
-
158
- ## workaround curl errno 23 when piping
159
- http_response=`${CURL} --insecure -L -o - "${url}"`
160
-
161
- echo "${http_response}" | egrep -q "${VALIDATE_KEYWORD}" || {
162
- return 1
163
- }
164
-
165
- ## add more checks
166
-
167
- done
168
- return 0
169
-}
170
-
171
-while [ 1 ]; do
172
- if [ ${RUN_STATE} -eq 0 ]; then
173
- check_urls && {
174
- RUN_STATE=1
175
- echo "announce route ${ROUTE} next-hop ${NEXTHOP}"
176
- }
177
- else
178
- check_urls || {
179
- RUN_STATE=0
180
- echo "withdraw route ${ROUTE} next-hop ${NEXTHOP}"
181
- }
182
- fi
183
-
184
- sleep ${INTERVAL}
185
-
186
-done
187
-
188
-exit 0
189
-
190
-
191
-```
192
-
193
-##### Run
194
-
195
- Normally SIGUSR1 to the exabgp process triggers a configuration update, but at occasion the process might need to be restarted - since its gracefull shutdown can be glitchy , this might be a bit difficult. Sending SIGKILL to the child(ren) and immediately after, the parent, does the job (quick-and-dirty).
196
-
197
-`USAGE: /etc/exabgp/run.sh [start|stop|restart]`
198
-
199
-```
200
-
201
-#!/bin/bash
202
-
203
-PID_FILE=/var/run/exaBGP/exabgp_PID
204
-
205
-######################################
206
-
207
-EXABGP=<path>/sbin/exabgp
208
-EXA_LOG=/var/log/exabgp.log
209
-CONF=/etc/exabgp/exabgp.conf
210
-
211
-
212
-start() {
213
- [ -f ${PID_FILE} ] && {
214
- echo "WARNING: `cat ${PID_FILE}`: exabgp already running"; return 1
215
- }
216
- ${EXABGP} ${CONF} &> ${EXA_LOG} &
217
- cpid=$!
218
- [ ${cpid} -eq 0 ] && {
219
- echo "ERROR: could not start process"; return 1
220
-
221
- }
222
- echo $! > ${PID_FILE}
223
-}
224
-
225
-stop(){
226
- [ -f ${PID_FILE} ] || return 1
227
- pkill -9 -P $(cat ${PID_FILE})
228
- kill -9 $(cat ${PID_FILE})
229
- rm -f ${PID_FILE}
230
-}
231
-
232
-case ${1} in
233
- start )
234
- start
235
- ;;
236
- stop )
237
- stop
238
- ;;
239
- restart )
240
- stop
241
- sleep 1
242
- start
243
- ;;
244
-esac
245
-
246
-exit 0
247
-
248
-```
249
-
250
-
251
-
252
-
... ...
\ No newline at end of file
services/Distributed-wiki.md
... ...
@@ -0,0 +1,252 @@
1
+## Distributed wiki sites
2
+
3
+The idea is to deploy the mirrors across dn42 using [anycast](https://en.wikipedia.org/wiki/Anycast) addressing (BGP), thus providing redundancy, load-balancing and improved access times for the site.
4
+The local webserver is monitored with a simple shell script (below) [working in conjuction](https://wiki.dn42/services/Anycast-Wiki#distributed-wiki-sites_exabgp) with [ExaBGP](https://github.com/Exa-Networks/exabgp), announcing/withdrawing the assigned route if the service is up/down.
5
+
6
+### Network
7
+
8
+ - Install wiki anycast address `172.23.0.80/32` on the system
9
+ - Setup tunnel(s) to the dn42 network (routing daemon not required)
10
+
11
+### Setup gollum
12
+
13
+ - Install [gollum](https://github.com/gollum/gollum)
14
+ - Clone the dn42 wiki repo:
15
+
16
+ `git clone ssh://[email protected]/dn42/wiki <path>`
17
+
18
+ - Setup cron for periodic pull/push jobs for the repo
19
+ - Generate a [CSR](/services/Certificate-Authority) and send to `[email protected]`. Wait for a reply containing internal.dn42/wiki.dn42 certificates.
20
+ - Start two gollum instances, read-only and editing on `127.0.0.1`:
21
+
22
+ Read/write (SSL access only):
23
+ ```
24
+gollum --css <path>/custom.css --gollum-path <path> --host 127.0.0.1 --port 4568
25
+ ```
26
+ Read-only:
27
+ ```
28
+gollum --css <path>/custom.css --gollum-path <path> --host 127.0.0.1 --port 4567 --no-edit
29
+ ```
30
+
31
+### Nginx proxy
32
+
33
+A custom header `X-SiteID` identifies the site you're connecting to:
34
+
35
+ + X-SiteID: `AS number`-`ISO country code`
36
+
37
+
38
+##### Config example
39
+
40
+```
41
+ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
42
+ssl_session_cache shared:SSL:2m;
43
+
44
+ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
45
+
46
+ssl_prefer_server_ciphers on;
47
+
48
+upstream wiki { server 127.0.0.1:4567; }
49
+
50
+server {
51
+ server_name internal.dn42 wiki.dn42;
52
+
53
+ listen 172.23.0.80:80 default;
54
+
55
+ add_header strict-transport-security "max-age=0; includeSubDomains";
56
+ add_header X-SiteID '<aut-num>-<cc>';
57
+
58
+ location / {
59
+ location =/robots.txt { root <path>/wiki.dn42/; }
60
+ location =/custom.css { root <path>/wiki.dn42/; }
61
+ proxy_pass http://wiki;
62
+ }
63
+}
64
+
65
+upstream wikirw { server 127.0.0.1:4568; }
66
+
67
+
68
+server {
69
+ server_name internal.dn42 wiki.dn42;
70
+
71
+ listen 172.23.0.80:443 ssl default;
72
+
73
+ ssl on;
74
+ ssl_certificate <path>/ssl.crt;
75
+ ssl_certificate_key <path>/ssl.key;
76
+
77
+ add_header strict-transport-security "max-age=0; includeSubDomains";
78
+ add_header Public-Key-Pins 'pin-sha256="mJ1xUCzfru8Ckq2+M6VkNKGOGgSETImRAHBF24mjalw="; pin-sha256="/gOyi7syRMR+d2jZoB/MzcSD++8ciZkSl/hZAQgzWws="; max-age=0; includeSubDomains';
79
+ add_header X-SiteID '<aut-num>-<cc>';
80
+
81
+ location / {
82
+ location =/robots.txt { root <path>/wiki.dn42/; }
83
+ location =/custom.css { root <path>/wiki.dn42/; }
84
+ proxy_pass http://wikirw;
85
+ }
86
+}
87
+
88
+```
89
+
90
+### [ExaBGP](https://github.com/Exa-Networks/exabgp)
91
+
92
+##### Announcing
93
+
94
+The prefix AS-PATH should show the announcement is originating from your AS. After peering ExaBGP to the nearest speaker(s), check if the prefix is routing properly inside your network. Try not to blackhole the passing traffic (e.g. no static routes to `172.23.0.80/28`). Test the whole thing by shutting down nginx/gollum and watch what happens.
95
+
96
+##### Configuration
97
+
98
+```
99
+# exabgp.conf
100
+
101
+group gollum-watchdog {
102
+ neighbor <peer1> {
103
+ router-id x.x.x.x;
104
+ local-address <source-address>;
105
+ local-as <ownas>;
106
+ peer-as <peeras>;
107
+ }
108
+
109
+ ## (example) peer with one of our iBGP speakers:
110
+ neighbor <172.22.0.1> {
111
+ router-id 172.23.0.80;
112
+ local-address 172.22.0.2;
113
+ local-as 123456;
114
+ peer-as 123456;
115
+ }
116
+
117
+ ## ...
118
+
119
+ process watch-gollum {
120
+ run <path>/gollum-watchdog.sh;
121
+ }
122
+}
123
+
124
+```
125
+
126
+##### Watchdog script
127
+
128
+Watchdog runs in an infinite loop, sending the appropriate commands to stdout. [ExaBGP](https://github.com/Exa-Networks/exabgp) attaches to the process' stdout and listens for instructions. Watchdog sends either a route announce or widthdraw.
129
+
130
+Run `gollum-watchdog.sh` in a shell first to validate it's working:
131
+
132
+```
133
+#!/bin/bash
134
+
135
+CURL=curl
136
+
137
+## url's to check (all listed must be alive to send announce)
138
+URL=( "http://172.23.0.80" "https://172.23.0.80" )
139
+
140
+## the anycast route (/28 due to prefix size limits)
141
+ROUTE='172.23.0.80/28'
142
+
143
+## the next-hop we'll be advertising to neighbor(s)
144
+NEXTHOP='<source-address>'
145
+
146
+## regex match this keyword against HTTP response from curl
147
+VALIDATE_KEYWORD='gollum'
148
+
149
+INTERVAL=60
150
+
151
+###########################
152
+
153
+RUN_STATE=0
154
+
155
+check_urls() {
156
+ for url in "${URL[@]}"; do
157
+
158
+ ## workaround curl errno 23 when piping
159
+ http_response=`${CURL} --insecure -L -o - "${url}"`
160
+
161
+ echo "${http_response}" | egrep -q "${VALIDATE_KEYWORD}" || {
162
+ return 1
163
+ }
164
+
165
+ ## add more checks
166
+
167
+ done
168
+ return 0
169
+}
170
+
171
+while [ 1 ]; do
172
+ if [ ${RUN_STATE} -eq 0 ]; then
173
+ check_urls && {
174
+ RUN_STATE=1
175
+ echo "announce route ${ROUTE} next-hop ${NEXTHOP}"
176
+ }
177
+ else
178
+ check_urls || {
179
+ RUN_STATE=0
180
+ echo "withdraw route ${ROUTE} next-hop ${NEXTHOP}"
181
+ }
182
+ fi
183
+
184
+ sleep ${INTERVAL}
185
+
186
+done
187
+
188
+exit 0
189
+
190
+
191
+```
192
+
193
+##### Run
194
+
195
+ Normally SIGUSR1 to the exabgp process triggers a configuration update, but at occasion the process might need to be restarted - since its gracefull shutdown can be glitchy , this might be a bit difficult. Sending SIGKILL to the child(ren) and immediately after, the parent, does the job (quick-and-dirty).
196
+
197
+`USAGE: /etc/exabgp/run.sh [start|stop|restart]`
198
+
199
+```
200
+
201
+#!/bin/bash
202
+
203
+PID_FILE=/var/run/exaBGP/exabgp_PID
204
+
205
+######################################
206
+
207
+EXABGP=<path>/sbin/exabgp
208
+EXA_LOG=/var/log/exabgp.log
209
+CONF=/etc/exabgp/exabgp.conf
210
+
211
+
212
+start() {
213
+ [ -f ${PID_FILE} ] && {
214
+ echo "WARNING: `cat ${PID_FILE}`: exabgp already running"; return 1
215
+ }
216
+ ${EXABGP} ${CONF} &> ${EXA_LOG} &
217
+ cpid=$!
218
+ [ ${cpid} -eq 0 ] && {
219
+ echo "ERROR: could not start process"; return 1
220
+
221
+ }
222
+ echo $! > ${PID_FILE}
223
+}
224
+
225
+stop(){
226
+ [ -f ${PID_FILE} ] || return 1
227
+ pkill -9 -P $(cat ${PID_FILE})
228
+ kill -9 $(cat ${PID_FILE})
229
+ rm -f ${PID_FILE}
230
+}
231
+
232
+case ${1} in
233
+ start )
234
+ start
235
+ ;;
236
+ stop )
237
+ stop
238
+ ;;
239
+ restart )
240
+ stop
241
+ sleep 1
242
+ start
243
+ ;;
244
+esac
245
+
246
+exit 0
247
+
248
+```
249
+
250
+
251
+
252
+
... ...
\ No newline at end of file