LinkedIn Sourceforge Twitter

Vincent's Blog

Pleasure in the job puts perfection in the work (Aristote)

Block bad visitors with PF

Posted on 2016-11-06 17:04:00 from Vincent in Open Bsd

Those days, when you fire-up a new machine, it takes few hours that bad persons are trying to connect to your machine via ssh, try default URL with default passwords, ...

This post will explain how OpenBSD can easily helps you to ban those persons out of your machine for quite a long time.

update: please look at log2table here

The main goal is to attentively look at your log files and specifically authlog. This idea has been largely developped since several years on Linux with fail2ban.

In /var/log/authlog OpenBSD informs you about any remote connections and their status: success, failed, disconnected, ...

So, basically the idea is to read this file regularly and take the IP of the "bad persons", add it in a specific PF table which will reject for a long time.

Let me explain how I did it in detail

1. Approach

1.1 Recognize the layout of the messages

Here after some of the main message I can see in this authlog file:

Oct 24 23:12:44 myopenbsdserver sshd[50476]: Failed password for root from xx.xx.xx.108 port 48822 ssh2
Oct 24 23:12:46 myopenbsdserver sshd[50476]: Received disconnect from xx.xx.xx.108 port 48822:11:  [preauth]
Oct 24 23:13:02 myopenbsdserver sshd[32493]: Invalid user adam from xx.xx.xx.218 port 24329
Oct 24 23:13:02 myopenbsdserver sshd[32493]: Failed password for invalid user adam from xx.xx.xx.218 port 24329 ssh2
Oct 25 11:49:34 myopenbsdserver sshd[94860]: Failed password for invalid user ubnt from xx.xx.xx.60 port 36656 ssh2
Oct 25 11:49:34 myopenbsdserver sshd[94860]: Connection closed by xx.xx.xx.60 port 36656 [preauth]
Oct 25 12:41:54 myopenbsdserver sshd[72644]: Connection closed by xx.xx.xx.216 port 40666 [preauth]
Oct 25 12:43:29 myopenbsdserver sshd[26963]: Connection closed by xx.xx.xx.216 port 53315 [preauth]
Oct 25 12:49:55 myopenbsdserver sshd[140]: Connection closed by xx.xx.xx.216 port 47433 [preauth]
Oct 25 13:25:05 myopenbsdserver sshd[45542]: Connection closed by xx.xx.xx.45 port 55353 [preauth]

(I have masked the IPs to avoid problems with their owners)

Basically the idea will be to recognize some of the most annoying messages and see where we can find the IP of the requestor.

In my case I'm interested to block persons trying false passwords and persons opening and closing connections. Thus my searching rules will be:

RE_FAILED = re.compile(".* Failed .* from ([\S]+)")
RE_CLOSED = re.compile(".* Connection closed by ([\S]+) .*")

As you may have deduce, I'm using Python's regular expression to help for such task. You can use several other programming languages, most of them have pattern recognition.

What this code does is:

  • to record the word just after "from", when we have Failed in the log file.
  • to record the word just after "closed by" when we have Connection closed by in the log file.

Thanks to PF, adding a bad IP is quite easy and could be done with a command like this:

pfctl -t bruteforce -T add 111.222.333.444

1.2 Block bad IPs listed in the associated PF table

As we are running this on OpenBSD, we can rely on the wonderful packet filter (called PF) provided with the base system.

So, within your PF rules you should have in /etc/pf.conf, you should add the following:

table <bruteforce> persist
block in quick proto tcp from <bruteforce> to any

Such command is quite easy to understand. It says that every IP listed in the table called bruteforce are immediately blocked.
We block them on any ports. So, they will no more be able to access the server.
In my case we block the TCP protocol. But you could use udp and icmp too.

1.3 Add some white lists

Imagine that, during one very hard day, you are so tired you mistype your password during your ssh connection. In such case, OpenBSD will says in the authlog file that your IP has provided a false password. The RE_FAILED rule will be triggered and you will be in big troubles.

So, let's define a white list of IPs that your script will never adds in the bruteforce table of PF.

2 Let's glue all those concept into one small program.

As said, I'm mainly using Python for my scripts. Feel free to use others languages if your prefer. Here after I'll just share how I've glued all those concepts together.

Before putting all those elements together, I would introduce one Python nice tool called pygtail which will allow you to read the file just where you were after the previous analysis. This avoid le to treat two times the same data of the log file. As for each Python's extension, you can install it with pip install pygtail command.

Our script will become something like this:

#if not present, install this extension with the command "pip install pygtail"
from pygtail import Pygtail
import re,os,os.path
import sys
import datetime

#the file we will check 
LOGFILE = "/var/log/authlog"
#the file containing our white list of IPs. One IP per line
CONFIG = "/etc/accepted_ips"

