FWKNOPD(8)
πΈ FWKNOPD(8) πΈ
okay bestie, buckle up β this is the manual page for fwknopd, the Fwknop Server π
(that's the FWKNOPD(8) bit at the top of the page if you were wondering, we're folding it in right here so it doesn't get lost β¨)
β¨ NAME β¨
fwknopd β Firewall Knock Operator Daemon π«Ά
π SYNOPSIS π
fwknopd [options]
π¦ DESCRIPTION π¦
okay so fwknopd is the server component for the FireWall Knock Operator, and it is literally responsible for monitoring and processing Single Packet Authorization (SPA) packets β the ones generated by fwknop clients π β then modifying a firewall or ACL policy to allow the desired access after authenticating and decrypting a valid SPA packet (in that order, no skipping steps bestie, the order matters π€), and then removing that access after a configurable timeout. the way it just cleans up after itself? obsessed.
the main application of this program is to conceal services such as SSH with an additional layer of security so that exploiting vulnerabilities (both 0-day and unpatched code, yes really) becomes much more difficult π₯ and like, bonus: services that are concealed in this fashion naturally cannot be scanned for with Nmap or Shodan. they just can't see you. main character invisibility energy ππ
the main configuration for fwknopd lives in two files: fwknopd.conf and access.conf. the default location for these files is determined at package configuration (typically /etc/fwknop). the configuration variables inside these files are described below π
more info can be found in the tutorial βSingle Packet Authorization: A Comprehensive Guide to Strong Service Concealment with fwknopβ, available online (see: http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html) π
β COMMAND-LINE OPTIONS β
-i,--interface=<interface>β manually specify the interface to sniff on, like-i eth0. usually you don't need this because thePCAP_INTFkeyword in thefwknopd.conffile already defines the sniffing interface π§-f,--foregroundβ runfwknopdin the foreground instead of becoming a daemon. when it runs in the foreground, messages that would go to the log get sent to stderr instead. this mode is usually used for testing and/or debugging π--fw-listβ list only the firewall rules that any runningfwknopddaemon has created, then exit. like a little receipts check π§Ύ-a,--access-file=<access-file>β specify the location of theaccess.conffile. if you don't give this option,fwknopduses the compile-time default location (typically/etc/fwknop/access.conf) π--access-folder=<access-folder>β specify the location of theaccess.conffolder. if you give this option, instead of loading a singleaccess.conffile, all the.conffiles in the given folders are processed ποΈ-c,--config=<config-file>β specify the location of thefwknopd.conffile. if you don't give this option,fwknopduses the default location (typically/etc/fwknop/fwknopd.conf) βοΈ-C,--packet-limit=<n>β specify the number of candidate SPA packets to process, and exit when this limit is reached π’-d,--digest-file=<digest-file>β specify the location of thedigest.cachefile. if you don't give this option,fwknopduses the compile-time default location (typically/var/fwknop/digest.cache) π-D,--dump-configβ dump the configuration values thatfwknopdderives from/etc/fwknop/fwknopd.conf(or override files) and/etc/fwknop/access.confonto stderr π€--dump-serv-err-codesβ dump all possiblefwknopderror codes to stdout and exit. this option is rarely needed in practice and was added to assist with test coverage π§ͺ--fault-injection-tag=<tag>β this option is only used for fault injection testing when fwknop is compiled to support thelibfiulibrary (see:http://blitiri.com.ar/p/libfiu/). under normal circumstances this option is not used, and any packaged version of fwknop will not have code compiled in, so this capability is not enabled at run time. it's documented here for completeness π«‘-A,--afl-fuzzingβ tellfwknopdto acquire SPA packets directly from stdin in support of fuzzing operations from the American Fuzzy Lop (AFL) fuzzer written by Michal Zalewski. this requires that fwknop is compiled with the--enable-afl-fuzzingargument to theconfigurescript, because that allows encryption/digest short circuiting in the manner necessary for AFL to function properly. the benefit of this strategy is that AFL can fuzz the SPA packet decoding routines implemented bylibfkoπ¬--fw-list-allβ list all firewall rules, including the ones that have nothing to do withfwknopdπ--fw-flushβ flush any firewall rules created by a runningfwknopdprocess. this option lets the user easily deletefwknopdfirewall rules without having to wait for them to time out β°-K,--killβ kill the currentfwknopdprocess. quick and easy way to stopfwknopdwithout having to go digging around in the process table π--exit-parse-configβ parse the config files (/etc/fwknop/fwknopd.confand/etc/fwknop/access.conf) and then exit. this is a way to test whether the config files are properly structured without having to start processing network traffic β--exit-parse-digest-cacheβ parse the digest cache file/var/fwknop/digest.cacheand exit. this validates the structure of the digest cache file without having to start processing network traffic. note that the standard configuration files are also parsed in this mode ποΈ-l,--locale=<locale>β set/override the system default locale setting π--no-ipt-check-supportβ disable the usage of theiptables -Coption. this isn't normally needed, and is only useful on older Linux distributions whereiptablesdoesn't have-Csupport π§-O,--override-config=<file>β override config variable values that are normally read from the/etc/fwknop/fwknopd.conffile with values from the specified file. multiple override config files can be given as a comma-separated list π--key-genβ havefwknopdgenerate both Rijndael and HMAC keys that can be used for SPA packet encryption and authentication. these keys are derived from/dev/urandomand then base64 encoded before being printed to stdout, and they're meant to be manually included in a stanza within the/etc/fwknop/access.conffile. such keys are generally more secure than passphrases πβ¨--key-gen-file=<file>β write generated keys to the specified file. note that the file is overwritten if it already exists. if this option is not given, then--key-genwrites the keys to stdout β οΈ--key-len=<length>β specify the number of bytes for a generated Rijndael key. the maximum size is currently 128 bytes π--hmac-key-len=<length>β specify the number of bytes for a generated HMAC key. the maximum size is currently 128 bytes π-p,--pid-file=<pid-file>β specify the location of thefwknopd.pidfile. if you don't give this option,fwknopduses the compile-time default location (typically/var/fwknop/fwknopd.pid) πͺͺ-P,--pcap-filter=<filter>β specify a Berkeley packet filter statement on thefwknopdcommand line. this overrides the value of thePCAP_FILTERvariable taken from the/etc/fwknop/fwknopd.conffile π―--pcap-file=<pcap-file>β this option instructsfwknopdto read packet data from a pcap file instead of sniffing an interface directly. this mode is usually used for debugging purposes, and it will disable SPA packet age checking unless it's manually enabled in the/etc/fwknop/fwknopd.conffile π¬--pcap-any-directionβ allowfwknopdto sniff SPA packets regardless of whether they're received on the sniffing interface or sent from the sniffing interface. in the latter case, this can be useful to havefwknopdsniff SPA packets that are forwarded through a system and destined for a different network. if the sniffing interface is the egress interface for such packets (and hence SPA packets are sent by this interface instead of received), then this option will need to be used in order forfwknopdto see them. the default is to only sniff packets that are received on the sniffing interface. note that this setting is independent of promiscuous mode ποΈποΈ-R,--restartβ restart the currently runningfwknopdprocesses. this option preserves the command line options that were supplied to the originalfwknopdprocess but forcesfwknopdto re-read thefwknopd.confand/etc/fwknop/access.conffiles. this will also force a flush of the current βFWKNOPβ iptables chain(s) π--rotate-digest-cacheβ rotate the digest cache file by renaming it to β<name>-oldβ, and starting a new one. the digest cache file is typically found in/var/fwknop/digest.cacheπ-r,--run-dir=<path>β specify the directory wherefwknopdwrites run time state files. the default is/varπ-S,--statusβ display the status of anyfwknopdprocesses that may or may not be running. if there's an existingfwknopdprocess then 0 is returned for the exit status, and 1 is returned otherwise π--syslog-enableβ allow messages to be sent to syslog even if the foreground mode is set π¨-t,--testβ runfwknopdin test mode. this instructsfwknopdto acquire and process SPA packets, but not manipulate firewall rules or execute commands that are provided by SPA clients. mostly useful for the fuzzing tests in the test suite to ensure broad code coverage under adverse conditions π§«-U,--udp-serverβ runfwknopdin UDP server mode so that SPA packets are acquired via a UDP socket directly, without having to uselibpcap. see the discussion of the βENABLE_UDP_SERVERβ configuration variable below for more information π‘-v,--verboseβ runfwknopdin verbose mode. this option can be specified multiple times to increase the verbosity of the output to the system log file (or to the screen if running in the foreground) π£οΈ-h,--helpβ display usage information and exit πββοΈ-V,--Versionβ display version information and exit π·οΈ
π FWKNOPD CONFIG AND ACCESS VARIABLES π
fwknopd references the /etc/fwknop/fwknopd.conf file for configuration variables that define operational parameters (what network interface and port to sniff, what features to enable/disable, etc.). the fwknopd.conf file does not define any access control directives or set any encryption or authentication keys π«π
the access control directives live in the /etc/fwknop/access.conf file. access control directives define encryption keys and the level of access that is granted to an fwknop client that has generated the appropriate encrypted SPA message ππ
π FWKNOPD.CONF VARIABLES π
Okay bestie, this is the part where we go through the more prominent config variables that fwknopd actually reads π. You're gonna wanna double-check these so they have values that make sense for your setup, but ngl, sensible defaults are already baked in for most systems β so like, don't panic. For extra deets, go peek at /etc/fwknop/fwknopd.conf itself. β¨
PCAP_INTF<interface> β tellsfwknopdwhich ethernet interface to sniff packets on. That's it. That's the whole vibe check. π¦ENABLE_PCAP_PROMISC<Y/N> β by defaultfwknopdputs the pcap interface into promiscuous mode (iconic of it). Set this toNto turn that off (aka non-promiscuous).PCAP_FILTER<pcap filter spec> β the filter used for PCAP modes;fwknopddefaults toUDP port 62201. BUT β and this is important β if an fwknop client uses the--rand-portoption to send the SPA packet over a random port, then you gotta update this variable to something likeudp dst portrange 10000-65535. Periodt. πENABLE_SPA_PACKET_AGING<Y/N> β this tellsfwknopdto not honor SPA packets that have an old time stamp. What counts as "old" is defined by theMAX_SPA_PACKET_AGEvariable. And ifENABLE_SPA_PACKET_AGINGis set toN,fwknopdwon't use the client time stamp at all. Zero time checking. None. πMAX_SPA_PACKET_AGE<seconds> β the maximum age (in seconds) an SPA packet will be accepted. Heads up: this requires the client system to be in relatively close time sync with thefwknopdserver system (NTP is good, bestie). Default age is120seconds (two minutes). βENABLE_DIGEST_PERSISTENCE<Y/N> β tracks the digest sums associated with previous SPA packets thatfwknopdhas processed, which keeps those digest sums persistent across executions offwknopd. Default isY. If it's set toN,fwknopdwon't check incoming SPA packet data against any previously saved digests β and honestly? It's a good idea to leave this feature on, because it reduces the possibility of being vulnerable to a replay attack. Keep it on, babe. π₯RULES_CHECK_THRESHOLD<count> β defines how many times firewall rule expiration times must be checked before a "deep" check gets run. This is what letsfwknopdremove rules that contain a properexp<time>even if a third party program added them instead offwknopditself. Default value is20, and that typically results in this check running every two seconds or so. Wanna disable this type of checking entirely? Set this variable to zero. Done. πENABLE_IPT_FORWARDING<Y/N> β lets SPA clients request access to services through an iptables firewall instead of just to it β meaning access through theFWKNOP_FORWARDchain instead of theINPUTchain. π§ENABLE_IPT_LOCAL_NAT<Y/N> β lets SPA clients request access to a local socket via NAT. This still puts anACCEPTrule into theFWKNOP_INPUTchain, but a different port gets translated via DNAT rules to the real one. So the user would dossh -p <port>to access the local service (peep the--NAT-localand--NAT-rand-porton the fwknop client command line π).ENABLE_IPT_SNAT<Y/N> β set this toYto enable a corresponding SNAT rule. By default, if forwarding access is enabled (see theENABLE_IPT_FORWARDINGvariable above),fwknopdcreates DNAT rules for incoming connections but does not also complement those rules with SNAT rules at the same time. Sometimes internal systems don't have a route back out for the source address of the incoming connection β in those situations it's necessary to also apply SNAT rules so the internal systems see the IP of the internal interface wherefwknopdis running. πΈSNAT_TRANSLATE_IP<ip_address> β the IP address for SNAT. This functionality is only enabled whenENABLE_IPT_SNATis set toY, and by default SNAT rules are built with theMASQUERADEtarget (since then the internal IP doesn't have to be defined here in the/etc/fwknop/fwknopd.conffile). But if you wantfwknopdto use theSNATtarget, you must also define an IP address with theSNAT_TRANSLATE_IPvariable. Note that this variable is generally deprecated in favor of theFORCE_SNATvariable in the/etc/fwknop/access.conffile, which enables per-stanza control over the SNAT IP. πENABLE_IPT_OUTPUT<Y/N> β addsACCEPTrules to theFWKNOP_OUTPUTchain. This is usually only useful if there are no state tracking rules to allow connection responses out, and theOUTPUTchain has a default-drop stance. π«ΆMAX_SNIFF_BYTES<bytes> β the maximum number of bytes to sniff per frame.1500is the default. βFLUSH_IPT_AT_INIT<Y/N> β flush all existing rules in the fwknop chains atfwknopdstart time. Default isY. π§ΉFLUSH_IPT_AT_EXIT<Y/N> β flush all existing rules in the fwknop chains whenfwknopdis stopped or otherwise exits cleanly. Default isY. π§ΉEXIT_AT_INTF_DOWN<Y/N> β whenfwknopdis sniffing an interface and that interface gets administratively downed or unplugged,fwknopdwill cleanly exit, and the assumption is made that some process-monitoring infrastructure like systemd or upstart will restart it. But iffwknopdis not being monitored by systemd, upstart, or anything else, this behavior can be disabled with theEXIT_AT_INTF_DOWNvariable. If it's disabled,fwknopdwill try to recover when a downed interface comes back up. πENABLE_RULE_PREPEND<Y/N> β for systems running iptables or firewalld, this makesfwknopdinsert new SPA rules at the beginning of the relevant chain (such asFWKNOP_INPUT) instead of appending them to the end. This causes newly created rules to have precedence over older ones. New rules, main character energy. πENABLE_NAT_DNS<Y/N> β allowsfwknopdto resolve hostnames in NAT access messages. π¦GPG_HOME_DIR<path> β if GPG keys are used instead of a Rijndael symmetric key, this is the default GPG keys directory. Note that each access stanza in/etc/fwknop/access.confcan specify its own GPG directory to override this default. And if it's not set here or in anaccess.confstanza, then it's the$HOME/.gnupgdirectory of the user runningfwknopd(most likely root). πGPG_EXE<path> β the path to GPG, defaulting to/usr/bin/gpgif not set. βLOCALE<locale> β sets the locale (via theLC_ALLvariable). You can set this to override the default system locale. πENABLE_SPA_OVER_HTTP<Y/N> β allowsfwknopdto acquire SPA data from HTTP requests (generated with the fwknop client in--HTTPmode). Note that when this is enabled, thePCAP_FILTERvariable would need to be updated to sniff traffic overTCP/80connections, and a web server should be running on the same server asfwknopd. πΈENABLE_X_FORWARDED_FOR<Y/N> β letsfwknopduse theX-Forwarded-forheader from a captured SPA packet over HTTP as the source IP. This can happen when using SPA through an HTTP proxy. π§ENABLE_TCP_SERVER<Y/N> β enables thefwknopdTCP server. This is a "dummy" TCP server that will accept TCP connection requests on the specifiedTCPSERV_PORT. If set toY,fwknopdwill fork off a child process to listen for and accept incoming TCP requests. This server only accepts the request β it does not otherwise communicate. It exists purely to allow the incoming SPA over TCP packet, which is detected via PCAP. The connection is closed after1second regardless. Note thatfwknopdstill only gets its data via pcap, so the filter defined byPCAP_FILTERneeds to be updated to include this TCP port. πTCPSERV_PORT<port> β the port number that the "dummy" TCP server listens on. This server is only spawned whenENABLE_TCP_SERVERis set toY. π₯ENABLE_UDP_SERVER<Y/N> β enables thefwknopdUDP server, which tellsfwknopdto acquire SPA packets via a UDP socket directly, without having to use libpcap. When this mode is enabled,fwknopshould be compiled with--enable-udp-server(passed to the configure script) so that libpcap can be removed as a dependency. As one would expect, when the UDP server is used, no incoming packets are ever acknowledged byfwknopdβ and therefore collecting SPA packets in this mode is a good alternative to sniffing the wire directly. Big slay for low-dependency setups. πUDPSERV_PORT<port> β the port number that the UDP server listens on. This server is only spawned whenENABLE_UDP_SERVERis set toY. β¨PCAP_DISPATCH_COUNT<count> β sets the number of packets that get processed when thepcap_dispatch()call is made. Default iszero, since this allowsfwknopdto process as many packets as possible in the corresponding callback, where the SPA handling routine is called for packets that pass a set of prerequisite checks. However, iffwknopdis running on a platform with an old version of libpcap, it may be necessary to change this value to a positive non-zero integer. More info lives in thepcap_dispatch(3)man page. πPCAP_LOOP_SLEEP<microseconds> β the number of microseconds passed as an argument tousleep()in the pcap loop. Default is100000, or 1/10th of a second. π€ENABLE_PCAP_ANY_DIRECTION<Y/N> β controls whetherfwknopdis permitted to sniff SPA packets regardless of whether they're received on the sniffing interface or sent from the sniffing interface. In the latter case, this can be useful to havefwknopdsniff SPA packets that are forwarded through a system and destined for a different network. If the sniffing interface is the egress interface for such packets, then this variable needs to be set toYin order forfwknopdto see them. Default isN, sofwknopdonly looks for SPA packets that are received on the sniffing interface β and note that this is independent of promiscuous mode. π¦SYSLOG_IDENTITY<identity> β overrides the syslog identity on messages logged byfwknopd. The defaults are usually ok. πSYSLOG_FACILITY<facility> β overrides the syslog facility. TheSYSLOG_FACILITYvariable can be set to
(yeah bestie, the original page literally trails off right there β that's the whole line, no cap π)
ENABLE_DESTINATION_RULE<Y/N> β controls whetherfwknopdwill set the destination field on the firewall rule to the destination address specified on the incoming SPA packet. This is useful for interfaces with multiple IP addresses hosting separate services. IfENABLE_IPT_OUTPUTis set toY, the source field of the firewall rule is set.FORWARDandSNATrules are not affected, however β butDNATrules will also have their destination field set. Default isN, which sets the destination field to0.0.0.0/0(any). πFWKNOP_RUN_DIR <path>β where fwknopd drops its run-time state files, bestie. Default is/var, so that's where the state lives unless you tell it otherwise π
π ACCESS.CONF VARIABLES π
Okay so this section is about the access control directives that live in /etc/fwknop/access.conf β the actual brain of the whole operation. These directives are what define your encryption and authentication keys, plus exactly how much access gets handed to fwknop clients that showed up with a properly encrypted and authenticated SPA packet. Like, they did the handshake, they get the goods. Periodt.
The variables below are the access directives for SPA packets whose source IP (or embedded request IP) matches an address or network range defined by the SOURCE variable. Every variable that follows a SOURCE belongs to that source's stanza β and each SOURCE directive kicks off a brand new stanza. New stanza, new vibe check πΈ
SOURCE <IP,..,IP/NET,..,NET/ANY>β this is the one that sets the source address the SPA packet has to come from to be accepted. The stringANYis also accepted, if a valid SPA packet should be honored from any source IP. Heads up: every authorization stanza in/etc/fwknop/access.confhas to start with theSOURCEkeyword β it's giving main character energy, it goes first, no exceptions. Networks should be written in CIDR notation (like192.168.10.0/24), and individual IP addresses work too. You can also list multiple IPs and/or networks as a comma separated list, like192.168.10.0/24,10.1.1.123β¨DESTINATION <IP,..,IP/NET,..,NET/ANY>β same idea but for the destination: this defines the destination address for which the SPA packet will be accepted. The stringANYis also accepted here, if a valid SPA packet should be honored to any destination IP. Networks in CIDR notation (like192.168.10.0/24), individual IPs are fine, and yes you can comma-separate a whole list of IPs and/or networks (like192.168.10.0/24,10.1.1.123) π¦OPEN_PORTS <proto/port>,...,<proto/port>β define the set of ports and protocols (tcporudp) that get opened if a valid knock sequence is seen. If you don't set this entry, fwknopd will attempt to honor any proto/port request that's specified in the SPA data (unless it matches anyRESTRICT_PORTSentries, obviously). Multiple entries are comma-separated. No cap, list as many as you want πRESTRICT_PORTS <proto/port>,...,<proto/port>β the exact opposite energy: define the set of ports and protocols (tcporudp) that are explicitly not allowed, regardless of how valid the incoming SPA packet is. Multiple entries are comma-separated. It's the velvet rope π«KEY <passphrase>β defines the symmetric key used for decrypting an incoming SPA packet that the fwknop client encrypted with Rijndael. The actual encryption key is derived from the standard PBKDF1 algorithm. This variable is required for all SPA packets unless GnuPG is used instead (scroll down to the GPG variables, bestie) πKEY_BASE64 <base64 encoded passphrase>β same as theKEYoption above, but you hand over the symmetric key as a base64 encoded string. This is how you sneak non-ascii characters into the base64-decoded key πHMAC_KEY <key>β sets the HMAC key for authenticated encryption of SPA packets. It supports both Rijndael and GPG encryption modes, and it's applied according to the encrypt-then-authenticate model β authenticate after you encrypt, that's the whole point πHMAC_KEY_BASE64 <base64 encoded key>β the HMAC key, but as a base64 encoded string. Same deal: it's how you get non-ascii characters into the base64-decoded key πFW_ACCESS_TIMEOUT <seconds>β how long fwknopd will grant access through the firewall after a valid knock sequence from a source IP address. IfFW_ACCESS_TIMEOUTisn't set, then the default timeout of30seconds is automatically set for you. Yes, 30 seconds, don't come crying to me when it closes β³%include <file>β have fwknopd import an additionalaccess.conffile. This means you can define more access stanzas in other locations on the filesystem, which is genuinely iconic in some scenarios: it lets non-privileged users define their own encryption and authentication keys for SPA operations. So users don't need write access to the main/etc/fwknop/access.conffile just to rotate keys or add new ones. Delegation slay π«Ά%include_folder <directory>β just like%includeabove, except the%include_folderdirective has fwknopd import all.conffiles from the directory you specify. There's also command line support for this via theaccess-folderoption, iykyk πENCRYPTION_MODE <mode>β specify the encryption mode when AES is used. Default is CBC mode, but other modes can be selected such as OFB and CFB. In general it's recommended that you don't use this variable and just leave it as the default β let the defaults cook π₯. Note that the stringlegacycan be specified in order to generate SPA packets with the old initialization vector strategy used by versions of fwknop before 2.5. With the 2.5 release, fwknop uses PBKDF1 for key derivation β¨HMAC_DIGEST_TYPE <digest algorithm>β sets the digest algorithm for incoming SPA packet authentication. Must be one ofMD5,SHA1,SHA256,SHA384,SHA512,SHA3_256, orSHA3_512. It's optional, and if you don't specify it then fwknopd defaults to usingSHA256if the access stanza requires an HMAC πACCESS_EXPIRE <MM/DD/YYYY>β sets an expiration date for the access stanza, inMM/DD/YYYYformat. All SPA packets that match an expired stanza will be ignored. Optional. It's giving limited-time offer β°ACCESS_EXPIRE_EPOCH <seconds>β same expiration idea but as the epoch time, which is useful when you need a more accurate expiration than the day resolution offered byACCESS_EXPIREabove. All SPA packets that match an expired stanza will be ignored. Also optional π°οΈENABLE_CMD_EXEC <Y/N>β this tells fwknopd to accept complete commands that are contained within an authorization packet. Any such command will be executed on the fwknopd server as the user specified byCMD_EXEC_USER, or as the user that started fwknopd if that's not set. Yes, this executes commands. Handle with care, bestie. πENABLE_CMD_SUDO_EXEC <Y/N>β sudo is a genuinely powerful way of restricting the sets of commands users can execute via thesudoersfile. By enabling this feature (and being inENABLE_CMD_EXECmode), all incoming commands from valid SPA packets get prefixed by/path/to/sudo -u <user> -g <group>β where the path to sudo is set by theSUDO_EXEvariable,<user>is set by theCMD_SUDO_EXEC_USERvariable (default isrootif not set), and<group>is set byCMD_SUDO_EXEC_GROUP(default is alsorootif not set) πCMD_EXEC_USER <username>β specify the user (viasetuid) that will execute a command contained within a SPA packet. If you don't give this variable, fwknopd will execute the command as the user it's running as (most likelyroot). Setting this to a non-root user such asnobodyis highly recommended if elevated permissions aren't needed β like, why would you not, bestie π§CMD_SUDO_EXEC_USER <username>β specify the user (viasudo -u <user>) that will execute a command contained within a SPA packet. If you don't give this variable, fwknopd will assume the command should be executed asrootπCMD_EXEC_GROUP <groupname>β specify the group (viasetgid) that will execute a command contained within a SPA packet. If you don't give this variable, fwknopd will execute the command as the user it's running as (most likelyroot). Setting this to a non-root group... okay so the original says non-root user such asnobodyis highly recommended if elevated permissions aren't needed, and honestly the same energy applies πCMD_SUDO_EXEC_GROUP <groupname>β specify the group (viasudo -g <group>) that will execute a command contained within a SPA packet. If you don't give this variable, fwknopd will assume the command should be executed asrootπΈCMD_CYCLE_OPEN <command>β sets a command open/close cycle to run when a valid SPA packet arrives. This directive sets the initial command, and it's meant to be used together with theCMD_CYCLE_CLOSEvariable below β they're a package deal, don't split them up π«Ά. The main application here is letting fwknopd interact with firewalls or ACLs that aren't natively supported, and get the same access model as the main supported firewalls like iptables. So: a command runs to open the firewall or ACL, and then a corresponding close command runs after a timer expires. BothCMD_CYCLE_OPENandCMD_CYCLE_CLOSEsupport special substitution strings so values can be pulled from the SPA payload and used on the command line of the executed command. These strings all start with a$character, and they include$IP(the allow IP decrypted from the SPA payload),$SRC(synonym for$IP),$PKT_SRC(the source IP in the network layer header of the SPA packet),$DST(the destination IP),$PORT(the allow port), and$PROTO(the allow protocol),$TIMEOUT(set the client timeout if specified) βCMD_CYCLE_CLOSE <command>β sets the close command that corresponds to the open command fromCMD_CYCLE_OPENabove. The same string substitutions such as$IP,$PORT, and$PROTOare supported. On top of that, the special valueNONEcan be set to allow no close command to be executed after the open command β which might be handy in certain situations where, say, indefinite access is desired and allowed. (Indefinite access. Bestie. Be sure. π)CMD_CYCLE_TIMER <seconds>β set the number of seconds after which the close command inCMD_CYCLE_CLOSEgets executed. This defines the open/close timer interval β±οΈSUDO_EXE <path>β the path to the sudo binary. Default is/usr/bin/sudoβ¨REQUIRE_USERNAME <username>β require a specific username from the client system, as encoded in the SPA data. This variable is optional, and if you don't specify it, the username data in the SPA data is just ignored πREQUIRE_SOURCE_ADDRESS <Y/N>β force all SPA packets to contain a real IP address within the encrypted data. This makes it impossible to use the-scommand line argument on the fwknop client command line, so either-Rhas to be used to automatically resolve the external address (if the client is behind a NAT) or the client must know the external IP and set it via the-aargument πREQUIRE_SOURCE_ADDRESS <Y/N>β synonym forREQUIRE_SOURCE_ADDRESS. Yes bestie. It's a synonym for itself. That's literally what the page says. We don't make the rules, we just report them ππFORCE_NAT <IP> <PORT>β for any valid SPA packet, force the requested connection to be NATβd through to the specified (usually internal) IP and port value. This is useful if there are multiple internal systems running a service such as SSHD, and you want to give transparent access to only one internal system for each stanza in theaccess.conffile. This way, multiple external users can each directly access only one internal system per SPA key. πFORCE_SNAT <IP>β for any valid SPA packet, add an SNAT rule in addition to any DNAT rule created with a corresponding (required)FORCE_NATvariable. This is analogous toSNAT_TRANSLATE_IPfrom the/etc/fwknop/fwknopd.conffile except that it is per access stanza and overrides any value set withSNAT_TRANSLATE_IP. This is useful for situations where an incoming NATβd connection may be otherwise unanswerable due to routing constraints (i.e. the system receiving the SPA authenticated connection has a default route to a different device than the SPA system itself).FORCE_MASQUERADE <Y/N>β this is similar to theFORCE_SNATvariable, except that it is not necessary to also specify an IP address for SNAT rules because the MASQUERADE target is used instead.FORWARD_ALL <Y/N>β in NAT scenarios, control whether all traffic is forwarded through thefwknopdsystem as opposed to just forwarding connections to specific services as requested by thefwknopclient.DISABLE_DNAT <Y/N>β control whether DNAT rules are created inFORCE_NATscenarios. This is mainly used in conjunction with theFORWARD_ALLvariable to allowfwknopdto act essentially as an SPA gateway. I.e., thefwknopclient is used to gain access via SPA to the broader Internet after being granted an IP via DHCP, but prior to sending the SPA packet all traffic is blocked by default to the Internet.GPG_DECRYPT_ID <keyID>β define a GnuPG key ID to use for decrypting SPA messages that have been encrypted by anfwknopclient. This keyword is required for authentication that is based on GPG keys. The GPG key ring on the client must have imported and signed thefwknopdserver key, and vice versa. It is ok to use a sensitive personal GPG key on the client, but eachfwknopdserver should have its own GPG key that is generated specifically forfwknopcommunications. The reason for this is that the decryption password for the server key must be placed within the/etc/fwknop/access.conffile forfwknopdto function (it has to be able to decrypt SPA messages that have been encrypted with the serverβs public key). For more information on usingfwknopwith GnuPG keys, see the following link:http://www.cipherdyne.org/fwknop/docs/gpghowto.html.GPG_DECRYPT_PW <decrypt password>β specify the decryption password for the gpg key defined by theGPG_DECRYPT_IDabove. This is a required field for gpg-based authentication.GPG_ALLOW_NO_PW <Y/N>β allowfwknopdto leverage a GnuPG key pair that does not have an associated password. While this may sound like a controversial deployment mode, in automated environments it makes sense because "there is usually no way to store a password more securely than on the secret keyring itself" according to:http://www.gnupg.org/faq/GnuPG-FAQ.html#how-can-i-use-gnupg-in-an-automated-environment. Using this feature and removing the passphrase from a GnuPG key pair is useful in some environments wherelibgpgmeis forced to usegpg-agentand/orpinentryto collect a passphrase.GPG_REQUIRE_SIG <Y/N>β with this setting set toY,fwknopdcheck all GPG-encrypted SPA messages for a signature (signed by the senderβs key). If the incoming message is not signed, the decryption process will fail. If not set, the default isY.GPG_DISABLE_SIG <Y/N>β disable signature verification for incoming SPA messages. This is not a recommended setting, and the default isN.GPG_IGNORE_SIG_VERIFY_ERROR <Y/N>β setting this will allowfwknopdto accept incoming GPG-encrypted packets that are signed, but the signature did not pass verification (i.e. the signer key was expired, etc.). This setting only applies if theGPG_REQUIRE_SIGis also set toY.GPG_REMOTE_ID <keyID,...,keyID>β define a list of gpg key IDβs that are required to have signed any incoming SPA message that has been encrypted with thefwknopdserver key. This ensures that the verification of the remote user is accomplished via a strong cryptographic mechanism. Signature verification is enabled by default, and can only be disabled ifGPG_DISABLE_SIGis set toY(not a recommended setting). Separate multiple entries with a comma.GPG_FINGERPRINT_ID <keyID,...,keyID>β specify a set of full-length GnuPG key fingerprints instead of the shorter key identifiers set with theGPG_REMOTE_IDvariable. Here is an example fingerprint for one of thefwknoptest suite keys:00CC95F05BC146B6AC4038C9E36F443C6A3FAD56.GPG_HOME_DIR <path>β define the path to the GnuPG directory to be used by thefwknopdserver. If this keyword is not specified within/etc/fwknop/access.confthenfwknopdwill default to using the/root/.gnupgdirectory for the server key(s) for incoming SPA packets handled by the matchingaccess.confstanza.GPG_EXE <path>β define the path to the GnuPG executable. If this keyword is not specified within/etc/fwknop/access.confthenfwknopdwill default to using/usr/bin/gpg.
π FILES π
/etc/fwknop/fwknopd.confβ the main configuration file forfwknop. π/etc/fwknop/access.confβ defines all knock sequences and access control directives. π¦
π§ DEPENDENCIES π§
fwknopd requires libfko which is normally included with both source and binary distributions, and is a dedicated library developed by the fwknop project.
For packet sniffing, fwknopd currently requires libpcap, but future versions will (optionally) remove this as a dependency.
For GPG functionality, GnuPG must also be correctly installed and configured along with the libgpgme library.
To take advantage of all of the authentication and access management features of the fwknopd daemon/service a functioning iptables, ipfw, or pf firewall is required on the underlying operating system. π₯
π©Ί DIAGNOSTICS π©Ί
fwknopd can be run in debug mode by combining the -f, --foreground and the -v, --verbose command line options. This will disable daemon mode execution, and print verbose information to the screen on stderr as packets are received. π
The most comprehensive way to gain diagnostic information on fwknopd is to run the test suite test-fwknop.pl script located in the test/ directory in the fwknop sources. The test suite runs sends fwknop through a large number of run time tests, has valgrind support, validates both SPA encryption and HMAC results against OpenSSL, and even has its own built in fuzzer for SPA communications. literally so thorough π
π SEE ALSO π
fwknopd(8), iptables(8), pf(4), pfctl(8), ipfw(8), gpg(1), libfko documentation.
More information on Single Packet Authorization can be found in the paper βSingle Packet Authorization with fwknopβ available at http://www.cipherdyne.org/fwknop/docs/SPA.html. A comprehensive tutorial on fwknop operations and theory can be found at http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html. This tutorial also includes information about the design of fwknop that may be worth reading for those interested in why fwknop is different from other SPA implementations. πΈ
fwknop uses the git versioning system as its source code repository along with Github for tracking of issues and milestones:
$ git clone https://github.com/mrash/fwknop.git fwknop.git
Additional commentary on Single Packet Authorization can be found via Michael Rashβs Twitter feed: http://twitter.com/michaelrash, @michaelrash π¦
π«Ά AUTHORS π«Ά
The primary developers of fwknop are Michael Rash (project creator) <mbr@cipherdyne.org>, Damien Stuart <dstuart@dstuart.org>, and Jonathan Bennett <jbennett@incomsystems.biz>.
π CONTRIBUTORS π
This βCβ version of fwknop was derived from the original Perl-based version on which many people who are active in the open source community have contributed. See the CREDITS file in the fwknop sources, or visit https://github.com/mrash/fwknop/blob/master/CREDITS to view the online list of contributors. A few contributors deserve to be singled out including: Franck Joncourt, Max Kastanas, Vlad Glagolev, Sean Greven, Hank Leininger, Fernando Arnaboldi, and Erik Gomez. π
The phrase βSingle Packet Authorizationβ was coined by MadHat and Simple Nomad at the BlackHat Briefings of 2005. iconic origin story fr fr β¨
π BUGS π
Send bug reports to dstuart@dstuart.org or mbr@cipherdyne.org, or open a new issue on Github (see https://github.com/mrash/fwknop.git). Suggestions and/or comments are always welcome as well. Additional information may be found in the fwknop mailing list archives (see: https://lists.sourceforge.net/lists/listinfo/fwknop-discuss).
π DISTRIBUTION π
fwknopd is distributed under the GNU General Public License (GPL v2+), and the latest version may be downloaded from http://www.cipherdyne.org.
okay bestie, footer shoutout: this oneβs the Fwknop Server page, dated 08/06/2018, section FWKNOPD(8) β and thatβs a wrap on the whole manual πππ¦
π¦ where this page comes from
- alpine 3.24: fwknop-doc 2.6.11-r2 Β· GPL-2.0-or-later
- arch rolling: fwknop 2.6.11-1 Β· GPL-2.0-only
- epel 10: fwknop 2.6.11-4.el10_1 Β· GPL-2.0-only
- epel 9: fwknop 2.6.10-10.el9 Β· GPLv2
- fedora 43: fwknop 2.6.11-5.fc43 Β· GPL-2.0-only
- fedora 43: fwknop 2.6.11-5.fc43 Β· GPL-2.0-only
- fedora 44: fwknop 2.6.11-6.fc44 Β· GPL-2.0-only
- fedora 44: fwknop 2.6.11-6.fc44 Β· GPL-2.0-only
- opensuse-leap 16.0: fwknopd 2.6.11-bp160.1.6 Β· GPL-2.0-or-later
- opensuse-leap 16.0: fwknopd 2.6.11-bp160.1.6 Β· GPL-2.0-or-later
- opensuse-leap 16.0: fwknopd 2.6.11-bp160.1.6 Β· GPL-2.0-or-later
- opensuse-leap 16.0: fwknopd 2.6.11-bp160.1.6 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms