การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

สวัสดีเพื่อนร่วมงาน! วันนี้ เมื่อความหลงใหลเกี่ยวกับ “การทำงานทางไกล” เข้มข้นลดลงเล็กน้อย ผู้ดูแลระบบส่วนใหญ่ได้รับภารกิจในการเข้าถึงระยะไกลของพนักงานไปยังเครือข่ายองค์กร ถึงเวลาแบ่งปันประสบการณ์อันยาวนานของฉันในการปรับปรุงความปลอดภัย VPN บทความนี้จะไม่เป็นที่นิยมในขณะนี้ IPSec IKEv2 และ xAuth มันเกี่ยวกับการสร้างระบบ การรับรองความถูกต้องด้วยสองปัจจัย (2FA) ผู้ใช้ VPN เมื่อ MikroTik ทำหน้าที่เป็นเซิร์ฟเวอร์ VPN กล่าวคือ เมื่อใช้โปรโตคอล "คลาสสิก" เช่น PPP

การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

วันนี้ผมจะมาบอกวิธีป้องกัน MikroTik PPP-VPN แม้ว่าบัญชีผู้ใช้จะถูก "ไฮแจ็ค" เมื่อโครงการนี้ได้รับการแนะนำให้รู้จักกับลูกค้ารายหนึ่งของฉัน เขาอธิบายสั้น ๆ ว่า "ตอนนี้มันก็เหมือนกับในธนาคาร!"

วิธีการนี้ไม่ได้ใช้บริการตัวรับรองความถูกต้องภายนอก งานจะดำเนินการภายในโดยเราเตอร์เอง ไม่มีค่าใช้จ่ายสำหรับไคลเอนต์ที่เชื่อมต่อ วิธีนี้ใช้ได้กับทั้งไคลเอนต์พีซีและอุปกรณ์มือถือ

รูปแบบการป้องกันทั่วไปมีดังนี้:

  1. ที่อยู่ IP ภายในของผู้ใช้ที่เชื่อมต่อกับเซิร์ฟเวอร์ VPN สำเร็จจะถูกขึ้นบัญชีสีเทาโดยอัตโนมัติ
  2. เหตุการณ์การเชื่อมต่อจะสร้างรหัสแบบใช้ครั้งเดียวโดยอัตโนมัติซึ่งส่งไปยังผู้ใช้โดยใช้วิธีใดวิธีหนึ่งที่มีอยู่
  3. ที่อยู่ในรายการนี้มีสิทธิ์เข้าถึงทรัพยากรเครือข่ายท้องถิ่นอย่างจำกัด ยกเว้นบริการ "authenticator" ซึ่งกำลังรอรับรหัสผ่านแบบใช้ครั้งเดียว
  4. หลังจากแสดงรหัสแล้ว ผู้ใช้จะสามารถเข้าถึงทรัพยากรภายในของเครือข่ายได้

เป็นครั้งแรก ปัญหาที่เล็กที่สุดที่ฉันต้องเผชิญคือการจัดเก็บข้อมูลการติดต่อเกี่ยวกับผู้ใช้เพื่อส่งรหัส 2FA ให้เขา เนื่องจากเป็นไปไม่ได้ที่จะสร้างฟิลด์ข้อมูลตามอำเภอใจสำหรับผู้ใช้ใน Mikrotik จึงใช้ฟิลด์ "ความคิดเห็น" ที่มีอยู่:

/ppp ความลับ เพิ่มชื่อ=รหัสผ่าน Petrov=4M@ngr! ความคิดเห็น = "89876543210"

สอง ปัญหากลายเป็นเรื่องร้ายแรงมากขึ้น - ทางเลือกของเส้นทางและวิธีการส่งรหัส ขณะนี้มีการใช้งานสามรูปแบบ: a) SMS ผ่านโมเด็ม USB b) อีเมล c) SMS ผ่านอีเมลสำหรับลูกค้าองค์กรของผู้ให้บริการโทรศัพท์มือถือสีแดง

