Skip to content

Commit 8f02ee5

Browse files
authored
Merge pull request #273 from cmckee786/u13-bonus-fixes
fix(u13-bonus): several clarifications and corrections
2 parents c80731d + e9c5c6b commit 8f02ee5

1 file changed

Lines changed: 52 additions & 30 deletions

File tree

src/u13b.md

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ the skills and principles outlined by this course.
3939

4040
First lets identify a couple dependencies for this lab. Since many of the labs in
4141
this course are predicated on Rocky we will provide commands like `dnf` and `rpm`
42-
to accomplish this task.
42+
to accomplish this task:
4343

4444
```bash
4545
rpm -ql openssh-server
@@ -50,14 +50,29 @@ to run an SSH server if `openssh-server` is installed locally. But be careful,
5050
sometimes this query will list lingering configuration files and directories even though
5151
it isn't installed.
5252

53-
To corroborate our findings, let's query `dnf`
53+
To corroborate our findings, let's query `dnf`:
5454

5555
```bash
5656
dnf list --installed | grep openssh-server
5757
```
5858

59-
If the piped grep command comes up empty `openssh-server` is not installed, install it.
60-
Hopefully these commands and strategies are familiar to you.
59+
All else fails you can always attempt a `find` command to verify the presence of SSH
60+
and its server side counter part SSHD (D for daemon):
61+
62+
```bash
63+
find / -name ssh; find / -name sshd
64+
```
65+
66+
You may need to use the `-xdev` flag if other filesystems are present or traversable that are
67+
external to the host that `find` executes from, this flag comes in handy with WSL subsystems or
68+
hosts residing within a hypervisor that have other host file systems mounted and accessible.
69+
70+
Fair warning, this command may spit out a lot of output. Familiarity with the Linux filesystem
71+
and its inner machinations should prepare you for this moment. If not, this command attempts to
72+
find every file with ssh or sshd in it from the root of the host's file system '/'.
73+
74+
If the piped grep or find command comes up empty `openssh-server` is likely not installed, attempt to
75+
install it. Hopefully these commands and strategies are familiar to you:
6176

6277
```bash
6378
dnf install openssh-server
@@ -137,7 +152,7 @@ Plus, it's kinda cool and pretty fun.
137152

138153
#### How Fail2Ban Works
139154

140-
Fail2Ban is designed to analyze log files and manipulates the host's firewall to programmatically ban
155+
Fail2Ban is designed to analyze log files and manipulate the host's firewall to programmatically ban
141156
offending IP addresses based on various conditions predicated by specific configuration files.
142157

143158
First let's briefly skim Fail2Ban's main configuration file:
@@ -290,6 +305,7 @@ ignoreip = {IP_ADDRESS} # useful to prevent banning oneself
290305
backend = systemd # required for systemd based systems
291306
enabled = true
292307
```
308+
293309
Let's make sure to save our new `jail.local` file before we restart Fail2Ban. The following command
294310
will write and persist the local jail configuration file and quit out of Vim, if you didn't know how
295311
to do this already.
@@ -324,22 +340,23 @@ fail2ban-client status sshd
324340

325341
<img src="./assets/downloads/u13/sshbans.png"></img>
326342

327-
Typically SSH services are not exposed publicly to the internet. It is a far better solution to lock
328-
SSH behind a Virtual Private Network (VPN) where something like a "slow brute-force" attack will be
329-
mitigated almost entirely.
343+
Typically SSH services should not be exposed publicly to the internet, and if they are they should utilize
344+
[public key infrastructure](https://www.fortinet.com/resources/cyberglossary/public-key-infrastructure)
345+
(PKI) with specific security constraints (see STIG or CIS Benchmark Controls). Generally It is a far better
346+
solution to lock SSH access behind an internal or Virtual Private Network (VPN) where the potential of a
347+
"slow brute-force" attack will be mitigated almost entirely.
330348

331-
However you still might institute Fail2Ban even behind the VPN in the event a threat actor does gain
332-
access to the VPN and attempts to brute force or slow brute force attack hosts with SSH services exposed.
333-
334-
Given how easy it is to implement Fail2Ban, why wouldn't you? Well, there's always a bigger fish, but that
335-
is a different conversation.
349+
However you still might institute Fail2Ban even behind a VPN in the event a threat actor does gain
350+
access to the VPN and attempts to brute force or slow brute force attack hosts with SSH services exposed that utilize
351+
passwords instead of PKI. However in this day and age password protected SSH access could be considered a security controls
352+
finding. Use PKI whenever possible.
336353

337354
### NGINX
338355

339356
If you've made it this far I appreciate your tenacity or perhaps deep captivation of this subject.
340357

341-
Now where Fail2Ban really shines is when integrated with an application like `nginx`. As we'll see
342-
Fail2Ban allows us to configure what they call "filters" that can further protect `nginx` and our website,
358+
Now where Fail2Ban really shines is when integrated with an application like [nginx](https://nginx.org/).
359+
As we'll see Fail2Ban allows us to configure what they call "filters" that can further protect `nginx` and our website,
343360
if we had one. Since this lab has ran long I will keep it brief.
344361

345362
Suffice it say for students this is theory, but as I will mention later these filters can be quite powerful.
@@ -387,25 +404,29 @@ journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
387404
# Author: Jan Przybylak
388405
```
389406

