วิธีใช้ Port Knocking บน Linux (และทำไมคุณไม่ควร)
เผยแพร่แล้ว: 2022-01-29การเคาะพอร์ตเป็นวิธีหนึ่งในการรักษาความปลอดภัยเซิร์ฟเวอร์ด้วยการปิดพอร์ตไฟร์วอลล์ แม้กระทั่งพอร์ตที่คุณรู้จักก็จะถูกนำไปใช้ พอร์ตเหล่านั้นจะเปิดขึ้นตามต้องการ ถ้า—และก็ต่อเมื่อ—คำขอเชื่อมต่อให้การเคาะแบบลับๆ
การเคาะพอร์ตเป็น "ความลับ"
ในปี ค.ศ. 1920 เมื่อมีการห้ามเต็มรูปแบบ หากคุณต้องการทำเหล้าเถื่อน คุณต้องรู้ความลับของการเคาะและเคาะออกอย่างถูกต้องเพื่อเข้าไปข้างใน
การเคาะพอร์ตเป็นสิ่งที่เทียบเท่าสมัยใหม่ หากคุณต้องการให้ผู้อื่นเข้าถึงบริการบนคอมพิวเตอร์ของคุณ แต่ไม่ต้องการเปิดไฟร์วอลล์ของคุณบนอินเทอร์เน็ต คุณสามารถใช้การเคาะพอร์ตได้ ช่วยให้คุณสามารถปิดพอร์ตบนไฟร์วอลล์ของคุณที่อนุญาตการเชื่อมต่อขาเข้า และเปิดพอร์ตเหล่านั้นโดยอัตโนมัติเมื่อมีการพยายามเชื่อมต่อรูปแบบที่จัดเตรียมไว้ล่วงหน้า ลำดับของความพยายามเชื่อมต่อทำหน้าที่เป็นความลับ ความลับอีกเคาะปิดพอร์ต
การเคาะพอร์ตเป็นเรื่องแปลกใหม่ แต่สิ่งสำคัญคือต้องรู้ว่านี่คือตัวอย่างของการรักษาความปลอดภัยผ่านความมืดมน และแนวคิดนั้นมีข้อบกพร่องโดยพื้นฐาน ความลับในการเข้าถึงระบบนั้นปลอดภัยเพราะมีเพียงคนในกลุ่มเท่านั้นที่รู้ แต่เมื่อความลับนั้นถูกเปิดเผย—ไม่ว่าจะเพราะเปิดเผย สังเกต เดา หรือรู้ผล—ความปลอดภัยของคุณจะถือเป็นโมฆะ คุณควรรักษาความปลอดภัยเซิร์ฟเวอร์ด้วยวิธีอื่นๆ ที่รัดกุมกว่า เช่น ต้องการการเข้าสู่ระบบโดยใช้คีย์สำหรับเซิร์ฟเวอร์ SSH
แนวทางที่แข็งแกร่งที่สุดในการรักษาความปลอดภัยทางไซเบอร์นั้นมีหลายชั้น ดังนั้นบางทีการเคาะพอร์ตควรเป็นหนึ่งในเลเยอร์เหล่านั้น ยิ่งหลายชั้นยิ่งดีใช่ไหม? อย่างไรก็ตาม คุณสามารถโต้แย้งได้ว่าการเคาะพอร์ตไม่ได้เพิ่มอะไรมาก (ถ้ามี) ให้กับระบบที่ปลอดภัยและแข็งแกร่ง
การรักษาความปลอดภัยทางไซเบอร์เป็นหัวข้อที่กว้างใหญ่และซับซ้อน แต่คุณไม่ควรใช้การเคาะพอร์ตเป็นรูปแบบการป้องกันเพียงอย่างเดียวของคุณ
ที่เกี่ยวข้อง: วิธีสร้างและติดตั้งคีย์ SSH จาก Linux Shell
การติดตั้ง knockd
เพื่อสาธิตการเคาะพอร์ต เราจะใช้เพื่อควบคุมพอร์ต 22 ซึ่งเป็นพอร์ต SSH เราจะใช้เครื่องมือที่เรียกว่าน็อค ใช้ apt-get
เพื่อติดตั้งแพ็คเกจนี้ลงในระบบของคุณ หากคุณใช้ Ubuntu หรือการแจกจ่ายแบบ Debian อื่น สำหรับลีนุกซ์รุ่นอื่นๆ ให้ใช้เครื่องมือจัดการแพ็คเกจของลินุกซ์แทน
พิมพ์ต่อไปนี้:
sudo apt-get ติดตั้ง knockd
คุณอาจมีไฟร์วอลล์ iptables ติดตั้งอยู่ในระบบของคุณแล้ว แต่คุณอาจต้องติดตั้งแพ็คเกจ iptables-persistent
มันจัดการการโหลดกฎ iptable
บันทึกไว้โดยอัตโนมัติ
พิมพ์ข้อมูลต่อไปนี้เพื่อติดตั้ง:
sudo apt-get ติดตั้ง iptables-persistent
เมื่อหน้าจอการกำหนดค่า IPV4 ปรากฏขึ้น ให้กดแป้นเว้นวรรคเพื่อยอมรับตัวเลือก "ใช่"
กดแป้นเว้นวรรคอีกครั้งในหน้าจอการกำหนดค่า IPv6 เพื่อยอมรับตัวเลือก "ใช่" และดำเนินการต่อไป
คำสั่งต่อไปนี้บอกให้ iptables
อนุญาตการเชื่อมต่อที่สร้างและต่อเนื่องเพื่อดำเนินการต่อ ตอนนี้เราจะออกคำสั่งอื่นเพื่อปิดพอร์ต SSH
หากมีคนเชื่อมต่อโดย SSH เมื่อเราออกคำสั่งนี้ เราไม่ต้องการให้พวกเขาถูกตัดออก:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
คำสั่งนี้เพิ่มกฎให้กับไฟร์วอลล์ซึ่งระบุว่า:
- -A : ผนวกกฎเข้ากับตารางกฎไฟร์วอลล์ นั่นคือเพิ่มไปที่ด้านล่าง
- INPUT : นี่เป็นกฎเกี่ยวกับการเชื่อมต่อขาเข้า
- -m conntrack : กฎไฟร์วอลล์ดำเนินการกับการรับส่งข้อมูลเครือข่าย (แพ็กเก็ต) ที่ตรงกับเกณฑ์ในกฎ พารามิเตอร์
-m
ทำให้iptables
ใช้โมดูลการจับคู่แพ็กเก็ตเพิ่มเติม ในกรณีนี้ พารามิเตอร์ที่เรียกว่าconntrack
จะทำงานกับความสามารถในการติดตามการเชื่อมต่อเครือข่ายของเคอร์เนล - –cstate ESTABLISHED,RELATED : สิ่งนี้ระบุประเภทของการเชื่อมต่อที่จะใช้กฎ ได้แก่ การเชื่อมต่อที่จัดตั้งขึ้นและที่เกี่ยวข้อง การเชื่อมต่อที่จัดตั้งขึ้นคือการเชื่อมต่อที่กำลังดำเนินการอยู่ การเชื่อมต่อที่เกี่ยวข้องคือการเชื่อมต่อที่เกิดขึ้นจากการดำเนินการจากการเชื่อมต่อที่สร้างไว้แล้ว บางทีคนที่เชื่อมต่อต้องการดาวน์โหลดไฟล์ ที่อาจเกิดขึ้นผ่านการเชื่อมต่อใหม่ที่โฮสต์เริ่มต้น
- -j ACCEPT : หากการรับส่งข้อมูลตรงกับกฎ ให้ข้ามไปที่เป้าหมาย ACCEPT ในไฟร์วอลล์ กล่าวอีกนัยหนึ่ง การรับส่งข้อมูลเป็นที่ยอมรับและได้รับอนุญาตให้ผ่านไฟร์วอลล์
ตอนนี้เราสามารถออกคำสั่งเพื่อปิดพอร์ต:
sudo iptables -A INPUT -p tcp --dport 22 -j REJECT
คำสั่งนี้เพิ่มกฎให้กับไฟร์วอลล์ซึ่งระบุว่า:
- -A : ผนวกกฎเข้ากับตารางกฎไฟร์วอลล์ กล่าวคือ เพิ่มไปที่ด้านล่าง
- INPUT : กฎนี้เกี่ยวกับการเชื่อมต่อขาเข้า
- -p tcp : กฎนี้ใช้กับการรับส่งข้อมูลที่ใช้ Transmission Control Protocol
- –dport 22 : กฎนี้ใช้กับทราฟฟิก TCP โดยเฉพาะที่กำหนดเป้าหมายพอร์ต 22 (พอร์ต SSH)
- -j REJECT : หากการรับส่งข้อมูลตรงกับกฎ ให้ข้ามไปที่เป้าหมาย REJECT ในไฟร์วอลล์ ดังนั้น หากการรับส่งข้อมูลถูกปฏิเสธ จะไม่ได้รับอนุญาตผ่านไฟร์วอลล์
เราต้องเริ่ม netfilter-persistent
daemon เราสามารถทำได้ด้วยคำสั่งนี้:
sudo systemctl เริ่ม netfilter-persistent
เราต้องการให้ netfilter-persistent
ผ่านรอบการบันทึกและโหลดซ้ำ ดังนั้นจึงโหลดและควบคุมกฎ iptable
พิมพ์คำสั่งต่อไปนี้:
sudo netfilter-persistent save
sudo netfilter- โหลดซ้ำอย่างต่อเนื่อง
คุณได้ติดตั้งยูทิลิตี้แล้ว และพอร์ต SSH ถูกปิด (หวังว่าจะไม่มีการเชื่อมต่อของใครเลย) ตอนนี้ได้เวลากำหนดค่าการน็อคแบบลับๆ
การกำหนดค่า knockd
มีสองไฟล์ที่คุณแก้ไขเพื่อกำหนดค่า knockd
ไฟล์แรกคือไฟล์คอนฟิกูเรชัน knockd
ต่อไปนี้:
sudo gedit /etc/knockd.conf
ตัวแก้ไข gedit
จะเปิดขึ้นพร้อมกับโหลดไฟล์คอนฟิกูเรชันที่ knockd
อยู่
เราจะแก้ไขไฟล์นี้เพื่อให้เหมาะกับความต้องการของเรา ส่วนที่เราสนใจคือ “openSSH” และ “closeSSH” สี่รายการต่อไปนี้อยู่ในแต่ละส่วน:
- ลำดับ : ลำดับของพอร์ตที่ผู้อื่นต้องเข้าถึงเพื่อเปิดหรือปิดพอร์ต 22 พอร์ตเริ่มต้นคือ 7000, 8000 และ 9000 เพื่อเปิด และ 9000, 8000 และ 7000 เพื่อปิด คุณสามารถเปลี่ยนพอร์ตเหล่านี้หรือเพิ่มพอร์ตอื่นๆ ลงในรายการได้ สำหรับจุดประสงค์ของเรา เราจะยึดตามค่าเริ่มต้น
- seq_timeout : ช่วงเวลาที่บุคคลต้องเข้าถึงพอร์ตเพื่อเรียกให้เปิดหรือปิด
- คำสั่ง : คำสั่งที่ส่งไปยังไฟร์วอลล์
iptables
เมื่อการดำเนินการเปิดหรือปิดถูกทริกเกอร์ คำสั่งเหล่านี้อาจเพิ่มกฎให้กับไฟร์วอลล์ (เพื่อเปิดพอร์ต) หรือนำออก (เพื่อปิดพอร์ต) - tcpflags : ประเภทของแพ็กเก็ตที่แต่ละพอร์ตต้องได้รับในลำดับลับ แพ็กเก็ต SYN (ซิงโครไนซ์) เป็นแพ็กเก็ตแรกในคำขอเชื่อมต่อ TCP ที่เรียกว่าการจับมือสามทาง
ส่วน "openSSH" สามารถอ่านได้ว่า "ต้องมีการร้องขอการเชื่อมต่อ TCP ไปยังพอร์ต 7000, 8000 และ 9000 ตามลำดับและภายใน 5 วินาที เพื่อให้คำสั่งเปิดพอร์ต 22 ถูกส่งไปยังไฟร์วอลล์"
ส่วน "closeSSH" สามารถอ่านได้ว่า "ต้องมีการร้องขอการเชื่อมต่อ TCP ไปยังพอร์ต 9000, 8000 และ 7000 ตามลำดับและภายใน 5 วินาที เพื่อให้คำสั่งปิดพอร์ต 22 ถูกส่งไปยังไฟร์วอลล์"
กฎไฟร์วอลล์
รายการ "คำสั่ง" ในส่วน openSSH และ closeSSH ยังคงเหมือนเดิม ยกเว้นพารามิเตอร์เดียว นี่คือวิธีที่พวกเขาประกอบด้วย:
- -A : เพิ่มกฎต่อท้ายรายการกฎไฟร์วอลล์ (สำหรับคำสั่ง openSSH)
- -D : ลบคำสั่งออกจากรายการกฎไฟร์วอลล์ (สำหรับคำสั่ง closeSSH)
- INPUT : กฎนี้เกี่ยวข้องกับการรับส่งข้อมูลเครือข่ายขาเข้า
- -s %IP% : ที่อยู่ IP ของอุปกรณ์ที่ร้องขอการเชื่อมต่อ
- -p : โปรโตคอลเครือข่าย; ในกรณีนี้คือ TCP
- –dport : พอร์ตปลายทาง; ในตัวอย่างของเราคือพอร์ต 22
- -j ACCEPT : ข้ามไปที่เป้าหมายที่ยอมรับภายในไฟร์วอลล์ กล่าวอีกนัยหนึ่ง ปล่อยให้แพ็กเก็ตผ่านกฎที่เหลือโดยไม่ต้องดำเนินการใดๆ
ไฟล์คอนฟิกูเรชันที่เคาะแล้วแก้ไข
การแก้ไขที่เราจะทำกับไฟล์จะถูกเน้นเป็นสีแดงด้านล่าง:
เราขยาย “seq_timeout” เป็น 15 วินาที นี่เป็นเรื่องที่ใจกว้าง แต่ถ้ามีคนส่งคำขอเกี่ยวกับการเชื่อมต่อด้วยตนเอง เขาอาจต้องใช้เวลามาก
ในส่วน "openSSH" เราเปลี่ยนตัวเลือก -A
(ต่อท้าย) ในคำสั่งเป็น -I
(แทรก) คำสั่งนี้แทรกกฎไฟร์วอลล์ใหม่ที่ ด้านบน ของรายการกฎไฟร์วอลล์ หากคุณปล่อยให้ตัวเลือก -A
จะ ผนวก รายการกฎไฟร์วอลล์และวางไว้ที่ ด้านล่าง
การรับส่งข้อมูลขาเข้าจะถูกทดสอบกับกฎไฟร์วอลล์แต่ละรายการจากบนลงล่าง เรามีกฎที่ปิดพอร์ต 22 อยู่แล้ว ดังนั้นหากทราฟฟิกขาเข้าถูกทดสอบกับกฎนั้นก่อนที่จะเห็นกฎที่อนุญาตทราฟฟิก การเชื่อมต่อจะถูกปฏิเสธ ถ้าเห็นกฎใหม่นี้ก่อน การเชื่อมต่อจะได้รับอนุญาต
คำสั่งปิดจะลบกฎที่เพิ่มโดย openSSH ออกจากกฎไฟร์วอลล์ การรับส่งข้อมูล SSH ได้รับการจัดการอีกครั้งโดยกฎ "พอร์ต 22 ที่ปิดอยู่" ที่มีอยู่แล้ว
หลังจากที่คุณทำการแก้ไขเหล่านี้แล้ว ให้บันทึกไฟล์การกำหนดค่า
ที่เกี่ยวข้อง: วิธีแก้ไขไฟล์ข้อความแบบกราฟิกบน Linux ด้วย gedit
ไฟล์ควบคุมที่เคาะแล้วแก้ไข
ไฟล์ควบคุม knockd
นั้นง่ายกว่าโดยสิ้นเชิง ก่อนที่เราจะลงลึกและแก้ไขสิ่งนั้น เราจำเป็นต้องทราบชื่อภายในสำหรับการเชื่อมต่อเครือข่ายของเรา หากต้องการค้นหา ให้พิมพ์คำสั่งนี้:
ip addr
การเชื่อมต่อที่เครื่องนี้ใช้ในการค้นคว้าบทความนี้เรียกว่า enp0s3
จดชื่อการเชื่อมต่อของคุณ
คำสั่งต่อไปนี้แก้ไขไฟล์คอนโทรล knockd
:
sudo gedit /etc/default/knockd
นี่คือไฟล์ knockd
ใน gedit
การแก้ไขบางส่วนที่เราต้องทำจะถูกเน้นด้วยสีแดง:
เราเปลี่ยนรายการ “START_KNOCKD=" เป็นจาก 0 เป็น 1
นอกจากนี้เรายังลบแฮช #
จากจุดเริ่มต้นของรายการ “KNOCKD_OPTS=” และแทนที่ “eth1” ด้วยชื่อการเชื่อมต่อเครือข่ายของเรา enp0s3
แน่นอน หากการเชื่อมต่อเครือข่ายของคุณคือ eth1
คุณจะไม่เปลี่ยนแปลง
หลักฐานอยู่ในพุดดิ้ง
ได้เวลาดูว่าจะได้ผลหรือไม่ เราจะเริ่ม knockd
daemon ด้วยคำสั่งนี้:
sudo systemctrl เริ่มเคาะ
ตอนนี้เราจะข้ามไปยังอีกเครื่องหนึ่งแล้วลองเชื่อมต่อ เราติดตั้งเครื่องมือ knockd
บนคอมพิวเตอร์เครื่องนั้นด้วย ไม่ใช่เพราะเราต้องการตั้งค่า port knocking แต่เนื่องจากแพ็คเกจ knockd
มีเครื่องมืออื่นที่เรียกว่า knock
เราจะใช้เครื่องนี้ยิงในลำดับลับของเราและเคาะแทนเรา
ใช้คำสั่งต่อไปนี้เพื่อส่งลำดับความลับของการร้องขอการเชื่อมต่อไปยังพอร์ตบนพอร์ตที่เคาะโฮสต์คอมพิวเตอร์ด้วยที่อยู่ IP 192.168.4.24:
น็อค 192.168.4.24 7000 8000 9000 -d 500
สิ่งนี้จะบอกการ knock
เพื่อกำหนดเป้าหมายคอมพิวเตอร์ที่ที่อยู่ IP 192.168.4.24 และส่งคำขอเชื่อมต่อกับพอร์ต 7000, 8000 และ 9000 โดยมีค่า -d
(หน่วงเวลา) 500 มิลลิวินาทีระหว่างกัน
ผู้ใช้ชื่อ “dave” จะส่งคำขอ SSH ไปที่ 192.168.4.24:
ssh [email protected]
การเชื่อมต่อของเขาได้รับการยอมรับ เขาป้อนรหัสผ่าน และเริ่มเซสชันระยะไกล พรอมต์คำสั่งของเขาเปลี่ยนจาก dave@nostromo
เป็น dave@howtogeek
ในการออกจากระบบคอมพิวเตอร์ระยะไกล เขาพิมพ์:
ทางออก
พรอมต์คำสั่งของเขาจะกลับสู่เครื่องคอมพิวเตอร์ของเขา เขาใช้การ knock
อีกครั้ง และครั้งนี้ มันกำหนดเป้าหมายพอร์ตในลำดับย้อนกลับเพื่อปิดพอร์ต SSH บนคอมพิวเตอร์ระยะไกล
น็อค 192.168.4.24 9000 8000 7000 -d 500
เป็นที่ยอมรับว่านี่ไม่ใช่เซสชันระยะไกลที่เกิดผลโดยเฉพาะ แต่แสดงให้เห็นถึงการเปิดและปิดพอร์ตผ่านการเคาะพอร์ตและพอดีกับภาพหน้าจอเดียว
แล้วมันมีลักษณะอย่างไรจากอีกด้านหนึ่ง? ผู้ดูแลระบบบนพอร์ต knocking host ใช้คำสั่งต่อไปนี้เพื่อดูรายการใหม่ที่มาถึงในบันทึกของระบบ:
tail -f /var/log/syslog
- คุณเห็นรายการ openSSH สามรายการ สิ่งเหล่านี้จะเพิ่มขึ้นเนื่องจากแต่ละพอร์ตเป็นเป้าหมายโดยยูทิลิตี้การน็อคระยะไกล
- เมื่อตรงตามทั้งสามขั้นตอนของลำดับทริกเกอร์ รายการที่ระบุว่า "OPEN SESAME" จะถูกบันทึก
- ส่งคำสั่งเพื่อแทรกกฎลงในรายการกฎ
iptables
อนุญาตการเข้าถึงผ่าน SSH บนพอร์ต 22 จากที่อยู่ IP เฉพาะของพีซีที่ให้การเคาะความลับที่ถูกต้อง (192.168.4.23) - ผู้ใช้ “เดฟ” เชื่อมต่อเพียงไม่กี่วินาทีเท่านั้น จากนั้นจึงตัดการเชื่อมต่อ
- คุณเห็นรายการ closeSSH สามรายการ สิ่งเหล่านี้ถูกยกขึ้นเนื่องจากแต่ละพอร์ตมีเป้าหมายโดยยูทิลิตี้การน็อคระยะไกล—มันบอกให้โฮสต์เคาะพอร์ตเพื่อปิดพอร์ต 22
- หลังจากที่ทั้งสามขั้นตอนทำงาน เราได้รับข้อความ "OPEN SESAME" อีกครั้ง คำสั่งถูกส่งไปยังไฟร์วอลล์เพื่อลบกฎ (ทำไมไม่ “ปิดงา” ตอนปิดพอร์ต ใครจะรู้?)
ตอนนี้กฎข้อเดียวในรายการกฎ iptables
เกี่ยวกับพอร์ต 22 คือกฎที่เราพิมพ์ตอนต้นเพื่อปิดพอร์ตนั้น ดังนั้นพอร์ต 22 จึงปิดอีกครั้ง
เคาะบนหัว
นั่นคือเคล็ดลับในห้องนั่งเล่นของ Port Knocking ปฏิบัติเหมือนเป็นการเบี่ยงเบนความสนใจ และอย่าทำในโลกแห่งความเป็นจริง หรือถ้าคุณจำเป็น อย่ายึดถือเป็นรูปแบบการรักษาความปลอดภัยเพียงอย่างเดียวของคุณ