ใช่ รูปแบบ SMS นำมาซึ่งค่าใช้จ่าย แต่ถ้าคุณมองว่า "ความปลอดภัยมักเกี่ยวกับเงิน" (ค)
โดยส่วนตัวแล้วฉันไม่ชอบรูปแบบการใช้อีเมล ไม่ใช่เพราะเซิร์ฟเวอร์อีเมลต้องพร้อมใช้งานสำหรับไคลเอนต์ที่กำลังตรวจสอบสิทธิ์ - การแยกทราฟฟิกไม่ใช่ปัญหา อย่างไรก็ตาม หากไคลเอ็นต์บันทึกทั้งรหัสผ่าน VPN และอีเมลในเบราว์เซอร์โดยไม่ได้ตั้งใจ แล้วทำแล็ปท็อปหาย ผู้โจมตีจะเข้าถึงเครือข่ายองค์กรได้อย่างเต็มที่จากไคลเอ็นต์

จึงตัดสินใจ - เราส่งรหัสแบบใช้ครั้งเดียวโดยใช้ข้อความ SMS

สาม ปัญหาอยู่ที่ไหน วิธีสร้างรหัสสุ่มหลอกสำหรับ 2FA ใน MikroTik. ไม่มีอะนาลอกของฟังก์ชัน random() ในภาษาสคริปต์ของ RouterOS และฉันเคยเห็นตัวสร้างตัวเลขสุ่มหลอกแบบสคริปต์ Crutch หลายตัวมาก่อน ฉันไม่ชอบพวกเขาด้วยเหตุผลหลายประการ

อันที่จริง มีเครื่องสร้างลำดับสุ่มหลอกใน MikroTik! มันถูกซ่อนจากการมองเพียงผิวเผินในบริบทของ /certificates scept-server วิธีแรก การรับรหัสผ่านครั้งเดียวนั้นง่ายและสะดวก - ด้วยคำสั่ง /certificates เซิร์ฟเวอร์ otp สร้าง. หากเราทำการกำหนดค่าตัวแปรอย่างง่าย เราจะได้ค่าอาร์เรย์ที่สามารถใช้ในสคริปต์ได้ในภายหลัง

วิธีที่สอง รับรหัสผ่านครั้งเดียวซึ่งง่ายต่อการสมัคร - โดยใช้บริการภายนอก สุ่ม.org เพื่อสร้างชนิดของลำดับที่ต้องการของตัวเลขสุ่มเทียม นี่คือแบบง่าย แพร่ง ตัวอย่างการรับข้อมูลเข้าตัวแปร:

รหัส
: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

คำขอที่จัดรูปแบบสำหรับคอนโซล (ต้องใช้อักขระพิเศษในการ Escape ในเนื้อหาของสคริปต์) จะได้รับสตริง 1 หลักในตัวแปร $rndXNUMX คำสั่ง "put" ต่อไปนี้จะแสดงตัวแปรในคอนโซล MikroTik

ปัญหาที่สี่ ซึ่งต้องได้รับการแก้ไขอย่างรวดเร็ว - นี่คือวิธีการและตำแหน่งที่ไคลเอนต์ที่เชื่อมต่อจะถ่ายโอนรหัสแบบใช้ครั้งเดียวในขั้นตอนที่สองของการตรวจสอบสิทธิ์

การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

ต้องมีบริการบนเราเตอร์ MikroTik ที่สามารถรับรหัสและจับคู่กับไคลเอ็นต์เฉพาะได้ หากรหัสที่ให้มาตรงกับรหัสที่คาดไว้ ที่อยู่ของลูกค้าควรรวมอยู่ในรายการ "สีขาว" ซึ่งเป็นที่อยู่ที่ได้รับอนุญาตให้เข้าถึงเครือข่ายภายในของบริษัท

