Halo rekan! Hari ini, ketika intensitas minat seputar "pekerjaan jarak jauh" sedikit mereda, sebagian besar admin memenangkan tugas akses jarak jauh karyawan ke jaringan perusahaan, saatnya berbagi pengalaman lama saya dalam meningkatkan keamanan VPN. Artikel ini tidak akan menjadi mode sekarang IPSec IKEv2 dan xAuth. Ini tentang membangun sistem.
Hari ini saya akan memberi tahu Anda cara melindungi MikroTik PPP-VPN meskipun akun pengguna "dibajak". Ketika skema ini diperkenalkan ke salah satu pelanggan saya, dia secara singkat menggambarkannya sebagai "yah, sekarang seperti di bank!".
Metode ini tidak menggunakan layanan autentikator eksternal. Tugas dilakukan secara internal oleh router itu sendiri. Tidak ada biaya untuk menghubungkan klien. Metode ini berfungsi untuk klien PC dan perangkat seluler.
Skema perlindungan umum adalah sebagai berikut:
- Alamat IP internal pengguna yang berhasil terhubung ke server VPN secara otomatis masuk daftar abu-abu.
- Peristiwa koneksi secara otomatis menghasilkan kode satu kali yang dikirim ke pengguna menggunakan salah satu metode yang tersedia.
- Alamat dalam daftar ini memiliki akses terbatas ke sumber daya jaringan lokal, kecuali layanan "authenticator", yang menunggu untuk menerima kode akses satu kali.
- Setelah menyajikan kode, pengguna memiliki akses ke sumber daya internal jaringan.
Pertama masalah terkecil yang harus saya hadapi adalah menyimpan informasi kontak tentang pengguna untuk mengirimkan kode 2FA kepadanya. Karena tidak mungkin membuat kolom data arbitrer yang sesuai dengan pengguna di Mikrotik, kolom "komentar" yang ada digunakan:
/rahasia ppp tambahkan nama=kata sandi Petrov=4M@ngr! komentar="89876543210"
Kedua masalahnya ternyata lebih serius - pilihan jalur dan metode pengiriman kode. Tiga skema saat ini diimplementasikan: a) SMS melalui USB-modem b) e-mail c) SMS melalui e-mail tersedia untuk klien korporat operator seluler merah.
Ya, skema SMS menimbulkan biaya. Tetapi jika Anda perhatikan, "keamanan selalu tentang uang" (c).
Saya pribadi tidak suka skema dengan email. Bukan karena ini membutuhkan server email yang tersedia untuk klien yang diautentikasi - tidak masalah untuk membagi lalu lintas. Namun, jika klien dengan ceroboh menyimpan kata sandi vpn dan email di browser dan kemudian kehilangan laptopnya, penyerang akan mendapatkan akses penuh ke jaringan perusahaan darinya.
Jadi, sudah diputuskan - kami mengirimkan kode sekali pakai menggunakan pesan SMS.
Π’ΡΠ΅ΡΡΡ Masalahnya adalah di mana cara generate pseudo-random code untuk 2FA di MikroTik. Tidak ada analog dari fungsi random() dalam bahasa scripting RouterOS, dan saya telah melihat beberapa generator angka pseudo-acak kruk skrip sebelumnya. Saya tidak menyukai salah satu dari mereka karena berbagai alasan.
Faktanya, ada generator urutan acak semu di MikroTik! Tersembunyi dari pandangan sekilas dalam konteks /certificates scep-server. Cara pertama mendapatkan kata sandi satu kali itu mudah dan sederhana - dengan perintah / sertifikat menghasilkan scep-server otp. Jika kita melakukan operasi penugasan variabel sederhana, kita akan mendapatkan nilai array yang nantinya dapat digunakan dalam skrip.
Cara kedua mendapatkan kata sandi satu kali yang juga mudah diterapkan - menggunakan layanan eksternal
kode
:global rnd1 [:pick ([/tool fetch url="https://www.random.org/strings/?num=1&len=7&digits=on&unique=on&format=plain&rnd=new" as-value output=user ]->"da
ta") 1 6]
:put $rnd1
Permintaan yang diformat untuk konsol (mengeluarkan karakter khusus akan diperlukan di badan skrip) menerima string enam digit ke dalam variabel $rnd1. Perintah "put" berikut hanya menampilkan variabel di konsol MikroTik.
Masalah keempat yang harus diselesaikan dengan cepat - ini adalah bagaimana dan di mana klien yang terhubung akan mentransfer kode satu kali pada tahap kedua otentikasi.
Harus ada layanan di router MikroTik yang dapat menerima kode dan mencocokkannya dengan klien tertentu. Jika kode yang diberikan cocok dengan yang diharapkan, alamat klien harus dimasukkan dalam daftar "putih" tertentu, alamat dari mana akses yang diizinkan ke jaringan internal perusahaan.
Karena pilihan layanan yang buruk, diputuskan untuk menerima kode melalui http menggunakan webproxy yang dibangun di Mikrotik. Dan karena firewall dapat bekerja dengan daftar alamat IP yang dinamis, firewalllah yang melakukan pencarian kode, mencocokkannya dengan IP klien dan menambahkannya ke daftar "putih" menggunakan regexp Layer7. Router itu sendiri telah diberi nama DNS bersyarat "gw.local", A-record statis telah dibuat di atasnya untuk diterbitkan ke klien PPP:
DNS
/ip dns statis tambahkan nama=gw.alamat lokal=172.31.1.1
Menangkap lalu lintas klien yang belum diverifikasi di proxy:
/ip firewall nat add chain=dstnat dst-port=80,443 in-interface=2fa protocol=tcp !src-address-list=2fa_approved action=redirect to-ports=3128
Dalam hal ini, proxy memiliki dua fungsi.
1. Buka koneksi tcp dengan klien;
2. Jika otorisasi berhasil, alihkan browser klien ke halaman atau gambar yang memberi tahu tentang otentikasi yang berhasil:
Konfigurasi proxy
/ip proxy
set enabled=yes port=3128
/ip proxy access
add action=deny disabled=no redirect-to=gw.local./mikrotik_logo.png src-address=0.0.0.0/0
Saya akan mencantumkan elemen konfigurasi penting:
- interface-list "2fa" - daftar dinamis antarmuka klien, lalu lintas dari mana memerlukan pemrosesan dalam 2FA;
- daftar alamat "2fa_jailed" - daftar "abu-abu" dari alamat IP terowongan klien VPN;
- address_list "2fa_approved" - daftar alamat IP terowongan klien VPN "putih" yang telah berhasil melewati autentikasi dua faktor.
- rantai firewall "input_2fa" - memeriksa paket tcp untuk keberadaan kode otorisasi dan mencocokkan alamat IP pengirim kode dengan yang diperlukan. Aturan dalam rantai ditambahkan dan dihapus secara dinamis.
Bagan alur pemrosesan paket yang disederhanakan terlihat seperti ini:
Untuk masuk ke pemeriksaan lalu lintas Layer7 dari klien dari daftar "abu-abu" yang belum melewati tahap kedua otentikasi, sebuah aturan telah dibuat dalam rantai "masukan" standar:
kode
/ip firewall filter add chain=input !src-address-list=2fa_approved action=jump jump-target=input_2fa
Sekarang mari kita mulai kencangkan semua kekayaan ini ke layanan PPP. MikroTik memungkinkan Anda untuk menggunakan skrip di profil (profil ppp) dan menugaskannya ke acara pembuatan dan pemutusan koneksi ppp. Pengaturan profil ppp dapat diterapkan ke server PPP secara keseluruhan dan ke pengguna individu. Pada saat yang sama, profil yang diberikan kepada pengguna memiliki prioritas, mengesampingkan parameter profil yang dipilih untuk server secara keseluruhan dengan parameter yang ditentukan.
Sebagai hasil dari pendekatan ini, kami dapat membuat profil khusus untuk autentikasi dua faktor dan menetapkannya tidak untuk semua pengguna, tetapi hanya untuk mereka yang menganggap perlu melakukannya. Ini mungkin relevan jika Anda menggunakan layanan PPP tidak hanya untuk menghubungkan pengguna akhir, tetapi pada saat yang sama untuk membangun koneksi situs ke situs.
Dalam profil khusus yang baru dibuat, kami menggunakan penambahan dinamis dari alamat dan antarmuka pengguna yang terhubung ke daftar alamat dan antarmuka "abu-abu":
kode
/ppp profile add address-list=2fa_jailed change-tcp-mss=no local-address=192.0.2.254 name=2FA interface-list=2fa only-one=yes remote-address=dhcp_pool1 use-compression=no use-encryption= required use-mpls=no use-upnp=no dns-server=172.31.1.1
Penting untuk menggunakan daftar "daftar alamat" dan "daftar antarmuka" untuk mendeteksi dan menangkap lalu lintas dari klien VPN non-sekunder dalam rantai dstnat (prerouting).
Saat persiapan selesai, rantai firewall tambahan dan profil dibuat, kami akan menulis skrip yang bertanggung jawab untuk pembuatan otomatis kode 2FA dan aturan firewall individual.
Kode yang digunakan dalam profil untuk acara koneksi PPP on-up
#ΠΠΎΠ³ΠΈΡΡΠ΅ΠΌ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ :log info (
quot;local-address")
:log info (quot;remote-address")
:log info (quot;caller-id")
:log info (quot;called-id")
:log info ([/int pptp-server get (quot;interface") name])
#ΠΠ±ΡΡΠ²Π»ΡΠ΅ΠΌ ΡΠ²ΠΎΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅
:local listname "2fa_jailed"
:local viamodem false
:local modemport "usb2"
#ΠΈΡΠ΅ΠΌ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΎΠ·Π΄Π°Π½Π½ΡΡ Π·Π°ΠΏΠΈΡΡ Π² Π°Π΄ΡΠ΅Ρ-Π»ΠΈΡΡΠ΅ "2fa_jailed"
:local recnum1 [/ip fi address-list find address=(quot;remote-address") list=$listname]
#ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΏΡΠ΅Π²Π΄ΠΎΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ΅ΡΠ΅Π· random.org
#:local rnd1 [:pick ([/tool fetch url="https://www.random.org/strings/?num=1&len=7&digits=on&unique=on&format=plain&rnd=new" as-value output=user]->"data") 0 4] #Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΏΡΠ΅Π²Π΄ΠΎΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ΅ΡΠ΅Π· Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ
#:local rnd1 [pick ([/cert scep-server otp generate as-value minutes-valid=1]->"password") 0 4 ]#ΠΡΠ΅ΠΌ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ ΠΊ Π·Π°ΠΏΠΈΡΠΈ Π² Π°Π΄ΡΠ΅Ρ-Π»ΠΈΡΡΠ΅. ΠΠ½ΠΎΡΠΈΠΌ ΠΈΡΠΊΠΎΠΌΡΠΉ ΠΊΠΎΠ΄ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ
/ip fir address-list set $recnum1 comment=$rnd1
#ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π½ΠΎΠΌΠ΅Ρ ΡΠ΅Π»Π΅ΡΠΎΠ½Π° ΠΊΡΠ΄Π° ΡΠ»Π°ΡΡ SMS
:local vphone [/ppp secret get [find name=$user] comment]#ΠΠΎΡΠΎΠ²ΠΈΠΌ ΡΠ΅Π»ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ ΠΊ VPN ΠΏΡΡΠΌΠΎ Ρ ΡΠ΅Π»Π΅ΡΠΎΠ½Π° Π΅ΠΌΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ
#Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ ΠΏΡΡΠΌΠΎ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅ ΠΈΠ· ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ
:local msgboby ("Your code: ".$comm1."n Or open link http://gw.local/otp/".$comm1."/")# ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ SMS ΠΏΠΎ Π²ΡΠ±ΡΠ°Π½Π½ΠΎΠΌΡ ΠΊΠ°Π½Π°Π»Ρ - USB-ΠΌΠΎΠ΄Π΅ΠΌ ΠΈΠ»ΠΈ email-to-sms
if $viamodem do={
/tool sms send phone-number=$vphone message=$msgboby port=$modemport }
else={
/tool e-mail send server=a.b.c.d [email protected] [email protected] subject="@".$vphone body=$msgboby }#ΠΠ΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌ Layer7 regexp
local vregexp ("otp\/".$comm1)
:local vcomment ("2fa_".(quot;remote-address"))
/ip firewall layer7-protocol add name=(quot;vcomment") comment=(
quot;remote-address") regexp=(
quot;vregexp")
#ΠΠ΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΠ΅Π΅ ΠΏΠΎ Layer7 ΡΡΠ°ΡΠΈΠΊ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π² ΠΏΠΎΠΈΡΠΊΠ°Ρ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°
#ΠΈ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠΉ Π·Π°ΡΠΈΡΠΎΠΉ ΠΎΡ Π±ΡΡΡΡΠΎΡΡΠ° ΠΊΠΎΠ΄ΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ dst-limit
/ip firewall filter add action=add-src-to-address-list address-list=2fa_approved address-list-timeout=none-dynamic chain=input_2fa dst-port=80,443,3128 layer7-protocol=(quot;vcomment") protocol=tcp src-address=(
quot;remote-address") dst-limit=1,1,src-address/1m40s
Terutama bagi mereka yang suka menyalin-tempel tanpa berpikir, saya peringatkan Anda - kode diambil dari versi uji dan mungkin mengandung kesalahan ketik kecil. Tidak akan sulit bagi orang yang pengertian untuk mencari tahu di mana tepatnya.Saat pengguna memutuskan sambungan, peristiwa "On-Down" dihasilkan dan skrip terkait dengan parameter dipanggil. Tugas skrip ini adalah membersihkan aturan firewall yang dibuat untuk pengguna yang terputus.
Kode yang digunakan dalam profil untuk peristiwa koneksi PPP on-down
:local vcomment ("2fa_".(
quot;remote-address"))
/ip firewall address-list remove [find address=(quot;remote-address") list=2fa_approved] /ip firewall filter remove [find chain="input_2fa" src-address=(
quot;remote-address") ] /ip firewall layer7-protocol remove [find name=$vcomment]
Anda kemudian dapat membuat pengguna dan menetapkan semua atau sebagian dari mereka ke profil autentikasi dua faktor.winbox
kode
/ppp secrets set [find name=Petrov] profile=2FA
Bagaimana tampilannya di sisi klien.
Saat koneksi VPN dibuat, ponsel/tablet Android/iOS dengan kartu SIM menerima SMS seperti ini:
SMS
Jika koneksi dibuat langsung dari ponsel / tablet, maka Anda dapat melewati 2FA hanya dengan mengklik link dari pesan tersebut. Ini nyaman.
Jika koneksi VPN dibuat dari PC, maka pengguna akan diminta untuk memasukkan formulir kata sandi minimal. Formulir kecil berupa file HTML diberikan kepada pengguna saat mengatur VPN. File tersebut bahkan dapat dikirim melalui surat sehingga pengguna menyimpannya dan membuat pintasan di tempat yang nyaman. Ini terlihat seperti ini:
Label di atas meja
Pengguna mengklik pintasan, formulir entri kode sederhana terbuka, yang akan menempelkan kode ke URL yang dibuka:
Bentuk layar
Bentuk paling primitif diberikan sebagai contoh. Mereka yang ingin dapat memodifikasi sendiri.
2fa_login_mini.html
<html> <head> <title>SMS OTP login</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form name="login" action="location.href='http://gw.local/otp/'+document.getElementById(βtext').value" method="post" <input id="text" type="text"/> <input type="button" value="Login" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> </form> </body> </html>
Jika otorisasi berhasil, pengguna akan melihat logo MikroTik di browser, yang menandakan otentikasi berhasil:
Perhatikan bahwa image dikembalikan dari server web MikroTik bawaan menggunakan WebProxy Deny Redirect.
Saya kira gambar dapat dikustomisasi menggunakan alat "hotspot", mengunggah versi Anda sendiri di sana dan mengatur URL Tolak Pengalihan ke sana dengan WebProxy.
Permintaan besar bagi mereka yang mencoba membeli Mikrotik "mainan" termurah seharga $20 dan mengganti router seharga $500 dengannya - jangan lakukan itu. Perangkat seperti "hAP Lite" / "hAP mini" (titik akses rumah) memiliki CPU yang sangat lemah (smips), dan kemungkinan besar perangkat tersebut tidak akan mengatasi beban di segmen bisnis.
PERINGATAN! Solusi ini memiliki satu kelemahan: ketika klien terhubung atau terputus, perubahan konfigurasi terjadi, yang coba disimpan oleh router dalam memori non-volatile. Dengan jumlah klien yang banyak dan koneksi serta pemutusan yang sering, hal ini dapat menyebabkan degradasi penyimpanan internal di router.
PS: Metode pengiriman kode ke klien dapat diperluas dan ditambah sejauh kemampuan pemrograman Anda memadai. Misalnya, Anda dapat mengirim pesan ke telegram atau ... menyarankan opsi!
Saya harap artikel ini bermanfaat bagi Anda dan membantu membuat jaringan usaha kecil dan menengah sedikit lebih aman.
Sumber: www.habr.com