Điểm:1

Freeradius với máy chủ dhcp: Các cuộc gọi đến mô-đun perl trả về lỗi

lá cờ us

Đây là phần tiếp theo của câu hỏi trước đây của tôi trong việc gửi các tuyến tĩnh từ việc triển khai máy chủ Freeradius DHCP kết hợp với máy chủ Strongswan VPN.

Khi gỡ lỗi Freeradius bằng tcpdump và Wireshark, tôi phát hiện ra rằng tôi có thể gửi các tuyến tĩnh không phân loại từ máy chủ Freeradius DHCP bằng cách thêm DHCP-Classless-Static-RouteDHCP-Site-cụ thể-25 (còn gọi là tuyến đường tĩnh của Microsoft) cho tôi DHCP-Khám pháYêu cầu DHCP các phần của tệp cấu hình máy chủ dhcp.

Tuy nhiên: Có vẻ như các tuyến tĩnh không được máy khách Microsoft VPN chấp nhận nếu tôi đặt cổng mặc định thành 0.0.0.0 theo đề xuất của tài liệu Strongswan.

Ít nhất tôi không thể tìm thấy các tuyến được quảng cáo trên máy khách Windows của mình khi sử dụng in tuyến đường -4.

Ngoài ra, tôi không thể thêm các tuyến theo cách thủ công trên máy khách Windows khi tôi đang sử dụng 0.0.0.0 làm cổng tiêu chuẩn trên giao diện VPN.

Tuy nhiên:

Hãy nói rằng tôi muốn truy cập mạng con 192.168.200.0/24 qua VPN và máy chủ VPN của tôi chỉ định địa chỉ 192.168.201.2/24 cho máy khách Windows của tôi. Sau đó, thực sự có thể tạo một tuyến tĩnh ở phía máy khách windows bằng cách khai báo rằng mạng con 192.168.200.0/24 có thể truy cập được qua 192.168.201.2 bằng cách sử dụng lệnh windows:

lộ trình thêm mặt nạ 192.168.200.0 255.255.255.0 192.168.201.2

Tôi biết nó trông hơi lạ, nhưng tôi có thể ping bất kỳ máy chủ nào trên 192.168.200.0 mạng con, miễn là nó hoạt động là tôi hài lòng. :-)

Nhưng: Tôi sẽ vui hơn nếu tôi có thể làm điều tương tự bằng cách quảng cáo các tuyến đường từ máy chủ VPN của mình thay vì thực hiện thủ công trên tất cả các máy khách VPN. :-)

Điều đó có nghĩa là tôi phải thực hiện một chút lập trình động cho cấu hình DHCP trong Freeradius. Trong trường hợp của tôi, điều đó có nghĩa là tôi phải tạo một tham chiếu đến một mô-đun perl trong DHCP-Discover và DHCP-request để lấy địa chỉ ip vpn của máy khách được chỉ định, chuyển đổi nó thành các octet và kết hợp nó với các tuyến tĩnh cũng được cung cấp dưới dạng octet.

Một ví dụ:

mạng con 192.168.200.0/24 sẽ được mã hóa thành 0x18c0a8c8 vì mặt nạ mạng con được mã hóa trước.

Khách hàng 192.168.201.2/24 sẽ được mã hóa thành 0xc0a8c902 vì nó chỉ chuyển đổi từng số trong địa chỉ ip thành hex.

Mã hóa cuối cùng cho tuyến đường sẽ là: 0x18c0a8c8c0a8c902 vì nó chỉ là sự kết hợp của hai chuỗi.

sau đó tôi phải sử dụng cập nhật trả lời với đoạn mã sau:

  cập nhật câu trả lời {
    &DHCP-Classless-Static-Route = 0x18c0a8c8c0a8c902
    &DHCP-Site-cụ thể-25 = 0x18c0a8c8c0a8c902
  }

Nếu có thêm bất kỳ tuyến đường nào thì tất cả các tuyến đường sẽ được nối thành một chuỗi dài.