#we are using dictionary for IPs to simplify and speedup the search 
bad_ips = {}

#we populate IPs contained in the CONFIG file into the accept_ips dictionary
def read_ips():
    if os.path.isfile(CONFIG):
        fid = open(CONFIG,"r")
        for line in fid.readlines():
            if line.strip():
                accept_ips[line.strip()] = ""

#We let the possibility to use an another input file for testing purposes   
if len(sys.argv) == 3 and sys.argv[1] == "-f":
   LOGFILE = sys.argv[2]

#Our 2 main rules
#May 31 01:15:15 myvultr sshd[18229]: Failed password for invalid user guest from xx.xx.xx.4 port 57493 ssh2
RE_FAILED = re.compile(".* Failed .* from ([\S]+)")

#May 31 09:40:23 myvultr sshd[22894]: Connection closed by xx.xx.xx.73 port 32863 [preauth]
RE_CLOSED = re.compile(".* Connection closed by ([\S]+) .*")


#The follwing part read the log file and store the bad IPs in the bad_ips dictionary
#This code, assign a counter to each rule defined. 
#This allows me to not ban a user having done very few bad manipulations. 
for line in Pygtail(LOGFILE):
    ret = RE_FAILED.match(line)
    if ret:
        bad_ip = ret.groups()[0]
        bad_ips[bad_ip] += 9           #9 points for such "bad " event
    ret = RE_CLOSED.match(line)
    if ret:
        bad_ip = ret.groups()[0]
        bad_ips[bad_ip] += 1           #1 point for such event

#We loop accross the bad_ips
for bad_ip,occurence in bad_ips.items():
    #Only if the bad ip identified is not present in our "white list" we will add it in the PF table
    if bad_ip not in accept_ips:
        print "Occurence: %s, IP:%s" % (occurence,bad_ip)
            #if the counter is above 5, we ban the IP. 
        if occurence>5:
            cmd = "pfctl -t bruteforce -T add %s " % bad_ip
            print "CMD:%s" % (cmd)
            if len(sys.argv)==3 and sys.argv[1] == "-f":
                    #we are in testing mode and we don't want to bad our test IPs

print "="*10

As you see, I'm providing points to bad IPs depending on their actions. If the total, for a specific IP, is bigger than 5, I ban it by adding this IP in the bruteforce table of PF.

The remaining task will be to add this scrip in the crontab. Since we are using pfctl command, the crontab of root will be required.
You could use doas and assure that your user is able to run this command in /etc/doas.conf. If you prefer this, I let you check the man pages of doas.conf.

*/5     *       *       *       *       /usr/local/bin/python2.7 -u /usr/local/bin/ >> /var/log/parse_authlog.log 2>&1

In this case, I'm doing the check every 5 minutes. Up to you to adapt this value. This is in fact a trade-off between the delay you let hackers try different techniques and the number of records you have in /var/log/authlog. If this delay is too short, you could not identify slow, but real attacks.

Please note that I'm using python -u to unbuffer the outputs. This allow me to follow, on real time, the data added into parse_authlog.log in real time. I know this not the ideal way of doing it, but I'm lazy :(

2.2 Performing some cleanup

As you could imagine our bruteforce table will increase days after days. This could become a problem if the table becomes too big.

So, here again, PF has a very decent solution:

pfctl -t bruteforce -T expire 86400

With this command, you can cleanup IPs added into bruteforce more than 1 day ago.

So, you can add this line in your crontab:

1       *       *       *       *       /sbin/pfctl -t bruteforce -T expire 86400 >> /var/log/parse_authlog.log 2>&1

Here I'm doing the cleanup every hours. Up to you to adapt this to your needs.

You can always check the content of the bruteforce table with the following command:

pfctl -t bruteforce -T show

For your info, my parse_autolog.log file look like this:

2016-10-24 01:55:01.929585
2016-10-24 02:00:02.162995
Occurence: 10, IP:xx.xx.xx.131
CMD:pfctl -t bruteforce -T add xx.xx.xx.131
1/1 addresses added.
1/1 addresses expired.
2016-10-24 02:05:01.285829
2016-10-24 02:10:01.439906
2016-10-24 02:15:01.580643

We see that 1 IP has been banned because is score is above 5 (score is 10).
We see too that 1 IP has been remove from the bruteforce table.
During the other scan, nothing has been performed.

3 Lessons learned

This small script runs quite well since few months.
I have nearly always 10 IPs banned. But they are not always the same.

This is a good alternative to the fail2ban, and it does a good job.

There are several possible improvement, like:

  • ban an IP forever (never remove it from bruteforce) if this IP try 2 attacks in the same week.
  • ban that range in which the banned IP reside
  • check the country of the IP before ban it
  • ...

22, 17
displayed: 3251

1. From thuban on Mon Nov 28 11:15:58 2016

This seems amazing and yet simple ! I think I'll hack it a little when I'll have some time. keep on the good work ;)

