Vi kopiis OpenVPN kaĝon el komunuma afiŝo, restartigis fail2ban, kaj neniu adreso iam estas blokita. La kialo preskaŭ ĉiam estas la logformo: Access Server ne skribas la malsukcesajn aŭtentikigajn liniojn, kiujn atendas norma filtro. Antaŭ ol tuŝi la filtron, kontrolu, ĉu la rikordoj entute ekzistas, ĉar ŝablono ne povas kongrui kun tio, kion la servo neniam registris.

Jen la runbook, kiun mi sekvas sur Access Server-gastiganto: konfirmi la formon de la rikordo, skribi unu ankritan esprimon, testi ĝin kontraŭ la reala log, poste dividi la kaĝojn laŭ la atakata surfaco kaj kontroli, ke la blokado atingas la fajroŝirmilon.

Konfirmu, ke la erarrikordo ekzistas

Access Server skribas siajn proprajn strukturajn liniojn al /var/log/openvpnas.log, kaj la klienta adreso troviĝas en kampo real_ip inter citiloj, ne komence de syslog-linio. Serĉu malsukcesan ensaluton, pri kiu vi scias, ke ĝi okazis, antaŭ ol skribi ajnan ŝablonon:

grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20

Se nenio aperas, la lognivelo estas la sekva suspektato. Access Server havas sencimigan ŝaltilon por la logdatumbazo en /usr/local/openvpn_as/etc/as.conf (DEBUG_LOGDB=1), kaj la servo devas esti restartigita post ŝanĝi ĝin. Traktu tiun ŝaltilon kiel diagnostikan agordon, kiun oni reŝraŭbas malsupren post kiam vi havas vian ŝablonon, ne kiel permanentan agordon.

Dum vi estas en la dosiero, notu, kiuj surfacoj skribas en ĝin. Malsukcesoj de la klienta portalo, de la administra interfaco kaj de la tunela aŭtentikigo finiĝas en la sama dosiero kun malsamaj markiloj, kaj tiu detalo decidas poste la aranĝon de la kaĝoj.

Ankru unu filtron sur real_ip

Tenu la esprimon mallarĝa. Filtro, kiu postulas ĉiun linion enhavantan IP-adreson, blokos homojn pro ordinaraj malkonektoj, kaj sur okupata servilo la sola simptomo estas uzantoj plendantaj, ke oni ŝlosis ilin ĉar ili fermis tekkomputilon. Postulu la erarrikordon kaj kaptu la adreson inter citiloj:

# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =

La komenca spaco ne estas kosmetika. Access Server deŝovas siajn rikordojn, kaj ankri sur ĝi malhelpas la ŝablonon ankaŭ postuli liniojn, kiujn sendependaj servoj skribas en la saman dosieron. Se viaj rikordoj male portas komencan temposignon, kongruu tiun prefikson, sed ankru sur io, kio vere ĉeestas en ĉiu rikordo, kiun vi intencas postuli.

Kiam vi bezonas precizecon laŭ surfaco, mallarĝigu plu postulante la surfacan markilon (WEB_CLIENT, WEB_ADMIN aŭ VPN) en la sama linio. Unu filtro kun tri ŝablonoj estas pli facile revidebla ol tri filtroj, kiuj diferencas per unu vorto.

Testu la esprimon antaŭ ol ebligi kaĝon

Neniam ebligu filtron, kiun vi ne ruligis kontraŭ la produktada log. La dokumentita testo pasigas la filtron dufoje, unufoje por ŝargi kaj unufoje por apliki, kaj la raporto pri maltrafitaj linioj estas la parto inda legi:

fail2ban-regex --print-all-missed /var/log/openvpnas.log \
  /etc/fail2ban/filter.d/openvpnaccess.local \
  /etc/fail2ban/filter.d/openvpnaccess.local > missed.txt

Komparu la nombron de trafoj kun la malsukcesoj, kiujn vi konfirmis en la unua paŝo. Nul trafoj signifas, ke la ŝablono estas malĝusta; trafoj sur linioj, kiuj ne estas aŭtentikigaj malsukcesoj, signifas, ke ĝi estas tro larĝa. Legu missed.txt ĝis vi povos klarigi ĉiun linion, kiun vi elektis ne postuli.

Faru ĉi tiun teston sur kopio, se la log estas granda, kaj ripetu ĝin post ĉiu ĝisdatigo de Access Server. La logformo estas la interfaco, kontraŭ kiu vi kongruas, kaj ĝi ne estas stabila API.

Dividu kaĝojn laŭ surfaco, ne laŭ demono

Unu Access Server prezentas plurajn aŭtentikigajn surfacojn: klientaj kaj administraj retinterfacoj sur 943/tcp, kaj la tunelo sur 1194/udp aŭ 443/tcp en plej multaj instaladoj. Unu kaĝo kovranta ĉiujn permesas al divenaj provoj sur la tunelo bloki adreson, kiu estas ankaŭ via administra vojo, kaj ĝi kaŝas, kiu surfaco estas fakte atakata. Donu al ĉiu surfaco sian propran kaĝon kun propra pordo kaj sojloj:

# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled  = true
port     = 943
protocol = tcp
filter   = openvpnaccess
logpath  = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime  = 1h
[openvpnas-tunnel]
enabled  = true
port     = 443
protocol = udp
filter   = openvpnaccess
logpath  = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime  = 1h

Komencu per malgrandaj nombriloj kaj mallonga blokado, poste altigu ilin, kiam vi observis semajnon da reala trafiko. Malavara sojlo sur komuna oficeja adreso punas ĉiun uzanton malantaŭ unu NAT, kaj agresema blokado sur la tunela surfaco malkonektas legitimajn klientojn, kies konservitaj akreditaĵoj eksvalidiĝis dum la nokto.

Kontrolu la blokadon, la backend kaj la flankan damaĝon

Post restarto, la statusa eligo estas la plej rapida konfirmo, ke la kaĝo ekzistas kaj kalkulas:

fail2ban-client status
fail2ban-client status openvpnas-tunnel

Poste konfirmu, ke la blokado atingas la fajroŝirmilon, kiun vi efektive funkciigas, ĉar kaĝo agordita por backend, kiun neniu plenumas, protektas nenion. Kun la iptables-ago la adresoj aperas en ĉeno nomita laŭ la kaĝo (f2b-openvpnas-tunnel); kun la nftables-ago ili falas en aron en la propra tabelo de fail2ban. Kontrolu tiun, kiun via gastiganto uzas, anstataŭ supozi.

Du flankaj kontroloj pli gravas ol la blokado mem. Unue, kontrolu, ke real_ip estas la klienta adreso kaj ne ŝarĝbalancilo aŭ inversa prokurilo; malantaŭ prokurilo ĉiu blokado falas sur la prokurilon kaj trenas la tutan servon kun si. Due, skribu la proceduron por malbloki, ĉar la adreso, kiu superas la sojlon je 02:00, kutime apartenas al la deĵora inĝeniero: fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24.

Memoru la limon dum agordado. Fail2ban estas rapidolimigilo sur unu aŭtentikiga surfaco, ne tavolo de alirkontrolo. Ĝi ne anstataŭas MFA, limigojn laŭ konto aŭ tenadon de la administra interfaco ekster la publika interreto, kaj Access Server havas proprajn autoban-agordojn, kiujn indas kontroli antaŭ ol staki du rapidolimigilojn sur la sama pordo.

Rilataj artikoloj