Integrating CrowdSec with Firewall appliances

In this article, we’ll show you how to integrate CrowdSec at the appliance level of a modern IT infrastructure thanks to Blocklist Mirror component.

The majority of modern IT infrastructures already includes some form of the security appliance. Our users requested some way to integrate CrowdSec at the appliance level, within their pre-existing ecosystem. In this article, we’ll show you how to make it happen, using the new crowdsec-blocklist-mirror component.  


Leveraging the firewall’s ability to pull IP blocklists from external HTTP URLs, we’ll deploy a crowdsec-blocklist-mirror in the network and configure the appliance to pull IP lists from it.

For this example we are going to use FortiGate, but the steps are similar for other vendors.

Deploying Blocklist Mirror

For this, you’ll need a machine that is accessible from the appliance. You can deploy the blocklist mirror in multiple ways, either by installing from a Linux package manager or deploying with docker. This machine should also be able to access the CrowdSec Local API. The Local API can either be installed on the same machine or can be deployed elsewhere.

For this tutorial we’ll assume that CrowdSec Local API is already installed and listening at port 8080. The OS being used here is ubuntu.

Install Blocklist Mirror

Make sure you have set up the CrowdSec repository. See this to learn how. Then run: 

sudo apt install crowdsec-blocklist-mirror

Or if you’re using a RPM-based Linux distribution, run 

‍sudo yum install crowdsec-blocklist-mirror

Configure Blocklist Mirror

After this, we will check and eventually modify the config file located at /etc/crowdsec/bouncers/crowdsec-blocklist-mirror.yaml

Make sure that the lapi_url parameter is correct. If your Local API is deployed on some other machine, please change the lapi_url to the appropriate address and set the lapi_key to a key generated by running the command sudo cscli bouncers add blocklistMirror on the LAPI machine.

By default the blocklist mirror server listens at, let’s change this to to make this simpler. We can do this by setting listen_uri parameter to

To load a new configuration use this command:

sudo systemctl restart crowdsec-blocklist-mirror

You can now see the blocklist being served at

You can do things like setting authentication, multiple endpoints, TLS etc by tweaking the configuration. Learn more here.

Configure firewall appliance to pull blocklist

This tutorial assumes you are using a FortiGate firewall. Please note that for other vendors steps may vary.

Configuring external blocklist

Open the FortiGate dashboard and navigate to Security Fabric -> External Connectors  and click on Create New button.

Scroll down and select Threat Feed -> IP Address and create a connector

Make sure that the appliance can access the URL. This URL should be the one where the blocklist we deployed earlier is serving the IP-list. Finally, click OK.

After a while you can see that this threat feed will be filled. These are from blocklist mirror. 

Create a firewall policy referencing the blocklist

You can now create a firewall policy/policy which will deny access to your infrastructure if the incoming IP is present in blocklist. To do this you can navigate to Policy & Objects and click on the Create New button. 

Specify the fields as required, and you need to reference the blocklist by selecting it in the Source dropdown

All you have to do next is save the policy and enable it by clicking OK.

Great job!

To sum up

In this way we leveraged CrowdSec in a firewall appliance by using blocklist mirror bouncer. You can further configure the blocklist mirror with authentication, TLS and other security goodies. If you have a question or a suggestion feel free to reach out to us on Discord.

Source :

CrowdWall, a tough Firewall for 50€ – Part 3: set up a canary device with CrowdSec

Using Orange Pi R1+, Netfilter, AdGuard and CrowdSec to preserve your security & privacy. The third part  is on how to set up a canary device that ‘tweets’ when unexpected events occur.

Welcome to the third and final part of our trilogy where the goal is to inspire and show you how to create a very efficient firewall to secure home network or your small business, which offers a serious level of security, at low cost.

The first part focuses on selecting hardware and installing the base OS.

The second part is dedicated to setting up firewall functionality, client VPN to protect your identity online, AdGuard for the entire network, DuckDNS if you don’t have a static IP as well as port knocking to close down your internet exposed services to anyone but you.

This third and final part is about how to secure your network even further with CrowdSec – how to set up a canary device that notifies you when unexpected events such as scanning occur; something you would typically never do yourself.

Part 3: Setting up a canary device with CrowdSec

The end goal of this third part is to show how CrowdSec can do cool stuff acting as a canary, but we need a few preliminary steps. We want to set up an alarming system so we know when a new system has been connected to our local network. That is a two-part thing consisting of installing ARP Watch and notifications via Pushover. After that we’ll talk about what CrowdSec can do in the sense of alarming you when odd things are happening on your network. First things first:

ARP Watch

To proceed further in securing ourselves, it would be cool to know whenever a new machine is connecting to the LAN. And since we can now get instant notifications with the above script, let’s send an alert every time a new device is detected in the LAN.

$ sudo apt-get install arpwatch

In the /etc/default/arpwatch file add lan0 (or whatever is the name of your LAN interface):


And create a file in /etc/arpwatch/lan0.iface (if lan0 is your LAN interface) to add some email addresses. Here, to reuse our pushover system, we can input the email address that is provided for your app in pushover. If you send an email to this address, it’ll be forwarded as a push notification to your phone.

$ cat | sudo tee /etc/arpwatch/lan0.iface



Where should be replaced by the email address listed under your login. As usual, end with CTRL + D to return to your shell.

Setting up a notification system 