2. From thuban on Mon Dec 19 16:55:58 2016

Hi, I used your work to write something usable for any file. See here : Regards.

3. From Karloszvop on Mon Jan 28 07:18:40 2019

Взять микрокредит на карту - легко и просто на портале ВСЕ-ЗАЙМЫ-ТУТ.РФ Денежные активы могут понадобиться в долг неожиданно. Сейчас почти не найти тех, кто не брал деньги в долг. Из-за этого большое количество заемщиков сталкивались с мошенниками. Если вы не хотите попасть в ловушку, вам надо получать займы на проверенных ресурсах. Многие задаются вопросом о том, где же найти такой ресурс. Оптимальное решение – найти портал, который размещает проверенные МФО. Одним из таких есть все-займы-тут.рф, на котором вы можете выбрать МФО, где вы сможете получить деньги сразу же. Если вас интересует ресурс, где вы можете получить деньги в долг без отказа, на сайте находится целый перечень таких МФО. На сайте приятный дизайн, удобный интерфейс, что не может не радовать посетителей. Разобраться на портале сможет любой посетитель. Вы можете взять займ на киви или WebMoney. Если вам нужен [url=http://все-займы-тут.рф/]онлайн займ[/url], вы стремитесь получить деньги на банковскую карту СберБанка, принять средства на Visa или MasterCard, сделать это теперь просто. На ресурсе вы можете найти надёжные сервисы, которые работают мало того, что круглосуточно, так еще и предоставляют большому количеству заемщиков средства. Отказ по статистике в целом маленький. Срочные онлайн займы на карту без проверок и без отказов Когда человеку в сжатые сроки нужны денежные средства, он идёт в банк. В наши дни в банках необходимо предоставить перечень документов. Их будут долго проверять, после чего вам выдадут кредит. Если вы не хотите длительное время ждать, обращайтесь на все-займы-тут.рф, где вы с легкостью сможете взять средства в кредит. Если вас смущают долгие проверки кредитных историй, у вас нет желания ждать, на сервисе вы сможете найти МФО, которое будет вам интересно. На ресурсе размещены компании, которые выдают средства от 1 дня до 30 дней и более. Условия займов у многих МФО очень лояльные. Ключевая цель МФО – помочь мужчинам решить финансовые вопросы. Именно по этой причине они стараются помочь заемщикам с любыми вопросами. Получить кредит вы можете, используя мобильное устройство или ноутбук. Для получения денег вам нужно зайти на ресурс и выбрать сервис. Сделать это очень просто. На ресурсе находятся самые лучшие МФО, которые предоставляют средства в долг. Время получения финансов у многих МФО от 3 до 10 минут. Вы можете быть спокойны, что, если вам потребуются срочно денежные средства, процентная ставка не будет расти из-за этого. На нашем финансов ресурсе собраны сервисы, которые предоставляют [url=http://все-займы-тут.рф/]срочно деньги онлайн на карту без отказа[/url] - вам не нужно поручительство со стороны или залог. Надо подчеркнуть и то, что вам не нужно брать справку с места работы, чтобы вы могли получить займ. Как оформить займ на банковскую карту Достаточно кредитных сервисов разрабатывают сложные алгоритмы того, как получить online займ. Если вам потребовались деньги, нужно зайти на все-займы-тут.рф, где вы можете выбрать интересующую вас МФО. Среди большинства компаний вам нужно выбрать именно ту, которая вас заинтересует. Надо выделить и то, что получить деньги можно только гражданам России. Для получения денежных активов надо иметь паспорт гражданина РФ, мобильный номер. После того, как вы зайдёте на портал и выберете сервис, вы можете выбрать также и вариант получения денежных средств. Это может быть Visa, MasterCard или МИР. В наши дни большое количество сервисов одобряют сразу же заявки. Вам не потребуется иметь официальный доход, который вы будете обязаны показать. После выбора МФО вам необходимо ознакомиться с условиями микрозайма. Все займы предоставляются на определенный срок и у них есть максимальная сумма. Процентная ставка не очень отличается от ставок в банковских учреждениях. Именно по этой причине МФО сейчас очень популярны и у них достаточно заемщиков. Нужно отметить и возрастную категорию. Некоторые сервисы предоставляют средства после 18 лет, а некоторые после 21 года. Для того, чтобы ваша заявка была обработана быстрее обычного, вы можете написать менеджеру в чат. Хотя, все заявки и так моментально мониторятся и проходят проверку администраторами. После просмотра вашей заявки она сразу получает одобрение. Можете не сомневаться, что, выбрав одну из организаций на ресурсе, вы получите в 95% случаев деньги в займ. Каким способом погасить займ Детальную информацию о том, как выплатить займ, можно получить у менеджеров по адресу Россия, Москва, улица Тверская, 22, куда вы можете явиться в любой момент. Для выплаты финансовых активов можно использовать терминал любого банка или его отделение. Погасить кредит можно также через удобный для вас платежный электронный сервис. Оптимально, чтобы после погашения займа вы получили квитанцию. Если вы проявите желание, погасить кредит можно также в МФО, которые выдали вам средства. Их контакты реально найти на портале или узнать у менеджеров. На все-займы-тут.рф вы можете детально ознакомится с информацией о том, как выплачивать займ. Погасить кредит можно в любое время суток. По интересующим Вас вопросам о погашении вы также можете обращаться к менеджерам.

4. From BardomPaurn on Wed Jan 30 14:44:32 2019

Сейчас почти у любого мужчины есть спортивные кроссовки. Они могут быть полезными не только в целях спорта, их можно использовать для переезда, туризма и т.д. Сегодня на рынке есть достаточно подделок на оригинальные модели. Именно из-за этого кое-каким покупателям перестают нравится кроссовки определенных брендов. Вы легко можете заказать кроссовки Nike или Adidas на портале интернет-магазина, где собраны крутые модели. Купить брендовые кроссы со скидкой в интернет магазине Если вы не знаете, где приобрести фирменные кроссовки, оптимально зайти в паутину и выбрать какой-то интернет-магазин. Там вас детально проконсультируют и расскажут о свойствах кроссовок. На вы найдете [url=]nike original[/url] и кроссовки фирмы Nike. Большинство моделей, которые доступны на сайте – модели прошлой коллекции. Вы можете в сжатые сроки найти что-то для себя со скидкой. Компания специализируется на спортивных кроссовках. У вас есть шанс купить варианты для отдыха или для мероприятий. Если у вас существует цель подобрать отличные кроссовки по небольшой цене, у вас будет шанс заказать кроссовки с огромной скидкой. Все товары, которые размещены на сайте являются известными брендами. Если вы стремитесь найти именно фирменные модели, на сайте интернет-магазина сделать это очень легко. В наличии магазина более 300 моделей для мужчин и женщин. На все товары есть скидки. Вы можете выбрать кроссы Nike Air Force 270 black по очень выгодной цене. Если вы длительное время желали купить женские кроссовки New Balance 998 Rose, такая модель также есть на ресурсе со скидкой. Сейчас многие хотят заказать кроссовки для любимого человека, хотя выбор сделать им очень сложно. Если вы не знаете, какие кроссы лучше заказать, получить справку можно у администраторов компании. Вы можете позвонить по телефону +7(495)642-26-83 и обсудить все по любым вопросам. Компания размещена по адресу Москва, Проспект мира 103., куда вы также можете приехать самостоятельно. Мужские и женские кроссовки с быстрой доставкой по Москве В наши дни доставка существует далеко не во всех интернет-магазинах в Москве. К сожалению, если вам пришлась по душе определенная модель, и вы её не можете купить – вам будет очень жалко. Оптимальный вариант – выбрать интернет-магазин, где вы моментально можете заказать кроссовки Nike или Adidas с доставкой. На вы в любом случае найдёте те кроссовки, в которые вы влюбитесь! На НГ часто молодые люди дарят своим девочкам кроссовки New Balance. Такие кроссовки очень практичные и их комфортно носить, как и [url=]nike белые air force[/url] . Вы можете использовать их в любых целях и даже заниматься бегом. Во многих моделях создана определенная технология, которая защищает ногу. Также нужно сказать пару слов и про бактериальную стельку, которая сейчас есть во многих кроссовках New Balance. Покупка кроссовок через сеть очень удобная. Вы получаете не только гарантийные обязательства, но у вас есть также возможность и обменять кроссовки в течение 14 дней. Если из-за чего-то вас не устроил товар, вы можете его сдать. Оплатить кроссовки Nike или New Balance вы можете через портал. Оплатить кроссовки вы можете с помощью кредитной карты Visa или MasterCard. Если у вас есть цель сравнить конкретные модели, сделать это также можно на сайте. Вы можете выбрать к сравнению цветовую гамму, модель, формат кроссовок. На данный момент очень ценятся мужские кроссовки Asics Gel Lyte 5, которые на постоянной основе заказывают. У этих кроссовок лояльная цена, а служат они не год и не два. Если вы хотите найти крутые кроссовки для спорта, вы легко можете заказать Adidas Equipment Running Support 93. Они будут служить вам минимум пару лет. Нужно также выделить, что, если вы не знаете, какую модель выбрать, лучше посоветоваться с консультантами. Сотрудники внимательно выслушают Вас и предложит отличный вариант.

How much does 3 plus 2 ?