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