aboutsummaryrefslogtreecommitdiff
path: root/template/tutorial-macos.html.j2
diff options
context:
space:
mode:
Diffstat (limited to 'template/tutorial-macos.html.j2')
-rw-r--r--template/tutorial-macos.html.j2506
1 files changed, 506 insertions, 0 deletions
diff --git a/template/tutorial-macos.html.j2 b/template/tutorial-macos.html.j2
new file mode 100644
index 00000000..df0ff757
--- /dev/null
+++ b/template/tutorial-macos.html.j2
@@ -0,0 +1,506 @@
1{% extends "common/base.j2" %}
2{% block body_content %}
3<div class="container">
4
5 <h2>{{ _("Tutorial: GNUnet on macOS 10.14 (Mojave)") }}</h2>
6
7 <h3>{{ _("Introduction") }}</h3>
8
9 <p>
10 Welcome to the hopefully painless GNUnet tutorial for macOS Mojave! It provides
11 concrete instructions on how to compile, install and configure a current
12 version of GNUnet. The goal is to support newcomers, either end users or
13 developers, who want to get in touch with GNUnet for the first time. After
14 installing GNUnet we will make sure that out new GNUnet installation is working
15 correctly.
16 </p>
17
18 <h3>{{ _("Requirements") }}</h3>
19
20 <p>
21 First, install <a href="https://brew.sh">homebrew</a> and <a href="https://developer.apple.com/xcode/">XCode</a>.
22 Then install the following packages:
23 </p>
24
25 <code>
26 $ sudo brew install git autoconf automake glpk gettext gnutls jansson libextractor libgcrypt libffi libidn2 libmicrohttpd libmpc libtool libunistring pkg-config unbound
27 </code>
28
29 <h3>{{ _("Make an installation directory") }}</h3>
30
31 <p>
32 Next we create a directory in our home directory where we store
33 the source code later. We should keep this directory after
34 installation because it contains Makefiles that can be used for
35 uninstalling GNUnet again (see chapter *Uninstall GNUnet and its
36 dependencies*).
37 </p>
38
39 <code>
40 $ mkdir ~/gnunet
41 </code>
42
43 <h3>{{ _("Get the source code") }}</h3>
44
45 <code>
46 $ cd ~<br>
47 $ git clone --depth 1 https://gnunet.org/git/gnunet.git gnunet_src<br>
48 </code>
49 <p>
50 In order to have a gnutls with DANE support, you need to edit the formula:
51 </p>
52 <code>
53 $ brew edit gnutls
54 </code>
55 <p>
56 Add the line "depends_on 'unbound'" to the dependencies in the formula.
57 Then in the install function before the configure add:
58 </p>
59 <code>
60 ENV['CFLAGS']='-I/usr/local/Cellar/unbound/1.9.0/include'<br/>
61 ENV['LDFLAGS']='-L/usr/local/Cellar/unbound/1.9.0/lib'
62 </code>
63 <p>
64 Reinstall gnutls from source:
65 </p>
66 <code>
67 $ brew reinstall -s gnutls
68 </code>
69
70 <h3>{{ _("Compile and Install") }}</h3>
71
72
73 <p>
74 We have two options:
75 installing a *production version* and installing a *development version*. If
76 you want to start writing GNUnet applications or join the GNUnet development
77 choose the development version (it will print more debug output and contains
78 debug symbols that can be displayed with a debugger). Otherwise choose the
79 production version.
80 </p>
81
82 <h4>{{ _("Option 1: GNUnet for production / usage") }}</h4>
83
84 <code>
85 $ cd ~/gnunet_src<br>
86 $ ./bootstrap<br>
87 $ export GNUNET_PREFIX=~/gnunet<br>
88 $ ./configure --prefix=$GNUNET_PREFIX --disable-documentation<br>
89 </code>
90 <p>
91 You might see configure failing telling you that it ``cannot run C compiled programs.''.
92 In this case, you might need to open/run Xcode once and you will be prompted to
93 install additonal packages.
94 Then, you might have to manually install the command line tools from here https://developer.apple.com/download/more/ (you need an Apple ID for this).
95 Install those and execute
96 </p>
97 <code>
98 $ open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
99 </code>
100 <p>
101 After configure passes, you need to add a 'gnunetdns' group using the macOS system preferences.
102 Further, you need to add a user 'gnunet'. Then:
103 </p>
104 <code>
105 $ make<br>
106 $ sudo make install
107 </code>
108
109 <h4>{{ _("Option 2: GNUnet for development") }}</h4>
110
111 <p>
112 Perform the same steps as for Option 1, but add the configure flat '--enable-experimental'
113 </p>
114 <!--
115 <h4>{{ _("Install GNUnet plugin for name resolution") }}</h4>
116 <p>
117 So now it gets a bit nasty. It's not so bad. All we have to do
118 is copy a file and edit another one. The file we need to copy
119 is GNUnet's plugin for the Name Service Switch (NSS) in unix
120 systems. Different unixes expect it in different locations and
121 GNUnet's build system does not try to guess. On Debian 9 we
122 have to do
123 <code>
124 $ sudo cp /usr/lib/gnunet/nss/libnss_gns.so.2 /lib/$(uname -m)-linux-gnu/
125 </code>
126 </p>
127
128 <p>
129 Congratulations! GNUnet is now installed! Before we start it we
130 need to create a configuration file. By default GNUnet looks in
131 our home directory for the file `~/.gnunet/gnunet.conf`. We can
132 start with an empty file for now:
133 </p>
134
135 <code>
136 $ touch ~/.config/gnunet.conf
137 </code>
138
139 <p>
140 Now we can start it with the command line tool
141 `gnunet-arm` (Automatic Restart Manager).
142 </p>
143
144 <code>
145 $ gnunet-arm -s
146 </code>
147
148 <p>
149 It starts the default GNUnet services. We can list them with the
150 `-I` option:
151 </p>
152
153 <code>
154 $ gnunet-arm -I<br>
155 Running services:<br>
156 ats (gnunet-service-ats)<br>
157 revocation (gnunet-service-revocation)<br>
158 set (gnunet-service-set)<br>
159 nat (gnunet-service-nat)<br>
160 transport (gnunet-service-transport)<br>
161 peerstore (gnunet-service-peerstore)<br>
162 hostlist (gnunet-daemon-hostlist)<br>
163 identity (gnunet-service-identity)<br>
164 namecache (gnunet-service-namecache)<br>
165 peerinfo (gnunet-service-peerinfo)<br>
166 datastore (gnunet-service-datastore)<br>
167 zonemaster (gnunet-service-zonemaster)<br>
168 zonemaster-monitor (gnunet-service-zonemaster-monitor)<br>
169 nse (gnunet-service-nse)<br>
170 cadet (gnunet-service-cadet)<br>
171 dht (gnunet-service-dht)<br>
172 core (gnunet-service-core)<br>
173 gns (gnunet-service-gns)<br>
174 statistics (gnunet-service-statistics)<br>
175 topology (gnunet-daemon-topology)<br>
176 fs (gnunet-service-fs)<br>
177namestore (gnunet-service-namestore)<br>
178vpn (gnunet-service-vpn)
179 </code>
180
181 <p>
182 For stopping GNUnet again we can use the `-e` option.
183 </p>
184
185 <code>
186 $ gnunet-arm -e
187 </code>
188
189
190 <h3>{{ _("Make sure it works") }}</h3>
191
192 <p>
193 Let's try out some of GNUnet's use cases. Some should be done
194 before others:
195 </p>
196
197 <ul>
198 <li>filesharing</li>
199 <li>A simple chat using CADET</li>
200 <li>Name resolution using GNS on the command line</li>
201 <li>Name resolution using GNS with a browser (do it on the command line first)</li>
202 <li>Serving a website using VPN (do name resolution with a browser first)</li>
203 </ul>
204
205 <h4>{{ _("filesharing") }}</h4>
206
207 <p>
208 Let's publish a file in the GNUnet filesharing network. We use the keywords
209 ("commons" and "state") so other people will be able to search for the file.
210 </p>
211
212 <p>
213 We can choose any file and describe it with meaningful keywords (using the
214 `-k` command line option).
215 </p>
216
217 <code>
218 $ gnunet-publish -k commons -k state ostrom.pdf<br>
219 Publishing `/home/myself/ostrom.pdf' done.<br>
220 URI is `gnunet://fs/chk/M57SXDJ72EWS25CT6307KKJ8K0GCNSPTAZ649NA1NS10MJB4A1GZ9EN4Y02KST9VA5BHE8B335RPXQVBWVZ587Y83WQ7J3DHMBX30Q8.DHNGBN4CB2DBX1QRZ1R0B1Q18WTEAK4R94S9D57C9JMJJ3H7SSQDCV4D1218C4S2VP085AMQQSMG18FCP6NQMZQZJ91XR5NBX7YF0V0.42197237'.
221 </code>
222
223
224 <p>Finding the file by keyword works with `gnunet-search`.</p>
225
226 <code>
227 $ gnunet-search commons<br>
228#1:<br>
229 gnunet-download -o "ostrom.pdf" gnunet://fs/chk/M57SXDJ72EWS25CT6307KKJ8K0GCNSPTAZ649NA1NS10MJB4A1GZ9EN4Y02KST9VA5BHE8B335RPXQVBWVZ587Y83WQ7J3DHMBX30Q8.DHNGBN4CB2DBX1QRZ1R0B1Q18WTEAK4R94S9D57C9JMJJ3H7SSQDCV4D1218C4S2VP085AMQQSMG18FCP6NQMZQZJ91XR5NBX7YF0V0.42197237
230 </code>
231
232 <p>
233 It gives us the command line call to download the file (and store it as
234 ostrom.pdf)!
235 </p>
236
237 <h4>{{ _("CADET (and Chat)") }}</h4>
238
239 <p>
240 We can use the `gnunet-cadet` command line tool to open a port and from
241 another machine connect to this port and chat or transfer data. First we need
242 our *peer ID* of the GNUnet peer opening the port.
243 </p>
244
245 <code>
246 $ gnunet-peerinfo -s<br>
247 I am peer `P4T5GHS1PCZ06R82D3KW8Z8J1113BQZWAWGYHTZ8G1ZXMWXQGAVG'.
248 </code>
249
250
251 <p>
252 Now we open the port (it can be any string!):
253 </p>
254
255 <code>
256 $ gnunet-cadet -o my-secret-port
257 </code>
258
259 <p>
260 On the other machine we can connect using the peer ID and the port
261 and start chatting!
262 </p>
263
264 <code>
265 $ gnunet-cadet P4T5GHS1PCZ06R82D3KW8Z8J1113BQZWAWGYHTZ8G1ZXMWXQGAVG my-secret-port
266 </code>
267
268 <h4>{{ _("Name resolution using GNS on the command line") }}</h4>
269
270 <p>
271 GNS is the GNU name service, a fully decentralized alternatice to
272 DNS. We'll publish an IP address in a GNS record try to resolve it
273 on the command line. First we need an identity which is the
274 equivalent to a zone in DNS. We'll call it "myself" and create it
275 using the `gnunet-identity` command line tool. Instead of "myself"
276 you can surely use your nick or any other name.
277 </p>
278
279 <code>
280 $ gnunet-identity -C myself
281 </code>
282
283 <p>
284 We can check if it worked using the same tool. We expect the name
285 of our identity and the corresponding public key to be
286 displayed.
287 </p>
288
289 <code>
290 $ gnunet-identity -d<br>
291 myself - HWTYD3P5D77JVFNVMZ1M5T10V4SZYNMY3PCGQCSVENKD6ZCRKPMG
292 </code>
293
294 <p>
295 Now we add a public `A` record to our zone. It has the name "ccc", a value
296 of "195.54.164.39" and it expires after one day.
297 </p>
298
299 <code>
300 $ gnunet-namestore -z myself -a -e "1 d" -p -t A -n ccc -V 195.54.164.39
301 </code>
302
303 <p>
304 Now we can query that record using the command line tool `gnunet-gns`.
305 </p>
306
307 <code>
308 $ gnunet-gns -t A -u ccc.myself<br>
309 ccc.myself:<br>
310 Got `A' record: 195.54.164.39
311 </code>
312
313 <p>
314 So it worked! But only resolving our own records is boring. So we
315 can give our identity (the public key of it to be precise) to
316 someone else so they can try to resolve our records, too. The
317 other person (Bob) has to add it to his namestore like this:
318 <p>
319
320 <code>
321 $ gnunet-namestore -z myself -a -e never -p -t PKEY -n alice -V HWTYD3P5D77JVFNVMZ1M5T10V4SZYNMY3PCGQCSVENKD6ZCRKPMG
322 </code>
323
324 <p>
325 Our identity in Bobs namestore is a public record (-p) and never
326 expires (-e never). Now Bob (let's assume he has called his identity
327 myself, too) should be able to resolve our "ccc" record, too!
328 </p>
329
330 <code>
331 $ gnunet-gns -t A -u ccc.alice.myself<br>
332 ccc.alice.myself:<br>
333 Got `A' record: 195.54.164.39
334 </code>
335
336 <p>
337 It can continue like this. A friend of Bob would be able to
338 resolve our records too because Bob published our identity in a
339 public record. Bobs friend would simply use "ccc.alice.bob.myself"
340 to resolve our "ccc" record.
341 </p>
342
343
344 <h4>{{ _("Name resolution using GNS with a browser") }}</h4>
345
346 <p>
347 In the previous use case "Name resolution using GNS on the
348 command line" we got an idea about what GNS is about, but now
349 let's use it with a browser, to make it actually useful. Currently
350 Firefox and Chromium are known to work.
351 </p>
352
353 <p>
354 Many websites enforce HTTPS and thus provide certificates for
355 their hostnames (and not our GNS names). Browsers don't like wrong
356 hostnames in certificates and will present error messages. So
357 GNUnet has to trick them by generating own certificates for our
358 GNS names. This means we need to create our own certificate
359 authority and tell our browser about it. Luckily there's a script
360 for it:
361 </p>
362
363 <code>
364 $ gnunet-gns-proxy-setup-ca
365 </code>
366
367 <p>
368 After executing this script the Browser has to be restarted.
369 </p>
370
371 <p>
372 GNUnet provides a proxy service (gnunet-gns-proxy) that the
373 browser can send DNS and HTTP traffic to. It will try to resolve
374 names with GNS first and forward the rest of the DNS traffic to
375 the system's DNS resolver. It will also take care of the HTTP
376 traffic, so the browser gets valid certificates and the web server
377 will not be confused by our GNS hostnames. Our GNS namestore
378 doesn't know about any DNS hostnames yet, so we have to store
379 them, too. For our "ccc" A record, we have to store a LEHO (legacy
380 hostname) record, too. It must contain the website's original DNS
381 hostname:
382 </p>
383
384 <code>
385 $ gnunet-namestore -z myself -a -e "1 d" -p -t LEHO -n ccc -V www.ccc.de
386 </code>
387
388 <p>
389 Now let's start gnunet-gns-proxy.
390 </p>
391
392 <code>
393 $ /usr/lib/gnunet/libexec/gnunet-gns-proxy
394 </code>
395
396 <p>
397 Our browser has to be configured so it uses our proxy. In Firefox
398 we have to set these options under "about:config":
399 </p>
400
401 <code>
402 network.proxy.socks: localhost<br>
403 network.proxy.socks_port: 7777<br>
404 network.proxy.socks_remote_dns true<br>
405 network.proxy.type: 1
406 </code>
407
408 <p>
409 To tell Chromium to use the proxy, it has to be started with the
410 "--proxy-server" command line option:
411 </p>
412
413 <code>
414 $ chromium --proxy-server="socks5://127.0.0.1:7777"
415 </code>
416
417 <p>
418 Now we should be able to resolve our GNS names in the browser! We
419 just have to type "https://ccc.myself" into the address bar. If
420 our friend Bob prepared his system, too, he can resolve our record
421 by typing "ccc.alice.myself".
422 </p>
423
424
425 <h4>{{ _("VPN") }}</h4>
426
427 <p>
428 TBD
429 </p>
430
431 <h3>{{ _("Uninstall GNUnet and its dependencies") }}</h3>
432
433 <code>
434 $ cd ~/gnunet_installation/gnunet<br>
435 $ sudo make uninstall<br>
436 $ cd ~/gnunet_installation/libmicrohttpd<br>
437 $ sudo make uninstall<br>
438 $ sudo apt remove git libtool autoconf autopoint build-essential libgcrypt-dev libidn11-dev zlib1g-dev libunistring-dev libglpk-dev miniupnpc libextractor-dev libjansson-dev libcurl4-gnutls-dev libsqlite3-dev<br>
439 $ sudo apt autoremove<br>
440 $ sudo userdel -r gnunet<br>
441 $ sudo groupdel gnunet<br>
442 $ sudo groupdel gnunetdns<br>
443 $ sudo mv /etc/nsswitch.conf.original /etc/nsswitch.conf<br>
444 $ sudo rm /lib/$(uname -m)-linux-gnu/libnss_gns.so.2
445 </code>
446
447 <h3>{{ _("Appendix A: Optional GNUnet features") }}</h3>
448
449 <p>
450 TBD
451 </p>
452
453 <h3>{{ _("Troubleshooting") }}</h3>
454
455 <h4>{{ _("You can't reach other people's nodes") }}</h4>
456
457 <p>
458 Should our computer not have reached the open GNUnet network automatically,
459 we can manually instruct our node how to reach the nodes of our friends. This
460 works by exchanging HELLO strings. This is how we get a hello string for our
461 computer.
462 </p>
463
464 <code>
465 $ gnunet-peerinfo -gn
466 </code>
467
468 <p>
469 We can now pass this string to our friends "out of band" (using
470 whatever existing chat or messaging technology). If the string
471 contains some private IP networks we don't want to share, we can
472 carefully edit them out.
473 </p>
474
475 <p>
476 Once we receive such strings from our friends, we can add them
477 like this:
478 </p>
479
480 <code>
481 gnunet-peerinfo -p <string>
482 </code>
483
484
485 <p>
486 Now our GNUnet nodes can attempt reaching each other directly. This may
487 still fail due to NAT traversal issues.
488 </p>
489
490
491 <!--
492 <h4>{{ _("OMG you guys broke my internet") }}</h4>
493
494 <p>
495 We can replace `/etc/nsswitch.conf` with the backup we made earlier
496 (`/etc/nsswitch.conf.original`). Now DNS resolution should work again without a
497 running GNUnet.
498 </p>
499
500 <code>
501 $ cp /etc/nsswitch.conf.original /etc/nsswitch.conf
502 </code>
503 -->
504
505 </div>
506{% endblock body_content %}