เนื่องจากทางเลือกของบริการที่ไม่ดี จึงตัดสินใจรับรหัสผ่าน http โดยใช้ webproxy ที่มีอยู่ใน Mikrotik และเนื่องจากไฟร์วอลล์สามารถทำงานกับรายการที่อยู่ IP แบบไดนามิกได้ จึงเป็นไฟร์วอลล์ที่ดำเนินการค้นหาโค้ด จับคู่กับ IP ไคลเอนต์ และเพิ่มลงในรายการ "สีขาว" โดยใช้ Layer7 regexp เราเตอร์ได้รับการกำหนดชื่อ DNS แบบมีเงื่อนไข "gw.local" ซึ่งมีการสร้างระเบียน A แบบคงที่สำหรับการออกไปยังไคลเอนต์ PPP:

DNS
/ip DNS เพิ่มชื่อคงที่ =gw.local address=172.31.1.1

การจับทราฟฟิกของไคลเอ็นต์ที่ไม่ได้รับการยืนยันบนพร็อกซี:
/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

ในกรณีนี้ พร็อกซีมีสองหน้าที่

1. เปิดการเชื่อมต่อ tcp กับลูกค้า

2. ในกรณีที่การอนุญาตสำเร็จ ให้เปลี่ยนเส้นทางเบราว์เซอร์ไคลเอ็นต์ไปยังหน้าหรือรูปภาพที่แจ้งเกี่ยวกับการตรวจสอบสิทธิ์ที่สำเร็จ:

การกำหนดค่าพร็อกซี
/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

ฉันจะแสดงรายการองค์ประกอบการกำหนดค่าที่สำคัญ:

  1. รายการอินเทอร์เฟซ "2fa" - รายการอินเทอร์เฟซไคลเอนต์แบบไดนามิก ทราฟฟิกที่ต้องใช้การประมวลผลภายใน 2FA
  2. รายการที่อยู่ "2fa_jailed" - รายการ "สีเทา" ของที่อยู่ IP ของช่องสัญญาณของไคลเอนต์ VPN
  3. address_list "2fa_approved" - รายการ "สีขาว" ของที่อยู่ IP ของช่องสัญญาณของไคลเอนต์ VPN ที่ผ่านการรับรองความถูกต้องด้วยสองปัจจัยสำเร็จ
  4. ไฟร์วอลล์เชน "input_2fa" - ตรวจสอบแพ็กเก็ต tcp สำหรับการมีอยู่ของรหัสการให้สิทธิ์และจับคู่ที่อยู่ IP ของผู้ส่งรหัสกับที่อยู่ที่ต้องการ กฎในห่วงโซ่จะถูกเพิ่มและลบออกแบบไดนามิก

ผังงานอย่างง่ายของการประมวลผลแพ็คเก็ตมีลักษณะดังนี้:

การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

ในการเข้าสู่การตรวจสอบการรับส่งข้อมูลของ Layer7 จากลูกค้าจากรายการ "สีเทา" ที่ยังไม่ผ่านขั้นตอนที่สองของการตรวจสอบความถูกต้อง กฎได้ถูกสร้างขึ้นในห่วงโซ่ "อินพุต" มาตรฐาน:

รหัส
/ip firewall filter add chain=input !src-address-list=2fa_approved action=jump jump-target=input_2fa

ตอนนี้เรามาเริ่มยึดความมั่งคั่งทั้งหมดนี้กับบริการ PPP MikroTik อนุญาตให้คุณใช้สคริปต์ในโปรไฟล์ (ppp-profile) และกำหนดให้กับเหตุการณ์ในการสร้างและทำลายการเชื่อมต่อ ppp การตั้งค่าโปรไฟล์ ppp ใช้ได้กับทั้งเซิร์ฟเวอร์ PPP โดยรวมและกับผู้ใช้แต่ละราย ในขณะเดียวกัน โปรไฟล์ที่กำหนดให้กับผู้ใช้จะมีลำดับความสำคัญ ซึ่งจะแทนที่พารามิเตอร์ของโปรไฟล์ที่เลือกสำหรับเซิร์ฟเวอร์โดยรวมด้วยพารามิเตอร์ที่ระบุ

