]> Cypherpunks.ru repositories - nncp.git/blob - doc/integration.texi
3ddfbd837479b2fd739feb395d0738ee65f826be
[nncp.git] / doc / integration.texi
1 @node Integration
2 @unnumbered Integration with existing software
3
4 Here is some examples of how you can solve popular tasks with NNCP,
5 making them store-and-forward friendly.
6
7 @menu
8 * Index files for freqing: FreqIndex.
9 * Postfix::
10 * Exim::
11 * Web feeds: Feeds.
12 * Web pages: WARCs.
13 * BitTorrent and huge files: BitTorrent.
14 * Downloading service: DownloadService.
15 * Git::
16 * Multimedia streaming: Multimedia.
17 @end menu
18
19 @node FreqIndex
20 @section Index files for freqing
21
22 In many cases you do not know exact files list on remote machine you
23 want to freq from. Because files can be updated there. It is useful to
24 run cron-ed job on it to create files listing you can freq and search
25 for files in it:
26
27 @example
28 0  4  *  *  *  cd /storage ; tmp=`mktemp` ; \
29     tree -f -h -N --du --timefmt \%Y-\%m-\%d |
30     zstdmt -19 > $tmp && chmod 644 $tmp && mv $tmp TREE.txt.zst ; \
31     tree -J -f --timefmt \%Y-\%m-\%d |
32     zstdmt -19 > $tmp && chmod 644 $tmp && mv $tmp TREE.json.zst
33 @end example
34
35 @node Postfix
36 @section Integration with Postfix
37
38 This section is taken from @url{http://www.postfix.org/UUCP_README.html,
39 Postfix and UUCP} manual and just replaces UUCP-related calls with NNCP
40 ones.
41
42 @strong{Setting up a Postfix Internet to NNCP gateway}
43
44 Here is how to set up a machine that sits on the Internet and that forwards
45 mail to a LAN that is connected via NNCP.
46
47 @itemize
48
49 @item You need an @ref{nncp-exec} program that extracts the sender
50 address from mail that arrives via NNCP, and that feeds the mail into
51 the Postfix @command{sendmail} command.
52
53 @item Define a @command{pipe(8)} based mail delivery transport for
54 delivery via NNCP:
55 @example
56 /usr/local/etc/postfix/master.cf:
57 nncp      unix  -       n       n       -       -       pipe
58           flags=F user=nncp argv=nncp-exec -quiet $nexthop sendmail $recipient
59 @end example
60
61 This runs the @command{nncp-exec} command to place outgoing mail into
62 the NNCP queue after replacing @var{$nexthop} by the the receiving NNCP
63 node and after replacing @var{$recipient} by the recipients. The
64 @command{pipe(8)} delivery agent executes the @command{nncp-exec}
65 command without assistance from the shell, so there are no problems with
66 shell meta characters in command-line parameters.
67
68 @item Specify that mail for @emph{example.com}, should be delivered via
69 NNCP, to a host named @emph{nncp-host}:
70
71 @example
72 /usr/local/etc/postfix/transport:
73     example.com     nncp:nncp-host
74     .example.com    nncp:nncp-host
75 @end example
76
77 See the @command{transport(5)} manual page for more details.
78
79 @item Execute the command @command{postmap /etc/postfix/transport}
80 whenever you change the @file{transport} file.
81
82 @item Enable @file{transport} table lookups:
83
84 @example
85 /usr/local/etc/postfix/main.cf:
86     transport_maps = hash:$config_directory/transport
87 @end example
88
89 @item Add @emph{example.com} to the list of domains that your site is
90 willing to relay mail for.
91
92 @example
93 /usr/local/etc/postfix/main.cf:
94     relay_domains = example.com ...other relay domains...
95 @end example
96
97 See the @option{relay_domains} configuration parameter description for
98 details.
99
100 @item Execute the command @command{postfix reload} to make the changes
101 effective.
102
103 @end itemize
104
105 @strong{Setting up a Postfix LAN to NNCP gateway}
106
107 Here is how to relay mail from a LAN via NNCP to the Internet.
108
109 @itemize
110
111 @item You need an @ref{nncp-exec} program that extracts the sender
112 address from mail that arrives via NNCP, and that feeds the mail into
113 the Postfix @command{sendmail} command.
114
115 @item Specify that all remote mail must be sent via the @command{nncp}
116 mail transport to your NNCP gateway host, say, @emph{nncp-gateway}:
117
118 @example
119 /usr/local/etc/postfix/main.cf:
120     relayhost = nncp-gateway
121     default_transport = nncp
122 @end example
123
124 Postfix 2.0 and later also allows the following more succinct form:
125
126 @example
127 /usr/local/etc/postfix/main.cf:
128     default_transport = nncp:nncp-gateway
129 @end example
130
131 @item Define a @command{pipe(8)} based message delivery transport for
132 mail delivery via NNCP:
133
134 @example
135 /usr/local/etc/postfix/master.cf:
136 nncp      unix  -       n       n       -       -       pipe
137           flags=F user=nncp argv=nncp-exec -quiet $nexthop sendmail $recipient
138 @end example
139
140 This runs the @command{nncp-exec} command to place outgoing mail into
141 the NNCP queue. It substitutes the hostname (@emph{nncp-gateway}, or
142 whatever you specified) and the recipients before execution of the
143 command. The @command{nncp-exec} command is executed without assistance
144 from the shell, so there are no problems with shell meta characters.
145
146 @item Execute the command @command{postfix reload} to make the changes
147 effective.
148
149 @end itemize
150
151 @node Exim
152 @section Integration with Exim
153
154 This section is unaltered copy-paste of
155 @url{https://changelog.complete.org/archives/10165-asynchronous-email-exim-over-nncp-or-uucp, Asynchronous Email: Exim over NNCP (or UUCP)}
156 article by John Goerzen, with his permission.
157
158 @strong{Sending from Exim to a smarthost}
159
160 One common use for async email is from a satellite system: one that
161 doesn't receive mail, or have local mailboxes, but just needs to get
162 email out to the Internet. This is a common situation even for
163 conventionally-connected systems; in Exim speak, this is a "satellite
164 system that routes mail via a smarthost". That is, every outbound
165 message goes to a specific target, which then is responsible for
166 eventual delivery (over the Internet, LAN, whatever).
167
168 This is fairly simple in Exim.
169
170 We actually have two choices for how to do this: bsmtp or rmail mode.
171 bsmtp (batch SMTP) is the more modern way, and is essentially a
172 derivative of SMTP that explicitly can be queued asynchronously.
173 Basically it's a set of SMTP commands that can be saved in a file. The
174 alternative is "rmail" (which is just an alias for sendmail these days),
175 where the data is piped to rmail/sendmail with the recipients given on
176 the command line. Both can work with Exim and NNCP, but because we're
177 doing shiny new things, we'll use bsmtp.
178
179 These instructions are loosely based on the
180 @url{https://people.debian.org/~jdg/bsmtp.html, Using outgoing BSMTP with Exim HOWTO}.
181 Some of these may assume Debianness in the configuration, but should be
182 easily enough extrapolated to other configs as well.
183
184 First, configure Exim to use satellite mode with minimal DNS lookups
185 (assuming that you may not have working DNS anyhow).
186
187 Then, in the Exim primary router section for smarthost
188 (@file{router/200_exim4-config_primary} in Debian split configurations),
189 just change @code{transport = remote_smtp_smarthost to transport = nncp}.
190
191 Now, define the NNCP transport. If you are on Debian, you might name this
192 @file{transports/40_exim4-config_local_nncp}:
193
194 @example
195 nncp:
196   debug_print = "T: nncp transport for $local_part@@$domain"
197   driver = pipe
198   user = nncp
199   batch_max = 100
200   use_bsmtp
201   command = /usr/local/nncp/bin/nncp-exec -noprogress -quiet hostname_goes_here rsmtp
202 .ifdef REMOTE_SMTP_HEADERS_REWRITE
203   headers_rewrite = REMOTE_SMTP_HEADERS_REWRITE
204 .endif
205 .ifdef REMOTE_SMTP_RETURN_PATH
206   return_path = REMOTE_SMTP_RETURN_PATH
207 .endif
208 @end example
209
210 This is pretty straightforward. We pipe to @command{nncp-exec}, run it
211 as the nncp user. @command{nncp-exec} sends it to a target node and runs
212 whatever that node has called @command{rsmtp} (the command to receive
213 bsmtp data). When the target node processes the request, it will run the
214 configured command and pipe the data in to it.
215
216 @strong{More complicated: Routing to various NNCP nodes}
217
218 Perhaps you would like to be able to send mail directly to various NNCP
219 nodes. There are a lot of ways to do that.
220
221 Fundamentally, you will need a setup similar to the UUCP example in
222 @url{https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_manualroute_router.html,
223 Exim's manualroute manual}, which lets you define how to reach various
224 hosts via UUCP/NNCP. Perhaps you have a star topology (every NNCP node
225 exchanges email with a central hub). In the NNCP world, you have two
226 choices of how you do this. You could, at the Exim level, make the
227 central hub the smarthost for all the side nodes, and let it
228 redistribute mail. That would work, but requires decrypting messages at
229 the hub to let Exim process. The other alternative is to configure NNCP
230 to just send to the destinations via the central hub; that takes
231 advantage of onion routing and doesn't require any Exim processing at
232 the central hub at all.
233
234 @strong{Receiving mail from NNCP}
235
236 On the receiving side, first you need to configure NNCP to authorize the
237 execution of a mail program. In the section of your receiving host where
238 you set the permissions for the client, include something like this:
239
240 @example
241 exec: @{
242     rsmtp: ["/usr/sbin/sendmail", "-bS"]
243 @}
244 @end example
245
246 The -bS option is what tells Exim to receive BSMTP on stdin.
247
248 Now, you need to tell Exim that nncp is a trusted user (able to set From
249 headers arbitrarily). Assuming you are running NNCP as the nncp user,
250 then add @code{MAIN_TRUSTED_USERS = nncp} to a file such as
251 @file{/etc/exim4/conf.d/main/01_exim4-config_local-nncp}. That's it!
252
253 Some hosts, of course, both send and receive mail via NNCP and will need
254 configurations for both.
255
256 @node Feeds
257 @section Integration with Web feeds
258
259 RSS and Atom feeds could be collected using
260 @url{https://github.com/wking/rss2email, rss2email} program. It
261 converts all incoming feed entries to email messages. Read about how to
262 integration @ref{Postfix} with email. @command{rss2email} could be run
263 in a cron, to collect feeds without any user interaction. Also this
264 program supports ETags and won't pollute the channel if remote server
265 supports them too.
266
267 After installing @command{rss2email}, create configuration file:
268
269 @example
270 $ r2e new rss-robot@@address.com
271 @end example
272
273 and add feeds you want to retrieve:
274
275 @example
276 $ r2e add http://www.git.cypherpunks.ru/?p=nncp.git;a=atom
277 @end example
278
279 and run the process:
280
281 @example
282 $ r2e run
283 @end example
284
285 @node WARCs
286 @section Integration with Web pages
287
288 Simple HTML web page can be downloaded very easily for sending and
289 viewing it offline after:
290
291 @example
292 $ wget http://www.example.com/page.html
293 @end example
294
295 But most web pages contain links to images, CSS and JavaScript files,
296 required for complete rendering.
297 @url{https://www.gnu.org/software/wget/, GNU Wget} supports that
298 documents parsing and understanding page dependencies. You can download
299 the whole page with dependencies the following way:
300
301 @example
302 $ wget \
303     --page-requisites \
304     --convert-links \
305     --adjust-extension \
306     --restrict-file-names=ascii \
307     --span-hosts \
308     --random-wait \
309     --execute robots=off \
310     http://www.example.com/page.html
311 @end example
312
313 that will create @file{www.example.com} directory with all files
314 necessary to view @file{page.html} web page. You can create single file
315 compressed tarball with that directory and send it to remote node:
316
317 @example
318 $ tar cf - www.example.com | zstd |
319     nncp-file - remote.node:www.example.com-page.tar.zst
320 @end example
321
322 But there are multi-paged articles, there are the whole interesting
323 sites you want to get in a single package. You can mirror the whole web
324 site by utilizing @command{wget}'s recursive feature:
325
326 @example
327 $ wget \
328     --recursive \
329     --timestamping \
330     -l inf \
331     --no-remove-listing \
332     --no-parent \
333     [...]
334     http://www.example.com/
335 @end example
336
337 There is a standard for creating
338 @url{https://en.wikipedia.org/wiki/Web_ARChive, Web ARChives}:
339 @strong{WARC}. Fortunately again, @command{wget} supports it as an
340 output format.
341
342 @example
343 $ wget \
344     --warc-file www.example_com-$(date '+%Y%M%d%H%m%S') \
345     --no-warc-compression \
346     --no-warc-keep-log \
347     [...]
348     http://www.example.com/
349 @end example
350
351 That command will create uncompressed @file{www.example_com-XXX.warc}
352 web archive. By default, WARCs are compressed using
353 @url{https://en.wikipedia.org/wiki/Gzip, gzip}, but, in example above,
354 we have disabled it to compress with stronger and faster
355 @url{https://en.wikipedia.org/wiki/Zstd, zstd}, before sending via
356 @command{nncp-file}.
357
358 There are plenty of software acting like HTTP proxy for your browser,
359 allowing to view that WARC files. However you can extract files from
360 that archive using @url{https://pypi.python.org/pypi/Warcat, warcat}
361 utility, producing usual directory hierarchy:
362
363 @example
364 $ python3 -m warcat extract \
365     www.example_com-XXX.warc \
366     --output-dir www.example.com-XXX \
367     --progress
368 @end example
369
370 @node BitTorrent
371 @section BitTorrent and huge files
372
373 If dealing with @ref{Git}, @ref{Feeds, web feeds} and @ref{Multimedia,
374 multimedia} goes relatively fast, then BitTorrent and huge files
375 consumes much time. You can not wait for downloads finish, but want to
376 queue them after.
377
378 @url{http://aria2.github.io/, aria2} multi-protocol download utility
379 could be used for solving that issue conveniently. It supports HTTP,
380 HTTPS, FTP, SFTP and BitTorrent protocols, together with
381 @url{http://tools.ietf.org/html/rfc5854, Metalink} format. BitTorrent
382 support is fully-featured: UDP trackers, DHT, PEX, encryption, magnet
383 URIs, Web-seeding, selective downloads, LPD. @command{aria2} can
384 accelerate HTTP*/*FTP downloads by segmented multiple parallel
385 connections.
386
387 You can queue you files after they are completely downloaded.
388 @file{aria2-downloaded.sh} contents:
389
390 @verbatiminclude aria2-downloaded.sh
391
392 Also you can prepare
393 @url{http://aria2.github.io/manual/en/html/aria2c.html#files, input file}
394 with the jobs you want to download:
395
396 @example
397 $ cat jobs
398 http://www.nncpgo.org/download/nncp-0.11.tar.xz
399     out=nncp.txz
400 http://www.nncpgo.org/download/nncp-0.11.tar.xz.sig
401     out=nncp.txz.sig
402 $ aria2c \
403     --on-download-complete aria2-downloaded.sh \
404     --input-file jobs
405 @end example
406
407 and all that downloaded (@file{nncp.txz}, @file{nncp.txz.sig}) files
408 will be sent to @file{remote.node} when finished.
409
410 @node DownloadService
411 @section Downloading service
412
413 Previous sections tell about manual downloading and sending results to
414 remote node. But one wish to remotely initiate downloading. That can be
415 easily solved with @ref{CfgExec, exec} handles.
416
417 @verbatim
418 exec: {
419   warcer: ["/bin/sh", "/path/to/warcer.sh"]
420   wgeter: ["/bin/sh", "/path/to/wgeter.sh"]
421   aria2c: [
422     "/usr/local/bin/aria2c",
423     "--on-download-complete", "aria2-downloaded.sh",
424     "--on-bt-download-complete", "aria2-downloaded.sh"
425   ]
426 }
427 @end verbatim
428
429 @file{warcer.sh} contents:
430
431 @verbatiminclude warcer.sh
432
433 @file{wgeter.sh} contents:
434
435 @verbatiminclude wgeter.sh
436
437 Now you can queue that node to send you some website's page, file or
438 BitTorrents:
439
440 @example
441 $ echo http://www.nncpgo.org/Postfix.html |
442     nncp-exec remote.node warcer postfix-whole-page
443 $ echo http://www.nncpgo.org/Postfix.html |
444     nncp-exec remote.node wgeter postfix-html-page
445 $ echo \
446     http://www.nncpgo.org/download/nncp-0.11.tar.xz
447     http://www.nncpgo.org/download/nncp-0.11.tar.xz.sig |
448     nncp-exec remote.node aria2c
449 @end example
450
451 @node Git
452 @section Integration with Git
453
454 @url{https://git-scm.com/, Git} version control system already has all
455 necessary tools for store-and-forward networking.
456 @url{https://git-scm.com/docs/git-bundle, git-bundle} command is
457 everything you need.
458
459 Use it to create bundles containing all required blobs/trees/commits and tags:
460
461 @example
462 $ git bundle create repo-initial.bundle master --tags --branches
463 $ git tag -f last-bundle
464 $ nncp-file repo-initial.bundle remote.node:repo-$(date % '+%Y%M%d%H%m%S').bundle
465 @end example
466
467 Do usual working with the Git: commit, add, branch, checkout, etc. When
468 you decide to queue your changes for sending, create diff-ed bundle and
469 transfer them:
470
471 @example
472 $ git bundle create repo-$(date '+%Y%M%d%H%m%S').bundle last-bundle..master
473 or maybe
474 $ git bundle create repo-$(date '+%Y%M%d').bundle --since=10.days master
475 @end example
476
477 Received bundle on remote machine acts like usual remote:
478
479 @example
480 $ git clone -b master repo-XXX.bundle
481 @end example
482
483 overwrite @file{repo.bundle} file with newer bundles you retrieve and
484 fetch all required branches and commits:
485
486 @example
487 $ git pull # assuming that origin remote points to repo.bundle
488 $ git fetch repo.bundle master:localRef
489 $ git ls-remote repo.bundle
490 @end example
491
492 Bundles are also useful when cloning huge repositories (like Linux has).
493 Git's native protocol does not support any kind of interrupted download
494 resuming, so you will start from the beginning if connection is lost.
495 Bundles, being an ordinary files, can be downloaded with native
496 HTTP/FTP/NNCP resuming capabilities. After you fetch repository via the
497 bundle, you can add an ordinary @file{git://} remote and fetch the
498 difference.
499
500 Also you can find the following exec-handler useful:
501
502 @verbatiminclude git-bundler.sh
503
504 And it allows you to request for bundles like that:
505 @code{echo some-old-commit..master | nncp-exec REMOTE bundler REPONAME}.
506
507 @node Multimedia
508 @section Integration with multimedia streaming
509
510 Many video and audio streams could be downloaded using
511 @url{http://yt-dl.org/, youtube-dl} program.
512 @url{https://rg3.github.io/youtube-dl/supportedsites.html, Look} how
513 many of them are supported, including @emph{Dailymotion}, @emph{Vimeo}
514 and @emph{YouTube}.
515
516 When you multimedia becomes an ordinary file, you can transfer it easily.
517
518 @example
519 $ youtube-dl \
520     --exec 'nncp-file @{@} remote.node:' \
521     'https://www.youtube.com/watch?list=PLd2Cw8x5CytxPAEBwzilrhQUHt_UN10FJ'
522 @end example