LuLu by Objective-See is a macOS firewall for outbound connections. While the built-in Apple product will protect you from network attacks from the networks around you, LuLu will give the user control over the network connections a running software on the Mac may want to open itself, e.g. to the Internet. LuLu can act as a freeware replacement for the firewall part in LittleSnitch, the other well-known security tool for the Mac. If you want to know more about LuLu, follow the link above.
In the “user-guided” mode LuLu will give the choice to create rules for a specific process with:
- either a single URL / IP and a sigle port (“Remote Endpoint”)
- or all URL’s / IP’s and all ports (“Process”)
… with the choice of allowing or blocking traffic
If you are like me, you might want to tweak those rules. And that’s where the “regex” checkbox comes into play. You can use it, for example, to allow access to all the machines in your home network.
However, the LuLu user documentation currently does a bad job to describe the regex syntax that’s expected by LuLu. Is it 192.168.1.*
as the asterisk in the “allow all” suggests? There are many variations of regular expressions, so an example would certainly be appreciated.
LuLu’s regex syntax
LuLu uses Objective-C’s NSExpression
class. You can find that documentation here. The most important elements for creating LuLu rules are:
Expression | Description | Example |
\ | “escape” special characters like * ? + [ ( ) { } ^ $ | \ . / in order to treat them as literals | 192\.168\.1\.1 |
. | placeholder for any character – exactly _one_ character! | 192\.168\.1\.... ...\.com |
a,b,c, ..A,B,C, ..0,1,2, .. | characters, numbers, symbols are treated as themselves | huf\.org |
[pattern] | match any one character from the pattern | [aeiou] |
In addition to the Expressions above there are modifiers, so you can tell LuLu to expect more than one “any character”. You place the modifier after the expression it applies to:
Modifier | Description | Example |
* | Match 0 or more times. Match as many times as possible. | |
+ | Match 1 or more times. Match as many times as possible. | |
? | Match 0 or 1 times. Prefers 1 times | |
*? | Match 0 or more times. Match as few times as possible. | |
+? | Match 0 or more times. Match as few times as possible. | |
{n}? | Match exactly n times. | |
{n,}? | Match at least n times, but no more than required for an overall pattern match. | |
{n,m}? | Match between n and m times. Match as few times as possible, but not less than n. |
Some regexamples
Expression | What it means | It Matches… |
192\.168\.1\..* | any IP address starting with 192.168.1. regardless what’s in the last octet, or whatever comes after the last dot. Note that there is a \. escaping the last dot and then the .* matching vor any amount of any character after that dot. | 192.168.1.1 |
192\.168\.1\.[0-9]{1,3}? | This is the safer version of the one above, as it only matches numbers in the last octet. | 192.168.1.1 |
192\.168\.123\.[0-9]{1,3}? | any IP address starting with 192.168.123. regardless what’s in the last octet. | 192.168.1.2 |
… more to come |
So, if your home network is 192.168.1.0/24
(e.g. using a netmask of 255.255.255.0
), the example below will tell LuLu to allow the Brave Browser to access any machine in your home network (on any port):
What’s next?
I plan to amend this blog post in a while: I think LuLu’s documentation is lacking a good explanation of basic regex and I volunteered to create something on the public Lulu Git.
I will add more examples (like URL regex-es) as I go ahead with that docu.