Phần khó khăn:

Giả sử bạn có cấu hình mặc định của máy chủ DHCP Freeradius như trong freeradius/3.0/sites-available/dhcp tập tin.

Cấu trúc chung của tệp cho DHCP-Discover và DHCP-Request như sau:

dhcp DHCP-Yêu cầu {
  cập nhật câu trả lời {
    &DHCP-Message-Type = DHCP-Ack
  }

  cập nhật câu trả lời {
    # Các tùy chọn DHCP chung, chẳng hạn như thời gian thuê GW, DNS, địa chỉ IP mặc định, v.v.
  }

  kiểm soát cập nhật {
    &Tên nhóm := "vpn_pool"
  }

  dhcp_sqlippool

  Vâng
}

Sau đó, theo như tôi đã thu thập được, tôi cần gọi mô-đun perl của mình sau dhcp_sqlippool đã được gọi và trước khi trở lại Vâng, bởi vì dhcp_sqlippool là mô-đun gán ipaddress cho máy khách VPN.

Điều đó có nghĩa là phiên bản của tôi sẽ giống như:

dhcp DHCP-Yêu cầu {
  cập nhật câu trả lời {
    &DHCP-Message-Type = DHCP-Ack
  }

  cập nhật câu trả lời {
    # Các tùy chọn DHCP chung, chẳng hạn như thời gian thuê GW, DNS, địa chỉ IP mặc định, v.v.
  }

  kiểm soát cập nhật {
    &Tên nhóm := "vpn_pool"
  }

  dhcp_sqlippool

  perl

  # Nếu mô-đun perl không trả về lỗi
  nếu (được) {
    cập nhật câu trả lời {
      # Perl-Route chứa một chuỗi mã hóa hex với tất cả các tuyến đường.
      &DHCP-Classless-Static-Route = Perl-Route
      &DHCP-Site-specific-25 = Perl-Route      
    }
  }

  # Không chắc chắn nếu cái này là cần thiết?
  cập nhật câu trả lời {
    &DHCP-Cuối-Tùy chọn = 255
  }

  Vâng
}

Để làm cho nó hoạt động, tôi phải kích hoạt perl bên dưới freeradius/3.0/đã bật mod thư mục và sửa đổi tên tệp trong freeradius/3.0/mods-enabled/perl để trỏ nó đến mô-đun perl của tôi. Chẳng hạn như:

tên tệp = ${modconfdir}/${.:instance}/dhcp/Options.pm

Nhưng làm cách nào để tham chiếu cuộc gọi đến perl đúng cách?

Tôi nghĩ rằng tôi phải kích hoạt dòng func_post_auth = post_auth Trong freeradius/3.0/mods-enabled/perl và tạo một post_auth phụ trong mô-đun perl của tôi để xử lý các cuộc gọi từ Freeradius, nhưng theo như tôi có thể thấy trong nhật ký của mình, tôi gặp lỗi sau trong Freeradius:

(8) perl: perl_embed:: module = /etc/freeradius/3.0/mods-config/perl/dhcp/Options.pm , 
func = trạng thái thoát post_auth = Chương trình con chưa xác định &main::post_auth được gọi.
...
(8) [perl] = thất bại
(8) } # dhcp DHCP-Discover = fail

Vì vậy, nó là gì mà tôi không nhìn thấy?

Điểm:0
lá cờ us

Tôi đã đập đầu vào tường vài lần, nhưng ít nhất tôi đã làm cho mô-đun perl hoạt động, mặc dù tôi không hoàn toàn ở nơi mình muốn, vì định tuyến tĩnh qua DHCP không chuyển từ máy chủ Freeradius DHCP sang máy khách VPN qua Strongswan , nhưng việc gỡ lỗi các gói UDP từ máy chủ Freeradius DHCP có nghĩa là vấn đề nằm ở chỗ khác.

