B. Secret Combination

本文介绍了一种通过操作组合锁的按钮来找到显示面板上能够构成的最小数字的方法。面对一个具有特定初始状态的n位数字显示面板,可以通过两种操作(增加每位数字或循环右移数字)来改变显示的数字。目标是找到经由这两种操作后所能得到的最小可能数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You got a box with a combination lock. The lock has a display showing n digits. There are two buttons on the box, each button changes digits on the display. You have quickly discovered that the first button adds 1 to all the digits (all digits 9 become digits 0), and the second button shifts all the digits on the display one position to the right (the last digit becomes the first one). For example, if the display is currently showing number 579, then if we push the first button, the display will show 680, and if after that we push the second button, the display will show 068.

You know that the lock will open if the display is showing the smallest possible number that can be obtained by pushing the buttons in some order. The leading zeros are ignored while comparing numbers. Now your task is to find the desired number.

Input

The first line contains a single integer n (1 ≤ n ≤ 1000) — the number of digits on the display.

The second line contains n digits — the initial state of the display.

Output

Print a single line containing n digits — the desired state of the display containing the smallest possible number.

Sample test(s)
input
3
579
output
024
input
4
2014
output
0142
这道题可以用暴力过,每次把最前的一个字符移到最后,然后把第一个字符变成'0',后面依次变化,求出最小的字符串。
#include<stdio.h>
#include<string.h>
char s[1005],str[1005],str1[1005];
char word[40]={'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0'};
int main()
{
	int n,m,i,j,len,t;
	char c;
	while(scanf("%d",&n)!=EOF)
	{
		memset(s,0,sizeof(s));
		scanf("%s",s);
		len=strlen(s);
		for(i=1;i<=len;i++){
			if(i!=1){
				c=s[0];
				for(j=1;j<=len-1;j++){
					s[j-1]=s[j];
				}
				s[len-1]=c;
			}
			strcpy(str,s);
			t='9'-s[0]+1;
			str[0]='0';
			for(j=1;j<len;j++){
				str[j]=word[str[j]-'0'+t];
			}
			str[len]='\0';
			if(i==1 || strcmp(str1,str)>0){
				strcpy(str1,str);
			}
			
		}
		printf("%s\n",str1);
	}
	return 0;
}
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 混合OCR识别模块 腾讯云二维码识别 + 阿里云文字识别 专门用于识别A-1、B-1、A-2、B-2标识 支持二维码优先识别功能 使用示例: from ocr_recognition import OCRRecognizer # 创建识别器实例 ocr = OCRRecognizer() # 识别图像 result = ocr.recognize_image('path/to/image.jpg') if result['success']: print(f"识别到标签: {result['detected_labels']}") else: print(f"识别失败: {result.get('error', '未知错误')}") # 配置二维码识别 ocr.set_qrcode_config(enable_qrcode=True, qrcode_priority=True) """ import os import cv2 import numpy as np import base64 import re from typing import List, Dict from PIL import Image import io import json # 阿里云SDK导入 from alibabacloud_ocr_api20210707.client import Client as OcrClient from alibabacloud_credentials.client import Client as CredentialClient from alibabacloud_tea_openapi import models as open_api_models from alibabacloud_ocr_api20210707 import models as ocr_models from alibabacloud_tea_util import models as util_models from alibabacloud_tea_util.client import Client as UtilClient # 腾讯云SDK导入 from tencentcloud.common import credential from tencentcloud.common.profile.client_profile import ClientProfile from tencentcloud.common.profile.http_profile import HttpProfile from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException from tencentcloud.ocr.v20181119 import ocr_client, models as tencent_models # -------- 腾讯云API配置 -------- TENCENT_SECRET_ID = "AKIDvX2NXUgf4LPH4kHpIcorrlbM2a8hZVM8" TENCENT_SECRET_KEY = "f6KLAmEk5DBwVsEPN8f4ampeNtFTdgmo" TENCENT_REGION = "ap-beijing" # 腾讯云区域 # -------- 阿里云API配置 -------- ALIYUN_ACCESS_KEY_ID = "LTAI5tSKNrm21thiWK3g7sjL" ALIYUN_ACCESS_KEY_SECRET = "MtVCmEhEDY9V0jaaLBH9ChZprERgre" ALIYUN_REGION = "cn-hangzhou" # 使用杭州区域 ALIYUN_ENDPOINT = f"ocr-api.{ALIYUN_REGION}.aliyuncs.com" # -------- 识别配置 -------- VALID_LABELS = ['A-1', 'A-2', 'B-1', 'B-2'] IMAGE_EXTS = ['.png', '.jpg', '.jpeg', '.bmp'] CONFIDENCE_THRESHOLD = 0.7 # 置信度阈值 # 二维码识别配置 ENABLE_QRCODE = True # 是否启用二维码识别 QRCODE_PRIORITY = True # 二维码优先识别 class OCRRecognizer: """ 混合OCR识别器 腾讯云二维码识别 + 阿里云文字识别 专门用于识别A-1、B-1、A-2、B-2标识 """ def __init__(self, enable_qrcode: bool = ENABLE_QRCODE, qrcode_priority: bool = QRCODE_PRIORITY): """ 初始化混合OCR客户端 Args: enable_qrcode: 是否启用二维码识别 qrcode_priority: 是否优先进行二维码识别 """ self.enable_qrcode = enable_qrcode self.qrcode_priority = qrcode_priority # 初始化阿里云OCR客户端 try: config = open_api_models.Config( access_key_id=ALIYUN_ACCESS_KEY_ID, access_key_secret=ALIYUN_ACCESS_KEY_SECRET ) config.endpoint = ALIYUN_ENDPOINT self.aliyun_client = OcrClient(config) print("阿里云OCR初始化成功") except Exception as e: print(f"阿里云OCR初始化失败: {e}") raise e # 初始化腾讯云OCR客户端 try: cred = credential.Credential(TENCENT_SECRET_ID, TENCENT_SECRET_KEY) httpProfile = HttpProfile() httpProfile.endpoint = "ocr.tencentcloudapi.com" clientProfile = ClientProfile() clientProfile.httpProfile = httpProfile self.tencent_client = ocr_client.OcrClient(cred, TENCENT_REGION, clientProfile) print("腾讯云OCR初始化成功") except Exception as e: print(f"腾讯云OCR初始化失败: {e}") raise e def preprocess_image(self, image_path: str) -> bytes: """ 预处理图像,转换为base64编码 Args: image_path: 图像文件路径 Returns: 图像的base64编码字节数据 """ try: with open(image_path, 'rb') as f: image_data = f.read() return image_data except Exception as e: print(f"图像预处理失败: {e}") return None def image_to_base64(self, image_path: str) -> str: """ 将图像转换为base64字符串 Args: image_path: 图像文件路径 Returns: base64编码的字符串 """ try: with open(image_path, 'rb') as f: image_data = f.read() return base64.b64encode(image_data).decode('utf-8') except Exception as e: print(f"图像base64转换失败: {e}") return None def recognize_text(self, image_path: str) -> List[Dict]: """ 使用阿里云OCR识别图像中的文字 Args: image_path: 图像文件路径 Returns: 识别结果列表 """ try: print(f"正在处理图像: {os.path.basename(image_path)}") # 读取图像二进制数据 image_data = self.preprocess_image(image_path) print("正在调用阿里云OCR API...") # 创建识别请求 request = ocr_models.RecognizeAllTextRequest() request.body = image_data request.type = "General" # 设置识别类型为通用文字识别 # 创建运行时选项 runtime = util_models.RuntimeOptions() # 调用API response = self.aliyun_client.recognize_all_text_with_options(request, runtime) print(f"阿里云OCR识别完成") # 解析结果 texts = [] if response.body and response.body.data: content = response.body.data.content if content: print(f"检测到 {len(content)} 个文字区域") for item in content: # 处理字符串格式的结果 if isinstance(item, str): text_info = { 'text': item, 'confidence': 1.0, 'location': { 'left': 0, 'top': 0, 'width': 100, 'height': 30 } } else: # 处理对象格式的结果 text_info = { 'text': getattr(item, 'text', '') if hasattr(item, 'text') else str(item), 'confidence': getattr(item, 'confidence', 1.0) if hasattr(item, 'confidence') else 1.0, 'location': { 'left': int(item.text_rectangles[0]) if hasattr(item, 'text_rectangles') and item.text_rectangles and len(item.text_rectangles) >= 1 else 0, 'top': int(item.text_rectangles[1]) if hasattr(item, 'text_rectangles') and item.text_rectangles and len(item.text_rectangles) >= 2 else 0, 'width': int(item.text_rectangles[2] - item.text_rectangles[0]) if hasattr(item, 'text_rectangles') and item.text_rectangles and len(item.text_rectangles) >= 3 else 100, 'height': int(item.text_rectangles[3] - item.text_rectangles[1]) if hasattr(item, 'text_rectangles') and item.text_rectangles and len(item.text_rectangles) >= 4 else 30 } } texts.append(text_info) print(f" 检测到文字: '{text_info['text']}' (置信度: {text_info['confidence']:.2f})") print(f"总共检测到 {len(texts)} 个文字区域") return texts except Exception as error: print(f"阿里云OCR识别失败: {error}") return [] def recognize_qrcode_with_tencent_api(self, image_path: str) -> List[Dict]: """ 使用腾讯云OCR API的QrcodeOCR接口识别二维码 Args: image_path: 图像文件路径 Returns: 二维码识别结果列表 """ try: print(f"正在使用腾讯云OCR API进行二维码识别: {os.path.basename(image_path)}") # 将图像转换为base64 image_base64 = self.image_to_base64(image_path) if not image_base64: return [] print("正在调用腾讯云QrcodeOCR API...") # 创建请求对象 req = tencent_models.QrcodeOCRRequest() # 设置请求参数 params = { "ImageBase64": image_base64 } req.from_json_string(json.dumps(params)) # 调用API resp = self.tencent_client.QrcodeOCR(req) print(f"腾讯云OCR二维码识别完成") # 解析二维码结果 qrcodes = [] if resp.CodeResults: print(f"检测到 {len(resp.CodeResults)} 个二维码/条形码") for code_result in resp.CodeResults: # 获取二维码内容 qr_text = getattr(code_result, 'Url', '') or getattr(code_result, 'Text', '') type_name = getattr(code_result, 'TypeName', 'UNKNOWN') if qr_text and qr_text.strip(): print(f"腾讯云API检测到二维码内容: {qr_text}") # 检查二维码内容是否包含目标标签 found_label = False for label in VALID_LABELS: if label in qr_text: found_label = True # 获取位置信息 left, top, width, height = 0, 0, 100, 100 if hasattr(code_result, 'Position') and code_result.Position: position = code_result.Position if hasattr(position, 'LeftTop') and hasattr(position, 'RightBottom'): left_top = position.LeftTop right_bottom = position.RightBottom if hasattr(left_top, 'X') and hasattr(left_top, 'Y'): left = int(left_top.X) top = int(left_top.Y) if hasattr(right_bottom, 'X') and hasattr(right_bottom, 'Y'): width = int(right_bottom.X - left) height = int(right_bottom.Y - top) qr_info = { 'text': qr_text, 'label': label, 'confidence': 1.0, # 腾讯云API识别置信度 'type': 'qrcode', 'method': f'腾讯云OCR API ({type_name})', 'location': { 'left': left, 'top': top, 'width': width, 'height': height } } qrcodes.append(qr_info) print(f"检测到二维码标签: '{label}' 内容: '{qr_text}' 类型: {type_name}") break if not found_label: print(f"二维码内容不包含目标标签 (A-1, A-2, B-1, B-2): '{qr_text}'") else: print("二维码数据为空或无效") else: print("腾讯云API未检测到二维码") print(f"腾讯云API总共检测到 {len(qrcodes)} 个有效二维码标签") return qrcodes except TencentCloudSDKException as error: print(f"腾讯云OCR二维码识别失败: {error}") return [] except Exception as error: print(f"腾讯云OCR二维码识别失败: {error}") return [] def recognize_qrcode(self, image_path: str) -> List[Dict]: """ 使用腾讯云OCR API进行二维码识别 Args: image_path: 图像文件路径 Returns: 二维码识别结果列表 """ try: print(f"正在进行腾讯云OCR二维码识别: {os.path.basename(image_path)}") # 直接使用腾讯云OCR API进行二维码识别 print("使用腾讯云OCR API (QrcodeOCR) 进行识别...") qrcodes = self.recognize_qrcode_with_tencent_api(image_path) if qrcodes: print("腾讯云OCR二维码识别成功!") return qrcodes else: print("腾讯云OCR二维码识别未找到有效标签") return [] except Exception as error: print(f"二维码识别失败: {error}") return [] def set_qrcode_config(self, enable_qrcode: bool = True, qrcode_priority: bool = True): """ 设置二维码识别配置 Args: enable_qrcode: 是否启用二维码识别 qrcode_priority: 是否优先进行二维码识别 """ self.enable_qrcode = enable_qrcode self.qrcode_priority = qrcode_priority print(f"二维码识别配置已更新: 启用={enable_qrcode}, 优先={qrcode_priority}") def normalize_text(self, text: str) -> str: """ 标准化文本,用于提高匹配准确率 Args: text: 原始文本 Returns: 标准化后的文本 """ if not text: return '' # 移除空格和特殊字符 text = re.sub(r'[\s\-_]', '', text) # 转换为大写 text = text.upper() # 处理常见的OCR错误 text = text.replace('O', '0') # 字母O替换为数字0 text = text.replace('I', '1') # 字母I替换为数字1 text = text.replace('L', '1') # 字母L替换为数字1 # 处理中文字符的OCR错误 text = text.replace('口', '0') # 中文"口"替换为数字0 text = text.replace('一', '1') # 中文"一"替换为数字1 return text def combine_consecutive_chars(self, ocr_results: List[Dict]) -> List[str]: """ 组合连续的字符,用于处理被分割的标签 Args: ocr_results: OCR识别结果列表 Returns: 组合后的字符串列表 """ if not ocr_results: return [] # 按位置排序(从左到右,从上到下) sorted_results = sorted(ocr_results, key=lambda x: (x['location']['top'], x['location']['left'])) # 提取所有文字 all_texts = [item['text'] for item in sorted_results] # 组合连续字符 combinations = [] # 单个字符 for text in all_texts: combinations.append(text) # 两个连续字符的组合 for i in range(len(all_texts) - 1): combinations.append(all_texts[i] + all_texts[i + 1]) # 三个连续字符的组合 for i in range(len(all_texts) - 2): combinations.append(all_texts[i] + all_texts[i + 1] + all_texts[i + 2]) # 四个连续字符的组合 for i in range(len(all_texts) - 3): combinations.append(all_texts[i] + all_texts[i + 1] + all_texts[i + 2] + all_texts[i + 3]) # 完整文本序列 full_text = ''.join(all_texts) combinations.append(full_text) return combinations def match_target_labels(self, ocr_results: List[Dict]) -> List[Dict]: """ 匹配目标标签 Args: ocr_results: OCR识别结果列表 Returns: 匹配到的标签列表 """ matched_labels = [] print("\n开始匹配目标标签...") # 直接匹配单个文字区域 for result in ocr_results: original_text = result['text'] normalized_text = self.normalize_text(original_text) print(f" 原文: '{original_text}' -> 标准化: '{normalized_text}'") for label in VALID_LABELS: normalized_label = self.normalize_text(label) if normalized_label == normalized_text: matched_labels.append({ 'label': label, 'original_text': original_text, 'confidence': result['confidence'], 'location': result['location'], 'type': 'text' }) print(f" 匹配成功: {original_text} -> {label}") break # 如果没有直接匹配,尝试连续字符组合匹配 if not matched_labels: print("\n尝试连续字符组合匹配...") combinations = self.combine_consecutive_chars(ocr_results) for combination in combinations: normalized_combination = self.normalize_text(combination) print(f"完整文本序列: '{combination}' -> 标准化: '{normalized_combination}'") for label in VALID_LABELS: normalized_label = self.normalize_text(label) if normalized_label in normalized_combination: # 计算平均位置和置信度 avg_confidence = sum(r['confidence'] for r in ocr_results) / len(ocr_results) avg_location = { 'left': int(sum(r['location']['left'] for r in ocr_results) / len(ocr_results)), 'top': int(sum(r['location']['top'] for r in ocr_results) / len(ocr_results)), 'width': int(sum(r['location']['width'] for r in ocr_results) / len(ocr_results)), 'height': int(sum(r['location']['height'] for r in ocr_results) / len(ocr_results)) } matched_labels.append({ 'label': label, 'original_text': combination, 'confidence': avg_confidence, 'location': avg_location, 'type': 'text' }) print(f" 组合匹配成功: {combination} -> {label}") break if matched_labels: break return matched_labels def recognize_image(self, image_path: str, debug: bool = False) -> Dict: """ 识别单张图像中的目标标签 Args: image_path: 图像文件路径 debug: 是否启用调试模式 Returns: 识别结果字典 """ print(f"\n{'='*60}") print(f"开始识别图像: {image_path}") print(f"{'='*60}") # 检查文件是否存在 if not os.path.exists(image_path): # 尝试添加扩展名 found = False for ext in IMAGE_EXTS: test_path = image_path + ext if os.path.exists(test_path): image_path = test_path found = True break if not found: return {'error': f'图像文件不存在: {image_path}'} try: matched_labels = [] recognition_method = "文字识别" # 优先进行二维码识别 if self.enable_qrcode and self.qrcode_priority: print("\n优先进行二维码识别...") qr_results = self.recognize_qrcode(image_path) if qr_results: # 将二维码结果转换为匹配标签格式 for qr_info in qr_results: matched_labels.append({ 'label': qr_info['label'], 'original_text': qr_info['text'], 'confidence': qr_info['confidence'], 'location': qr_info['location'], 'type': 'qrcode' }) recognition_method = "二维码识别" print(f"二维码识别成功,找到 {len(matched_labels)} 个标签,跳过文字识别") else: print("二维码识别未找到有效标签,继续进行文字识别...") # 如果二维码识别未找到结果,或者未启用二维码识别,则进行文字识别 if not matched_labels: print("\n开始文字识别...") # 执行OCR识别 ocr_results = self.recognize_text(image_path) if not ocr_results: return {'error': '未检测到任何文字'} # 匹配目标标签 matched_labels = self.match_target_labels(ocr_results) recognition_method = "文字识别" print(f"\n匹配结果: 找到 {len(matched_labels)} 个目标标签") # 构建结果 result = { 'image_path': image_path, 'ocr_service': '混合OCR (腾讯云二维码 + 阿里云文字)', 'recognition_method': recognition_method, 'total_text_regions': len(ocr_results) if 'ocr_results' in locals() else 0, 'matched_labels': matched_labels, 'detected_labels': [match['label'] for match in matched_labels], 'success': len(matched_labels) > 0 } # 打印最终结果 print(f"\n{'='*60}") print(f"识别方法: {recognition_method}") if matched_labels: print("识别成功!检测到以下标签:") for match in matched_labels: method_type = "(二维码)" if match.get('type') == 'qrcode' else "(文字)" print(f"{match['label']} {method_type}: '{match['original_text']}' (置信度: {match['confidence']:.2f})") else: print("未识别到目标标签 (A-1, A-2, B-1, B-2)") print(f"{'='*60}") return result except Exception as e: error_msg = f"识别过程出错: {e}" print(f"{error_msg}") return {'error': error_msg} def find_image_file(image_path: str) -> str: """ 查找图像文件,支持自动添加扩展名 Args: image_path: 图像路径(可能不包含扩展名) Returns: 完整的图像文件路径,如果找不到则返回None """ # 如果文件已存在,直接返回 if os.path.exists(image_path): return image_path # 尝试添加不同的扩展名 for ext in IMAGE_EXTS: test_path = image_path + ext if os.path.exists(test_path): return test_path return None # 便捷函数 def recognize_image(image_path: str, enable_qrcode: bool = True, qrcode_priority: bool = True) -> Dict: """ 便捷的图像识别函数 Args: image_path: 图像文件路径 enable_qrcode: 是否启用二维码识别 qrcode_priority: 是否优先进行二维码识别 Returns: 识别结果字典 """ ocr = OCRRecognizer(enable_qrcode=enable_qrcode, qrcode_priority=qrcode_priority) return ocr.recognize_image(image_path) def recognize_text_only(image_path: str) -> Dict: """ 仅使用文字识别的便捷函数 Args: image_path: 图像文件路径 Returns: 识别结果字典 """ ocr = OCRRecognizer(enable_qrcode=False, qrcode_priority=False) return ocr.recognize_image(image_path) def recognize_qrcode_only(image_path: str) -> Dict: """ 仅使用二维码识别的便捷函数 Args: image_path: 图像文件路径 Returns: 识别结果字典 """ ocr = OCRRecognizer(enable_qrcode=True, qrcode_priority=True) # 临时禁用文字识别回退 original_method = ocr.recognize_image def qrcode_only_recognize(image_path: str, debug: bool = False) -> Dict: print(f"\n{'='*60}") print(f"开始二维码识别: {image_path}") print(f"{'='*60}") if not os.path.exists(image_path): for ext in IMAGE_EXTS: test_path = image_path + ext if os.path.exists(test_path): image_path = test_path break else: return {'error': f'图像文件不存在: {image_path}'} try: qr_results = ocr.recognize_qrcode(image_path) matched_labels = [] if qr_results: for qr_info in qr_results: matched_labels.append({ 'label': qr_info['label'], 'original_text': qr_info['text'], 'confidence': qr_info['confidence'], 'location': qr_info['location'], 'type': 'qrcode' }) result = { 'image_path': image_path, 'ocr_service': '腾讯云二维码识别', 'recognition_method': '二维码识别', 'total_text_regions': 0, 'matched_labels': matched_labels, 'detected_labels': [match['label'] for match in matched_labels], 'success': len(matched_labels) > 0 } print(f"\n{'='*60}") if matched_labels: print("二维码识别成功!检测到以下标签:") for match in matched_labels: print(f"{match['label']} (二维码): '{match['original_text']}' (置信度: {match['confidence']:.2f})") else: print("未识别到目标标签 (A-1, A-2, B-1, B-2)") print(f"{'='*60}") return result except Exception as e: error_msg = f"二维码识别过程出错: {e}" print(f"{error_msg}") return {'error': error_msg} return qrcode_only_recognize(image_path)将上述的程序中使用阿里云密钥的替换成我的密钥
最新发布
08-17
{ // DHCPv4 configuration starts here. This section will be read by DHCPv4 server // and will be ignored by other components. "Control-agent": { "http-host": "localhost", "http-port": 8000 }, "Dhcp4": { "interfaces-config": { "interfaces": [ "enp3s0f0" ] }, "control-socket": { "socket-type": "unix", "socket-name": "/path/to/kea4-ctrl-socket" }, } "Dhcp4": { // Add names of your network interfaces to listen on. "interfaces-config": { // See section 8.2.4 for more details. You probably want to add just // interface name (e.g. "eth0" or specific IPv4 address on that // interface name (e.g. "eth0/192.0.2.1"). "interfaces": ["enp3s0f1/192.168.100.1"] // Kea DHCPv4 server by default listens using raw sockets. This ensures // all packets, including those sent by directly connected clients // that don't have IPv4 address yet, are received. However, if your // traffic is always relayed, it is often better to use regular // UDP sockets. If you want to do that, uncomment this line: // "dhcp-socket-type": "udp" }, // Kea supports control channel, which is a way to receive management // commands while the server is running. This is a Unix domain socket that // receives commands formatted in JSON, e.g. config-set (which sets new // configuration), config-reload (which tells Kea to reload its // configuration from file), statistic-get (to retrieve statistics) and many // more. For detailed description, see Sections 8.8, 16 and 15. "control-socket": { "socket-type": "unix", "socket-name": "kea4-ctrl-socket" }, // Use Memfile lease database backend to store leases in a CSV file. // Depending on how Kea was compiled, it may also support SQL databases // (MySQL and/or PostgreSQL). Those database backends require more // parameters, like name, host and possibly user and password. // There are dedicated examples for each backend. See Section 7.2.2 "Lease // Storage" for details. "lease-database": { // Memfile is the simplest and easiest backend to use. It's an in-memory // C++ database that stores its state in CSV file. "type": "memfile", "lfc-interval": 3600 }, // Kea allows storing host reservations in a database. If your network is // small or you have few reservations, it's probably easier to keep them // in the configuration file. If your network is large, it's usually better // to use database for it. To enable it, uncomment the following: // "hosts-database": { // "type": "mysql", // "name": "kea", // "user": "kea", // "password": "1234", // "host": "localhost", // "port": 3306 // }, // See Section 7.2.3 "Hosts storage" for details. // Setup reclamation of the expired leases and leases affinity. // Expired leases will be reclaimed every 10 seconds. Every 25 // seconds reclaimed leases, which have expired more than 3600 // seconds ago, will be removed. The limits for leases reclamation // are 100 leases or 250 ms for a single cycle. A warning message // will be logged if there are still expired leases in the // database after 5 consecutive reclamation cycles. // If both "flush-reclaimed-timer-wait-time" and "hold-reclaimed-time" are // not 0, when the client sends a release message the lease is expired // instead of being deleted from the lease storage. "expired-leases-processing": { "reclaim-timer-wait-time": 10, "flush-reclaimed-timer-wait-time": 25, "hold-reclaimed-time": 3600, "max-reclaim-leases": 100, "max-reclaim-time": 250, "unwarned-reclaim-cycles": 5 }, // Global timers specified here apply to all subnets, unless there are // subnet specific values defined in particular subnets. "renew-timer": 900, "rebind-timer": 60, "valid-lifetime": 3600, // Many additional parameters can be specified here: // - option definitions (if you want to define vendor options, your own // custom options or perhaps handle standard options // that Kea does not support out of the box yet) // - client classes // - hooks // - ddns information (how the DHCPv4 component can reach a DDNS daemon) // // Some of them have examples below, but there are other parameters. // Consult Kea User's Guide to find out about them. // These are global options. They are going to be sent when a client // requests them, unless overwritten with values in more specific scopes. // The scope hierarchy is: // - global (most generic, can be overwritten by class, subnet or host) // - class (can be overwritten by subnet or host) // - subnet (can be overwritten by host) // - host (most specific, overwrites any other scopes) // // Not all of those options make sense. Please configure only those that // are actually useful in your network. // // For a complete list of options currently supported by Kea, see // Section 7.2.8 "Standard DHCPv4 Options". Kea also supports // vendor options (see Section 7.2.10) and allows users to define their // own custom options (see Section 7.2.9). "option-data": [ // When specifying options, you typically need to specify // one of (name or code) and data. The full option specification // covers name, code, space, csv-format and data. // space defaults to "dhcp4" which is usually correct, unless you // use encapsulate options. csv-format defaults to "true", so // this is also correct, unless you want to specify the whole // option value as long hex string. For example, to specify // domain-name-servers you could do this: // { // "name": "domain-name-servers", // "code": 6, // "csv-format": "true", // "space": "dhcp4", // "data": "192.0.2.1, 192.0.2.2" // } // but it's a lot of writing, so it's easier to do this instead: { "name": "domain-name-servers", "data": "192.0.2.1, 192.0.2.2" }, // Typically people prefer to refer to options by their names, so they // don't need to remember the code names. However, some people like // to use numerical values. For example, option "domain-name" uses // option code 15, so you can reference to it either by // "name": "domain-name" or "code": 15. { "code": 15, "data": "example.org" }, // Domain search is also a popular option. It tells the client to // attempt to resolve names within those specified domains. For // example, name "foo" would be attempted to be resolved as // foo.mydomain.example.com and if it fails, then as foo.example.com { "name": "domain-search", "data": "mydomain.example.com, example.com" }, // String options that have a comma in their values need to have // it escaped (i.e. each comma is preceded by two backslashes). // That's because commas are reserved for separating fields in // compound options. At the same time, we need to be conformant // with JSON spec, that does not allow "\,". Therefore the // slightly uncommon double backslashes notation is needed. // Legal JSON escapes are \ followed by "\/bfnrt character // or \u followed by 4 hexadecimal numbers (currently Kea // supports only \u0000 to \u00ff code points). // CSV processing translates '\\' into '\' and '\,' into ',' // only so for instance '\x' is translated into '\x'. But // as it works on a JSON string value each of these '\' // characters must be doubled on JSON input. { "name": "boot-file-name", "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00" }, // Options that take integer values can either be specified in // dec or hex format. Hex format could be either plain (e.g. abcd) // or prefixed with 0x (e.g. 0xabcd). { "name": "default-ip-ttl", "data": "0xf0" } // Note that Kea provides some of the options on its own. In particular, // it sends IP Address lease type (code 51, based on valid-lifetime // parameter, Subnet mask (code 1, based on subnet definition), Renewal // time (code 58, based on renew-timer parameter), Rebind time (code 59, // based on rebind-timer parameter). ], // Other global parameters that can be defined here are option definitions // (this is useful if you want to use vendor options, your own custom // options or perhaps handle options that Kea does not handle out of the box // yet). // You can also define classes. If classes are defined, incoming packets // may be assigned to specific classes. A client class can represent any // group of devices that share some common characteristic, e.g. Windows // devices, iphones, broken printers that require special options, etc. // Based on the class information, you can then allow or reject clients // to use certain subnets, add special options for them or change values // of some fixed fields. "client-classes": [ { // This specifies a name of this class. It's useful if you need to // reference this class. "name": "voip", // This is a test. It is an expression that is being evaluated on // each incoming packet. It is supposed to evaluate to either // true or false. If it's true, the packet is added to specified // class. See Section 12 for a list of available expressions. There // are several dozens. Section 8.2.14 for more details for DHCPv4 // classification and Section 9.2.19 for DHCPv6. "test": "substring(option[60].hex,0,6) == 'Aastra'", // If a client belongs to this class, you can define extra behavior. // For example, certain fields in DHCPv4 packet will be set to // certain values. "next-server": "192.0.2.254", "server-hostname": "hal9000", "boot-file-name": "/dev/null" // You can also define option values here if you want devices from // this class to receive special options. } ], // Another thing possible here are hooks. Kea supports a powerful mechanism // that allows loading external libraries that can extract information and // even influence how the server processes packets. Those libraries include // additional forensic logging capabilities, ability to reserve hosts in // more flexible ways, and even add extra commands. For a list of available // hook libraries, see https://gitlab.isc.org/isc-projects/kea/wikis/Hooks-available. "hooks-libraries":[ { "library": "/usr/local/lib64/kea/hooks/libdhcp_macauth.so", "parameters": { "server_ip": "10.10.10.1", "ac_ip": "10.10.10.102", "port": 5001, "shared_secret": "7a5b8c3e9f" } }, { "library": "/usr/local/lib64/kea/hooks/libdhcp_lease_cmds.so" } //{ // "library": "/usr/local/lib64/kea/hooks/libdhcp_lease_query.so" // } ], // "hooks-libraries": [ // { // // Forensic Logging library generates forensic type of audit trail // // of all devices serviced by Kea, including their identifiers // // (like MAC address), their location in the network, times // // when they were active etc. // "library": "/usr/local/lib64/kea/hooks/libdhcp_legal_log.so", // "parameters": { // "base-name": "kea-forensic4" // } // }, // { // // Flexible identifier (flex-id). Kea software provides a way to // // handle host reservations that include addresses, prefixes, // // options, client classes and other features. The reservation can // // be based on hardware address, DUID, circuit-id or client-id in // // DHCPv4 and using hardware address or DUID in DHCPv6. However, // // there are sometimes scenario where the reservation is more // // complex, e.g. uses other options that mentioned above, uses part // // of specific options or perhaps even a combination of several // // options and fields to uniquely identify a client. Those scenarios // // are addressed by the Flexible Identifiers hook application. // "library": "/usr/local/lib64/kea/hooks/libdhcp_flex_id.so", // "parameters": { // "identifier-expression": "relay4[2].hex" // } // }, // { // // the MySQL host backend hook library required for host storage. // "library": "/usr/local/lib64/kea/hooks/libdhcp_mysql.so" // } // ], // Below an example of a simple IPv4 subnet declaration. Uncomment to enable // it. This is a list, denoted with [ ], of structures, each denoted with // { }. Each structure describes a single subnet and may have several // parameters. One of those parameters is "pools" that is also a list of // structures. "subnet4": [ { // This defines the whole subnet. Kea will use this information to // determine where the clients are connected. This is the whole // subnet in your network. // Subnet identifier should be unique for each subnet. "id": 1, // This is mandatory parameter for each subnet. "subnet": "192.168.30.0/24", // Pools define the actual part of your subnet that is governed // by Kea. Technically this is optional parameter, but it's // almost always needed for DHCP to do its job. If you omit it, // clients won't be able to get addresses, unless there are // host reservations defined for them. "pools": [ { "pool": "192.168.30.10 - 192.168.30.200" } ], // This is one of the subnet selectors. Uncomment the "interface" // parameter and specify the appropriate interface name if the DHCPv4 // server will receive requests from local clients (connected to the // same subnet as the server). This subnet will be selected for the // requests received by the server over the specified interface. // This rule applies to the DORA exchanges and rebinding clients. // Renewing clients unicast their messages, and the renewed addresses // are used by the server to determine the subnet they belong to. // When this parameter is used, the "relay" parameter is typically // unused. // "interface": "eth0", // This is another subnet selector. Uncomment the "relay" parameter // and specify a list of the relay addresses. The server will select // this subnet for lease assignments when it receives queries over one // of these relays. When this parameter is used, the "interface" parameter // is typically unused. // "relay": { // "ip-addresses": [ "10.0.0.1" ] // }, // These are options that are subnet specific. In most cases, // you need to define at least routers option, as without this // option your clients will not be able to reach their default // gateway and will not have Internet connectivity. "option-data": [ { // For each IPv4 subnet you most likely need to specify at // least one router. "name": "routers", "data": "192.0.2.1" } ], // Kea offers host reservations mechanism. Kea supports reservations // by several different types of identifiers: hw-address // (hardware/MAC address of the client), duid (DUID inserted by the // client), client-id (client identifier inserted by the client) and // circuit-id (circuit identifier inserted by the relay agent). // // Kea also support flexible identifier (flex-id), which lets you // specify an expression that is evaluated for each incoming packet. // Resulting value is then used for as an identifier. // // Note that reservations are subnet-specific in Kea. This is // different than ISC DHCP. Keep that in mind when migrating // your configurations. "reservations": [ // This is a reservation for a specific hardware/MAC address. // It's a rather simple reservation: just an address and nothing // else. // { // "hw-address": "1a:1b:1c:1d:1e:1f", // "ip-address": "192.0.2.201" // }, // This is a reservation for a specific client-id. It also shows // the this client will get a reserved hostname. A hostname can // be defined for any identifier type, not just client-id. { "client-id": "01:11:22:33:44:55:66", "ip-address": "192.168.30.202", "hostname": "special-snowflake" }, // The third reservation is based on DUID. This reservation defines // a special option values for this particular client. If the // domain-name-servers option would have been defined on a global, // subnet or class level, the host specific values take preference. { "duid": "01:02:03:04:05", "ip-address": "192.168.30.203", "option-data": [ { "name": "domain-name-servers", "data": "10.1.1.202, 10.1.1.203" } ] }, // The fourth reservation is based on circuit-id. This is an option // inserted by the relay agent that forwards the packet from client // to the server. In this example the host is also assigned vendor // specific options. // // When using reservations, it is useful to configure // reservations-global, reservations-in-subnet, // reservations-out-of-pool (subnet specific parameters) // and host-reservation-identifiers (global parameter). { "client-id": "01:12:23:34:45:56:67", "ip-address": "192.168.30.204", "option-data": [ { "name": "vivso-suboptions", "data": "4491" }, { "name": "tftp-servers", "space": "vendor-4491", "data": "10.1.1.202, 10.1.1.203" } ] }, // This reservation is for a client that needs specific DHCPv4 // fields to be set. Three supported fields are next-server, // server-hostname and boot-file-name { "client-id": "01:0a:0b:0c:0d:0e:0f", "ip-address": "192.168.30.205", "next-server": "192.168.30.1", "server-hostname": "hal9000", "boot-file-name": "/dev/null" }, // This reservation is using flexible identifier. Instead of // relying on specific field, sysadmin can define an expression // similar to what is used for client classification, // e.g. substring(relay[0].option[17],0,6). Then, based on the // value of that expression for incoming packet, the reservation // is matched. Expression can be specified either as hex or // plain text using single quotes. // // Note: flexible identifier requires flex_id hook library to be // loaded to work. { "flex-id": "'s0mEVaLue'", "ip-address": "192.168.30.206" } // You can add more reservations here. ] // You can add more subnets there. }, { "subnet": "192.168.100.0/24", "id":100, "pools": [ { "pool": "192.168.100.100 - 192.168.100.200" } ], "option-data": [ { "name": "routers", "data": "192.168.100.2" }, { "name": "domain-name-servers", "data": "8.8.8.8, 8.8.4.4" } ] }, { "subnet": "192.168.10.0/24", "id":10, "pools": [ { "pool": "192.168.10.100 - 192.168.10.200" } ], "relay": { "ip-addresses": ["192.168.10.1"] }, "option-data": [ { "name": "routers", "data": "192.168.10.1" }, { "name": "domain-name-servers", "data": "114.114.114.114,8.8.8.8" } ] }, { "id":20, "subnet": "192.168.20.0/24", "pools": [ { "pool": "192.168.20.100 - 192.168.20.200" } ], "relay": { "ip-addresses": ["192.168.20.1"] }, "option-data": [ { "name": "routers", "data": "192.168.20.1" }, { "name": "domain-name-servers", "data": "114.114.114.114, 8.8.4.4" } ] } ], // There are many, many more parameters that DHCPv4 server is able to use. // They were not added here to not overwhelm people with too much // information at once. // Logging configuration starts here. Kea uses different loggers to log various // activities. For details (e.g. names of loggers), see Chapter 18. "loggers": [ { // This section affects kea-dhcp4, which is the base logger for DHCPv4 // component. It tells DHCPv4 server to write all log messages (on // severity INFO or more) to a file. "name": "kea-dhcp4", "output-options": [ { // Specifies the output file. There are several special values // supported: // - stdout (prints on standard output) // - stderr (prints on standard error) // - syslog (logs to syslog) // - syslog:name (logs to syslog using specified name) // Any other value is considered a name of the file "output": "kea-dhcp4.log" // Shorter log pattern suitable for use with systemd, // avoids redundant information // "pattern": "%-5p %m\n", // This governs whether the log output is flushed to disk after // every write. // "flush": false, // This specifies the maximum size of the file before it is // rotated. // "maxsize": 1048576, // This specifies the maximum number of rotated files to keep. // "maxver": 8 } ], // This specifies the severity of log messages to keep. Supported values // are: FATAL, ERROR, WARN, INFO, DEBUG "severity": "INFO", // If DEBUG level is specified, this value is used. 0 is least verbose, // 99 is most verbose. Be cautious, Kea can generate lots and lots // of logs if told to do so. "debuglevel": 0 } ] } } 查看以上配置文件查看看dhcp配置接口开放配置有什么问题及语法错误并修复
08-15
"Control-agent": { "http-host": "localhost", "http-port": 8000 }, "Dhcp4": { "interfaces-config": { "interfaces": [ "enp3s0f0" ] }, "control-socket": { "socket-type": "unix", "socket-name": "/path/to/kea4-ctrl-socket" }, } "Dhcp4": { // Add names of your network interfaces to listen on. "interfaces-config": { // See section 8.2.4 for more details. You probably want to add just // interface name (e.g. "eth0" or specific IPv4 address on that // interface name (e.g. "eth0/192.0.2.1"). "interfaces": ["enp3s0f1/192.168.100.1"] // Kea DHCPv4 server by default listens using raw sockets. This ensures // all packets, including those sent by directly connected clients // that don't have IPv4 address yet, are received. However, if your // traffic is always relayed, it is often better to use regular // UDP sockets. If you want to do that, uncomment this line: // "dhcp-socket-type": "udp" }, // Kea supports control channel, which is a way to receive management // commands while the server is running. This is a Unix domain socket that // receives commands formatted in JSON, e.g. config-set (which sets new // configuration), config-reload (which tells Kea to reload its // configuration from file), statistic-get (to retrieve statistics) and many // more. For detailed description, see Sections 8.8, 16 and 15. "control-socket": { "socket-type": "unix", "socket-name": "kea4-ctrl-socket" }, // Use Memfile lease database backend to store leases in a CSV file. // Depending on how Kea was compiled, it may also support SQL databases // (MySQL and/or PostgreSQL). Those database backends require more // parameters, like name, host and possibly user and password. // There are dedicated examples for each backend. See Section 7.2.2 "Lease // Storage" for details. "lease-database": { // Memfile is the simplest and easiest backend to use. It's an in-memory // C++ database that stores its state in CSV file. "type": "memfile", "lfc-interval": 3600 }, // Kea allows storing host reservations in a database. If your network is // small or you have few reservations, it's probably easier to keep them // in the configuration file. If your network is large, it's usually better // to use database for it. To enable it, uncomment the following: // "hosts-database": { // "type": "mysql", // "name": "kea", // "user": "kea", // "password": "1234", // "host": "localhost", // "port": 3306 // }, // See Section 7.2.3 "Hosts storage" for details. // Setup reclamation of the expired leases and leases affinity. // Expired leases will be reclaimed every 10 seconds. Every 25 // seconds reclaimed leases, which have expired more than 3600 // seconds ago, will be removed. The limits for leases reclamation // are 100 leases or 250 ms for a single cycle. A warning message // will be logged if there are still expired leases in the // database after 5 consecutive reclamation cycles. // If both "flush-reclaimed-timer-wait-time" and "hold-reclaimed-time" are // not 0, when the client sends a release message the lease is expired // instead of being deleted from the lease storage. "expired-leases-processing": { "reclaim-timer-wait-time": 10, "flush-reclaimed-timer-wait-time": 25, "hold-reclaimed-time": 3600, "max-reclaim-leases": 100, "max-reclaim-time": 250, "unwarned-reclaim-cycles": 5 }, // Global timers specified here apply to all subnets, unless there are // subnet specific values defined in particular subnets. "renew-timer": 900, "rebind-timer": 60, "valid-lifetime": 3600, // Many additional parameters can be specified here: // - option definitions (if you want to define vendor options, your own // custom options or perhaps handle standard options // that Kea does not support out of the box yet) // - client classes // - hooks // - ddns information (how the DHCPv4 component can reach a DDNS daemon) // // Some of them have examples below, but there are other parameters. // Consult Kea User's Guide to find out about them. // These are global options. They are going to be sent when a client // requests them, unless overwritten with values in more specific scopes. // The scope hierarchy is: // - global (most generic, can be overwritten by class, subnet or host) // - class (can be overwritten by subnet or host) // - subnet (can be overwritten by host) // - host (most specific, overwrites any other scopes) // // Not all of those options make sense. Please configure only those that // are actually useful in your network. // // For a complete list of options currently supported by Kea, see // Section 7.2.8 "Standard DHCPv4 Options". Kea also supports // vendor options (see Section 7.2.10) and allows users to define their // own custom options (see Section 7.2.9). "option-data": [ // When specifying options, you typically need to specify // one of (name or code) and data. The full option specification // covers name, code, space, csv-format and data. // space defaults to "dhcp4" which is usually correct, unless you // use encapsulate options. csv-format defaults to "true", so // this is also correct, unless you want to specify the whole // option value as long hex string. For example, to specify // domain-name-servers you could do this: // { // "name": "domain-name-servers", // "code": 6, // "csv-format": "true", // "space": "dhcp4", // "data": "192.0.2.1, 192.0.2.2" // } // but it's a lot of writing, so it's easier to do this instead: { "name": "domain-name-servers", "data": "192.0.2.1, 192.0.2.2" }, // Typically people prefer to refer to options by their names, so they // don't need to remember the code names. However, some people like // to use numerical values. For example, option "domain-name" uses // option code 15, so you can reference to it either by // "name": "domain-name" or "code": 15. { "code": 15, "data": "example.org" }, // Domain search is also a popular option. It tells the client to // attempt to resolve names within those specified domains. For // example, name "foo" would be attempted to be resolved as // foo.mydomain.example.com and if it fails, then as foo.example.com { "name": "domain-search", "data": "mydomain.example.com, example.com" }, // String options that have a comma in their values need to have // it escaped (i.e. each comma is preceded by two backslashes). // That's because commas are reserved for separating fields in // compound options. At the same time, we need to be conformant // with JSON spec, that does not allow "\,". Therefore the // slightly uncommon double backslashes notation is needed. // Legal JSON escapes are \ followed by "\/bfnrt character // or \u followed by 4 hexadecimal numbers (currently Kea // supports only \u0000 to \u00ff code points). // CSV processing translates '\\' into '\' and '\,' into ',' // only so for instance '\x' is translated into '\x'. But // as it works on a JSON string value each of these '\' // characters must be doubled on JSON input. { "name": "boot-file-name", "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00" }, // Options that take integer values can either be specified in // dec or hex format. Hex format could be either plain (e.g. abcd) // or prefixed with 0x (e.g. 0xabcd). { "name": "default-ip-ttl", "data": "0xf0" } // Note that Kea provides some of the options on its own. In particular, // it sends IP Address lease type (code 51, based on valid-lifetime // parameter, Subnet mask (code 1, based on subnet definition), Renewal // time (code 58, based on renew-timer parameter), Rebind time (code 59, // based on rebind-timer parameter). ], // Other global parameters that can be defined here are option definitions // (this is useful if you want to use vendor options, your own custom // options or perhaps handle options that Kea does not handle out of the box // yet). // You can also define classes. If classes are defined, incoming packets // may be assigned to specific classes. A client class can represent any // group of devices that share some common characteristic, e.g. Windows // devices, iphones, broken printers that require special options, etc. // Based on the class information, you can then allow or reject clients // to use certain subnets, add special options for them or change values // of some fixed fields. "client-classes": [ { // This specifies a name of this class. It's useful if you need to // reference this class. "name": "voip", // This is a test. It is an expression that is being evaluated on // each incoming packet. It is supposed to evaluate to either // true or false. If it's true, the packet is added to specified // class. See Section 12 for a list of available expressions. There // are several dozens. Section 8.2.14 for more details for DHCPv4 // classification and Section 9.2.19 for DHCPv6. "test": "substring(option[60].hex,0,6) == 'Aastra'", // If a client belongs to this class, you can define extra behavior. // For example, certain fields in DHCPv4 packet will be set to // certain values. "next-server": "192.0.2.254", "server-hostname": "hal9000", "boot-file-name": "/dev/null" // You can also define option values here if you want devices from // this class to receive special options. } ], // Another thing possible here are hooks. Kea supports a powerful mechanism // that allows loading external libraries that can extract information and // even influence how the server processes packets. Those libraries include // additional forensic logging capabilities, ability to reserve hosts in // more flexible ways, and even add extra commands. For a list of available // hook libraries, see https://gitlab.isc.org/isc-projects/kea/wikis/Hooks-available. "hooks-libraries":[ { "library": "/usr/local/lib64/kea/hooks/libdhcp_macauth.so", "parameters": { "server_ip": "10.10.10.1", "ac_ip": "10.10.10.102", "port": 5001, "shared_secret": "7a5b8c3e9f" } }, { "library": "/usr/local/lib64/kea/hooks/libdhcp_lease_cmds.so" } //{ // "library": "/usr/local/lib64/kea/hooks/libdhcp_lease_query.so" // } ], // "hooks-libraries": [ // { // // Forensic Logging library generates forensic type of audit trail // // of all devices serviced by Kea, including their identifiers // // (like MAC address), their location in the network, times // // when they were active etc. // "library": "/usr/local/lib64/kea/hooks/libdhcp_legal_log.so", // "parameters": { // "base-name": "kea-forensic4" // } // }, // { // // Flexible identifier (flex-id). Kea software provides a way to // // handle host reservations that include addresses, prefixes, // // options, client classes and other features. The reservation can // // be based on hardware address, DUID, circuit-id or client-id in // // DHCPv4 and using hardware address or DUID in DHCPv6. However, // // there are sometimes scenario where the reservation is more // // complex, e.g. uses other options that mentioned above, uses part // // of specific options or perhaps even a combination of several // // options and fields to uniquely identify a client. Those scenarios // // are addressed by the Flexible Identifiers hook application. // "library": "/usr/local/lib64/kea/hooks/libdhcp_flex_id.so", // "parameters": { // "identifier-expression": "relay4[2].hex" // } // }, // { // // the MySQL host backend hook library required for host storage. // "library": "/usr/local/lib64/kea/hooks/libdhcp_mysql.so" // } // ], // Below an example of a simple IPv4 subnet declaration. Uncomment to enable // it. This is a list, denoted with [ ], of structures, each denoted with // { }. Each structure describes a single subnet and may have several // parameters. One of those parameters is "pools" that is also a list of // structures. "subnet4": [ { // This defines the whole subnet. Kea will use this information to // determine where the clients are connected. This is the whole // subnet in your network. // Subnet identifier should be unique for each subnet. "id": 1, // This is mandatory parameter for each subnet. "subnet": "192.168.30.0/24", // Pools define the actual part of your subnet that is governed // by Kea. Technically this is optional parameter, but it's // almost always needed for DHCP to do its job. If you omit it, // clients won't be able to get addresses, unless there are // host reservations defined for them. "pools": [ { "pool": "192.168.30.10 - 192.168.30.200" } ], // This is one of the subnet selectors. Uncomment the "interface" // parameter and specify the appropriate interface name if the DHCPv4 // server will receive requests from local clients (connected to the // same subnet as the server). This subnet will be selected for the // requests received by the server over the specified interface. // This rule applies to the DORA exchanges and rebinding clients. // Renewing clients unicast their messages, and the renewed addresses // are used by the server to determine the subnet they belong to. // When this parameter is used, the "relay" parameter is typically // unused. // "interface": "eth0", // This is another subnet selector. Uncomment the "relay" parameter // and specify a list of the relay addresses. The server will select // this subnet for lease assignments when it receives queries over one // of these relays. When this parameter is used, the "interface" parameter // is typically unused. // "relay": { // "ip-addresses": [ "10.0.0.1" ] // }, // These are options that are subnet specific. In most cases, // you need to define at least routers option, as without this // option your clients will not be able to reach their default // gateway and will not have Internet connectivity. "option-data": [ { // For each IPv4 subnet you most likely need to specify at // least one router. "name": "routers", "data": "192.0.2.1" } ], // Kea offers host reservations mechanism. Kea supports reservations // by several different types of identifiers: hw-address // (hardware/MAC address of the client), duid (DUID inserted by the // client), client-id (client identifier inserted by the client) and // circuit-id (circuit identifier inserted by the relay agent). // // Kea also support flexible identifier (flex-id), which lets you // specify an expression that is evaluated for each incoming packet. // Resulting value is then used for as an identifier. // // Note that reservations are subnet-specific in Kea. This is // different than ISC DHCP. Keep that in mind when migrating // your configurations. "reservations": [ // This is a reservation for a specific hardware/MAC address. // It's a rather simple reservation: just an address and nothing // else. // { // "hw-address": "1a:1b:1c:1d:1e:1f", // "ip-address": "192.0.2.201" // }, // This is a reservation for a specific client-id. It also shows // the this client will get a reserved hostname. A hostname can // be defined for any identifier type, not just client-id. { "client-id": "01:11:22:33:44:55:66", "ip-address": "192.168.30.202", "hostname": "special-snowflake" }, // The third reservation is based on DUID. This reservation defines // a special option values for this particular client. If the // domain-name-servers option would have been defined on a global, // subnet or class level, the host specific values take preference. { "duid": "01:02:03:04:05", "ip-address": "192.168.30.203", "option-data": [ { "name": "domain-name-servers", "data": "10.1.1.202, 10.1.1.203" } ] }, // The fourth reservation is based on circuit-id. This is an option // inserted by the relay agent that forwards the packet from client // to the server. In this example the host is also assigned vendor // specific options. // // When using reservations, it is useful to configure // reservations-global, reservations-in-subnet, // reservations-out-of-pool (subnet specific parameters) // and host-reservation-identifiers (global parameter). { "client-id": "01:12:23:34:45:56:67", "ip-address": "192.168.30.204", "option-data": [ { "name": "vivso-suboptions", "data": "4491" }, { "name": "tftp-servers", "space": "vendor-4491", "data": "10.1.1.202, 10.1.1.203" } ] }, // This reservation is for a client that needs specific DHCPv4 // fields to be set. Three supported fields are next-server, // server-hostname and boot-file-name { "client-id": "01:0a:0b:0c:0d:0e:0f", "ip-address": "192.168.30.205", "next-server": "192.168.30.1", "server-hostname": "hal9000", "boot-file-name": "/dev/null" }, // This reservation is using flexible identifier. Instead of // relying on specific field, sysadmin can define an expression // similar to what is used for client classification, // e.g. substring(relay[0].option[17],0,6). Then, based on the // value of that expression for incoming packet, the reservation // is matched. Expression can be specified either as hex or // plain text using single quotes. // // Note: flexible identifier requires flex_id hook library to be // loaded to work. { "flex-id": "'s0mEVaLue'", "ip-address": "192.168.30.206" } // You can add more reservations here. ] // You can add more subnets there. }, { "subnet": "192.168.100.0/24", "id":100, "pools": [ { "pool": "192.168.100.100 - 192.168.100.200" } ], "option-data": [ { "name": "routers", "data": "192.168.100.2" }, { "name": "domain-name-servers", "data": "8.8.8.8, 8.8.4.4" } ] }, { "subnet": "192.168.10.0/24", "id":10, "pools": [ { "pool": "192.168.10.100 - 192.168.10.200" } ], "relay": { "ip-addresses": ["192.168.10.1"] }, "option-data": [ { "name": "routers", "data": "192.168.10.1" }, { "name": "domain-name-servers", "data": "114.114.114.114,8.8.8.8" } ] }, { "id":20, "subnet": "192.168.20.0/24", "pools": [ { "pool": "192.168.20.100 - 192.168.20.200" } ], "relay": { "ip-addresses": ["192.168.20.1"] }, "option-data": [ { "name": "routers", "data": "192.168.20.1" }, { "name": "domain-name-servers", "data": "114.114.114.114, 8.8.4.4" } ] } ], // There are many, many more parameters that DHCPv4 server is able to use. // They were not added here to not overwhelm people with too much // information at once. // Logging configuration starts here. Kea uses different loggers to log various // activities. For details (e.g. names of loggers), see Chapter 18. "loggers": [ { // This section affects kea-dhcp4, which is the base logger for DHCPv4 // component. It tells DHCPv4 server to write all log messages (on // severity INFO or more) to a file. "name": "kea-dhcp4", "output-options": [ { // Specifies the output file. There are several special values // supported: // - stdout (prints on standard output) // - stderr (prints on standard error) // - syslog (logs to syslog) // - syslog:name (logs to syslog using specified name) // Any other value is considered a name of the file "output": "kea-dhcp4.log" // Shorter log pattern suitable for use with systemd, // avoids redundant information // "pattern": "%-5p %m\n", // This governs whether the log output is flushed to disk after // every write. // "flush": false, // This specifies the maximum size of the file before it is // rotated. // "maxsize": 1048576, // This specifies the maximum number of rotated files to keep. // "maxver": 8 } ], // This specifies the severity of log messages to keep. Supported values // are: FATAL, ERROR, WARN, INFO, DEBUG "severity": "INFO", // If DEBUG level is specified, this value is used. 0 is least verbose, // 99 is most verbose. Be cautious, Kea can generate lots and lots // of logs if told to do so. "debuglevel": 0 } ] } } 查看以上代码判断其是否有错误点并纠正过来
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值