Score:1

Freeradius พร้อมเซิร์ฟเวอร์ dhcp: การเรียกไปยังโมดูล perl ส่งคืนข้อผิดพลาด

ธง us

นี่คือความต่อเนื่องของคำถามก่อนหน้าของฉัน ในการส่งเส้นทางคงที่จากการใช้งานเซิร์ฟเวอร์ Freeradius DHCP ร่วมกับเซิร์ฟเวอร์ Strongswan VPN

เมื่อทำการดีบัก Freeradius โดยใช้ tcpdump และ Wireshark ฉันพบว่าฉันสามารถส่งเส้นทางคงที่แบบไม่มีคลาสจากเซิร์ฟเวอร์ Freeradius DHCP โดยการเพิ่ม DHCP-Classless-Static-เส้นทาง และ DHCP-ไซต์เฉพาะ-25 (หรือที่เรียกว่า Microsoft static route) ตัวเลือกของฉัน DHCP-ค้นพบ และ DHCP-คำขอ ส่วนของไฟล์การกำหนดค่าเซิร์ฟเวอร์ dhcp

อย่างไรก็ตาม: ปรากฏว่าไคลเอนต์ Microsoft VPN ไม่ยอมรับเส้นทางแบบคงที่หากฉันตั้งค่าเกตเวย์เริ่มต้นเป็น 0.0.0.0 ตามที่ เอกสารสตรองสวอน.

อย่างน้อยฉันก็ไม่พบเส้นทางที่โฆษณาบนไคลเอนต์ Windows ของฉันเมื่อใช้งาน พิมพ์เส้นทาง -4.

นอกจากนี้ ฉันไม่สามารถเพิ่มเส้นทางด้วยตนเองบนไคลเอนต์ Windows เมื่อฉันใช้งาน 0.0.0.0 เป็นเกตเวย์มาตรฐานผ่านอินเทอร์เฟซ VPN

อย่างไรก็ตาม:

สมมติว่าฉันต้องการเข้าถึงซับเน็ต 192.168.200.0/24 ผ่าน VPN และเซิร์ฟเวอร์ VPN ของฉันกำหนดที่อยู่ 192.168.201.2/24 ไปยังไคลเอ็นต์ Windows ของฉัน จากนั้นเป็นไปได้ที่จะสร้างเส้นทางคงที่บนฝั่งไคลเอนต์ windows โดยประกาศว่าซับเน็ต 192.168.200.0/24 สามารถเข้าถึงได้ผ่าน 192.168.201.2 โดยใช้คำสั่ง windows:

เส้นทางเพิ่ม 192.168.200.0 มาสก์ 255.255.255.0 192.168.201.2

ฉันรู้ว่ามันดูแปลกๆ แต่ฉันสามารถ ping โฮสต์ใดก็ได้บน 192.168.200.0 subnet ตราบเท่าที่ใช้งานได้ฉันก็มีความสุข :-)

แต่: ฉันจะมีความสุขมากกว่านี้ถ้าฉันสามารถทำสิ่งเดียวกันได้ด้วยการโฆษณาเส้นทางจากเซิร์ฟเวอร์ VPN ของฉัน แทนที่จะดำเนินการด้วยตนเองบนไคลเอนต์ VPN ทั้งหมด :-)

นั่นหมายความว่าฉันต้องทำโปรแกรมไดนามิกเล็กน้อยกับการกำหนดค่า DHCP ใน Freeradius กรณีของฉันหมายความว่าฉันต้องอ้างอิงถึงโมดูล Perl ใน DHCP-Discover และ DHCP-request ที่คว้าที่อยู่ IP VPN ของไคลเอ็นต์ที่กำหนด แปลงเป็นออคเต็ตและรวมเข้ากับเส้นทางสแตติกที่กำหนดเป็นออคเต็ตด้วย

ตัวอย่าง:

เครือข่ายย่อย 192.168.200.0/24 จะถูกเข้ารหัสเป็น 0x18c0a8c8 เนื่องจากซับเน็ตมาสก์ถูกเข้ารหัสก่อน

ลูกค้า 192.168.201.2/24 จะถูกเข้ารหัสเป็น 0xc0a8c902 เนื่องจากเป็นเพียงการแปลงตัวเลขแต่ละตัวในที่อยู่ IP เป็นเลขฐานสิบหก

การเข้ารหัสขั้นสุดท้ายสำหรับเส้นทางจะเป็น: 0x18c0a8c8c0a8c902 เนื่องจากเป็นเพียงการต่อสายสองสายเข้าด้วยกัน

แล้วต้องใช้ อัปเดตการตอบกลับ ด้วยรหัสต่อไปนี้:

  อัปเดตคำตอบ {
    &DHCP-Classless-Static-เส้นทาง = 0x18c0a8c8c0a8c902
    &DHCP-ไซต์เฉพาะ-25 = 0x18c0a8c8c0a8c902
  }