จากแนวทางนี้ เราสามารถสร้างโปรไฟล์พิเศษสำหรับการตรวจสอบสิทธิ์แบบสองปัจจัยและไม่ได้กำหนดให้กับผู้ใช้ทุกคน แต่เฉพาะผู้ที่พิจารณาว่าจำเป็นต้องทำเช่นนั้นเท่านั้น สิ่งนี้อาจเกี่ยวข้องหากคุณใช้บริการ PPP ไม่เพียงแต่เพื่อเชื่อมต่อผู้ใช้ปลายทางเท่านั้น แต่ในขณะเดียวกันก็เพื่อสร้างการเชื่อมต่อแบบไซต์ต่อไซต์

ในโปรไฟล์พิเศษที่สร้างขึ้นใหม่ เราใช้การเพิ่มที่อยู่และส่วนต่อประสานแบบไดนามิกของผู้ใช้ที่เชื่อมต่อกับรายการที่อยู่และส่วนต่อประสาน "สีเทา":

วินบ็อกซ์
การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

รหัส
/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

จำเป็นต้องใช้ทั้งรายการ "รายการที่อยู่" และ "รายการส่วนต่อประสาน" เพื่อตรวจหาและบันทึกการรับส่งข้อมูลจากไคลเอนต์ VPN ที่ไม่ใช่รองในห่วงโซ่ dstnat (การกำหนดเส้นทางล่วงหน้า)

เมื่อการเตรียมการเสร็จสิ้น ไฟร์วอลล์เชนเพิ่มเติมและโปรไฟล์จะถูกสร้างขึ้น เราจะเขียนสคริปต์ที่รับผิดชอบในการสร้างรหัส 2FA และกฎไฟร์วอลล์แต่ละตัวโดยอัตโนมัติ

เอกสารประกอบ wiki.mikrotik.com บน PPP-Profile เพิ่มคุณค่าให้กับเราด้วยข้อมูลเกี่ยวกับตัวแปรที่เกี่ยวข้องกับเหตุการณ์เชื่อมต่อ-ตัดการเชื่อมต่อไคลเอนต์ PPP "เรียกใช้สคริปต์ในเหตุการณ์การเข้าสู่ระบบของผู้ใช้ สิ่งเหล่านี้คือตัวแปรที่มีอยู่ซึ่งสคริปต์เหตุการณ์สามารถเข้าถึงได้: ผู้ใช้, ที่อยู่ในระบบ, ที่อยู่ระยะไกล, หมายเลขผู้โทร, รหัสผู้โทร, อินเทอร์เฟซ". บางคนมีประโยชน์มากสำหรับเรา

รหัสที่ใช้ในโปรไฟล์สำหรับเหตุการณ์การเชื่อมต่อ 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

ฉันเตือนคุณโดยเฉพาะอย่างยิ่งสำหรับผู้ที่ชอบคัดลอกและวางอย่างไม่ตั้งใจ - โค้ดนี้นำมาจากเวอร์ชันทดสอบและอาจมีการพิมพ์ผิดเล็กน้อย คนที่เข้าใจจะเข้าใจได้ไม่ยากว่าที่ไหน

เมื่อผู้ใช้ยกเลิกการเชื่อมต่อ เหตุการณ์ "เปิด-ปิด" จะถูกสร้างขึ้นและเรียกสคริปต์ที่เกี่ยวข้องพร้อมพารามิเตอร์ วัตถุประสงค์ของสคริปต์นี้คือเพื่อล้างกฎไฟร์วอลล์ที่สร้างขึ้นสำหรับผู้ใช้ที่ไม่ได้เชื่อมต่อ

รหัสที่ใช้ในโปรไฟล์สำหรับเหตุการณ์การเชื่อมต่อเปิด-ปิด PPP

: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]
จากนั้น คุณสามารถสร้างผู้ใช้และกำหนดทั้งหมดหรือบางส่วนให้กับโปรไฟล์การตรวจสอบสิทธิ์แบบสองปัจจัย

วินบ็อกซ์
การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

รหัส
/ppp secrets set [find name=Petrov] profile=2FA

มันดูเป็นอย่างไรในฝั่งไคลเอ็นต์

