cipherdyne.org

Michael Rash, Security Researcher



Software Release: fwknop-2.6.11

The 2.6.11 release of fwknop is available for download (or via the github release tag). Here is the complete ChangeLog:

  • [server] (Amin Massad) Fixed two bugs in PF handling code - one for indefinitely repeating error messages "Did not find expire comment in rules list 0" in rule deletion code, and the second where min_exp was not computed correctly for min_exp equal to zero. See github issue #295.
  • [server] Add ALLOW_ANY_USER_AGENT for ENABLE_SPA_OVER_HTTP mode so that fwknopd will accept any User-Agent string coming from the client. By default this is disabled, so only SPA packets with a User-Agent string that begins with 'Fwknop' will be accepted. Just set this variable to 'Y' to override this. Then, on the fwknop client command line, use the --user-agent option to specify any desired User-Agent string. This feature was added to close issue #296 reported by github user @fishcreek.
  • [AppArmor] (Francois Marier) Various fixes to the AppArmor profile to support recent versions of Debian and Ubuntu.
  • [test suite] Add gpg.conf and gpg-agent.conf to set 'pinentry-mode loopback' to restore GPG full cycle tests. This works with GPG 2.2.27 on Ubuntu 22.04 for example.
  • [test suite] Prefer the 'ip' command over the older 'ifconfig' command for interface operations and loopback detection.
  • [test suite] Update the 'spa_fuzzing.py' fuzzer to use Python3.

Wireguard, macOS, and Linux Virtual Machines