หากมีเส้นทางเพิ่มเติม เส้นทางทั้งหมดจะถูกเชื่อมเข้าด้วยกันเป็นสตริงยาวเส้นเดียว

ส่วนที่ยุ่งยาก:

สมมติว่าคุณมีการกำหนดค่าเริ่มต้นของเซิร์ฟเวอร์ Freeradius DHCP ตามที่พบใน freeradius/3.0/sites-available/dhcp ไฟล์.

โครงสร้างทั่วไปของไฟล์สำหรับ DHCP-Discover และ DHCP-Request เป็นดังนี้:

dhcp DHCP-คำขอ {
  อัปเดตคำตอบ {
    &DHCP-Message-Type = DHCP-Ack
  }

  อัปเดตคำตอบ {
    # ตัวเลือก DHCP ทั่วไป เช่น GW เริ่มต้น, DNS, เวลาเช่าที่อยู่ IP เป็นต้น
  }

  อัปเดตการควบคุม {
    &ชื่อพูล := "vpn_pool"
  }

  dhcp_sqlippool

  ตกลง
}

เท่าที่ฉันรวบรวมได้ฉันต้องเรียกโมดูล perl ของฉันหลังจากนั้น dhcp_sqlippool ได้รับการเรียกและก่อนที่จะกลับ ตกลง, เพราะ dhcp_sqlippool เป็นโมดูลที่กำหนด ipaddress ให้กับไคลเอนต์ VPN

นั่นหมายความว่าเวอร์ชันของฉันจะเป็นดังนี้:

dhcp DHCP-คำขอ {
  อัปเดตคำตอบ {
    &DHCP-Message-Type = DHCP-Ack
  }

  อัปเดตคำตอบ {
    # ตัวเลือก DHCP ทั่วไป เช่น GW เริ่มต้น, DNS, เวลาเช่าที่อยู่ IP เป็นต้น
  }

  อัปเดตการควบคุม {
    &ชื่อพูล := "vpn_pool"
  }

  dhcp_sqlippool

  เพิร์ล

  # หากโมดูล Perl ไม่ส่งคืนข้อผิดพลาด
  ถ้า (ตกลง) {
    อัปเดตคำตอบ {
      # Perl-Route มีสตริงเข้ารหัสฐานสิบหกพร้อมเส้นทางทั้งหมด
      &DHCP-Classless-Static-Route = Perl-เส้นทาง
      &DHCP-ไซต์เฉพาะ-25 = Perl-เส้นทาง      
    }
  }

  #ไม่แน่ใจว่าจำเป็นไหม?
  อัปเดตคำตอบ {
    &DHCP-จุดสิ้นสุดของตัวเลือก = 255
  }

  ตกลง
}

เพื่อให้มันใช้งานได้ ฉันต้องเปิดใช้งาน perl ภายใต้ freeradius/3.0/mods-enabled โฟลเดอร์และแก้ไขชื่อไฟล์ใน freeradius/3.0/mods-enabled/perl เพื่อชี้ไปที่โมดูล Perl ของฉัน เช่น:

ชื่อไฟล์ = ${modconfdir}/${.:instance}/dhcp/Options.pm

แต่ฉันจะอ้างอิงการโทรไปยัง perl ได้อย่างไร?

ฉันคิดว่าฉันต้องเปิดใช้งานสาย func_post_auth = post_auth ใน freeradius/3.0/mods-enabled/perl และสร้าง ย่อย post_auth ในโมดูล perl ของฉันเพื่อจัดการการโทรจาก Freeradius แต่เท่าที่ฉันเห็นในบันทึกของฉัน ฉันได้รับข้อผิดพลาดต่อไปนี้ใน Freeradius:

(8) perl: perl_embed:: module = /etc/freeradius/3.0/mods-config/perl/dhcp/Options.pm , 
func = post_auth exit status= รูทีนย่อยที่ไม่ได้กำหนด &main::post_auth ถูกเรียก
...
(8) [perl] = ล้มเหลว
(8) } # dhcp DHCP-ค้นพบ = ล้มเหลว

แล้วอะไรล่ะที่ฉันไม่เห็น?

Score:0
ธง us

ฉันเอาหัวโขกกำแพงสองสามครั้ง แต่อย่างน้อยฉันก็ได้โมดูล Perl ที่ใช้งานได้ แม้ว่าฉันจะไม่ได้อยู่ในจุดที่ต้องการ เนื่องจากการกำหนดเส้นทางแบบสแตติกผ่าน DHCP ไม่ได้ส่งผ่านจากเซิร์ฟเวอร์ Freeradius DHCP ไปยังไคลเอนต์ VPN ผ่าน Strongswan แต่การดีบักแพ็คเกจ UDP จากเซิร์ฟเวอร์ Freeradius DHCP แสดงว่าปัญหาอยู่ที่อื่น