เมื่อสร้างการเชื่อมต่อ VPN แล้ว โทรศัพท์/แท็บเล็ต Android/iOS ที่มีซิมการ์ดจะได้รับ SMS ดังนี้:

ข้อความ
การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

หากเชื่อมต่อโดยตรงจากโทรศัพท์ / แท็บเล็ต คุณสามารถผ่าน 2FA ได้ง่ายๆ โดยคลิกที่ลิงก์จากข้อความ สะดวกสบาย

หากสร้างการเชื่อมต่อ VPN จากพีซี ผู้ใช้จะต้องป้อนรหัสผ่านขั้นต่ำ ผู้ใช้จะได้รับแบบฟอร์มขนาดเล็กในรูปแบบของไฟล์ HTML เมื่อตั้งค่า VPN สามารถส่งไฟล์ทางไปรษณีย์เพื่อให้ผู้ใช้บันทึกและสร้างทางลัดในที่ที่สะดวก ดูเหมือนว่า:

ฉลากบนโต๊ะ
การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

ผู้ใช้คลิกที่ทางลัด แบบฟอร์มป้อนรหัสอย่างง่ายจะเปิดขึ้น ซึ่งจะวางรหัสลงใน URL ที่เปิด:

แบบสกรีน
การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

ตัวอย่างรูปแบบดั้งเดิมที่สุด ผู้ที่ต้องการสามารถปรับเปลี่ยนได้เอง

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>

หากการอนุญาตสำเร็จ ผู้ใช้จะเห็นโลโก้ MikroTik ในเบราว์เซอร์ ซึ่งควรส่งสัญญาณการยืนยันตัวตนที่สำเร็จ:

การยืนยันตัวตนแบบสองปัจจัยของผู้ใช้ VPN ผ่าน MikroTik และ SMS

โปรดทราบว่ารูปภาพจะถูกส่งคืนจากเว็บเซิร์ฟเวอร์ MikroTik ในตัวโดยใช้ WebProxy Deny Redirect

ฉันคิดว่ารูปภาพสามารถปรับแต่งได้โดยใช้เครื่องมือ "ฮอตสปอต" อัปโหลดเวอร์ชันของคุณเองที่นั่น และตั้งค่า URL ปฏิเสธการเปลี่ยนเส้นทางให้กับรูปภาพด้วย WebProxy

คำขอที่ยิ่งใหญ่สำหรับผู้ที่พยายามซื้อ Mikrotik "ของเล่น" ที่ถูกที่สุดในราคา $ 20 และเปลี่ยนเราเตอร์ราคา $ 500 - อย่าทำเช่นนั้น อุปกรณ์เช่น "hAP Lite" / "hAP mini" (จุดเชื่อมต่อที่บ้าน) มี CPU ที่อ่อนแอมาก (smips) และมีแนวโน้มว่าพวกเขาจะไม่สามารถรับมือกับโหลดในกลุ่มธุรกิจได้

คำเตือน! โซลูชันนี้มีข้อเสียอย่างหนึ่ง: เมื่อไคลเอนต์เชื่อมต่อหรือยกเลิกการเชื่อมต่อ การกำหนดค่าจะเกิดขึ้น ซึ่งเราเตอร์พยายามบันทึกลงในหน่วยความจำแบบไม่ลบเลือน ด้วยไคลเอ็นต์จำนวนมากและการเชื่อมต่อและการตัดการเชื่อมต่อบ่อยครั้ง อาจทำให้ที่จัดเก็บข้อมูลภายในเราเตอร์เสื่อมประสิทธิภาพลงได้

PS: วิธีการส่งโค้ดไปยังไคลเอนต์สามารถขยายและเสริมได้เท่าที่ความสามารถในการเขียนโปรแกรมของคุณเพียงพอ ตัวอย่างเช่น คุณสามารถส่งข้อความไปยังโทรเลขหรือ ... แนะนำตัวเลือก!

ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับคุณและจะช่วยให้เครือข่ายของธุรกิจขนาดเล็กและขนาดกลางมีความปลอดภัยมากขึ้น

ที่มา: will.com