(The primary material for this blog post was released on github. I'm reproducing part it here as a blog post.)

Over the long term, the Wireguard VPN is set to send shockwaves through the VPN community with its modern cryptographic design, performance, stealthiness against active network scanners, and commitment to security through a minimally complex code base. It is my belief that these characteristics firmly place Wireguard among the best VPN options available. Over time, it is likely that commercial solutions will be developed around Wireguard similarly to commercial wrappers around OpenVPN.

This repository is dedicated to deploying a Wireguard VPN on macOS via a Linux VM running under a virtualization solution such as Parallels. There are many alternatives to this approach - including omitting the Linux piece altogether and using the cross-platform macOS Wireguard tools - but I'm interested in using the Wireguard kernel module from a Mac. This has to be done from a Linux VM or container, and we'll talk about the VM route in this write up.

The primary use case for running such a VPN solution is to provide security for network traffic emanating from a Mac laptop that is connected to a potentially hostile wireless network. This includes the network at the local coffee shop among many others. Nothing against coffee shops of course (I love coffee), but they are in the business of making wonderful caffeinated potions - not hardening their network infrastructure against adversaries. In terms of general threats to network traffic, a properly deployed VPN allows you to shift much of the security burden to the other side of the VPN. In this case, the remote Wireguard end point will be deployed in a major cloud provider or ISP network. The security of, say, Google's GCE network or Amazon's AWS network is far higher than the network of the local coffee shop.

Note macOS security is a broad topic, and this repository is meant only to discuss a VPN solution based on Wireguard. For a comprehensive treatment of macOS security, including other VPN options, see the excellent macOS Security and Privacy Guide.

Prerequisites

To fully implement Wireguard in this manner, we'll assume the following:

  • An Ubuntu Linux VM is running under Parallels on a Mac laptop. Wireguard will run from this VM, and will constitute the "client" side of the VPN.
  • The Mac laptop will be connected wirelessly to the network at the local coffee shop, and have an IP assigned via DHCP as usual.
  • The "server" side of the Wireguard VPN is an Ubuntu system running on a major cloud provider with an Internet-facing IP address.
  • Wireguard has been [installed](https://www.wireguard.com/install/) on both Ubuntu VM's, and key pairs have been [generated and shared](https://www.wireguard.com/quickstart/).
  • Wireguard client - Mac laptop hostname and IP addresses:
  • Mac laptop hostname: maclaptop
  • Mac laptop wireless IP on the coffee shop network: 192.168.0.54, interface: en0
  • Mac laptop virtual NIC IP (under Parallels): 10.211.44.2, interface: vnic0
  • Mac laptop Ubuntu VM Wireguard hostname: wgclientvm, IP: 10.211.44.31
  • Mac laptop Ubuntu VM Wireguard IP: 10.33.33.2, interface: wg0
  • Wireguard server - Ubuntu system hostname and IP addresses:
  • Hostname: wgserver
  • IP: 1.1.1.1, interface: eth0
  • Wireguard IP: 10.33.33.1, interface: wg0
Graphically, the network setup looks like this: Wireguard network diagram For the remainder of the writeup, head on over to the github repository.

Software Release: fwknop-2.6.10

The 2.6.10 release of fwknop is available for download (or via the github release tag). Here is the complete ChangeLog:

  • [server] Add MAX_FW_TIMEOUT to access.conf stanzas to allow a maximum number of seconds for client-specified timeouts in SPA packets. This fixes issue #226 which was spotted by Jeremiah Rothschild.
  • [server] Bug fix in CMD_EXEC mode to make sure to call exit() upon any error from execvpe(). Without this fix, additional fwknopd processes would be started upon a user specifying a command without the necessary permissions. This bug was reported by Stephen Isard.
  • [build] Jérémie Courrèges-Anglas and Ingo Feinerer contributed a patch to fix endian detection on OpenBSD systems based on information contained here: https://www.opengroup.org/austin/docs/austin_514.txt
  • [client/server] (Michael Stair) Added client and server infrastructure written in Erlang. See the erlang/ directory.

Software Release: psad-2.4.6 and fwsnort-1.6.8

A pair of software releases is available for download - psad-2.4.6 and fwsnort-1.6.8. The main change is that now both pieces of software support the Snort 'metadata' keyword. This keyword and associated field is a common fixture of modern Snort rule sets, and usually contains important data such as IPS policy preferences, information about vulnerable target software or OS, date created, and more.

As an example, when fwsnort detects TCP traffic over port 21 that matches the Snort rule "ET ATTACK_RESPONSE FTP inaccessible directory access COM2" (sid 2000500), the following syslog message is generated:
Jul 30 21:24:44 moria kernel: [650982.555939] [1] SID2000500 ESTAB IN=enx0014d1b0da65 OUT= MAC=00:12:34:56:78:65:60:e3:27:39:12:34:56:00 SRC=192.168.10.11 DST=192.168.10.1 LEN=59 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=58801 DPT=21 WINDOW=4117 RES=0x00 ACK PSH URGP=0 OPT (0101080A4538966A09B20FBC)
When psad monitors this out of the syslog data, an email alert is generated as usual. However, in this email alert the metadata 'created_at' and 'updated_at' fields are now included as defined in the original rule:
   "ET ATTACK_RESPONSE FTP inaccessible directory access COM2"
          dst port:  21 (no server bound to local port)
          flags:     ACK PSH
          content:   "/COM2/"
          content:   "/COM2/"
          sid:       2000500
          chain:     FWSNORT_INPUT_ESTAB
          packets:   36
          classtype: string-detect
          reference: (url) http://doc.emergingthreats.net/bin/view/Main/2000500
          reference: (url) http://doc.emergingthreats.net/bin/view/Main/2000500
          created_at 2010_07_30
          updated_at 2010_07_30

Software Release: fwknop-2.6.9

The 2.6.9 release of fwknop is available for download (or via the github release tag). Here is the complete ChangeLog:

  • (Jonathan Bennett) Added support for the SHA3 "Keccak" algorithm (specifically SHA3_256 and SHA3_512) for SPA HMAC and digest checking. Enabling SHA3 from the fwknop client command line is done with the -m option for the embedded SPA digest, or with the --hmac-digest-type argument for the HMAC. On the server side, SHA3_256 or SHA3_512 can be required for the incoming SPA packet HMAC via the HMAC_DIGEST_TYPE configuration variable in access.conf stanzas. The SHA3 implementation is from, Keyak and Ketje Teams, namely, Guido Bertoni, Joan Daemen, Michael Peeters, Gilles Van Assche and Ronny Van Keer - see: http://keyak.noekeon.org/
  • (Damien Stuart) Added support for libnetfilter_queue so that fwknopd can acquire SPA packets via the NFQ target. This feature is enabled with a new command line switch --enable-nfq-capture for the configure script, and libpcap is not required in this mode. In support of capturing SPA packets via the NFQ target, new configuration variables have been added to the fwknopd.conf file: ENABLE_NFQ_CAPTURE, NFQ_INTERFACE, NFQ_PORT, NFQ_TABLE, NFQ_CHAIN, NFQ_QUEUE_NUMBER, and NFQ_LOOP_SLEEP.
  • (Vlad Glagolev) Added support for deriving the source IP from the X-Forwarded-For HTTP header when SPA packets are sent over HTTP connections.
  • Bug fix in command open/close cycle feature to ensure that the first successful match on a valid incoming SPA packet finishes all access.conf stanza processing. That is, no other stanzas should be looked at after the first match, and this is consistent with other SPA modes (such as basic access requests). This bug was reported by Jonathan Bennett.
  • (Jonathan Bennett) Various fixes and enhancements to the test suite to extend code coverage to new code, ensure valgrind bytes lost detection works for amount of memory less than 10 bytes, better timing strategy for fwknop client/server interactions, and more.

Single Packet Authorization and Third Party Devices

A major new feature in fwknop has been introduced today with the 2.6.8 release (github tag) - the ability to integrate with third-party devices. This brings SPA operations easily to any device or software that offers a command line interface. By default, the fwknop daemon supports four different firewalls: iptables, firewalld, ipfw, and PF. But, suppose you want to have fwknopd leverage ipset instead? Or, suppose you have an SSH pre-shared key between a Linux system and a Cisco router, and you want fwknopd (running on the Linux box) to control the ACL on the router for the filtering portion of SPA? Finally, suppose that you want a stronger measure of protection for an SSH daemon that may have been backdoored, and that runs on a proprietary OS where fwknopd can't be deployed natively? The sky is the limit, and I would be interested in hearing about other deployment scenarios.

These scenarios and many others are now supported with a new "command open/close cycle" feature in fwknop-2.6.8. Essentially, fwknopd has the ability to execute an arbitrary command upon receiving a valid SPA packet (the "open"), and then execute a different command after a configurable timeout (the "close"). This allows fwknopd to integrate with any third-party device or software if open and close commands can be defined for how to interact. These commands are specified on a per-stanza basis in the access.conf file, and a set of variable substitutions are supported such as '$SRC', '$PORT', '$PROTO', and '$CLIENT_TIMEOUT'. Naturally, the IP address, port, and protocol are authenticated and decrypted out a valid SPA packet - i.e., SPA packet headers are not trusted.

Let's see an example on a Linux system ("spaserver"). Here, we're going to have fwknopd interface with ipset instead of iptables. First, we'll create an ipset named fwknop_allow, and we'll link it into the local iptables policy. If a packet hits the fwknop_allow ipset and there is no matching source IP, then the DROP rule at the end of the iptables policy implements the default-drop policy. No userspace daemon such as SSHD can be scanned or otherwise attacked from remote IP addresses without first producing a valid SPA packet.
[spaserver]# ipset create fwknop_allow hash:ip,port timeout 30
[spaserver]# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
[spaserver]# iptables -A INPUT -m set --match-set fwknop_allow src,dst -j ACCEPT
[spaserver]# iptables -A INPUT -j DROP
Now, we create a stanza in the fwknop /etc/fwknop/access.conf file and fire up fwknopd like this:
[spaserver]# cat /etc/fwknop/access.conf
SOURCE            ANY
KEY_BASE64        <base64 string>
HMAC_KEY_BASE64   <base64 string>
CMD_CYCLE_OPEN    ipset add fwknop_allow $SRC,$PROTO:$PORT timeout $CLIENT_TIMEOUT
CMD_CYCLE_CLOSE   NONE

[spaserver]# service fwknopd start
With fwknopd running and iptables configured to drop everything except for IP communications that match the fwknop_allow ipset, let's use the fwknop client from a remote system "spaclient" to gain access to SSHD on the server for 30 seconds (note that the iptables conntrack module will keep the connection open after the SPA client IP is removed from the ipset). We'll assume that the encryption and HMAC keys have been previous shared between the two systems, and on the client these keys have been written to the "spaserver" stanza in the ~/.fwknoprc file:
[spaclient]$ fwknop -A tcp/22 -a 1.1.1.1 -f 30 -n spaserver
[spaclient]$ ssh user@spaserver
[spaserver]$
So, behind the scenes after the SPA packet has been sent above, fwknopd on the server has authenticated and decrypted the SPA packet, and has executed the following ipset command. In this case, there is no need for a corresponding close command because ipset implements the timer provided by the client itself, so the client IP is deleted from the ipset automatically. (In other scenarios, the close command can be fully specified instead of using the string 'NONE' as we have above.) Here are the syslog messages that fwknopd has generated, along with the 'ipset list' command output to show the 1.1.1.1 IP as a member of the set:
[spaserver]# grep fwknopd /var/log/syslog |tail -n 2
Dec 23 15:38:06 ubuntu fwknopd[13537]: (stanza #1) SPA Packet from IP: 1.2.3.4 received with access source match
Dec 23 15:38:06 ubuntu fwknopd[13537]: [1.2.3.4] (stanza #1) Running CMD_CYCLE_OPEN command: /sbin/ipset add fwknop_allow 1.1.1.1,6:22 timeout 30

[spaserver]# ipset list
Name: fwknop_allow
Type: hash:ip,port
Revision: 5
Header: family inet hashsize 1024 maxelem 65536 timeout 30
Size in memory: 224
References: 0
Members:
1.1.1.1,tcp:22 timeout 27
In addition to the ability to swap out the existing firewall with a completely different filtering infrastructure, there are other notable features and fixes in the 2.6.8 release. The most important of these is a new feature implemented by Jonathan Bennett (and suggested by Hank Leininger in github issue #62) that allows access.conf files to be imported via a new '%include' directive. This can be advantageous in some scenarios by letting non-privledged users define their own encryption and authentication keys for SPA operations. This way, users do not need write permissions to the main /etc/fwknop/access.conf file to change keys around or define new ones.

The complete ChangeLog is available here, and the current test suite has achieved 90.7% code coverage (measured by lines).

Software Release: fwknop-2.6.7

fwknop-2.6.7 software release The 2.6.7 release of fwknop is available for download (or via the github release tag). This release adds significant support for running commands delivered by SPA packets via 'sudo' on the server, and this allows the powerful 'sudoers' syntax to filter commands that remote users are allowed to execute.

In addition, the --key-gen (key generation) mode has been added to fwknopd. This will allow better integration with Jonathan Bennett's Fwknop2 Android client - particularly when only the fwknopd server is installed on a system (as is usually the case for embedded distributions such as OpenWRT). Further, Jonathan contributed a console QR code generator, so that fwknop encryption and HMAC keys can be imported into the Fwknop2 Android client via the phone's camera. Here is an example: $ fwknopd --key-gen | ./extras/console-qr/console-qr.sh fwknop QR key code In other news, Jonathan and I will be giving a lengthy interview on Single Packet Authorization with fwknop for the FLOSS Weekly show organized by the venerable Randal Schwartz of perl fame. Tune in September 2nd at 11am Eastern time.

As usual, fwknop has a Coverity Scan score of zero, and the code coverage report achieved by the 2.6.7 test suite is available here. Note that the fwknop test suite is now achieving 90% code coverage counted by lines, and 100% code coverage counted by functions. This reflects the commitment the fwknop project makes towards rigorous security and testing quality.

Here is the complete ChangeLog for fwknop-2.6.7:

  • [server] When command execution is enabled with ENABLE_CMD_EXEC for an access.conf stanza, added support for running commands via sudo. This was suggested by Github user 'freegigi' (issue #159) as a means to provide command filtering using the powerful sudoers syntax. This feature is implemented by prefixing any incoming command from a valid SPA packet with the sudo command along with optional user and group requirements as defined by the following new access.conf variables: ENABLE_CMD_SUDO_EXEC, CMD_SUDO_EXEC_USER, and CMD_SUDO_EXEC_GROUP.
  • [server] Kevin Layer reported a bug to the fwknop mailing list that simultaneous NAT access for two different access.conf stanza was not functioning properly. After some diagnosis, this was a result of rule_exists() not properly detecting and differentiating existing DNAT rules from new ones with different port numbers when 'iptables -C' support is not available. This was against iptables-1.4.7, and has been fixed in this release of fwknop (tracked as issue #162).
  • [server] Added --key-gen to fwknopd. This feature was suggested by Jonathan Bennett, and will help with ease of use efforts. The first platform to take advantage of this will likely be OpenWRT thanks to Jonathan.
  • [server] By default, fwknopd will now exit if the interface that it is sniffing goes down (patch contributed by Github user 'sgh7'). If this happens, it is expected that the native process monitoring feature in things like systemd or upstart will restart fwknopd. However, if fwknopd is not being monitored by systemd, upstart, or anything else, this behavior can be disabled with the EXIT_AT_INTF_DOWN variable in the fwknopd.conf file. If disabled, fwknopd will try to recover when a downed interface comes back up.
  • [extras] Added a script from Jonathan Bennett at extras/console-qr/console-qr.sh to generate QR codes from fwknopd access.conf keys.
  • [build] Added --with-firewalld to the autoconf configure script. This is a synonym for --with-firewall-cmd to avoid confusion. Some package maintainers use --with-firewalld to build fwknop.