อย่างไรก็ตามนี่คือสิ่งที่ฉันทำ:

  1. เปิดใช้งานโมดูล Perl ใน freeradius/3.0/mods-enabled และตั้งค่าบรรทัดต่อไปนี้เป็นอย่างน้อย:
เพิร์ล {
  # ตำแหน่งรหัส Perl: ("freeradius/3.0/mods-config/dhcp/Options.pm")
  ชื่อไฟล์ = ${modconfdir}/${.:instance}/dhcp/Options.pm

  # โมดูล DHCP ถูกเรียกระหว่าง freeradius post_auth
  func_post_auth = post_auth
}
  1. แก้ไข freeradius/3.0/sites-enabled/dhcp สถานที่ที่เกี่ยวข้องคือ DHCP-ค้นพบ และ DHCP-คำขอ:
dhcp DHCP-ค้นพบ {

        อัปเดตคำตอบ {
               DHCP-Message-Type = DHCP-ข้อเสนอ
        }

        #เนื้อหาที่นี่ประดิษฐ์ขึ้น เปลี่ยนพวกเขา!
        อัปเดตคำตอบ {
                &DHCP-โดเมนชื่อเซิร์ฟเวอร์ = 192.168.200.1
                &DHCP-ซับเน็ตมาสก์ = 255.255.255.0
                &DHCP-IP-Address-Lease-Time = 86400
                &DHCP-DHCP-ตัวระบุเซิร์ฟเวอร์ = 192.168.200.4
        }

        # หรือจัดสรร IP จากพูล DHCP ใน SQL คุณอาจจำเป็นต้อง
        # ตั้งชื่อพูลที่นี่หากยังไม่ได้ตั้งที่อื่น
        อัปเดตการควบคุม {
                &พูลชื่อ := "vpn_pool"
        }

        dhcp_sqlippool

        # โทรสร้างเส้นทางคงที่
        เพิร์ล

        ตกลง
}

dhcp DHCP-คำขอ {

        # ประเภทแพ็กเก็ตการตอบสนองดูหัวข้อ DHCP-Discover ด้านบน
        อัปเดตคำตอบ {
               &DHCP-Message-Type = DHCP-Ack
        }

        #เนื้อหาที่นี่ประดิษฐ์ขึ้น เปลี่ยนพวกเขา!
        อัปเดตคำตอบ {
                &DHCP-โดเมนชื่อเซิร์ฟเวอร์ = 192.168.200.1
                &DHCP-ซับเน็ตมาสก์ = 255.255.255.0
                &DHCP-IP-Address-Lease-Time = 86400
                &DHCP-DHCP-ตัวระบุเซิร์ฟเวอร์ = 192.168.200.4
        }

        # หรือจัดสรร IP จากพูล DHCP ใน SQL คุณอาจจำเป็นต้อง
        # ตั้งชื่อพูลที่นี่หากยังไม่ได้ตั้งที่อื่น
        อัปเดตการควบคุม {
                &พูลชื่อ := "vpn_pool"
        }
 
        dhcp_sqlippool

        # โทรสร้างเส้นทางคงที่
        เพิร์ล

        ตกลง
}
  1. สร้างรหัส Perl อยู่ที่ freeradius/3.0/mods-config/perl/dhcp/Options.pm:
ใช้อย่างเข้มงวด
ใช้คำเตือน
ใช้ Data::Dumper;
ใช้ Net::IP;

# นำแฮชส่วนกลางเข้าสู่ขอบเขตแพ็คเกจ
ของเรา (%RAD_REQUEST, %RAD_REPLY, %RAD_CHECK);

#
# นี่คือการแมปค่าส่งคืนใหม่
#
ใช้ค่าคงที่ {
    RLM_MODULE_REJECT => 0, # ปฏิเสธคำขอทันที
    RLM_MODULE_OK => 2, # โมดูลตกลง ดำเนินการต่อ
    RLM_MODULE_HANDLED => 3, # โมดูลจัดการคำขอ ดังนั้นหยุด
    RLM_MODULE_INVALID => 4, # โมดูลถือว่าคำขอไม่ถูกต้อง
    RLM_MODULE_USERLOCK => 5, # ปฏิเสธคำขอ (ผู้ใช้ถูกล็อกไม่ให้ใช้งาน)
    RLM_MODULE_NOTFOUND => 6 ไม่พบผู้ใช้ # ราย
    RLM_MODULE_NOOP => 7, # โมดูลสำเร็จโดยไม่ต้องทำอะไรเลย
    RLM_MODULE_UPDATED => 8, # OK (แก้ไขคู่)
    RLM_MODULE_NUMCODES => 9 # มีรหัสส่งคืนกี่รหัส
};

