สวัสดีเพื่อนร่วมงาน! วันนี้ เมื่อความหลงใหลเกี่ยวกับ “การทำงานทางไกล” เข้มข้นลดลงเล็กน้อย ผู้ดูแลระบบส่วนใหญ่ได้รับภารกิจในการเข้าถึงระยะไกลของพนักงานไปยังเครือข่ายองค์กร ถึงเวลาแบ่งปันประสบการณ์อันยาวนานของฉันในการปรับปรุงความปลอดภัย VPN บทความนี้จะไม่เป็นที่นิยมในขณะนี้ IPSec IKEv2 และ xAuth มันเกี่ยวกับการสร้างระบบ
วันนี้ผมจะมาบอกวิธีป้องกัน MikroTik PPP-VPN แม้ว่าบัญชีผู้ใช้จะถูก "ไฮแจ็ค" เมื่อโครงการนี้ได้รับการแนะนำให้รู้จักกับลูกค้ารายหนึ่งของฉัน เขาอธิบายสั้น ๆ ว่า "ตอนนี้มันก็เหมือนกับในธนาคาร!"
วิธีการนี้ไม่ได้ใช้บริการตัวรับรองความถูกต้องภายนอก งานจะดำเนินการภายในโดยเราเตอร์เอง ไม่มีค่าใช้จ่ายสำหรับไคลเอนต์ที่เชื่อมต่อ วิธีนี้ใช้ได้กับทั้งไคลเอนต์พีซีและอุปกรณ์มือถือ
รูปแบบการป้องกันทั่วไปมีดังนี้:
- ที่อยู่ IP ภายในของผู้ใช้ที่เชื่อมต่อกับเซิร์ฟเวอร์ VPN สำเร็จจะถูกขึ้นบัญชีสีเทาโดยอัตโนมัติ
- เหตุการณ์การเชื่อมต่อจะสร้างรหัสแบบใช้ครั้งเดียวโดยอัตโนมัติซึ่งส่งไปยังผู้ใช้โดยใช้วิธีใดวิธีหนึ่งที่มีอยู่
- ที่อยู่ในรายการนี้มีสิทธิ์เข้าถึงทรัพยากรเครือข่ายท้องถิ่นอย่างจำกัด ยกเว้นบริการ "authenticator" ซึ่งกำลังรอรับรหัสผ่านแบบใช้ครั้งเดียว
- หลังจากแสดงรหัสแล้ว ผู้ใช้จะสามารถเข้าถึงทรัพยากรภายในของเครือข่ายได้
เป็นครั้งแรก ปัญหาที่เล็กที่สุดที่ฉันต้องเผชิญคือการจัดเก็บข้อมูลการติดต่อเกี่ยวกับผู้ใช้เพื่อส่งรหัส 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 สร้าง. หากเราทำการกำหนดค่าตัวแปรอย่างง่าย เราจะได้ค่าอาร์เรย์ที่สามารถใช้ในสคริปต์ได้ในภายหลัง
วิธีที่สอง รับรหัสผ่านครั้งเดียวซึ่งง่ายต่อการสมัคร - โดยใช้บริการภายนอก
รหัส
: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
ปัญหาที่สี่ ซึ่งต้องได้รับการแก้ไขอย่างรวดเร็ว - นี่คือวิธีการและตำแหน่งที่ไคลเอนต์ที่เชื่อมต่อจะถ่ายโอนรหัสแบบใช้ครั้งเดียวในขั้นตอนที่สองของการตรวจสอบสิทธิ์
ต้องมีบริการบนเราเตอร์ 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
ฉันจะแสดงรายการองค์ประกอบการกำหนดค่าที่สำคัญ:
- รายการอินเทอร์เฟซ "2fa" - รายการอินเทอร์เฟซไคลเอนต์แบบไดนามิก ทราฟฟิกที่ต้องใช้การประมวลผลภายใน 2FA
- รายการที่อยู่ "2fa_jailed" - รายการ "สีเทา" ของที่อยู่ IP ของช่องสัญญาณของไคลเอนต์ VPN
- address_list "2fa_approved" - รายการ "สีขาว" ของที่อยู่ IP ของช่องสัญญาณของไคลเอนต์ VPN ที่ผ่านการรับรองความถูกต้องด้วยสองปัจจัยสำเร็จ
- ไฟร์วอลล์เชน "input_2fa" - ตรวจสอบแพ็กเก็ต tcp สำหรับการมีอยู่ของรหัสการให้สิทธิ์และจับคู่ที่อยู่ IP ของผู้ส่งรหัสกับที่อยู่ที่ต้องการ กฎในห่วงโซ่จะถูกเพิ่มและลบออกแบบไดนามิก
ผังงานอย่างง่ายของการประมวลผลแพ็คเก็ตมีลักษณะดังนี้:
ในการเข้าสู่การตรวจสอบการรับส่งข้อมูลของ 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 ไม่เพียงแต่เพื่อเชื่อมต่อผู้ใช้ปลายทางเท่านั้น แต่ในขณะเดียวกันก็เพื่อสร้างการเชื่อมต่อแบบไซต์ต่อไซต์
ในโปรไฟล์พิเศษที่สร้างขึ้นใหม่ เราใช้การเพิ่มที่อยู่และส่วนต่อประสานแบบไดนามิกของผู้ใช้ที่เชื่อมต่อกับรายการที่อยู่และส่วนต่อประสาน "สีเทา":
รหัส
/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 และกฎไฟร์วอลล์แต่ละตัวโดยอัตโนมัติ
รหัสที่ใช้ในโปรไฟล์สำหรับเหตุการณ์การเชื่อมต่อ 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]
จากนั้น คุณสามารถสร้างผู้ใช้และกำหนดทั้งหมดหรือบางส่วนให้กับโปรไฟล์การตรวจสอบสิทธิ์แบบสองปัจจัยวินบ็อกซ์
รหัส
/ppp secrets set [find name=Petrov] profile=2FA
มันดูเป็นอย่างไรในฝั่งไคลเอ็นต์
เมื่อสร้างการเชื่อมต่อ VPN แล้ว โทรศัพท์/แท็บเล็ต Android/iOS ที่มีซิมการ์ดจะได้รับ SMS ดังนี้:
ข้อความ
หากเชื่อมต่อโดยตรงจากโทรศัพท์ / แท็บเล็ต คุณสามารถผ่าน 2FA ได้ง่ายๆ โดยคลิกที่ลิงก์จากข้อความ สะดวกสบาย
หากสร้างการเชื่อมต่อ VPN จากพีซี ผู้ใช้จะต้องป้อนรหัสผ่านขั้นต่ำ ผู้ใช้จะได้รับแบบฟอร์มขนาดเล็กในรูปแบบของไฟล์ HTML เมื่อตั้งค่า VPN สามารถส่งไฟล์ทางไปรษณีย์เพื่อให้ผู้ใช้บันทึกและสร้างทางลัดในที่ที่สะดวก ดูเหมือนว่า:
ฉลากบนโต๊ะ
ผู้ใช้คลิกที่ทางลัด แบบฟอร์มป้อนรหัสอย่างง่ายจะเปิดขึ้น ซึ่งจะวางรหัสลงใน URL ที่เปิด:
แบบสกรีน
ตัวอย่างรูปแบบดั้งเดิมที่สุด ผู้ที่ต้องการสามารถปรับเปลี่ยนได้เอง
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 ในเบราว์เซอร์ ซึ่งควรส่งสัญญาณการยืนยันตัวตนที่สำเร็จ:
โปรดทราบว่ารูปภาพจะถูกส่งคืนจากเว็บเซิร์ฟเวอร์ MikroTik ในตัวโดยใช้ WebProxy Deny Redirect
ฉันคิดว่ารูปภาพสามารถปรับแต่งได้โดยใช้เครื่องมือ "ฮอตสปอต" อัปโหลดเวอร์ชันของคุณเองที่นั่น และตั้งค่า URL ปฏิเสธการเปลี่ยนเส้นทางให้กับรูปภาพด้วย WebProxy
คำขอที่ยิ่งใหญ่สำหรับผู้ที่พยายามซื้อ Mikrotik "ของเล่น" ที่ถูกที่สุดในราคา $ 20 และเปลี่ยนเราเตอร์ราคา $ 500 - อย่าทำเช่นนั้น อุปกรณ์เช่น "hAP Lite" / "hAP mini" (จุดเชื่อมต่อที่บ้าน) มี CPU ที่อ่อนแอมาก (smips) และมีแนวโน้มว่าพวกเขาจะไม่สามารถรับมือกับโหลดในกลุ่มธุรกิจได้
คำเตือน! โซลูชันนี้มีข้อเสียอย่างหนึ่ง: เมื่อไคลเอนต์เชื่อมต่อหรือยกเลิกการเชื่อมต่อ การกำหนดค่าจะเกิดขึ้น ซึ่งเราเตอร์พยายามบันทึกลงในหน่วยความจำแบบไม่ลบเลือน ด้วยไคลเอ็นต์จำนวนมากและการเชื่อมต่อและการตัดการเชื่อมต่อบ่อยครั้ง อาจทำให้ที่จัดเก็บข้อมูลภายในเราเตอร์เสื่อมประสิทธิภาพลงได้
PS: วิธีการส่งโค้ดไปยังไคลเอนต์สามารถขยายและเสริมได้เท่าที่ความสามารถในการเขียนโปรแกรมของคุณเพียงพอ ตัวอย่างเช่น คุณสามารถส่งข้อความไปยังโทรเลขหรือ ... แนะนำตัวเลือก!
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับคุณและจะช่วยให้เครือข่ายของธุรกิจขนาดเล็กและขนาดกลางมีความปลอดภัยมากขึ้น
ที่มา: will.com