390-
Whenever nginx receives a "bad request", think a request for a link, file, or directory that doesn't
391-
exist in the domain or shouldn't be accessible, Fail2Ban will recognize it from the `nginx` access.log
392-
by a 404 return made by `nginx` and act appropriately based upon our default action options.
407+
Whenever nginx receives a ["bad request"](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/400), think
408+
an HTTP method request for a link, file, or API call that is malformed or improperly formatted from a client, Fail2Ban
409+
will recognize it from the `nginx` access.log by an HTTP Status Code 400 returned by `nginx` and act appropriately based
410+
upon our default action options.
393411

394412
(After 2 bad requests, you get banned for an hour. After that timeout, if you send 2 more bad requests
395-
the timeout is extended for 24 hours, growing exponentially for each occurrence afterwards up to a 5 week ban.
396-
It is typically advised against implementing permanent bans as over time this will lead to potentially significant
397-
overhead for the host.)
413+
the timeout is extended for 12 hours, growing exponentially for each occurrence afterwards up to a 5 week ban.
414+
It is typically advised against implementing permanent bans as over time this could lead to potentially significant
415+
overhead for the host or lockout legitimate users unintentionally.)
398416

399417
When running this filter on my own personal nginx web server over the course of 30 days I will have
400-
banned over 40,000 IP addresses with varying ban times.
418+
banned over 40,000 IP addresses with varying ban times. But note that this filter can and will match requests that are
419+
malformed from the site itself. If a link or API implementation hosted from the nginx web server is incorrect Fail2Ban could be
420+
banning legitimate traffic unintentionally. Be sure to observe due diligence in log files or web traffic when first implementing
421+
such a filter.
401422

402423
As of rebooting my publicly available website not minutes ago this is how many IP addresses are already banned.
403424

404425
<img src="./assets/downloads/u13/nginxbans.png"></img>
405426

406-
And here is how Fail2Ban manipulates `iptables` by default, though ideally Fail2Ban is configured to utilize
407-
`nftables`, [a modernized and significantly improved firewall solution](https://debian-handbook.info/browse/stable/sect.firewall-packet-filtering.html),
408-
or `firewalld` which has access to firewall [architectures](https://firewalld.org/documentation/architecture.html) like `iptables`, and `nftables`.
427+
Ideally Fail2Ban is configured to utilize `nftables`, [a modernized and significantly improved Linux firewall backend solution](https://wiki.debian.org/nftables),
428+
and some type of firewall backend wrapper like `firewalld` which can be configured for specific firewall backend
429+
[architectures](https://firewalld.org/documentation/architecture.html) like `iptables`, and `nftables`.
409430

410431
Configuring Fail2Ban with `firewalld` or `nftables` will look like such:
411432

@@ -432,8 +453,8 @@ I highly, highly encourage students have a working understanding of Linux firewa
432453
It's important to be stated that this should be understood as a **mitigation**, not a perfect solution. Primarily
433454
to minimize automated bots scraping a domain, usually for nefarious purposes.
434455

435-
And I will iterate there are far better solutions for free ([Cloudflare WAF](https://developers.cloudflare.com/waf/get-started/))
436-
that protect more intelligently and robustly than Fail2Ban. Migrating your domain over to Cloudflare or equivalent service
456+
And I will iterate that there are far better solutions. Some for free and others, ([Cloudflare WAF](https://developers.cloudflare.com/waf/get-started/)),
457+
for a modest fee that protect more intelligently and robustly than Fail2Ban. Migrating your domain over to Cloudflare or equivalent service
437458
is probably the far smarter and less work intensive task than a comprehensive Fail2Ban setup. But I like to think we're building our
438459
muscles... you know, putting in reps.
439460

@@ -454,14 +475,15 @@ enabled = true
454475
port = http,https
455476
logpath = %(nginx_access_log)s
456477
```
457-
Be sure to fave the file:
478+
479+
Append these lines to the earlier file we implemented after our SSHD section and let the regex do the work for us.
480+
481+
Be sure to save the file:
458482

459483
```bash
460484
:wq
461485
```
462486

463-
Append these lines to the earlier file we implemented after our SSHD section and let the regex do the work for us.
464-
465487
Then finally restart Fail2Ban again:
466488

467489
```bash

0 commit comments

Comments
 (0)