# เหมือนกับ src/include/radiusd.h
ใช้ค่าคงที่ L_DBG=> 1;
ใช้ค่าคงที่ L_AUTH=> 2;
ใช้ค่าคงที่ L_INFO=> 3;
ใช้ค่าคงที่ L_ERR=> 4;
ใช้ค่าคงที่ L_PROXY=> 5;
ใช้ค่าคงที่ L_ACCT=> 6;

# ฟังก์ชั่นสำหรับจัดการ post_auth

ย่อย post_auth {

    # รับ IP ไคลเอนต์ VPN จากเซิร์ฟเวอร์ Freeradius DHCP
    $client_ip ของฉัน = ใหม่ Net::IP ( $RAD_REQUEST{'DHCP-Requested-IP-Address'} ) หรือตาย (Net::IP::Error());

    # ตัวอย่างกฎการกำหนดเส้นทาง 2 รายการที่ส่ง ('192.168.20.0/24' และ '192.168.200.0/24') 
    @routes ของฉัน = (ใหม่ Net::IP('192.168.20/24'), ใหม่ Net::IP('192.168.200/24'));

    # วัดจำนวนองค์ประกอบที่มีในอาร์เรย์เส้นทาง
    ขนาด $ ของฉัน = @เส้นทาง;

    # แปลง ip ไคลเอนต์เป็นรหัสฐานสิบหก
    $client_octets ของฉัน = get_ip_octets ($client_ip->ip(),$client_ip->prefixlen());

    # Freeradius ต้องการให้สตริงที่เข้ารหัสเริ่มต้นด้วย '0x'
    # ตามด้วย octets ที่เข้ารหัสเป็นฐานสิบหก
    $octet_str ของฉัน = "0x";

    สำหรับ ($i ของฉัน = 0; $i < $size; $i++)
    {
        # แปลง subnet เป็น octets ข้ามการสิ้นสุดศูนย์
        $route_octets ของฉัน = get_ip_octets ($routes[$i]->ip(),$routes[$i]->prefixlen());

        # แปลงคำนำหน้าเครือข่ายเป็น octets
        $hex_prefix ของฉัน = sprintf("%02x", $routes[$i]->prefixlen());

        # เส้นทางถูกเข้ารหัสโดย octets เครือข่ายตามด้วย octets เครือข่ายย่อย
        $route_octets = $hex_prefix $route_octets;

        # สตริงเส้นทางทั้งหมดคือ octets เส้นทางตามด้วย octets เกตเวย์ ('ไคลเอ็นต์ VPN ip')
        $route_str = $route_octets ของฉัน $client_octets;

        $octet_str = $octet_str $route_str;
    }

    # การกำหนดเส้นทางคงที่แบบไม่มีคลาส (ตัวเลือก dhcp 121)
    $RAD_REPLY{'DHCP-Classless-Static-Route'} = $octet_str;

    # การกำหนดเส้นทางคงที่แบบไม่มีคลาสของ Microsoft (ตัวเลือก dhcp 249)
    $RAD_REPLY{'DHCP-เฉพาะไซต์-25'} = $octet_str;

    ส่งคืน RLM_MODULE_OK;

}

ย่อย get_ip_octets {
    # พารามิเตอร์แรก: ที่อยู่ IP ต้นทาง
    $sip ของฉัน = $_[0];

    # พารามิเตอร์ที่สอง: ความยาวบิตของเครือข่าย (หรือที่เรียกว่า CIDR)
    $cidr ของฉัน = $_[1];

    @decimals = split('\.', $sip);
    $index = int($cidr / 8) ของฉัน ;

    ผลลัพธ์ $ = '';
    สำหรับ ($i ของฉัน = 0; $i < $index; $i++)
    {
        # แปลงแต่ละหมายเลขในที่อยู่ IP เป็นเลขฐานสิบหกและจัดรูปแบบด้วยการนำหน้า
        # ศูนย์ในกรณีที่แปลงตัวเลขน้อยกว่า 16
        $result = ผลลัพธ์ $ sprintf("%02x", $ทศนิยม[$i]);
    }

    ส่งคืนผลลัพธ์ $;
}

รหัส Perl สามารถปรับแต่งได้จากที่นี่ ดังนั้นตัวเลือก 121 หรือ ตัวเลือก 249 ถูกส่งขึ้นอยู่กับระบบปฏิบัติการไคลเอ็นต์

ฉันยังทิ้งความเป็นไปได้ที่จะทำให้โค้ดทั่วไปมากขึ้น ดังนั้นเส้นทางคงที่สามารถกำหนดได้โดยตรงในไฟล์กำหนดค่า Freeradius ไปยังผู้อ่าน

โพสต์คำตอบ

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