We’ve been seeing repeated SSL VPN login attempts from various IP addresses with the same usernames recently. While implementing a login limit and login timeout is generally helpful, we’re seeing IP addresses used only twice. Is it possible to block VPN login failures based on username in a similar manner? For example, if the username ‘admin’ is used more than twice, any following attempts using that username will be blocked. All help appreciated! We’re running a FG 200F on 7.0.13.
My suggestion is to use Threat Feed and ISDB to deny traffic when you put your SSL VPN interface on Loopback.
Also use local webserver with your own IP deny list because sometime these bad IP are not black listed based on the number or reports so you can block your own list as well if IP is hitting too much and its not in the Threat Feed black list.
Dont use common username like firstname.lastname as attacker try the generic user and also get the info from Linkden.
Just found this via monthly pinned content. Yurisk has a ton of super useful info.
https://yurisk.info/2023/03/21/fortigate-vpn-ssl-hardening-guide/
any following attempts using that username will be blocked.
What exactly are you expecting from this? It’s not like the username is advertised in the SYN packet, so to “block a specific login name”, you need to go the whole way of TCP handshake, TLS handshake, some GET request, process the POST request with the attempted credentials, then deny the attempt due to bad username/password combination. In other words, just process the login as usual.
Get the ASN of the IP it’s coming from, look at the company. Is it an ISP? or a hosting provider?
If it won’t break other stuff, create threat feed and block the whole ASN.
We have 13 blocked ASNs.
Using automation stitches here with FortiAnalyzer.
Don’t know if you have access to FAZ?
Otherwise you could build it yourself with something like Wazuh.
Put the VPN listening ports on a loopback interface and set up a threat feed to apply to a deny policy AND limit VPN access to your geographic area. I dont track usernames, thats too generic. I track IP addresses and usually block the /24 or /16 depending on the number of attempts from a subnet I see.
The best way to go about this is a local In policy for sslvpn and restrict it to your geolocation, unless u want to whitelist by source ip of all your users (which is virtually impossible for most orgs) just lock it down by country, implement mfa and check logs regularly.
If we do SAML SSO for users, are brute force still a risk? Or will that be offloaded to the authentication platform instead
We do something similar (leverage a few threat feeds), but also created a dynamic list orchestration:
- Setup a small *nix web server with a http served text file as a threat feed that our FG can read (security fabric\external connectors).
- Purchased Rapid7 Insight Connect to enable the orchestration between reading the logs that indicated a failed login using a invalid username, extracting the IP from that log, adding it to the text file on the web server.
- Insight Connect relies on a list of “bad” usernames which consists of things like admin, root, tech, system, etc. and any former usernames for folks no longer with the org. This prevents it from triggering on valid failed user logins due to typos.
- As a final step, we use Insight Connect to replicate this block list to OKTA.
- As mentioned above, we periodically review the list and if we have enough IPs from a specific subnet, we’ll collapse those to a /24 or /16, assuming we won’t see legit traffic from that subnet anyway. This of course is more difficult if you have a user population that is spread out all over.
It is a nice “trip wire”.
We currently have 1960 blocked IPs/ranges in that list after 4 months of operation. The attacks come in waves. Mainly consumer cable modems in Canada and US so far.
As an aside, if you are using FortiAuthenticator for MFA, make sure the PCI DSS 3.2 option is enabled.
When you enable this, "All failed authentications will return the same generic message, so as not to reveal any clue to an attacker about which piece of information was valid or invalid:
“Please enter correct credentials. Note that the password is case-sensitive.”
It is a bit silly but a good practice.
My hope would be something along the lines of If known bad username is used then block associated IP/IPs
Starting to get the feeling this is a little too much to ask, I guess.
Thanks. Didn’t know FAZ can do this. Insert the network into an object and add that to the “deny sslvpn” list ?
We’ve already got a deny policy and a geographic restriction applied, but I don’t think we have a threat feed - I’ll look into that one. The issue is these attacks are coming from within the same geo area so that policy isn’t helping stop them. That’s where my desire for blocking IPs based on usernames comes from but is sounds like that probably isn’t possible at this point.
Any performance hit on this? Have a few hundred vpn users and have been contemplating this . For migrating, could I just add the new loopback into all the rules with the sslvpn tunnel interface and also add it as a listener in vpn settings?. Then switch the IP in the VPN url we use to the new public loopback IP? Then when it’s all working remove the old ssl vpn interface from the rules and listener? Thanks in advance
My hope would be something along the lines of If known bad username is used then block associated IP/IPs
You would most likely require a SIEM solution to do this - if the appropriate rule is triggered, run a script that adds an IP address to a maintained list, that you use as a FGT external IP Address Threat feed.
Alright, described like that, it could actually work!
Consider automation stitches.
Trigger: failed SSL-VPN logon event, filtered for username= (filtering is 7.0+ feature).
Action: CLI (or API) call that bans the IP from that log entry.
Doable with just the FortiGate, but not very intelligent. You’d need to clone the stitch for every suspicious name you want to trigger blocking. I’m also not sure if this would be capable of doing subnet-wide blocks. (if the command is willing to accept e.g. 1.2.3.4/24 to block 1.2.3.0/24, then yes. Otherwise no)
For anything more intelligent, you’d need to hook into something that can be made more clever, let it digest the logs, and then feed back the results via e.g. REST API.
We Ban the entire IP with a stitch.
FAZ creates a FortiGate Event Handler and the Fortigate gets the src ip and adds it to the ban list.
I was playing whack-a-mole with login attempts until I set up a threat feed. I had a few hundred Address objects (/16 subnets) blocked but ended up overhauling my approach to use a feed. Im up to about 34,000 networks in the feed now and my SSL attacks have fallen to zero over the last few weeks.
I mean, probably. You could set up all the rules and policies for the loopback interface first, then go into your SSLVPN settings and change the listening interface from your WAN to the loopback interface.
You need to create a Virtual IP that forwards from your WAN IP to the loopback IP, then set the SSLVPN to listen on the loopback interface. There are many guides on how to do this.
Watch your CPU usage as users pile on and see if you have performance problems. Also, is all DNS going through your VPN interface when connected to it or are you using split tunneling? Split tunneling might take some of the load off if its not a security concern for your org.
A few years ago, eveyone wanted $75k for their SOAR products. We were already using Rapid7s Insight VM for vuln scanning so when they came back to us and said we could have Insight Connect for less than $10k we were sold. They price now based on the size of your environment which is far more reasonable. It’s a really nice product, give it a look.