1 .\" Process this file with
2 .\" groff -man -Tascii foo.1
4 .TH FWKNOP 8 "August, 2009" Linux
7 \- Firewall Knock Operator
9 .B fwknop \-A <ports> \-R|\-a|\-s \-D <host> [options]
13 implements an authorization scheme known as Single Packet Authorization (SPA) for
14 Linux systems running iptables, and for Mac OS X and FreeBSD systems running ipfw.
15 This mechanism requires only a single encrypted and non-replayed
16 packet to communicate various pieces of information including desired access
17 through an iptables or ipfw policy. The main application of this program is to
18 use iptables or ipfw in a default-drop stance to protect services such as
20 with an additional layer of security in order to make the exploitation of
21 vulnerabilities (both 0-day and unpatched code) much more difficult. An
24 passively monitors authorization packets via
26 and hence there is no "server" to which to connect in the traditional sense.
27 Any service protected by fwknop is inaccessible (by using iptables or ipfw to intercept
28 packets within the kernel) before authenticating; anyone scanning for
29 the service will not be able to detect that it is even listening. Single Packet
30 Authorization offers many advantages over port knocking, including non-replayability
31 of SPA packets, ability to use asymmetric ciphers (such as Elgamal), and SPA cannot
32 be broken by simply spoofing packets to duplicate ports within the knock sequence
33 on the server to break port knocking authentication. SPA packets can easily be
34 spoofed as well (this is a good thing in this context), and this makes it possible
35 to make it appear as though, say, www.yahoo.com is trying to authenticate to a
36 target system but in reality the actual connection will come from a seemingly
37 unrelated IP. Although the default data collection method in Single Packet
38 Authorization mode is to use libpcap to sniff packets off the wire, fwknop can also
39 read packets out of a file that is written by the iptables
41 pcap writer (or a separate sniffer process that is writing packet data to a file).
43 Authorization packets are either encrypted with the Rijndael block cipher
44 or via GnuPG and associated asymmetric ciphers. If the symmetric encryption
45 method is chosen, then the encryption key is shared between the
46 client and server (see the
47 .I /etc/fwknop/access.conf
49 method is chosen, then the encryption keys are derived from GnuPG key
50 rings. SPA packets generated by fwknop running as a client adhere
51 to the following format (before they are encrypted):
53 random number (16 bytes)
57 mode (command mode (0) or access mode (1))
58 if command mode => command to execute
59 else access mode => IP,proto,port
60 message digest (SHA256 / SHA1 / MD5)
62 Each of the above fields are separated by a ":" character due to the
63 variable length of several of the fields, and those that might contain
64 ":" characters are base64 encoded. The message digest (SHA256 by default
67 greater than 1.9.1) allows the server to check message integrity after decryption,
68 and the 16 bytes of random data ensures (with high probability) that no two messages
69 are identical. This ensures that replay attacks are not possible against fwknop.
70 For each packet coming from an
74 server caches the SHA256 digest calculated over the entire packet and compares against
75 previous packet digests in order to detect attempted replay attacks. The digest
76 cache file is located at
77 .I /var/log/fwknop/digest.cache
78 and is not rotated so that the detection of duplicate SPA messages is maximized.
79 Both syslog and email alerts are generated if a replay is detected (although
80 this can be tuned via the
83 .I /etc/fwknop/fwknop.conf
84 file). By default, the
86 client sends authorization packets over UDP
87 port 62201, but this can be altered with the
89 argument. The server must first be configured to acquire the SPA data on
90 the changed protocol-port. Also, fwknop can send the SPA packet over a random
91 port via the \-\-rand-port argument. See
93 for further details. See the
95 section for example invocations of the
99 .SH REQUIRED ARGUMENTS
102 .BR \-D "\fR,\fP " \-\^\-Destination\ \<IP-address>
105 client to authenticate with the
107 daemon/service at the destination address <IP> . The connection mode is discovered by the
109 daemon/service when it decrypts and parses the authentication packet.
111 .BR \-A "\fR,\fP " \-\^\-Access\ \<port\ list>
112 Provide a list of ports and protocols to access on a remote computer running
114 The format of this list is '<proto>/<port>...<proto>/<port>,
115 e.g. "tcp/22,udp/53".
117 The vast majority of usages for
119 require the \-A argument, but sending full commands with the \-\-Server-cmd
120 argument via an SPA packet to be executed by
122 does not require this argument.
125 One of these options (see below) is required to tell the remote
127 daemon what IP should be let through the local firewall. It is recommend to use
128 the \-R or \-a options instead of \-s in order to harden SPA communications against
129 possible MITM attacks.
134 .BR \-a "\fR,\fP " \-\^\-allow-IP\ \<IP-address>
135 Specify IP address that should be permitted through the destination
137 server firewall (this IP is encrypted within the SPA packet itself). This is
138 useful to prevent a Man-In-The-Middle (MTIM) attack where an SPA packet can be
139 intercepted en-route and sent from a different IP than the original. Hence, if
142 server trusts the source address on the SPA packet IP header then the attacker
145 option puts the source address within the encrypted
146 SPA packet, and so thwarts this attack. The
148 option is also useful to specify the IP that will be granted access when SPA
149 packet itself is spoofed with the
151 option. Another related option is \-R (see below) which instructs the
153 client to automatically resolve the externally routable IP address the local
154 system is connected to by querying the
155 .B http://www.whatismyip.com
158 .BR \-R "\fR,\fP " \-\^\-Resolve-external-IP
159 This is an important option, and instructs the
163 daemon/service to query
164 .B http://www.whatismyip.com
165 to determine the IP address that should be allowed through the iptables policy
168 server side. This is useful if the
170 client is being used on a system that is behind an obscure NAT address. Note
173 option to have fwknop resolve an externally routable address by using the
174 specific web service instead of http://www.whatismyip.org (see below).
177 .BR \-\^\-NAT-access\ \<internalIP:forwardPort>
180 server offers the ability to provide SPA access through an iptables firewall
181 to an internal service by interfacing with the iptables NAT capabilities. So,
182 if the fwknopd server is protecting an internal network on RFC 1918 address
183 space, an external fwknop client can request that the server port forward an
184 external port to an internal IP, i.e. "\-\-NAT-access 192.168.10.2:55000". In
185 this case access will be granted to 192.168.10.2 via port 55000 to whatever
186 service is requested via the \-\-Access argument (usually tcp/22). Hence, after
187 sending such an SPA packet, one would then do "ssh \-p 55000 user@host" and
188 the connection would be forwarded on through to the internal 192.168.10.2
189 system automatically. Note that the port "55000" can be randomly generated
190 via the \-\-NAT-rand-port argument (described later).
195 server, a NAT operation can apply to the local system instead of being
196 forwarded through the system. That is, for iptables firewalls, a connection
197 to, say, port 55,000 can be translated to port 22 on the local system. By
198 making use of the \-\-NAT-local argument, the fwknop client can be made to
199 request such access. This means that any external attacker would only see
200 a connection over port 55,000 instead of the expected port 22 after the SPA
203 .BR \-\^\-URL\ \<web\ resolution\ \URL>
204 This option is used in conjunction with the
206 option so that fwknop will resolve the externally routable IP address (useful
207 if fwknop is run on a system being a NAT) via a web service URL supplied on
208 the command line. A custom web resolution CGI script is available at the URL
209 below if http://www.whatismyip.org is not available:
210 .B http://www.cipherdyne.org/cgi/clientip.cgi
215 to acquire GnuPG key password from a running
219 .BR \-\^\-gpg-agent-info\ \<connection\ \info>
220 Specify the value of the GPG_AGENT_INFO environment variable as returned
222 .B gpg-agent \-\-daemon
224 .B fwknop \-\-gpg-agent
225 command line argument is used instead of
226 .B \-\-gpg-agent-info,
227 then fwknop assumes that the GPG_AGENT_INFO environment variable has already
228 been set in the current shell.
230 .BR \-\^\-gpg-default-key
231 Use the key that GnuPG defines as the default, i.e. the key that is specified
238 variable is not defined
241 , then GnuPG tries to use the first suitable key on
242 its key ring. If the user does not know the password for this key, then the
243 standard password error will be thrown by GnuPG and reported back to the
246 .BR \-\^\-gpg-home-dir\ \<dir>
247 Specify the path to the GnuPG directory; normally this path is derived from the
248 home directory of the user that is running the
250 client. This is useful when a 'root' user wishes to log into a remote machine
253 daemon/service does not permit 'root' login.
255 .BR \-\^\-gpg-recipient\ \<key\ \ID>
256 Specify the GnuPG key ID, e.g. "1234ABCD" (see the output of "gpg \-\-list-keys")
257 of the recipient of the Single Packet Authorization message. This key is imported
260 server and the associated private key is used to decrypt the SPA packet. The
261 recipient's key must first be imported into the client GnuPG key ring.
263 .BR \-\^\-gpg-signing-key\ \<key\ \ID>
264 Specify the GnuPG key ID, e.g. "ABCD1234" (see the output of "gpg \-\-list-keys")
265 to use when signing the SPA message. The user is prompted for
266 the associated GnuPG password to create the signature. This
267 adds a cryptographically strong mechanism to allow the
269 daemon on the remote server to authenticate who created the SPA message.
271 .BR \-\^\-gpg-verbose
274 to allow all output from the
276 process that is used by fwknop in GnuPG mode. This is primarily used for debugging
277 purposes if it appears that the GnuPG encrypt/decrypt is not performing correctly.
279 .BR \-\^\-gpg-use-options
282 client instructs gpg to not reference any options file in gpg mode, but this
283 command line argument can be used to re-enable them.
285 .BR \-\^\-Home-dir\ \<dir>
286 Specify the path to the user home directory where files such as .fwknop.hosts
287 or .fwknop.run should be stored or retrieved.
289 .BR \-l "\fR,\fP " \-\^\-last-cmd
292 client to run with the same command line arguments that were used in a previous execution.
293 This option is useful because the clients'
295 command line can be complex and difficult to recall.
297 .BR \-\^\-Last-host\ \<host>
300 to use the same command line arguments that were used to authenticate to
303 .BR \-q "\fR,\fP " \-\^\-quiet
304 This option instructs the
306 to be as quiet as possible and only print absolutely necessary information to
309 .BR \-s "\fR,\fP " \-\^\-source-ip
312 client to form an SPA packet that contains the special-case IP
313 address "0.0.0.0" which will inform the destination
315 SPA server to use the source IP address from which the SPA packet originates as
316 the IP that will be allowed through upon modification of the firewall ruleset.
317 This option is useful if the fwknop client is deployed on a machine that is
318 behind a NAT device. The permit-address options
324 are mutually exclusive.
326 .BR \-\^\-Server-port\ \<port>
327 Specify the port number where
329 accepts packets via libpcap or ulogd pcap writer. By default fwknopd looks for
330 authorization packets over UDP port 62201.
333 Instruct the fwknop client to send an SPA packet over a random destination port
334 between 10,000 and 65535. The fwknopd server must use a PCAP_FILTER variable
335 that is configured to accept such packets. For example, the PCAP_FILTER variable
337 .B udp dst portrange 10000-65535
339 .BR \-\^\-NAT-rand-port
340 Usually fwknop is used to request access to a specific port such as tcp/22 on a
341 system running fwknopd. However, by using the \-\-NAT-rand-port argument, it is
342 possible to request access to a particular service (again, such as tcp/22), but
343 have this access granted via a random translated port. That is, once the fwknop
344 client has been executed in this mode and the random port selected by fwknop is
345 displayed, the destination port used by the follow-on client must be changed to
346 match this random port. For SSH, this is accomplished via the \-p argument.
347 See the \-\-NAT-local and \-\-NAT-access command line arguments to fwknop for
348 additional details on gaining access to services via a NAT operation.
350 .BR \-\^\-Save-packet
353 client to write a newly created SPA packet out to a file so that it can be
354 examined off-line. The default path is
355 .I ~/fwknop_save_packet.<pid>
356 where <pid> is the process ID of the fwknop client process, but this can be
357 changed with the \-\-Save-packet-file argument (see below).
359 .BR \-\^\-Save-packet-file\ \<file>
360 Specify the file to write a new SPA packet to in
364 .BR \-\^\-Save-packet-append
367 mode fwknop normally overwrite the file used to save a new SPA packet, but
368 this command line argument instructs fwknop to append a new SPA packet to
369 the file instead. This is useful for generating large sets of SPA packets
370 in order to test randomness or encryption properties.
372 .BR \-\^\-time-offset-plus\ \<time>
375 daemon on the server side enforces time synchronization between the clocks
376 running on client and server systems. The fwknop client places the local time
377 within each SPA packet as a time stamp to be validated by the fwknopd server
378 after decryption. However, in some circumstances, if the clocks are out of
379 sync and the user on the client system does not have the required access to
380 change the local clock setting, it can be difficult to construct and SPA
381 packet with a time stamp the server will accept. In this situation, the
382 \-\-time-offset-plus option can allow the user to specify an offset (e.g.
383 "60sec", "60min", "2days", etc.) that is added to the local time.
385 .BR \-\^\-time-offset-minus\ \<time>
386 This is similar to the \-\-time-offset-plus option (see above), but subtracts
387 the specified time offset instead of adding it to the local time stamp.
389 .BR \-\^\-Show-last-cmd
390 Display the last command-line arguments used by
393 .BR \-\^\-Show-host-cmd\ \<host>
394 Display the last command-line arguments used to contact a SPA server running on
398 .BR \-\^\-Spoof-proto\ \<protocol>
399 Send an SPA packet over a raw socket of the specified protocol. Accepted
400 values are tcp, udp, and icmp. This is useful if you want to send the SPA
401 packet over an orphaned TCP ACK or an ICMP packet.
403 .BR \-\^\-Spoof-src\ \<IP>
404 Spoof the source address from which the
406 client sends SPA packets. This requires root on the client side access since a raw socket
407 is required to accomplish this. Note that the
409 argument can be given in this mode in order to pass any
413 .I /etc/fwknop/access.conf.
415 .BR \-\^\-Spoof-user\ \<user>
416 Specify the username that is included within SPA packet. This allows
419 client to satisfy any non-root
425 mode requires that the
427 client is executed as root).
429 .BR \-\^\-icmp-type\ \<type>
432 argument to send an SPA packet over and ICMP packet, the ICMP type may be set
433 with this command line argument. The default is "8" for an ICMP echo-request
438 .BR \-\^\-icmp-code\ \<code>
441 argument to send an SPA packet over and ICMP packet, the ICMP code may be set
442 with this command line argument. The default is "0" for an ICMP echo-request
447 .BR \-\^\-Max-packet-size\ \<size>
450 to restrict message length to
452 bytes, and the client will not send an SPA packet that is larger than this
453 (i.e. perhaps a long command was included in \-\-Server-cmd mode). This alters
454 the default value of 1500 bytes. See also the
455 MAX_SNIFF_BYTES variable in
462 client send an SPA packet as a web request over HTTP. This requires that the
465 is also running a webserver to receive the SPA web request. The web request
466 is built as a modified version of base64-encoded data where the "+" and "/"
467 chars are replace with "-" and "_" respectively (to avoid URL encoding issues).
469 .BR \-\^\-HTTP-proxy\ \<proxy\ host>
474 client to send SPA packets through an HTTP proxy when the
476 option is also used. The expected format for the argument is
477 .B http://some.host.com
478 and an optional port number is supported with the
479 .B http://some.host.com:PORT
482 .BR \-\^\-HTTP-user-agent\ \<agent\ string>
483 Specify the HTTP user-agent whenver the
485 client is used to send an SPA packet over an HTTP request, or when the
486 .I \-\-Resolve-external-IP
487 option is used. The default user-agent is "Fwknop/VERSION", so "Fwknop/1.9.12"
488 for the 1.9.12 release.
490 .BR \-T "\fR,\fP " \-\^\-TCP-sock
493 client send an SPA packet over an established TCP connection (created by the fwknop
494 client to the specified listening port on the server with the
496 argument). This is not normally done, but is useful for compatibility with the Tor
497 for strong anonymity; see
498 .B http://tor.eff.org/.
503 daemon to listen on a TCP port (62201 by default).
505 .BR \-h "\fR,\fP " \-\^\-help
506 Display usage information and exit.
508 .BR \-V "\fR,\fP " \-\^\-Version
509 Display version information and exit.
511 .BR \-v "\fR,\fP " \-\^\-verbose
514 client in verbose mode.
516 .BR \-\^\-locale\ \<locale>
517 Provide a locale setting other than the default "C" locale.
520 Do not set the locale at all so that the default system locale will apply.
522 .BR \-\^\-Server-cmd\ \<cmd>
524 This is for command mode only (i.e. when you want to send a command across
527 and have it execute the command). This option is not needed when trying to
528 gain access to a service via the SPA mechanism. To use this feature, please
529 ensure that ENABLE_CMD_EXEC; is set in the file
530 .I /etc/fwknop/access.conf
533 server you are sending the command to.
534 The \-\-Server-cmd argument allows a complete command (e.g. "ping \-c 1 www.yahoo.com",
535 or "iptables \-t nat \-A PREROUTING \-p tcp \-s 65.x.x.x \-\-dport 443 \-i eth0 \-j DNAT \-\-to 192.168.10.20:443")
538 server, which will execute the command as root. Command execution is enabled only
540 .B ENABLE_CMD_EXEC keyword is given in
541 .I /etc/fwknop/access.conf
542 (note that commands can easily be restricted with the
547 .B Legacy Port-knock mode only
549 All of the following options in this section are for the traditional port knocking
550 mode mode. This is a legacy mode and is
552 the preferred or recommended mode next to Single Packet Authorization ( see
553 .B http://www.cipherdyne.org/fwknop/docs/SPA.html
557 .BR \-\^\-offset\ \<port>
558 Specify a port offset to use when running
560 in encrypted knock mode. The default is 61000.
562 .BR \-r "\fR,\fP " \-\^\-rotate-proto
563 Rotate the protocol across tcp and udp for
564 encrypted sequences. This just adds one more additional layer of obfuscation
565 to an encrypted sequence.
567 .BR \-\^\-Server-mode\ \<mode>
568 This command line switch provides an interface to
569 the old port knocking method if
570 the mode argument is "knock". If the
572 argument is not given then the
574 client defaults to using the SPA method which provides much better
575 security characteristics than port knocking (encrypted or not).
577 .BR \-t "\fR,\fP " \-\^\-time-delay\ \<seconds>
578 Specify a time delay to introduce between successive
579 connection attempts. This option is used by the
581 client. On the server side,
583 uses the variables MIN_TIME_DIFF
584 and MAX_TIME_DIFF to control whether the time delay actually means
585 something (i.e. if the MIN_TIME_DIFF is 2 seconds for a SOURCE block,
586 then the argument to the \-\-time-delay option must be at least 2 at the
589 .BR \-u "\fR,\fP " \-\^\-user-rc\ \<rc-file>
590 The default connection rc file the
592 client uses to know what shared port knocking sequence to send to a destination machine
593 is defined in the file
595 The path to this file can be changed with the
603 Contains the last command line arguments that the
605 client was invoked with.
609 Contains the last command line arguments for individual hosts that the
611 client has been used to gain access to. By using the
613 switch, these arguments can be recalled and used.
618 (only used in \-\-gpg-agent mode).
621 The following examples illustrate the command line arguments that could
624 client in a few situations:
626 .B Access mode examples
628 Packet contents printed to stdout at the
630 client when creating a 'access mode' SPA packet:
632 Random data: 6565240948266426
634 Timestamp: 1203863233
636 Type: 1 (access mode)
637 Access: 127.0.0.2,tcp/22
638 SHA256 sum: gngquSL8AuM7r27XsR4qPmJhuBo9pG2PYwII06AaJHw
641 Use the Single Packet Authorization mode to gain access to tcp/22 (ssh)
642 and udp/53 running on the system 10.0.0.123 from the IP 192.168.10.4:
644 .B $ fwknop \-A 'tcp/22,udp/53' \-a 192.168.10.4 \-D 10.0.0.123
646 Same as above example, but gain access from whatever source IP is seen
647 by the fwknop server (useful if the fwknop client is behind a NAT device):
649 .B $ fwknop \-A 'tcp/22,udp/53' \-s \-D 10.0.0.123
651 Same as above example, but use the IP identification website http://www.whatismyip.com/
652 to derive the client IP address. This is a safer method of acquiring the client IP
653 address than using the
655 option because the source IP is put within the encrypted
656 packet instead of having the
658 daemon grant the requested access from whatever IP address the SPA packet originates:
660 .B $ fwknop \-A 'tcp/22,udp/53' \-R \-D 10.0.0.123
662 Use the Single Packet Authorization mode to gain access to tcp/22 (ssh)
663 and udp/53 running on the system 10.0.0.123, and use GnuPG keys to encrypt
666 .B $ fwknop \-A 'tcp/22,udp/53' \-\-gpg-sign ABCD1234 \-\-gpg--recipient 1234ABCD \-R \-D 10.0.0.123
668 Instruct the fwknop server running at 10.0.0.123 to allow 172.16.5.4 to
669 connect to TCP/22, but spoof the authorization packet from an IP associated
672 .B # fwknop \-\-Spoof-src 'www.yahoo.com' \-A tcp/22 \-a 172.16.5.4 \-D 10.0.0.123
676 .B Command mode examples
679 Please ensure that ENABLE_CMD_EXEC; is set in the file
680 .I /etc/fwknop/access.conf
683 server you are attempting to connect to.
684 Packet contents printed to stdout at the
686 client when creating a 'command mode' SPA packet:
688 Random data: 4621962433020664
690 Timestamp: 1203864394
692 Type: 0 (command mode)
693 Cmd: echo "The commands sent \- minus quote charaters around the command" & sleep 10; echo "The End"
694 SHA256 sum: eN8c8mNArZxF066iulbxlTK4Gt/EO0ALLYwzVzCkXww
696 Instruct the fwknop server running at 10.0.0.123 to send a single ICMP
697 echo request to www.yahoo.com:
699 .B $ fwknop \-\-Server-cmd 'ping \-c 1 www.yahoo.com' \-D 10.0.0.123
703 .B Port-knock mode (legacy) examples
705 This connection mode is a legacy mode and is
707 the preferred or recommended mode.
709 Packet contents printed to stdout at the
711 client when in 'port-knock mode':
714 Send an encrypted knock sequence to the IP "10.0.0.123" instructing the
715 fwknop daemon running there to open tcp port 22 to source address
718 .B $ fwknop \-\-Server-mode 'knock' \-A tcp/22 \-a 192.168.10.4 \-D 10.0.0.123
720 Same as above, but this time instruct the remote fwknop daemon to open
721 tcp port 22 to whatever source address the encrypted sequence originates
722 from (useful if the fwknop client is behind a NAT device):
724 .B $ fwknop \-\-Server-mode 'knock' \-A tcp/22 \-s \-D 10.0.0.123
726 Same as above, but rotate the knock sequence through the tcp and udp
727 protocols (remember that iptables must be configured to log both tcp and
728 udp packets to the default port range of 61000-61255):
730 .B $ fwknop \-\-Server-mode 'knock' \-A tcp/22 \-s \-r \-D 10.0.0.123
732 Same as above, but change the base port for the encrypted sequence to
733 55000 (the default is 61000):
735 .B $ fwknop \-\-Server-mode 'knock' \-A tcp/22 \-s \-r \-\-offset 55000 \-D 10.0.0.123
737 Send a shared knock sequence to the IP 10.11.11.123. The fwknop client
738 will read the sequence out of the file
740 and the server will read the sequence out of
741 .B /etc/fwknop/access.conf:
743 .B $ fwknop \-\-Server-mode 'knock' \-D 10.11.11.123
748 requires perl. To take advantage of all of the authentication and access management features of the
750 daemon/service a functioning iptables firewall is required on the underlying
751 operating system. If fwknop is being run in the legacy port knocking mode,
752 then iptables must log packets via syslog, and ideally the
753 .B \-\-log-tcp-options
754 argument will be specified in the iptables logging rule so that the
757 be able to use a strategy similar to
759 to passively fingerprint operating systems.
763 can be run in debug mode with the
765 command line option. This will
766 disable daemon mode execution, and print verbose information to the screen
767 on STDERR as packets are received.
777 More information on the
778 differences between port knocking and Single Packet Authorization can be found
779 in the paper "Single Packet Authorization with fwknop" available here:
780 .B http://www.cipherdyne.org/fwknop/docs/SPA.html
783 Michael Rash <mbr@cipherdyne.org>
786 Many people who are active in the open source community have contributed to fwknop.
789 file in the fwknop sources, or visit
790 .B http://www.cipherdyne.org/fwknop/docs/contributors.html
791 to view the online list of contributors.
793 The phrase "Single Packet Authorization" was coined by MadHat and Simple
794 Nomad at the BlackHat Briefings of 2005 (see: http://www.nmrc.org/).
795 The term "port knocking" was coined by Martin Krzywinski (see:
796 http://www.portknocking.org/). The original p0f passive OS fingerprinter was
797 written by Michal Zalewski, and is available here:
798 .B http://lcamtuf.coredump.cx/p0f.shtml
801 Send bug reports to mbr@cipherdyne.org. Suggestions and/or comments are
802 always welcome as well.
806 is distributed under the GNU General Public License (GPL), and the latest
807 version may be downloaded from
808 .B http://www.cipherdyne.org/