Nhưng dù sao đây là những gì tôi đã làm:

  1. Kích hoạt mô-đun perl trong freeradius/3.0/đã bật mod và đặt ít nhất các dòng sau:
perl {
  # Vị trí mã Perl: ("freeradius/3.0/mods-config/dhcp/Options.pm")
  tên tệp = ${modconfdir}/${.:instance}/dhcp/Options.pm

  # Mô-đun DHCP được gọi trong freeradius post_auth
  func_post_auth = post_auth
}
  1. Biến đổi freeradius/3.0/sites-enabled/dhcp Những nơi có liên quan là DHCP-Khám pháYêu cầu DHCP:
dhcp DHCP-Khám phá {

        cập nhật câu trả lời {
               DHCP-Message-Type = DHCP-Ưu đãi
        }

        # Nội dung ở đây được phát minh. Thay đổi chúng!
        cập nhật câu trả lời {
                &DHCP-Domain-Name-Server = 192.168.200.1
                &DHCP-Subnet-Mask = 255.255.255.0
                &DHCP-IP-Địa chỉ-Thời gian thuê = 86400
                &DHCP-DHCP-Số nhận dạng máy chủ = 192.168.200.4
        }

        # Hoặc, phân bổ IP từ nhóm DHCP trong SQL. bạn có thể cần phải
        # đặt tên nhóm ở đây nếu bạn chưa đặt ở nơi khác.
        kiểm soát cập nhật {
                &Tên nhóm := "vpn_pool"
        }

        dhcp_sqlippool

        # Gọi tạo tuyến đường tĩnh.
        perl

        Vâng
}

dhcp DHCP-Yêu cầu {

        # Loại gói phản hồi.Xem phần Khám phá DHCP ở trên.
        cập nhật câu trả lời {
               &DHCP-Message-Type = DHCP-Ack
        }

        # Nội dung ở đây được phát minh. Thay đổi chúng!
        cập nhật câu trả lời {
                &DHCP-Domain-Name-Server = 192.168.200.1
                &DHCP-Subnet-Mask = 255.255.255.0
                &DHCP-IP-Địa chỉ-Thời gian thuê = 86400
                &DHCP-DHCP-Số nhận dạng máy chủ = 192.168.200.4
        }

        # Hoặc, phân bổ IP từ nhóm DHCP trong SQL. bạn có thể cần phải
        # đặt tên nhóm ở đây nếu bạn chưa đặt ở nơi khác.
        kiểm soát cập nhật {
                &Tên nhóm := "vpn_pool"
        }
 
        dhcp_sqlippool

        # Gọi tạo tuyến đường tĩnh.
        perl

        Vâng
}
  1. Tạo mã perl nằm ở freeradius/3.0/mods-config/perl/dhcp/Options.pm:
Sử dụng nghiêm ngặt;
sử dụng cảnh báo;
sử dụng Dữ liệu::Dumper;
sử dụng Mạng::IP;

# Mang giá trị băm toàn cầu vào phạm vi gói
của chúng tôi (%RAD_REQUEST, %RAD_REPLY, %RAD_CHECK);

#
# Đây là ánh xạ lại của các giá trị trả về
#
sử dụng hằng số {
    RLM_MODULE_REJECT => 0, # ngay lập tức từ chối yêu cầu
    RLM_MODULE_OK => 2, # mô-đun vẫn ổn, tiếp tục
    RLM_MODULE_HANDLED => 3, # mô-đun đã xử lý yêu cầu nên dừng
    RLM_MODULE_INVALID => 4, # mô-đun cho rằng yêu cầu không hợp lệ
    RLM_MODULE_USERLOCK => 5, # từ chối yêu cầu (người dùng bị khóa)
    RLM_MODULE_NOTFOUND => 6, # người dùng không tìm thấy
    RLM_MODULE_NOOP => 7, # mô-đun thành công mà không làm gì cả
    RLM_MODULE_UPDATED => 8, # OK (đã sửa cặp)
    RLM_MODULE_NUMCODES => 9 # Có bao nhiêu mã trả về
};