Pushover is an iOS and Android app that allows you to send plenty of notifications to your phone for free (around 7500 per app per month). You can obviously use it wherever you feel, for whatever reason. In the above crontab script you can, for example, notify yourself when the machine boots. But we may also want to know when a new mac address is registering in our network or if a port scan was fired from within the LAN area (which is quite bad news, see below section “Protecting yourself even from (w)LAN devices”

So, once you have set up your Pushover App and account online, you should have a user token and an app token:

Next, create an APP and locate your App token. 

Create a script to send yourself notifications:

$ cat > /usr/local/scripts/

cut/paste the script below, finish it with CTRL+D and issue the classical chmod:

$ chmod 755 /usr/local/scripts/

curl -s -F "token=YOUR_APP_TOKEN" -F "user=YOUR_USER_TOKEN" -F “title=$1” -F "message=$2"

Now to send yourself a message, you just need to type in:

$ ./ "Most kittens" "Are too cute"

And you should get this on your phone screen:

Protecting yourself even from (w)LAN devices

One thing you cannot really trust, but nevertheless like to have, are connected speakers like Sonos, your voice assistants like Alexa or even your IP cameras or just your smartphone. All those IoT devices make our life easier but also come with a substantial amount of potential security issues.

I’ve tried several approaches here, but none is at the same time realistic in terms of daily usage and secure enough. Segregating all those machines in a sub-lan (or rather a sub-wlan for most of them) using a different vlanid and trying to limit the exposure to your secure devices is a complicated task and usually cripples the usability we all appreciate as well.

One simple example would be your Sonos speakers. You want them to connect to online streaming systems like Deezer or Spotify and be able to control them with your phone through airplay. At the same time, if (when) a hacker is able to upload a rigged firmware by breaching into Sonos systems, they can infect your local speakers and establish a local presence in your LAN, scan, harvest, invade, etc. The same is true of most voice assistants, IP cameras, smartwatch, smartphone, TV, and generally speaking of *any* IoT devices.

Now if you isolate them in a sub (w)LAN, you’ll not really be able to control them comfortably since anytime a friend comes over you’d have to add a rule to your firewall as well as probably other cumbersome modifications. 

So to be more realistic, I decided to proceed in a different way. Let’s not suspect those things right away but rather detect if (when) they start to behave suspicious. Apart from cameras that should not be able to access the Internet and send private video streams across the globe to god knows how, we can just monitor our IoT devices. Most of those devices could be let loose and if ever they are compromised a hacker will very likely use them to scan and compromise your network. 

There are other more complicated ways, like having different, firewalled vlans, tag packets, and using multicast forwarding, but beyond complication, you’re not always sure not to lose functionalities of some of your IoT devices. Also this method is more generic (although less protective).

Using CrowdSec to setup a Canary device

The concept is fairly old and simple. Coal miners during the 19th century used to bring a canary with them down the mine and if a gas leak would occur (which was odorless) it’d kill the canary and miners would evacuate, hopefully before a potential blast.

Nowadays, and in an IT context, a canary is a device that is stealthy sitting in your network that should bever be queried. It’s doing nothing, hosts no service and there is no reason in the world it should ever be poked. If it is accessed, that means something/someone in your network is scanning it and 99.999% of the time, this is bad news. 

If a hacker ever hijacks any of your IoT devices, no matter the method, it’s very likely that they’ll scan your LAN. In this case your canary should be triggered and alerting you. We have all the needed tools to do it already, either locally on the firewall we are building, or on a separate similar pi device with just one LAN interface. No matter how you choose to do it, CrowdSec will be a very useful tool to set up the canary and our pushover script can alert us. After all, our scenario is known : multiport scan and it already exists on the hub. The bouncer (the component that deals with the detect menace) also exists: we’ll simply use the one that triggers a script, here our script to send us a notification using pushover.

Remember we added those lines in our firewalling script:

define antilanscan        = { 22, 8080 } 

And in the Input section:

iif $lan tcp dport != $fwopenports log prefix "LAN SCAN:"  drop

Well, basically they say that if ports on the LAN interface are contacted on any other ports than 22:TCP and 8080:TCP (8080 is just an example), then someone is scanning you and you should drop the packets. But the trick here is that since we drop the packet, CrowdSec iptables multiscan scenario,  crowdsecurity/iptables-scan-multi_ports , will catch the signal.will catch the signal.


CrowdSec will spot hacking attempts by looking at the logs generated on the OPI. If you intend to run more services than just those in this tutorial, remember to reconfigure it (either by running the installation wizard again or by adding it manually to /etc/crowdsec/acquis.yaml). If you choose the latter method make sure to install a suitable scenario either using cscli or by visiting

In one sentence, CrowdSec is crowd powered cyber security software. It’s an open source & free IPS system. It detects attacks in your logs, bans the IP and then shares the aggressive IP with the community so that everyone else is also protected against this aggressor. As well, your instance of CrowdSec benefits from the global sightings of the network.

While CrowdSec is available in Debian (but not Ubuntu) it’s highly recommended to add our own repo since the available package has been deprecated since last OS release. To do that follow the (easy) instructions at our documentation site. Once added, simply install the CrowdSec package and the nftables bouncer:

$ sudo apt-get install crowdsec 
$ sudo apt-get install crowdsec-firewall-bouncer-nftables

Installing both packages with one command can be a bit of a hassle since we can’t control the order of which packages are installed. So to make sure that the agent is installed first, we do it like this. This ensures that the bouncer is added automatically to the CrowdSec agent.

The installer will pretty much do all the job for you. After installing add the netfilter log collection by issuing this:

$ sudo cscli collections install crowdsecurity/iptables
$ sudo systemctl reload crowdsec

(note: In spite of the name, the collection is also valid for nftables)

Ok we’re all set on that front. CrowdSec will create two nftables IP sets named crowdsec and crowdsec6, containing ipv4 blocklist for the first one and ipv6 for the latter. Basically those sets are automatically banned by the firewall bouncer daemon residing in memory. If someone agresses your machine and tries to port scan it, scan your web server or bruteforce your ssh / ftp or other accesses, not only will it get banned, but its IP will also be reported to the central CTI. In return, we do benefit for free from the knowledge of the Crowd as well and our IP sets are automatically filled with new dangerous IPs sent by the central API of CrowdSec. We defend, we partake and in return we are even better defended by all the other members. Neat.

You can obviously block those IP sets yourself wherever you feel. 

The configuration resides in /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml and is very straightforward:

mode: nftables
pid_dir: /var/run/
update_frequency: 10s
daemonize: true
log_mode: file
log_dir: /var/log/
log_level: info
api_url: http://localhost:8080/
disable_ipv6: false
deny_action: DROP
deny_log: true
deny_log_prefix: "crowdsec:"
  - input
  - output
  - forward

Note: you won’t need to edit the file; this is the default configuration.

So not only will your (potential) services be protected, but your firewall output will also generate bans for people trying to hack you, share their IP to protect everyone else and CrowdSec will send you dangerous IPs constantly to be blocked directly in your firewall.  One stone, three birds. Bingo!

Next, we need to set up the custom bouncer that comes with CrowdSec. Luckily it’s also available as binary package on arm-based devices running debian-based distros:

$ sudo apt install crowdsec-custom-bouncer

In its essence the custom bouncer simply executes a custom script whenever a scenario triggers.

Obviously, we’re using it to execute the script whenever a scenario triggers.

After installation, we need to edit the config file located in/etc/crowdsec/bouncers/crowdsec-custom-bouncer.yaml:

bin_path: /usr/local/scripts/
piddir: /var/run/
update_frequency: 10s
cache_retention_duration: 10s
daemonize: true
log_mode: file
log_dir: /var/log/
log_level: info
api_url: http://localhost:8080/

You would only need to edit the bin_path item in the configuration file above as everything else, even registering the bouncer with the agent has been taken care of by the install script run automatically upon installation. 

Copy/paste the content of the script after this command to ensure  that the script is added to the file system correctly:

$ cat | sudo tee /usr/local/scripts/

[[ `echo $2 | cut -f 1,2 -d"."` == "192.168" ]] && curl -s -F "token=" -F "user=" -F "title='LAN Scan'" -F "message=Scanned by $2"

Remember to chmod 755to make the script executable.

Now, anytime a scan would be initiated from the LAN, we are notified directly on our Phone. Our Canary is alive and kicking!


For a marginal budget, you can protect your family, your work and your privacy. All it takes is 50€ and a couple of hours. You’ll learn a lot, be autonomous and better protected. Doesn’t it sound like a fair investment of your time in 2022?

Source :

CrowdWall, a Tough Firewall for 50€ – Part 2: The Software Stack

How to set up an effective firewall and preserve your security & privacy with Orange Pi R1+, Netfilter, AdGuard and CrowdSec.

Welcome to the second part of our trilogy where the goal is to inspire you to create a very efficient firewall to protect your remote work environment, family, or your small business, which offers a serious level of security, at a low cost.

Have you not yet read the first part that focuses on selecting hardware and installing the base OS it’s not too late. Find it here.

This second part is focused on how to set up firewall functionality, setup client VPN to protect your identity online, setting up AdGuard for the entire network, DuckDNS if you don’t have a static IP as well as port knocking which is a cool way to close down your internet exposed services to anyone but you (or anyone else who knows the secret combination to enter). The third and final part will be about how to secure your network even more with CrowdSec – how to set up a canary device that ‘tweets’ when unexpected events like for instance port scanning occurs; something you would typically never do yourself.

It’s also being part of a larger project, CrowdSec, which is blocking Internet attacks and sharing IPs that launched them. You protect yourself and others at the same time. In essence, this comprehensive guide will show you how to:

  • Create security robust enough to resist even if passwords are compromised
  • Create a reliable hardware environment for your firewall
  • Install the OS on it and create a rock-solid Firewall to protect your activities
  • Add CrowdSec to protect your WLAN services you’d like to expose over the Internet and detect if any local IoT device is going rogue (e.g. cams, assistants, connected speakers, etc.)
  • Allow external access to DMZ-like services to control your home on distance and access your firewall
  • Add a VPN to protect your anonymity online
  • Add an anti-advertisement & anti-tracking system

Part 2: The Software stack

The firewall

It’s already in there, provided by the netfilter subsystem, which is integrated into the kernel. The nft (nftables) command is here to help us interact with the netfilter layer. The following script is commented so that you can easily modify it according to your needs and projects or even port it to iptables (nftable  predecessor). All scripts can be found here.

Out of the box, it handles:

  • Multiple internet connection with a dynamic routing table capable of sending packets to one or the other connection based on your rules (destination port, src or destination IP, protocols, etc.)
  • Protection against usual network shenanigans
  • Inbound, forward and outbound traffic filtering
  • CrowdSec integration to defend your exposed services and have a Canary to detect if your LAN is being scanned
  • Port knocking integration so that you can simply use a port knocking app to unlock access to your network from wherever you are.

Just cut/paste it from this doc:

$ cat | sudo tee /etc/nftables.conf

Here is the script to adapt and copy/paste:

#!/usr/sbin/nft -f

#Part 1: Setting statics
define wan                     = eth0
define lan                       = lan0
define vpn                      = tun0
define localhost            = lo
define vpn_net              =
define vpnserver           = tun1
define vpn_server_net  =
define machine1           =
define machine2           =
define antilanscan        = { 22, 8080 } #Part 8: Anti lan scan
define cameras             = {, }
define icmp_v6          = { destination-unreachable, echo-reply, echo-request, nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, packet-too-big, parameter-problem, time-exceeded }

#Part 2: Reset nft tables
flush ruleset

#Part 3: NAT
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100; policy accept;
      iif $wan tcp dport 2222 dnat to $machine1:22 # incoming connexion on port 2222 will be forwarded to  on 22
      iif $wan tcp dport 5001 dnat to $machine2      # sames port 5001 and but this time port is 5001 to 5001, no change
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
      oif $wan snat to
      oif $wan2 snat to
      oifname $vpn masquerade # snat to $vpnip
      oifname $vpnserver snat to

#Part 4: Creating IP sets
table inet filter {

  set whitelist_candidates {
    type ipv4_addr . inet_service
    flags timeout

  set whitelist {
     type ipv4_addr
     flags interval, timeout

  set whitelist_portknockd {
     type ipv4_addr
     flags timeout

  chain input {
    type filter hook input priority 0; policy drop;
      icmpv6 type $icmp_v6 accept
    #Part 5: Portknocking (next 4 lines)
      tcp dport 314 add @whitelist_candidates {ip  saddr . 18 timeout 2s}
      tcp dport 18 ip saddr . tcp dport @whitelist_candidates add @whitelist_candidates {ip  saddr . 939 timeout 2s}
      tcp dport 939 ip saddr . tcp dport @whitelist_candidates add @whitelist_candidates {ip  saddr . 101 timeout 2s}
      tcp dport 101 ip saddr . tcp dport @whitelist_candidates add @whitelist {ip saddr timeout 180s} log prefix "Portknocked: "
      ct state related,established            accept
      iif $lan tcp dport != $fwopenports log prefix "LAN SCAN:"  drop #Part 8: Anti lan scan
      ip saddr @whitelist                            accept
      ip saddr @whitelist_portknockd      accept
      iifname $lan                                       accept
      iifname $localhost                            accept
      iifname $vpnserver                           accept
      iifname $wan ip saddr != @whitelist                             drop
      iifname $wan ip saddr != @whitelist_portknockd       drop
      iifname $wan ct state invalid                                        log prefix "Invalid packet:" drop
      iif != lo ip saddr                                            log prefix "Fake localhost:" drop

  chain forward {
    type filter hook forward priority 0; policy drop;
    #Part 6: Prerouting (next two lines)
      iifname $vpn meta l4proto udp ip daddr $machine1 udp dport 22 accept
      iifname $vpn meta l4proto tcp ip daddr $machine2 tcp dport 5001 accept
    #Part 4: Creating IP sets (next two lines)
      ip saddr @whitelist                       accept
      ip saddr @whitelist_portknockd accept
      iif $lan                                            accept
      iifname $vpnserver                      accept
      ct state established,related       accept
      ip saddr $cameras log prefix "Camera trying to exit:" drop
      ct state invalid log prefix "Invalid packet:" drop

  chain output {
    type filter hook output priority 0; policy accept;
#Part 7: Mangling
table ip mangle {
  chain prerouting {
    type filter hook prerouting priority -150; policy accept;
      mark != 0x0                                               meta mark set ct mark
      ip saddr $machine1 tcp sport 10001    meta mark set 0x2
      ip saddr $machine1 udp sport 10001   meta mark set 0x2
      ip saddr $machine1                                meta mark set 0x1
      ip saddr $machine2                                meta mark set 0x4

  chain postrouting {
    type filter hook postrouting priority -150; policy accept;
      ct mark set mark

After inserting it, save the file by pressing CTRL+D.

This version is a simplified version of the firewall script available from the repo above, but the most important part is here already. This nftables.conf file would not be enough by itself to handle several possible routes. Be sure to also use the ip rules script to create your routing tables, see below, section IP route.

NFtables (netfilter) Firewall details

  • Part 1 are basic variable definitions.
  • Part 2 resets all nft tables. (Used to take 10 lines with Iptables)
  • In part 3 (NAT) we are defining what happens to packets that are incoming and destined to another machine behind the firewall. They are dealt with very early in the filtering process, in a prerouting chain. The postrouting chain is about telling what IP should be used for translating IPs coming from various subnets.
  • The second table, filter, is part 4 that create IP sets. They are tables that contain IP addresses, sometimes with expiry dates. Three sets are created, one for potential candidates to whitelisting, the second for confirmed whitelisted IPs and the third will be used in conjunction with port knocking. The reason for creating two different whitelists of IPs is that the port knocking integrated in this NFT configuration (part 5) will only store the IP that knocked. Logical? No, not really. But CGNAT, used by telecom operators to run 4G networks, ruins it all and usually, it’s not a 1:1 IP translation but a range of IP that is used. So when your phone is port knocking 3 ports quickly, it’s usually with one IP but then when you connect on your SSH port, another IP is used. Luckily, they often sit in the same /24 range. The problem doesn’t exist with IPv6 obviously. So knockd will fill the second set with a range and the first one is still useful when you connect from elsewhere like a hotel. (I didn’t find any way to add a range to the set directly from an nft configuration file)
  • Part 6 is related to prerouting. It’s not enough to redirect the connection since the packet is passing two interfaces, we also need to accept this in the forward rules.
  • Part 7 is mangling. This is where we instruct the firewall to mark packets according to our own rules. 0x03 is the VPN server you host yourself and where you receive inbound traffic, 0x02 is the VPN client which you use to establish an outbound tunnel through a VPN provider. It’s through here you send the traffic of machine 1. In this example, we want machine1 to be using connection 2 when it’s starting a connection on port UDP or TCP 10001, otherwise it will be using connection 1. Machine 2 will always use your alt connection (here marked as 0x4) and machine 1, except for ports 10001 will use connection 1. This can be adapted with ports, source addresses, destination addresses, protocols, etc. (Note that the table has the highest priority and will be “executed” first, before all other rules). Use cases are easy here: you can send your professional workstation packets through a dedicated connection for example. Or send all your peer-to-peer traffic through a VPN or your TV IP through a VPN to avoid Geo limitations, etc. See the IP route section to understand fully how nft mangle + IP route cooperate here.
  • Part 8, Anti lan scan will be covered later on in this guide, but the global concept is to watch for unusual port scans, coming from our LAN-facing ethernet adapter, that would denote an IoT device being compromised or a hacker doing a lateral move in your network (classic in Ransomware scenario). We’ll have a canary setup here, see below for a more detailed description.

Obviously, all those rules are given as examples but it should be fairly easy for you to adapt them to your own context.

Port knocking

So this script handles port knocking by itself with the lines tagged in yellow, but the CGNAT problem forces us to have a fallback plan. We’ll use knockd to handle the matter on our machine.

But why is port knocking in the first place?

Well, take for granted that any application you expose might have an unknown security flaw. Or that your passwords are compromised. If the attacker doesn’t have access to the application port in the first place, even if he knows your pass or has a secret “headshot” 0 days exploit to launch, with port knocking he cannot even try in the first place, except if he uses the exact same IP as you do. This very heavily limits the risks of getting compromised. Also, using your 4G connection is far less risky than connecting to a Hotel (or public place) Wifi. But how to just allow a temporary connection from those locations? Well, port knocking is the (very underrated) key.

So before connecting to your machine, you will just launch a little app that will port “knock” your machine, nicely whitelisting the public IP you’re using and give you access to VPN, SSH, RDP, whatever you want.

KnockonD will do nicely on iOS, Knock on Ports for Android). It sends a stream of packets, in a certain order, to add your current IP address in a set that is whitelisted in the firewall. (Careful, some ISPs (like broadband carriers) are doing CGNAT, which can cripple this technique, but we’ll try to put a workaround together)

On the OPI you just need to run:

$ apt-get install knockd

And edit the configuration file (/etc/knockd.conf) as follows. Modify to your own port sequence:

        logfile = /var/log/knockd.log
        interface = eth0


sequence = 17:tcp,19:tcp,39:tcp,105:tcp seq_timeout = 10 command = nft add element inet filter whitelist_portknockd “{ `echo %IP% | cut -f1,2,3 -d “.”`”.0/24″ timeout 180s }” tcpflags = syn


sequence = 443:tcp,25:tcp,53:udp,80:tcp,53:udp,80:tcp,443:tcp seq_timeout = 10 command = nft add element inet filter whitelist_portknockd “{ `echo %IP% | cut -f1,2,3 -d “.”`”.0/24″ timeout 180s }” tcpflags = syn

Two sequences here, one classic and another one that is compatible with heavily filtered networks that won’t allow you to access all ports freely. Both add not just your IP but your IP in a 24 range in the whitelisted set. This one is really made to address the pesky CGNAT problem.

IP Route

You also need a script that will create those multiple routing tables, and that will be able to use the marks we set in the script (part 7 in the nftables script).

Here is the script creating multiple routing tables, allowing different default routes for different usages. It’s also available from my GitHub:

Note: If you don’t have multiple wan connections like me, adjust accordingly by removing all occurrences of WAN2.


# Provides:                  multiroute
# Required-Start:        $network
# Required-Stop:        $network
# Should-Start:
# Should-Stop:
# Default-Start:            2 3 4 5
# Default-Stop:            0 1 6
# Short-Description:    Multiroute manager
# Description:              Manage multi-routing

   VPN=`ifconfig|grep tun0`
   VPNSERVER=`ifconfig|grep tun1`
 [[ ! -z "$VPN" ]] && VPNIF="tun0" && VPN=1 && VPNCLIENTIP=`ip -o addr | grep -v inet6 | grep tun0 | awk '{split($4, a, "/"); print a[1]}'` &&  VPNCLIENTROUTE=`ip route show|grep -v inet6 | grep "tun0 proto" | cut -f 1 -d " "`
  [[ ! -z "$VPNSERVER" ]] && VPNSERVERIF="tun1" && VPNSERVER=1 && VPNSERVERIP=`ip -o addr |grep -v inet6 | grep $VPNSERVERIF |awk '{split($4, a, "/"); print a[1]}'` && VPNSERVERROUTE=`ip route show |grep -v inet6 | grep $VPNSERVERIF | cut -f 1 -d " " | head -1`

  ip rule del from all fwmark 1 2>/dev/null
  ip rule del from all fwmark 2 2>/dev/null
  ip rule del from all fwmark 3 2>/dev/null
  ip rule del from all fwmark 4 2>/dev/null
  ip rule del lookup maincnx    2>/dev/null
  ip rule del lookup vpnclient  2>/dev/null
  ip rule del lookup vpnserver  2>/dev/null
  ip rule del lookup altcnx     2>/dev/null
  ip route flush table maincnx
  ip route flush table vpnclient
  ip route flush table vpnserver
  ip route flush table altcnx
  for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > "$i"; done # To avoid packet drop

  [[ $VPN ]] && echo -e "$ORANGE -> VPN IS UP (route: $VPNCLIENTROUTE, on dev: $VPNIF, ip: $VPNCLIENTIP) $END"

  ip route add table maincnx default dev $WAN via
  ip route add table maincnx dev $LAN src
  ip route add table maincnx dev $WAN src
  ip route add table maincnx dev $WAN2 src
  [[ $VPN ]] && ip route add table maincnx $VPNCLIENTROUTE dev $VPNIF src $VPNCLIENTIP
  [[ $VPNSERVER ]] && ip route add table maincnx dev $VPNSERVERIF src
  ip rule add from table maincnx

  [[ $VPN ]] && ip route add table vpnclient default dev $VPNIF via $VPNCLIENTIP
  [[ $VPN ]] && ip route add table vpnclient $VPNCLIENTROUTE dev $VPNIF src $VPNCLIENTIP
  [[ $VPN ]] && ip route add table vpnclient dev $LAN src
  [[ $VPN ]] && ip route add table vpnclient dev $WAN src
  [[ $VPN ]] && ip route add table vpnclient dev $WAN2 src
  ip rule add from $VPNCLIENTIP table vpnclient

  [[ $VPNSERVER ]] && ip route add table vpnserver default dev $VPNSERVERIF via $VPNSERVERIP
  [[ $VPNSERVER ]] && ip route add table vpnserver dev $LAN src
  [[ $VPNSERVER ]] && ip route add table vpnserver dev $WAN src
  [[ $VPNSERVER ]] && ip route add table vpnserver dev $WAN2 src
  [[ $VPNSERVER ]] && ip route add table vpnserver dev $VPNSERVERIF src
  [[ $VPNSERVER ]] && ip rule add from $VPNSERVERIP table vpnserver

  ip route add table altcnx default dev $WAN2 via
  ip route add table altcnx dev $LAN src
  ip route add table altcnx dev $WAN src
  ip route add table altcnx dev $WAN2 src
  ip rule add from table altcnx

  ip rule add from all fwmark 1 table maincnx
  [[ $VPN ]] && ip rule add from all fwmark 2 table vpnclient
  [[ $VPNSERVER ]] && ip rule add from all fwmark 3 table vpnserver
  ip rule add from all fwmark 4 table altcnx
  ip route flush cache

  for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > "$i"; done # To avoid packet drop
  echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null

case "$1" in

  [[ $VPN ]] && sleep 5 # Wait for VPN to be up if not yet started when the firewall script kicks in
  /usr/bin/logger -t "Multi route" "Starting" -p4
  /usr/bin/logger -t "Multi route" "VPN CLIENT DETECTED, ADDING RULES" -p4
  /usr/bin/logger -t "Multi route" "VPN SERVER DETECTED, ADDING RULES" -p4
  exit 0

  /usr/bin/logger -t "Multi route" "Stopped" -p4
  echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null
  ip rule del from all fwmark 1 2>/dev/null
  ip rule del from all fwmark 2 2>/dev/null
  ip rule del from all fwmark 3 2>/dev/null
  ip rule del from all fwmark 4 2>/dev/null
  ip route flush cache
  exit 0

  /usr/bin/logger -t "Multiroute" "restart initiated" -p4
  $0 stop
  sleep 1
  echo -e '\n'
  $0 start

  echo -e "$YELLOW Usage: /etc/init.d/ {start|stop|restart}$END"
  exit 1

exit 0

The script is an old-fashioned SysV init script that goes into /etc/init.d after you’ve made it executable with chmod 755 and will be executed during startup.

This script basically creates four different routing tables. So instead of having just one “default route” for all your machines, your firewall now has four different tables, each containing a set of specific routing rules. So if you mark a packet with 0x2, (see in the nftables configuration, the mangle part) the machine will ship it through the VPN connection. If you tag it with 0x4, it will use your alternate connection, say a 4G for example. The tag 0x3 will be for the VPN Server and the 0x2 for VPN client. It’s just magic how many opportunities this kind of IPtables / Nftables mangling system, coordinated with IP routing can open.


We speak here of a client VPN. A VPN that you subscribed to and want to be able to use in certain situations, or more precisely with certain packets. If you want to bypass a geographical lock from some TV broadcasters or Netflix or use some protocols rather on an anonymous connection than the usual one, or just to preserve your anonymity this is the way to do it.

Once you find your dream VPN provider, they will most likely give you files to set up your VPN connection, and usually, they are made for both Wireguard and OpenVPN. I will show you how to install and configure the latter.
You will just need to install OpenVPN, upload those files (usually a .conf file also embedding all certificates and a user.pass file with the credentials) in the /etc/openvpn directory, enable openvpn in /etc/default/openvpn and you should be able to connect.

$ sudo apt-get install openvpn
$ sudo sed -i '/#AUTOSTART="all"/s/^#//g' /etc/default/openvpn

A typical OpenVPN client configuration looks like this:

dev tun
proto udp
remote [OPENVPN SERVER IP] 1194
resolv-retry infinite
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
ping 15
ping-restart 0
reneg-sec 0
comp-lzo no
log /var/log/openvpn.log
remote-cert-tls server
auth-user-pass /etc/openvpn/user.pass.vpn
verb 3
cipher AES-256-CBC
auth SHA512
script-security 2
up "/etc/init.d/firewall restart"
down "/etc/init.d/firewall restart"


key-direction 1

# 2048 bit OpenVPN static key

There is a minor security vulnerability here. Using the auth-user-pass /etc/openvpn/user.pass.vpn file is not ideal. This file contains your credentials for connection in plaintext to avoid providing them manually during initialization of the VPN. This plaintext isn’t encrypted and could expose your credentials if your firewall is ever seized or you become prone to a very critical vulnerability, like a 0day buffer overflow of some sort, would successfully compromise your firewall. On my end, I live with it, but you’ve been warned.

PS: The firewall is automatically reloaded when the VPN goes up or down to add the proper rules.

Create the directory for custom scripts

We need a directory to save custom scripts. Create /usr/local/scripts and sudo chown it to your current user for convenience.


While we are at it, let’s make this machine easy for you to locate online. Should you have a dynamic IP address, just crash by DuckDNS, create yourself an account and register your IP and subdomain for free. Here is a little script to help you update it on a regular basis:

$ echo url="" | curl -k -o /var/log/duckdns.log -K -

The token is found under your login at after clicking the ‘>>> reCAPTCHA <<<’ button.

Use the script by saving it to e.g./usr/local/scripts/duckdns.shchmod 755 it and execute it every half an hour with a crontab like this:

$ crontab -e

$ crontab -e

It should look somewhat like this:


#m   h  dom mon dow      command
17   *   *   *   *       cd / && run-parts --report /etc/cron.hourly
45  10   *   *   *       test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47   6   *   *   7       test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52   6   1   *   *       test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
30   *   *   *   6       /usr/local/scripts/

Only the last line is added by us. The first lines are usually present default. YMMV.

Note: In order for the user who executes the script to have permissions to write a log file in /var/log it needs to be part of the syslog group. This can easily be done by running sudo addgroup <user> syslog.


Adguard is a really cool piece of software that is basically running a DNS that resolves all advertisement servers to (resulting in many ads not being shown. Hooray!). You install it on your LAN and instead of connecting directly to or your ISP DNS, you tell all your LAN users to rather use it.

If your request is not going toward an Ad server, it’s just resolved by the DNS you instructed Adguard to use. Otherwise, your client, say your mobile phone, will just ask this ad from (himself), getting nothing in return. With this, a chrome plugin like Adblock as well as youtube Adblock and advertisement will be a thing of the past.

I highly recommend visiting their Github here. Installation is fairly easy:

$ curl -s -S -L | sh -s -- -v

Note: The script will obtain root permissions and ask for those as needed.

Now we have a DNS relay running on localhost.

You can also just use the DNS servers of Adguard directly. These are present at and

If you want to finalize your setup of Adguard, just connect with a browser to the firewall (likely on at this stage), on port 3000. It should look like this:

Adguard wizard

Use the wizard to set up Adguard and continue the tutorial.

Adding a DHCP server to finalize our LAN setup

Well, now that most of the tools are up & running, let’s have a DHCP running to give addresses to machines in the LAN, which your ISP box won’t do anymore since it’s on the other side of the firewall. While we are at it, we can now ship IP addresses with the local Adguard DNS to get rid of ads.

$ sudo apt-get install isc-dhcp-server
$ cat | sudo tee /etc/dhcp/dhcpd.conf

Copy/paste this (and end with CTRL+D):

deny declines;
log-facility local7;

subnet netmask {
  interface eth1;
  option routers;
  option broadcast-address;
  option domain-name-servers,; # Local adguard DNS proxy + online adguard DNS
  default-lease-time 259200;
  max-lease-time 604800;

host machine1 {
  hardware ethernet 00:11:22:33:AA:DD;

host machine2 {
  hardware ethernet 85:55:85:42:12;

Given as an example, I advise you to have static IPs directly like for machine 1 & 2 in this file if you can. This makes it easier to locate them later. We point the DNS to our local instance of Adguard and, as a backup also to their online DNS if our own is not replying fast enough.

So this was part 2 of our trilogy of how to install the CrowdWall. I hope you enjoyed reading it as much as I enjoyed writing it. Stay tuned for part 3 where things really start to get interesting once we add CrowdSec to the mix.

Source :

CrowdWall: a Tough Firewall for 50€ – Part 1

How to set up an effective firewall and preserve your security & privacy with Orange Pi R1+, Netfilter, AdGuard and CrowdSec.

Welcome to the first part of our trilogy where the goal is to inspire you to create a very efficient firewall to protect your remote work environment, family, or your small business, which offers a serious level of security, at a low cost.

This first part will be centered around the basics: choosing hardware and installing the operating system and doing basic configuration. Part two will be on how to set up firewall functionality, setup client VPN to protect your identity online, setting up AdGuard for the entire network, DuckDNS if you don’t have a static IP as well as port knocking which is a cool way to close down your internet exposed services to anyone but you (or anyone else who knows the secret combination to enter). The third and final part will be about how to secure your network even more with CrowdSec – how to set up a canary device that ‘tweets’ when unexpected events like for instance port scanning occurs; something you would typically never do yourself.

It’s also being part of a larger project, CrowdSec, which is blocking Internet attacks and sharing IPs that launched them. You protect yourself and others at the same time. In essence, this comprehensive guide will show you how to:

  • Create security robust enough to resist even if passwords are compromised
  • Create a reliable hardware environment for your firewall
  • Install the OS on it and create a rock-solid Firewall to protect your activities
  • Add CrowdSec to protect your WLAN services you’d like to expose over the Internet and detect if any local IoT device is going rogue (e.g. cams, assistants, connected speakers, etc.)
  • Allow external access to DMZ-like services to control your home on distance and access your firewall
  • Add a VPN to protect your anonymity online
  • Add an anti-advertisement & anti-tracking system

Needed skills

You should have basic knowledge of Linux and Shell. If you can download and install a Linux distribution by yourself, nothing should sound overly difficult.

Enough talk. Let’s get started!

Part 1: Choosing hardware and installing OS

Needed hardware

The CrowdWall is among the cheapest possible decent security setup you can get.

The components are correct but your networks will not be very isolated internally. The advanced version offers both better security and performance. The “expert” CrowdWall is made to protect a small business of tens of coworkers.

In the basic CrowdWall setup, you can also add cost-efficient Wifi Access Points like this Tenda (around 45€) or add a third Ethernet interfaceor Wifi connection (over USB).

Should you want to organize a large distribution of the CrowdWall, say equip all your remote working force with it, you can look at the GL Inet products line. They are nicely priced if you go for volumes and offer real good performances for the money.

Table 1: Possible variations

The Orange PI R1+ benefits from very interesting characteristics beyond its small price tag. It runs on a 1.5 GHzGhz SoC with 1 GB ram which is enough for the job. It also provides two ethernet ports, has marginal power consumption, and even provides a USB port and a GPIO. (The Rock Pi-E can also do the job nicely and offers a bigger GPIO but for slightly more money)

Photo 1, an Orange PI 1 R+, 2 & 3, its 3D printed case

If you don’t have an Orange PI R1+ other similar single-board computers can be used instead: Orange PI R1+ LTS (Same SOC, slower, low power RAM), NanoPi R2SNanoPi R4SROCK Pi E, or even a Raspberry Pi 3 or 4 with an extra ethernet plug. In the latter case, you probably want to use one connected via HAT. In either case, you won’t be able to use the same fancy case but would have to design your own or adapt mine.

Setting up your firewall

Going forward I will describe setting up using Orange PI R1+.

Physical setup

Just plug your Internet connection (usually the Box from your ISP) to the lower port (the one down, closest to the GPIO, on the above picture) and your LAN (usually your switch) to the left port above picture.

Plug the Orange Pi (from hereon ‘OPI’) to the Power supply, or if you want for redundant power supply, power up the OPI from the power bank and the bank from a regular power plug. This should give you some hours before the firewall shuts down and eventually give it time to notify you beforehand.

The physical setup should look like this:

Figure 1: The set-top box, local LAN & WAN setup, you can leave the Box Wifi for home & family use and dedicate the other Access Point to business.

Software initial setup

1/ At the time of writing the newest supported version of Armbian is Armbian 22.05 Jammy, based on Ubuntu 22.04 Jammy Jellyfish. It doesn’t matter too much if the version of Armbian you install on is based on Debian or Ubuntu as long as it’s a supported version. Download it here. Other Debian-based distros like should also work although this hasn’t been tested.

2/ Download a USB stick/SDcard flasher. Balena etcher is great for this. It’s very straightforward to use and runs on both Windows, Linux & macOS environments.

Remember we are on a headless device with no HDMI port, so we are going to use it in command-line (CLI) mode only. That being said you could get a serial TTY console, but the effort and complication is really not worth the time (unless you need it for debugging).

After flashing and booting your appliance you should connect it to the eth0/WAN ethernet plug (furthest away from the power connector). You will have to check your DHCP server which IP is assigned to your CrowdWall (it’s usually residing on the box you got from your internet provider). The default ssh login is root and the password is 1234. After connecting to it you will be walked through an installation wizard that will set you up with a personal user account and sudo.

The other ethernet interface will be called lan0. And for everything to work you will need to configure it.

Setting up lan0

Configure a static IP on lan0 by editing /etc/network/interfaces and adding the following:

auto lan0
iface lan0 inet static

Start lan0 with the new configuration by typing sudo ifup lan0. Verify that the lan0 interface is up by typing ip addr show lan0 in a terminal.

Setting up your Internet Box in DMZ mode (Full NAT)

No two providers have the same box, OS, hardware, interface etc. hence no universal cut/paste commands, or screenshots to help here.

The feature you’re looking for is usually named “DMZ IP”. Enabling this feature requires you to input a LAN IP address, which will be the one to which all the Internet traffic will be redirected, without filtering. This is essential if you later intend to accept connections from the Internet to your home by exposing some services, like your home automation, NVR / IP cameras, or even a VPN server.

There are other ways of doing this, like enabling ports one by one, probably in a “Network”, “NAT” or “Network Address Translation” tab, but this requires you to get into the box interface every time you need to update a port, it’s error-prone and less flexible.

Basically, where/when possible, one shouldn’t trust the ISP’s Box either. So if you can bypass it totally, do it. Often enough, specifically in an FDDI context, you can just use the little modem that connects to your fiber and connects with Ethernet to your box, and plug yourself right in instead of the ISP box. There are tutorials online, just Duckduckgo (same as Googling but with privacy) for “how to bypass [BOX PROVIDER NAME] box”.

Absolutely not mandatory and mainly interesting for paranoïd people, but if you can do it, this is an even safer setup, even though bringing back the TV and Phone feature (should you want them), could be slightly more complicated, but far from impossible for advanced users.

So this was part 1 of our trilogy of how to install the CrowdWall. Part 2 will continue with configuring your installation with essential firewall functionality like traffic filtering, anti-ad features, and much more. Stay tuned!

Source :

Protect your WordPress sites with CrowdSec

You can secure your WordPress sites with CrowdSec using our latest application bouncer, available on the WordPress marketplace. This new plugin is compatible with versions 1.0.x and beyond. Given that the vast majority of websites in the world are hosted on WordPress, this plugin improves our defense arsenal in our mission to defend the greatest number.

Step one: Install CrowdSec agent

This bouncer has been designed to protect WordPress-hosted websites from all kinds of attacks. To be able to use this blocker, the first step is to install the CrowdSec agent.

Then, both installation and configuration of the plugin can be done in a few clicks from the WordPress marketplace.

CrowdSec plugin available on WordPress

Please note that first and foremost CrowdSec must be installed on a server that is accessible via the WordPress site.  Remember: CrowdSec detects, bouncers deter.

Both pieces of software don’t have to be installed on the same server, although that would be easiest. To protect your server in the best possible way, the CrowdSec agent needs to be able to read relevant logs – either via file, syslog or whatever works best in your environment.

Step two: Install WordPress plugin

Installing the CrowdSec WordPress plugin is as easy as installing any other WordPress plugin:

  • Click ‘Plugins’ in the left navigation on your site’s dashboard. 
  • Type ‘CrowdSec’ in the text field to the right. Hit enter. 
  • In the CrowdSec plugin click ‘Install Now’

Once installed click ‘activate’ as illustrated below.

Now configure the plugin by clicking CrowdSec in the left navigation as shown below.

Set LAPI URL to the location of your CrowdSec agent. Is it installed on the same server, fill it out as shown above.

‘Bouncer API’ is created in cscli. Just follow the instructions. 

For details on how to configure the CrowdSec WordPress bouncer, go to the official documentation or read on. Pay special attention to the option ‘Public website only’. This must be disabled if you wish to protect wp-admin (which you most likely would want to).

The “Flex mode” – a bulwark agains false positives

Thanks to the “Flex mode”, it is impossible to accidentally block access to your site to people who don’t deserve it. This mode makes it possible to never ban an IP but only to offer a Captcha, in the worst-case scenario.

CrowdSec blends into your design

When a user is suspected to be malevolent, CrowdSec will either send them her a Captcha to resolve or simply a page notifying that access is denied. Please note that it is possible to customize all the colors of these pages in a few clicks so that they integrate best with your design. On the other hand, all texts are also fully customizable. This will allow you, for example, to present translated pages in your users’ language.

The right balance between performance and security

By default, the “live mode” is enabled. The first time a stranger connects to your website, this mode means that the IP will be checked directly by the CrowdSec API. The rest of your user’s browsing will be even more transparent thanks to the fully customizable cache system.

But you can also activate the “Stream mode.” This mode allows you to constantly feed the bouncer with the malicious IP list via a background task (CRON), making it even faster when checking the IP of your visitors. Besides, if your site has a lot of unique visitors at the same time, this will not influence the traffic to the API of your CrowdSec instance.

Stream mode activation

If you’ve ever been confronted with high traffic, you are probably familiar with Redis or Memcached technologies. You have the capability to activate these caching technologies in the CrowdSec bouncer settings to guarantee invisible IP control on your site. For further explanation on stream vs live mode, check the official documentation.

CDN-friendly without forgetting other load balancers

If you use a CDN, a reverse proxy, or a load balancer, it is now possible to indicate in the bouncer settings the IP ranges of these devices to check the IP of your users. For other IPs, the bouncer will not trust the X-Forwarded-For header.

Coming up next

Soon, the plugin will have a dashboard allowing you to visualize the activity of your bouncer in live. It will also be possible to connect directly to CrowdSec’s global reputation database, without having to install an agent on your machine if you don’t wish to.

Widely tested, 100% open source

This plugin has been tested on the vast majority of WordPress versions installed in the world (90%+), according to WordPress real-time statistics. It has also been tested on a very wide range of PHP versions (7.2, 7.3, 7.4 and 8), the language in which WordPress is coded.

This plugin is released under MIT license, the most permissive and free license in the world. Its source code is fully available on GitHub. You can discover the entire collection of CrowdSec bouncers at our Hub. Beyond this one, you will find there more freshly released additions.

We would love to hear your feedback about this WordPress plugin. If you are interested in testing the bouncer to protect your sites or would like to get in touch with the team, give us a shout!

Source :

Announcing Our Partnership with CrowdSec

Today we’re thrilled to announce our new partnership with CrowdSec.

This is easily one of the most exciting developments in WordPress security for a long time, and it aligns with our goals to make Shield Security the best WordPress security solution, for everyone.

Our #1 mission with Shield is to deliver the most powerful security for WordPress sites. We’re not out to make millions in sales and scare you into upgrading to ShieldPRO because we have KPI targets.

We’re here simply to protect people and their businesses.

Our partnership with CrowdSec helps us fulfill that aspiration as we’re convinced it’ll deliver major security enhancements for every WordPress site running on Shield Security.

We hope you’ll be as excited as we are, after you learn about this collaboration!

In this article you’ll discover:

  • What CrowdSec is.
  • Why we decided to partner with CrowdSec.
  • How your WordPress security is enhanced with this integration.
  • How the CrowdSec integration differs between ShieldPRO and ShieldFREE

What Is CrowdSec?

CrowdSec is a global, open-sourced, crowdsourcing initiative launched in an effort to combat the threat of malicious machines and bots that attack our websites and apps.

By gathering threat data about bots from millions of different sources, Crowdsec can build and share reliable intelligence about malicious bots (their IP addresses).

As a subscriber to CrowdSec, they’ll notify you about bad IP addresses, so that when those IPs send requests to your site/app, you can take action to block them immediately.

The reason this is so powerful is that when you block an IP address that you know is “bad”, you block all security threats from that IP completely. So the more quickly you can know about those bad IPs, the safer your sites will be.

Summary: Crowdsec offers you faster identification of bad IP addresses based on information gathered from other sites/servers across the globe.

So Why Partner With CrowdSec?

We’ve wanted to build this type of intelligence network for Shield, for a long time.

It’s a complex system and we were working our way through it when we stumbled upon CrowdSec. It immediately piqued our interest since their focus is somewhat similar to our own.

We figured that if we could get their knowledge fed into Shield, then our customers could indentify bad bots more quickly and thereby instantly increase their protection.

We reached out to them to discuss whether there was scope for collaboration and they could immediately see, in-principle, that there was potential for mutual benefit.

Afterall, if Shield can give them access to data points about bad IPs from across 60,000+ WordPress websites, it’d be a huge addition to their network.

And conversely, if WordPress sites running Shield can access shared intelligence from all those sites and other websites/apps/platforms, our customers will also benefit.

What’s not to like about this idea?

They agreed that a collaboration between was definitely beneficial, and so here we are today!

How Does the CrowdSec Partnership Enhance Your WordPress Security?

We briefly touched upon this topic already, but we’ll go into a bit more below.

On any given WordPress site, Shield’s Automatic IP blocking system gathers intelligence about IP addresses that send requests to the site. It keeps track of bad IPs using a counter of “offenses” and when that IP has exceeded the allowed limit, it’s blocked from further access.

Basically a bad bot has 10 chances before it’s completely blocked. (10 is configurable)

This means there’s a small “window” open to any IP address to probe, attack or exploit your site, before Shield can be sure that they’re malicious.

With the CrowdSec integration, your WordPress sites will have access to intelligence about malicious IP addresses before they’ve ever accessed your website. (This intelligence will have already been gathered for you by other websites.)

This reduces that “window” available to malicious bots to zero.

Reducing the time window to zero means a malicious bot can’t:

  • probe your site
  • exploit known/unknown vulnerabilities
  • inject malware and/or exploit malware previously injected
  • register users
  • create fake WooCommerce orders
  • steal your data or customers’ data
  • consume your server/hosting resources
  • etc. etc.

Of course, this IP intelligence is formed through the activity of IP addresses on other websites, and sometimes your own.

With CrowdSec’s integration switched on, Shield will share its internal offenses-tracking with CrowdSec, which ultimately then shares the data with other WordPress sites.

This all happens seamlessly with zero effort or configuration needed by the security admin.

So in a nutshell, CrowdSec gives us a head-start against malicious bots and lets us block IPs before your Shield plugin needs to perform any assessments, relying on tracking already done by other Shield plugins, elsewhere on the Internet.

How Does The CrowdSec Integration Differ Between ShieldPRO and ShieldFREE?

ShieldPRO is designed to protect businesses and mission critical WordPress sites. If your WordPress site plays a critical role in your business, or even your personal endeavours, then ShieldPRO is definitely something you should consider.

If, however, your website isn’t so important, or you’re comfortable with restoring a website quickly from a backup after a hack, or you have other security systems in-place and feel you don’t need the extra protection that ShieldPRO offers, then ShieldFREE will go a long way to protecting your sites and users and offering useful extra features like Two-Factor Authentication.

The CrowdSec integration with Shield reflects this. When you’re running ShieldPRO you’ll get access to much more IP intelligence data, and also IP data from sources that reflect business or mission-critical websites, such as e-commerce stores etc.

As well receiving more relevant IP data, and at higher volumes, ShieldPRO installations will receive IP data more frequently. The current implementation is “every 2 hours” for ShieldPRO and “every week” for ShieldFREE.

This simply means that if you’re running ShieldFREE, your IP intelligence data will become increasingly stale, but you’ll be refreshed with the latest data each week.

We may adjust these settings over time.

If you need or desire greater protection based on the nature and purpose of the WordPress sites you’re operating, then we strongly urge you to move to the extra protection afforded to you by ShieldPRO.

CrowdSec and GDPR Compliance

Like ourselves, CrowdSec is commited to full compliance with privacy regulations, such as GDPR.

You can see more details on their GDPR compliance here.

Please note, also, that CrowdSec integration is completely voluntary – you can switch it off on your Shield website at any time with no impact on your performance or security. Shield will continue to protect your site as it’s always done.

Future Plans For Our Partnership

You can already create a free account with CrowdSec over on their homepage. And once our Shield integration has been released, you’ll able to link your WordPress sites into your CrowdSec App account and view the data being sent to the network from all your sites.

We have a few further things under consideration to deepen our integration with CrowdSec, but we’ll annouce these as the integration progresses.

When Can You Get ShieldPRO + CrowdSec?

We’re getting set to release v16 of Shield Security in the coming weeks. Stay tuned to the newsletter or the changelog to get further details as they are published.

Thoughts, Suggestions and Feedback?

As always, we encourge our clients to share their thoughts with us when at any time, and in particular when we release a new feature such as this. Please feel free to leave your comments in the section below.

Source :

Don’t Believe The Hype: Why WordPress Malware Isn’t Your Biggest Threat

Scanning your WordPress sites for Malware is the most important thing you can do to protect your site.

This approach is common and is actually the USP (Unique Selling Point) of several popular WordPress security plugins and services.

Conventional wisdom and marketing emphasises to us all that scanning for malware is pinnacle of WordPress security greatness.

In this article I’ll argue that incessent Malware scanning isn’t going to keep your WordPress site secured.

I want to challenge your approach to WordPress site security and hope that by the end of the article your focus will have shifted a little.

Instead of endless “scanning for malware” treadmill, along with the anxiety that this produces in us, I want to show you there’s an alternative. And it’s a hugely effective way to keep your WordPress sites secure, and your data (and your customers’ data) safe.

Malware Scanning Is Super Important If You’re Already Hacked!

So yes, malware scanning is hugely important when you’re already compromised. You gotta find and eliminate the infection!

But let’s be absolutely clear here, statistically speaking, your site probably isn’t hacked. Yet.

Give me any random WordPress site and I’ll bet that “no”, it hasn’t been hacked. Afterall there are more non-hacked websites than hacked sites, so we’ve got better than a 50:50 chance.

So why on earth do we need powerful security plugins like ShieldPRO? What’s all that malware scanning for then?

Firstly, it’s important to realise that “under attack” and “hacked” are 2 different things. While you may not be compromised, if you’re not already under attack, I’d be very, very suprised.

So while I’d bet that you’re probably not hacked yet, the odds are good that if your site isn’t hacked today, it’ll be hacked eventually without robust security practices and defenses in-place.

The strategies and tools we need to handle both these scenarios (hacked and under attack) are different. ShieldPRO comes with all the powerful tools that work for both, but we’ll get to that a little later.

So What Is The Most Important Aspect Of WordPress Security Protection?

The clue is in the question – “PROTECTION“.

You’ll have heard the phrase that “prevention is better than cure”. This is a real thing.

It’s not a marketing ploy or persuasion tactic. It’s one of the rare times you can say ‘true fact‘ without sounding a little silly.

It is why, for example, Smallpox has been eradicated from planet earth, and why vaccines are the fastest way out of a global pandemic. <insert conspiracy theory counterargument here>

So it is, too, for WordPress site security.

It’s much easier and far cheaper to prevent a WordPress site from getting hacked and keep it clean, than it is to clean up after a site has been compromised.

If you’ve ever had to clean up a hacked site, you’ll know this to be true.

So Is Malware Scanning Important?

Of course, malware scanning is important. And ShieldPRO has strong malware scanning capabilities.

But it is depends on what you’re using you malware scanner for.

Malware scanning has 2 primary purposes:

  1. To quickly detect hidden malware scripts, allowing you to eliminate infection more easily.
  2. To let you know your website is vulnerable.

You see, many of us get it backwards. We think our website is vulnerable because we have malware.

But it’s the other way around: we have a malware infection because our website is vulnerable!

So if your favourite WordPress security plugin touts their primary feature is that they’re the #1 malware detector for WordPress, then you should also double-check with them that they actually prevent infection in the first place.

Sure you can detect and remove malware, but if you haven’t eliminated the root cause, you’re playing whack-a-mole with malware scripts.

Life’s too short for that.

I would never say, and certainly don’t imply, that malware scanning isn’t necessary as part of a holistic WordPress security strategy. We’ve made huge investments into our malware detection and repair engine within ShieldPRO because we know it’s important.

Being able to detect malware reliably, and eliminate it quickly, is critical in our efforts to secure WordPress sites after they’ve been compromised, and Shield fulfills this role for us.

But once malware has been discovered and cleaned, your work is only beginning. You’ll need to plug the hole that allowed the malware to get in there in the first place.

So, rather than set your primary goal to be detecting and eliminating malware, you’ll want to shift your focus a little and ask yourself…

What’s the Best Way To Stop Hacking in WordPress?

We said this earlier – good prevention is the path to robust WordPress security.

To prevent WordPress malware infections, we must understand how it happens in the first place.

There are a couple of angles to answering this. The most common answer you’ll hear is that vulnerable plugins and themes are single biggest vector for WordPress compromise.

This is true. But it’s not the whole story.

Let’s Play: Hacker Role Play

So let’s pretend you’re a WordPress website hacker and your stated goal is:

hack as many WordPress sites as you can all day, every day, and infect them with your malware scripts.

Here are some of your likely thoughts:

  • Firstly, you’d have a think about your target market – i.e. there are millions and millions of WordPress websites. Win!
  • Next, in order to hack 30,000+ websites every day you will need either:
    • a whole lot people to do a lot of manual work, or
    • automated bots and scripts to do all the hard work for you quickly
  • Since you don’t have the resources to hire people, you decide to build automated bots and scripts.

At this point you’ve decided to create automated bots to do your hacking for you. But there are a few things you must take into consideration when you design these bots:

  • You must “discover” the WordPress sites. Not all sites are WordPress, so you have to first find potential targets. So you’ll have your bots probe the websites to determine if they’re actually WordPress sites.
  • You have a library of publicly known (and maybe even non-public) WordPress plugin and theme vulnerabilities you’re going to exploit to gain access. So you narrow down your list of WordPress sites based on which sites have these vulnerable plugins/themes installed. This involves a lot more probing on the site.
  • You’ve now got a good list of sites to attack.
  • Attack!

Of course this layout is for illustrative purposes. But the principle of what’s happens in the real world is no different.

Some bots may not probe for discovery first, and instead go straight for the vulnerability itself, only to find it’s not present. But this can be considered a probing/exploit attempt, too.

In the end you’ll have lots of bots probing lots of websites.

Back To Preventing Malware and Hacking…

The first stage in hacking at scale is probing, with the use of bots/scripts, by either checking what the site has, or by directly targeting known vulnerabilities and hoping to get a hit.

If you track 404 errors on your own WordPress sites, you’ll see for example, there are often many requests to URLs that simply don’t exist. You’re being probed.

If we can detect these probing bots, determine that they’re sending requests for nefarious purposes, then we can completely block them from accessing our sites altogether.

This is true prevention and it works far better, and much more efficiently than repeatedly cleaning-up our sites after they’ve been compromised.

And this holds true not only for malware infections, but any possible compromise to your WordPress sites.

So your #1 goal shouldn’t be “find the best malware cleaner” – it should be: “find the best prevention against WordPress site hacking and compromise”.

How Does ShieldPRO Prevent WordPress Site Hacking?

The main area of focus of Shield Security for WordPress is in prevention.

We believe strongly that if we can prevent problems in the first place, we free ourselves and our WordPress sites to focus on the work that’s most important.

ShieldPRO achieves this by doing its utmost to detect bad bots and block them.

  • We use our exclusive, custom built AntiBot Detection Engine to detect bad bots. Detecting bad bots isn’t simple, because they do everything they can to hide their malicious intent. Shield builds up a profile for each IP address based on their activities and depending on their reputation, blocks certain requests.
  • Use our exclusive “NotBot” javascript snippet to quickly and reliably identify bots vs humans.
  • Gathers 25+ distinct “bot signals” to monitor, track and score visitors to build a unique “bot” profile.

Once we’ve accessed a visitor and determined it to be a bot, and more specifically, a bad bot, we prevent that visitor from performing certain requests against the site. And, depending on the Shield configuration, we can block that bot from sending any requests to the site entirely.

ShieldPRO prevents 10,000s of WordPress sites from being hacking every single day by standing in the way of malicious bots.

Of course, Shield will also scan for malware and filesystem modifications, vulnerable plugins and all the other usual suspects, but this “after-the-fact” scanning is no match for preventing such things in the first place.

Is Your WordPress Protection Focused On Prevention, or Cure?

If you ask yourself nothing else after reading this article, it should be whether your existing WordPress Security strategy is focused on prevention, or focused on cure.

We’ve argued that the biggest positive impact on your security lies in preventing the problems in the first place, and that ShieldPRO is built with this strategy in-mind.

While you might have the best or most expensive malware scanning engine on the market, if it’s consistently picking up threats, then you may not have the best WordPress protection available.

Source :

WordPress Core 6.0.2 Security & Maintenance Release – What You Need to Know

On August 30, 2022, the WordPress core team released WordPress version 6.0.2, which contains patches for 3 vulnerabilities, including a High Severity SQLi vulnerability in the Links functionality as well as two Medium Severity Cross-Site Scripting vulnerabilities.

These patches have been backported to every version of WordPress since 3.7. WordPress has supported automatic core updates for security releases since WordPress 3.7, and the vast majority of WordPress sites should receive a patch for their major version of WordPress automatically over the next 24 hours. We recommend verifying that your site has been automatically updated to one of the patched versions. Patched versions are available for every major version of WordPress since 3.7, so you can update without risking compatibility issues. If your site has not been updated automatically we recommend updating manually.

Vulnerability Analysis

As with every WordPress core release containing security fixes, the Wordfence Threat Intelligence team analyzed the code changes in detail to evaluate the impact of these vulnerabilities on our customers, and to ensure our customers remain protected.

We have determined that these vulnerabilities are unlikely to be targeted for exploitation due to the special cases needed to exploit. In most circumstances these vulnerabilities require either elevated privileges, such as those of an administrator, or the presence of a separate vulnerable or malicious plugin. Nonetheless, the Wordfence firewall should protect against any exploits that do not require administrative privileges. In nearly all cases administrators already have the maximum level of access and attackers with that level of access are unlikely to use convoluted and difficult exploits when simpler paths to making configuration changes or obtaining sensitive information are readily available.

Description: SQL Injection via Links LIMIT clause
Affected Versions: WordPress Core < 6.0.2
Researcher: FVD
CVE ID: Pending
CVSS Score: 8.0 (High)
Fully Patched Version: 6.0.2

The WordPress Link functionality, previously known as “Bookmarks”, is no longer enabled by default on new WordPress installations. Older sites may still have the functionality enabled, which means that millions of legacy sites are potentially vulnerable, even if they are running newer versions of WordPress. Fortunately, we found that the vulnerability requires administrative privileges and is difficult to exploit in a default configuration. It is possible that 3rd party plugins or themes might allow this vulnerability to be used by editor-level users or below, and in these cases the Wordfence firewall will block any such exploit attempts.

Vulnerable versions of WordPress failed to successfully sanitize the limit argument of the link retrieval query in the get_bookmarks function, used to ensure that only a certain number of links were returned. In a default configuration, only the Links legacy widget calls the get_bookmarks function in a way that allows this argument to be set by a user. Legacy widgets involve additional safeguards, and the injection point of the query itself poses additional difficulties, making this vulnerability nontrivial to exploit.

Description: Contributor+ Stored Cross-Site Scripting via use of the_meta function
Affected Versions: WordPress Core < 6.0.2
Researcher: John Blackbourn
CVE ID: Pending
CVSS Score: 4.9 (Medium)
Fully Patched Version: 6.0.2

WordPress content creators, such as Contributors, Editors, Authors, and Administrators, have the ability to add custom fields to any page and post created. The purpose of this is to make it possible for site content creators to add and associate additional data to posts and pages.

WordPress has several functions available to site owners to display custom fields created and associated with posts and pages. One of these functions is the the_meta function which retrieves the supplied post’s or page’s custom field data, which is stored as post meta data, through the get_post_custom_keys and get_post_custom_values functions. Once the custom fields for a post/page are retrieved, the function outputs the post meta keys and values data as a list. Unfortunately, in versions older than 6.0.2 this data was unescaped on output making it possible for any injected scripts in post meta keys and values to be executed.

Due to the fact that any user with access to the post editor can add custom meta fields, users with access to the editor such as contributors could inject malicious JavaScript that executes on any page or post where this function is called.

WordPress core does not call the_meta anywhere in its codebase by default. As such this vulnerability does require a plugin or theme that calls the the_meta function, or for this function to have been programmatically added to a PHP file for execution, so the vast majority of site owners are not vulnerable to this issue. The the_meta function is considered deprecated as of 6.0.2 and get_post_meta is the recommended alternative.

The Wordfence Threat Intelligence Team deployed a firewall rule to help protect Wordfence PremiumCare & Response customers today. Wordfence Free users will receive the same protection in 30 days on September 29, 2022.

Description: Stored Cross-Site Scripting via Plugin Deactivation and Deletion errors
Affected Versions: WordPress Core < 6.0.2
Researcher: ​​Khalilov Moe
CVE ID: Pending
CVSS Score: 4.7 (Medium)
Fully Patched Version: 6.0.2

The final vulnerability involves the error messages displayed when a plugin has been deactivated due to an error, or when a plugin can not be deleted due to an error. As these error messages were not escaped, any JavaScript present in these error messages would execute in the browser session of an administrator visiting the plugins page. This vulnerability would require a separate malicious or vulnerable plugin or other code to be installed on the site, which would typically require an administrator to install it themselves. In almost all cases where this vulnerability might be exploitable an attacker would already have a firm foothold on the vulnerable site.

Our built-in XSS rule should block any attempts to generate crafted error messages based on user input to a vulnerable plugin, and the Wordfence scanner will detect any malicious plugins uploaded by an administrator.


In today’s article, we covered three vulnerabilities patched in the WordPress 6.0.2 Security and Maintenance Release. Most actively used WordPress sites should be patched via automatic updates within the next 24 hours, and any sites that remain vulnerable would only be exploitable under very specific circumstances.

We have released a firewall rule to Wordfence PremiumCare, and Response users to protect against any exploits targeting the the_meta function and this rule should become available to Wordfence free users after 30 days, on on September 29, 2022.

As always, we strongly recommend updating your site to a patched version of WordPress if it hasn’t been updated automatically. As long as you are running a version of WordPress greater than 3.7, an update is available to patch these vulnerabilities while keeping you on the same major version, so you will not need to worry about compatibility issues.

Props to Khalilov Moe, John Blackbourn, & FVD for discovering and responsibly disclosing these vulnerabilities. Special thanks to Wordfence Threat Intelligence Lead Chloe Chamberland for collaborating on this post.

Source :

A CISO’s Ultimate Security Validation Checklist

If you’re heading out of the office on a well-deserved vacation, are you certain the security controls you have in place will let you rest easy while you’re away? More importantly – do you have the right action plan in place for a seamless return?

Whether you’re on the way out of – or back to – the office, our Security Validation Checklist can help make sure your security posture is in good shape.

1. Check the logs and security events of your key critical systems. Stay up-to-date on recent activities. Check for changes – and attempted changes – and any potential indicators of compromise. Planning to be gone for longer than a week? Designate a team member to perform a weekly review in your absence, reducing the chances of a critical event going undetected.

2. Check for any new security vulnerabilities that were identified on your vacation. Use your preferred scanning tool or check one of the regularly updated databases, such as CVE Details.

3. Investigate failures of critical components and the reasons behind them. If remediation is needed, create an action plan to address the immediate issues and prevent repeated failures in the future.

4. Review whether there were any key changes to your products and their corresponding security controls. While now isn’t the time to implement major changes to your EDR, SIEM system, or other corresponding solutions, do make sure you’re aware of any updates that were made in your absence. Once you’re back – and able to monitor the impact on your overall security posture – you can make larger-scale changes to your controls.

5. Check with HR for any relevant changes. Did any new employees join the company and therefore need access to specific systems? Conversely, did any employees leave and need their credentials revoked? Were there any other incidents or red flags that require your attention?

6. Be aware of new business orientations. Did the organization introduce any new services or products that expanded the potential attack surface? For instance, did a new website or mobile app go live, or was a new version of a software product rolled out? Make sure your team is up to speed on the latest changes.

7. Check your password policies. Password policies shouldn’t be dependent on your vacation status, but as you work through this security checklist, take the opportunity to make sure policies are appropriately protecting the organization. Consider reviewing length, complexity, and special character requirements, as well as expiration and re-use policies.

8. Review firewall configurations . With many security experts recommending a review of firewall configurations every three to six months, now is an opportune time for an audit. Review network traffic filtering rules, configuration parameters, and authorized administrators – among other configurations – to make sure you’re using the appropriate configurations

There are plenty of tools that can help work through this checklist – but do you have all the resources needed to make sure everything will be addressed?

If you need help automating and standardizing your processes – or making sure critical vulnerabilities aren’t slipping through the cracks – Automated Security Validation can help. With real-time visibility, complete attack surface management, and actual exploitation measures – not just simulations – it provides what you need to rest easy while you’re away. And when you get back? Risk-based remediation plans help you create your roadmap for keeping your organization protected.

When you’re back, we’ve got your back. To learn more about protecting your security posture with Automated Security Validation, request a demo of the Pentera platform.

Source :

Use this Identity Checklist to secure your M365 tenant

Securing a Microsoft 365 tenant must start with identity.

Protecting identities is a fundamental part of Zero Trust and it’s the first “target” that most attackers look for. We used to say that attackers hack their way in, now we say they log in, using bought, found or stolen/phished credentials. This article will show you why MFA is so important and how to implement advanced security features in Azure AD such as PIM, Password protection, Conditional Access policies (also a strong part of Zero Trust), auditing and more.

Below is the first chapter from our free Microsoft 365 Security Checklist eBook. The Microsoft 365 Security Checklist shows you all the security settings and configurations you need to know for each M365 license to properly secure your environment. Download the full eBook and checklist spreadsheet.

Multi-Factor Authentication

It should be no surprise that we start with identity, it’s the new security perimeter or the new firewall and having a strong identity equals strong security. The first step to take here is implementing Multi Factor Authentication (MFA). It’s free for all Office / Microsoft tenants. If you want to use Conditional Access (CA) to enforce it (rather than just enabling users “in bulk”), you need Azure AD Premium P1+ licensing. A username and a simple password are no longer adequate (it never was, we just never had a simple, affordable, easy to use alternative) to protect your business.

Hand-in-hand with MFA you need user training. If your business is relying on users doing the right thing when they get the prompt on their phone – they MUST also know that if they get a prompt when they’re NOT logging in anywhere, they must click Block / No / Reject.

To enable MFA on a per-user basis, go to, login as an administrator, click Azure Active Directory – Security – MFA and click on the blue link “Additional cloud-based MFA settings”.

Additional MFA settings

Additional MFA settings

There are two parts (tabs) on this page, “service settings” where you should disable app passwords (a workaround for legacy clients that don’t support MFA, shouldn’t be necessary in 2022), add trusted public IP addresses (so that users aren’t prompted when they’re in the corporate office – we and Microsoft recommend not using this setting), disabling Call and Text message to phone and remember MFA on trusted devices setting (1-365 days), Microsoft recommends either using CA policies to manage Sign-In frequency or setting this to 90 days. Phone call / text message MFA are not strong authentication methods and should not be used unless there’s no other choice.

On the user’s tab you can enable MFA for individual users or click bulk update and upload a CSV file with user accounts.

If you have AAD Premium P1, it’s better to use a CA policy to enforce MFA, it’s more flexible and the MFA settings page will eventually be retired.

Enforcing MFA with a Conditional Access Policy

Enforcing MFA with a Conditional Access Policy

A few words of caution, enabling MFA for all your administrators is a given today. Seriously, if you aren’t requiring every privileged account to use MFA (or 2FA / passwordless, see below), stop reading and go and do that right now. Yes, it’s an extra step and yes, you’ll get push back but there’s just no excuse – it’s simply unprofessional and you don’t belong in IT if you’re not using it. For what it is worth, I’ve been using Azure MFA for over seven years and require it for administrators at my clients – no exceptions.

Enabling MFA for all users is also incredibly important but takes some planning. You may have some users who refuse to run the Microsoft Authenticator app on their personal phone – ask for it to be put in their hiring contract. You need to train them as to why MFA is being deployed, what to do, both for authentic logins and malicious ones. Furthermore, you need to have a smooth process for enrolling new users and offboarding people who are leaving.

You should also strongly consider creating separate (cloud only) accounts for administrators. They don’t require a license and it separates the day-to-day work of a person who only performs administrative actions in your tenant occasionally (or use PIM, Chapter 10).

MFA protects you against 99.9% of identity-based attacks but it’s not un-phishable. Stronger alternatives include biometrics such as Windows Hello for Business (WHFB) and 2FA hardware keys which bring you closer to the ultimate in identity security: passwordless.

Legacy Authentication

However, it’s not enough to enable MFA for all administrators and users, the bad guys can still get in with no MFA prompt in sight. The reason is that Office 365 still supports legacy protocols that don’t support modern authentication / MFA. You need to disable these; you can’t just turn them off, you need to check if there are legitimate applications / workflows / scripts that use any of them. Go to, login as a Global Administrator, click Azure Active Directory – Monitoring – Sign-in logs. Change the time to last one month, and click Add filters, then click Client app and then None Selected, in the drop-down pick all 13 checkboxes under Legacy Authentication Clients and click Apply.

Filtering Azure AD Sign-in logs for legacy authentication

Filtering Azure AD Sign-in logs for legacy authentication

This will show you all the logins over the last month that used any of the legacy protocols. If you get a lot of results, add a filter for Status and add Success to filter out password stuffing attacks that failed. Make sure you check the four different tabs for interactive / non-interactive, service principals and managed identity sign-ins.

You’ll now need to investigate the logins. In my experience there will be some users who are using Android / Apple mail on smartphones; point them to the free Outlook app instead (Apple mail can be configured to use modern authentication). There’s also likely to be line-of-business (LOB) applications and printers / scanners that send emails via Office 365, so you’ll need updates for these. Alternatively, you can use another email service for these such as smtp2go.

Once you have eliminated all legitimate legacy authentication protocol usage you can disable it in two ways, it’s best to use both. Start by creating a Conditional Access policy based on the new template to block it, also go to, Settings – Org settings – Services – Modern authentication and turn off basic authentication protocols.

Disable legacy authentication protocols in the M365 Admin Center

Disable legacy authentication protocols in the M365 Admin Center

Break Glass accounts

Create at least one, preferably two break glass accounts, also known as emergency access accounts. These accounts are exempted from MFA, all CA policies and PIM (see below) and have very long (40 characters+), complex passwords. They’re only used if AAD MFA is down, for example, to gain access to your tenant to temporarily disable MFA or a similar setting, depending on the outage.

A second part to this is that you want to be notified if these accounts are ever used. One way to do this is to send your Azure AD sign-in logs to Azure Monitor (also known as Log Analytics), with instructions here. Another option is to use Microsoft Sentinel (which is built on top of Log Analytics) and create an Analytics rule.

Microsoft Sentinel alert rule when a Break Glass account is used

Microsoft Sentinel alert rule when a Break Glass account is used

Security Defaults

If yours is a very small business, with few requirements for flexibility, the easiest way to set up Azure AD with MFA for everyone, plus several other security features enabled, is to turn on Security Defaults. Note that you can’t have break-glass accounts or other service accounts with Security Defaults as there’s no way to configure exceptions. Go to Properties for your Azure AD tenant and scroll to the bottom, and click on Manage Security defaults, here you can enable and disable it.

Privileged Identity Management

It’s worth investing in Azure Active Directory (AAD) Premium P2 for your administrator’s accounts and enabling Privileged Identity Management (PIM). This means their accounts are ordinary user accounts who are eligible to elevate their privileges to whatever administrator type they are assigned (see Chapter 10).

If you’re not using PIM, create dedicated admin accounts in AAD only. Don’t sync these accounts from on-premises but enforce MFA and strong passwords. Since they won’t be used for day-to-day work, they won’t require an M365 license.

Password Protection

After MFA, your second most important step is banning bad passwords. You’re probably aware that we’ve trained users to come up with bad passwords over the last few decades with “standard” policies (at least 8 characters, uppercase, lowercase, special character and numbers) which results in P@ssw0rd1 and when they’re forced to change it every 30 days, P@ssw0rd2. Both NIST in the US and GHCQ in the UK now recommends allowing (but not enforcing) the use of upper / lowercase etc., but not mandating frequent password changes and instead of checking the password at the time of creation against a list of known, common bad passwords and blocking those. In Microsoft’s world that’s called Password protection which is enabled for cloud accounts by default. There’s a global list of about 2000 passwords (and their variants) that Microsoft maintains, based on passwords they find in dumps, and you should add (up to 1000) company-specific words (brands, locations, C-suite people’s names, local sports teams, etc.) for your organization.

You find Password protection in the AAD portal – Security – Authentication Methods.

Password protection settings

Password protection settings

Remember, you don’t have to add common passwords to the list, they’re already managed by Microsoft, just add company / region specific words that your staff are likely to use.

If you’re syncing accounts from Active Directory on-premises to AAD, you should also extend Password protection to your DCs. It involves the installation of an agent on each DC, a proxy agent, and a reboot of each DC.

Continuous Access Evaluation

This feature has been in preview for quite some time but is now in general availability. Before Continuous Access Evaluation (CAE), when you disabled a user’s account, or they changed location (from the office to a public Wi-Fi for example) it could be up to one hour before their state was re-evaluated and new policies applied, or they were blocked from accessing services. With CAE, this time is much shorter, in most cases in the order of a few minutes. It’s turned on by default for all tenants (unless you were part of the preview and intentionally disabled it). Another benefit of CAE is that tokens are now valid for 28 hours, letting people keep working during a shorter Azure AD outage. You can disable CAE in a CA policy, but it’s not recommended.

Conditional Access policies

We’ve mentioned Conditional Access (CA) policies several times already as it’s a crucial component of strong identity security and Zero Trust. Unlike other recommendations, there isn’t a one size fit all set of CA policies we can give you, however (at a minimum) you should have policies for:

  • Require MFA for admins (see MFA above)
  • Require MFA for users (see MFA above)
  • Require MFA for Azure management
  • Block legacy authentication (see MFA above)
  • Require compliant or Hybrid AAD joined device for admins
  • Require compliant or Hybrid AAD joined device for users
  • Block access to M365 from outside your country
  • Require MFA for risky sign-ins (if you have AAD Premium P2)
  • Require password change for high-risk users (if you have AAD Premium P2)

This is all going to be a lot easier going forward with the new policy templates for identity and devices. Go to Azure AD – Security – Conditional Access – New policy – Create a new policy from templates. Another step to take is to create a system for managing the lifecycle of policies and there’s an API for backing up and updating policies, that you can access in several ways, including PowerShell. There’s even a tutorial to set up a backup system using a Logic App.

Conditional Access policy templates for identity

Conditional Access policy templates for identity

A common question is if there’s a priority when policies are evaluated and there isn’t, they’re all processed together for a particular sign-in, from a specific device and location to an individual application. If there are multiple policies with different controls (MFA + compliant device), all controls must be fulfilled for access. And if there are conflicting policies with different access (block vs grant), block access will win.

To get you started, here are the step-by-step instructions for a policy blocking access to M365 from outside your country, appropriate for most small and medium businesses that only operate in one or a few countries. Keep in mind that travelling staff may be caught out by this so make sure you align with business objectives and be aware that this won’t stop every attack as a VPN or TOR exit node can make it appear as if the attacker is in your country, but it’s one extra step they must take. Remember, you don’t have to run faster than the Fancy Bear, just faster than other companies around you.

Start by going to Azure AD – Security – Conditional Access – Named locations and click +Countries location and call the location Blocked countries. Leave Determine location by IP address, a new feature is using GPS location from the Microsoft Authenticator app which will be more accurate once all your users are using Azure AD MFA (and therefore can be located via GPS). Click the box next to Name to select all countries, then find the one(s) that you need to allow login from and click Create.

Creating a Named Location for a Conditional Access Policy

Creating a Named Location for a Conditional Access Policy

Go to Azure AD – Security – Conditional Access – New policy – Create new policy and name your policy with a name that clearly defines what the policy does and adheres to your naming standard. Click on All Users… and Include All users and Exclude your Break Glass accounts.

Click on No cloud apps… and select All cloud apps. Select 0 conditions… and click Not configured under Locations. Pick Selected locations under Include and select your newly created location. Finally, under Access controls – Grant, click 0 controls selected and then Block access.

CA policies can be either in Report-only mode where you can look at reports of what they would have blocked and control they would have enforced, or they can be turned on / off. Report-only can be handy to make sure you don’t get fired for accidentally locking everyone out but turn this policy on as soon as possible.

Conditional Access policy to block logins from outside Australia

Conditional Access policy to block logins from outside Australia

A common question is, how can I control how often users are prompted for MFA or signing in again? While it might be counterintuitive, the default in Azure AD is a rolling windows of 90 days. Remember, if you change a user’s password, block non-compliant devices, or disable an account (plus any number of other CA policies you have in place that might affect the security posture of the session), it’ll automatically require new authentications. Don’t prompt the users for authentication when nothing has changed because if you do it too frequently, they’re more likely to approve a malicious login.

Branding Log-on Pages

While in the Azure AD portal, click on Company branding and add a company-specific Sign-in page background image (1920x1080px) and a Banner logo (280x60px). Note that these files have to be small (300 KB and 10 KB respectively) so you may have to do some fancy compression. This isn’t just a way to make users feel at home when they see a login page, in most cases when attackers send phishing emails to harvest credentials, they’ll send users to a fake login page that looks like the generic Office 365 one, not your custom one which is another clue that should alert your users to the danger. Also – Windows Autopilot doesn’t work unless you have customized AAD branding.

Edit Azure AD Company Branding images

Edit Azure AD Company Branding images

Self Service Password Reset

The benefit of Self Service Password Reset (SSPR) is to lower the load on your help desk to manage password resets for users. Once enabled, users must register various ways of being identified when they’re resetting their password, mobile app notification/code, email (non-Office 365), mobile/office phone call, security questions (not available to administrators, plus you can create custom questions). If you are synchronizing user accounts from AD to Azure AD, take care in setting up SSPR as the passwords must be written back to AD from the cloud once changed.

Configuring Self Service Password Reset in Azure AD

Configuring Self Service Password Reset in Azure AD

Unified Auditing

Not restricted to security but nevertheless, a fundamental building block is auditing across Microsoft 365. Go to the Microsoft 365 Defender portal and find Audit in the left-hand menu (it’s almost at the end). If for some reason unified auditing isn’t enabled in your tenant a yellow banner will give you a button to turn it on (it’s on by default for new tenants). Once enabled, click the Audit retention policies tab, and create a policy for your tenant. You want to ensure that you have logs to investigate if there’s a breach and you want them kept for as long as possible.

With Business Premium you get a maximum of 90 days of retention and Microsoft 365 E5 gives you one year, but you want to make sure to create a policy to set this, rather than rely on the default policy (which you can’t see). Give the policy a name, a description and add all the record types, one by one. This policy will now apply to all users (including new ones that are created) for all activities. Only use the Users option when you want to have a specific policy for a particular user. Give the policy a priority, 1 is the highest and 10,000 is the lowest.

Create an audit retention policy for maximum retention

Create an audit retention policy for maximum retention

Integrating applications into Azure AD

One of the most powerful but often overlooked features (at least in SMBs) is the ability to use Azure AD to publish applications to your users. Users can go to (or and see tiles for all applications they have access to. But there’s more to that story. Say, for example, you have a shared, corporate Twitter account that a few executives and marketing staff should have access to. Instead of sharing a password amongst them all and having to remember to reset it if someone leaves the organization, you can create a security group in AAD, add the relevant users, link Twitter to the group and they’ll automatically have access – without knowing the password to the account. There are a lot more actions you can take here to simplify access and secure management of applications, here’s more information.

Azure AD Connect

If you’re synchronizing accounts from Active Directory to Azure Active Directory (AAD), check the configuration of AAD Connect and make sure you’re not replicating an entire domain or forest to AAD. There’s no reason that service accounts etc. should be exposed in both directories, start the AAD Connect wizard on the server where it’s installed and double-check that only relevant OUs are synchronized. One other thing to note here is the fact that any machine running Azure AD Connect should be treated with the same care (in terms of security) as a domain controller. This is because AAD Connect requires the same level of access as AD itself and has the ability to read password hashes. Making sure security best practices for access, patching, etc. are followed to the letter for the system running AAD connect is critically important.

The M365 Identity Checklist

Work through the Identity checklist.
Enable MFA for administrators
Enable MFA for users
Create cloud-only administrator accounts for privileged users / occasional administrators
Disable app passwords
(Configure trusted IPs)
Disable text message MFA
Disable phone call MFA
Remember MFA trusted devices 90 days
Train staff in using MFA correctly
Use Windows Hello where possible
Use FIDO2 / 2FA keys where possible
Investigate legacy authentication protocol usage in AAD Sign-in logs
Block legacy authentication with CA Policy
Block legacy authentication in M365 Admin Center
Create two Break glass accounts and exempt from MFA, CA Policies etc.
Configure alerting if a Break glass account is used
Enable Security Defaults in AAD (consider the limitations)
Enable PIM (AAD Premium P2) for all admin users
Add organization-specific words to Password protection
Deploy Password protection in AD on-premises
CA Policy Require MFA for admins
CA Policy Require MFA for users
CA Policy Require MFA for Azure management
CA Policy Block legacy authentication
CA Policy Require compliant or Hybrid AAD joined device for admins
CA Policy Require compliant or Hybrid AAD joined device for users
CA Policy Block access to M365 from outside your country
Require MFA for risky sign-ins [Only for E5)
Require password change for high-risk users [Only for E5)
Create custom branding logos and text in Azure AD
Enable and configure Self Service Password Reset, including password writeback
Check that Unified Auditing is enabled
Define audit retention policies (90 or 365 days)
Integrate applications into Azure AD

Download the Excel template to use with your team >

Go Further than Identity to Protect your M365 Tenant

There you have it, all the most important steps to take to make sure your users’ identities are kept secure, and therefore your tenant and its data also safeguarded. Keen to learn and do more?

The Microsoft 365 Security Checklist has another nine chapters of security recommendations each with its own checklist for:

  • Email
  • Teams
  • SharePoint
  • Applications
  • Endpoint Manager
  • Information Protection
  • Secure Score
  • Business Premium
  • Microsoft 365 Enterprise E5

Download the full Microsoft 365 Security Checklist eBook and checklist template >

Source :