# Tương tự như src/include/radiusd.h
sử dụng hằng số L_DBG=> 1;
sử dụng hằng số L_AUTH=> 2;
sử dụng hằng số L_INFO=> 3;
sử dụng hằng số L_ERR=> 4;
sử dụng hằng số L_PROXY=> 5;
sử dụng hằng số L_ACCT=> 6;

# Hàm xử lý post_auth

phụ post_auth {

    # Nhận IP máy khách VPN từ máy chủ Freeradius DHCP.
    của tôi $client_ip = new Net::IP ( $RAD_REQUEST{'DHCP-Requested-IP-Address'} ) hoặc chết (Net::IP::Error());

    # Ví dụ về 2 quy tắc định tuyến đã gửi ('192.168.20.0/24' và '192.168.200.0/24') 
    @routes của tôi = (Mạng mới::IP('192.168.20/24'), Mạng mới::IP('192.168.200/24'));

    # Đo xem có bao nhiêu phần tử trong mảng route.
    kích thước $ của tôi = @routes;

    # Chuyển đổi ip máy khách thành mã hex.
    của tôi $client_octets = get_ip_octets ($client_ip->ip(),$client_ip->prefixlen());

    # Freeradius muốn chuỗi được mã hóa bắt đầu bằng '0x'
    # theo sau là các octet được mã hóa dưới dạng hex.
    của tôi $octet_str = "0x";

    for(của tôi $i = 0; $i < $size; $i++)
    {
        # Chuyển đổi mạng con thành octet, bỏ qua các số 0 ở cuối.
        của tôi $route_octets = get_ip_octets ($routes[$i]->ip(),$routes[$i]->prefixlen());

        # Chuyển đổi tiền tố mạng thành octet
        của tôi $hex_prefix = sprintf("%02x", $routes[$i]->prefixlen());

        # Tuyến đường được mã hóa bởi các octet mạng theo sau bởi các octet mạng con
        $route_octets = $hex_prefix . $route_octet;

        # Toàn bộ chuỗi tuyến đường là octet tuyến đường theo sau là octet cổng ('ipn vpn máy khách').
        $route_str = $route_octets của tôi. $client_octets;

        $octet_str = $octet_str . $route_str;
    }

    # Định tuyến tĩnh không phân loại (tùy chọn dhcp 121)
    $RAD_REPLY{'DHCP-Classless-Static-Route'} = $octet_str;

    # Định tuyến tĩnh không phân lớp của Microsoft (tùy chọn dhcp 249)
    $RAD_REPLY{'DHCP-Site-specific-25'} = $octet_str;

    trả về RLM_MODULE_OK;

}

phụ get_ip_octet {
    # Tham số đầu tiên: Địa chỉ ip nguồn
    của tôi $sip = $_[0];

    # Tham số thứ hai: Độ dài bit của mạng (còn gọi là ký hiệu CIDR).
    của tôi $cidr = $_[1];

    @decimals của tôi = split('\.', $sip);
    của tôi $index = int($cidr / 8) ;

    kết quả $ của tôi = '';
    for(của tôi $i = 0; $i < $index; $i++)
    {
        # Chuyển đổi từng số trong địa chỉ ip thành hex và định dạng có đầu
        # 0 trong trường hợp số chuyển đổi nhỏ hơn 16.
        $result = $result . sprintf("%02x", $decimals[$i]);
    }

    trả lại kết quả $;
}

Mã perl có thể được điều chỉnh từ đây, vì vậy tùy chọn 121 hoặc tùy chọn 249 được gửi tùy thuộc vào hệ điều hành máy khách.

Tôi cũng để lại khả năng làm cho mã chung chung hơn, vì vậy các tuyến tĩnh có thể được xác định trực tiếp trong tệp cấu hình Freeradius cho trình đọc.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.